Search code examples
pythonconfigparser

configparser does not show sections


I added sections and its values to ini file, but configparser doesn't want to print what sections I have in total. What I've done:

import configparser
import os


# creating path
current_path = os.getcwd()
path = 'ini'
try:
    os.mkdir(path)
except OSError:
    print("Creation of the directory %s failed" % path)


# add section and its values
config = configparser.ConfigParser()
config['section-1'] = {'somekey' : 'somevalue'}
file = open(f'ini/inifile.ini', 'a')
with file as f:
    config.write(f)
file.close()

# get sections
config = configparser.ConfigParser()
file = open(f'ini/inifile.ini')
with file as f:
    config.read(f)
    print(config.sections())
file.close()

returns

[]

The similar code was in the documentation, but doesn't work. What I do wrong and how I could solve this problem?


Solution

  • From the docs, config.read() takes in a filename (or list of them), not a file descriptor object:

    read(filenames, encoding=None)

    Attempt to read and parse an iterable of filenames, returning a list of filenames which were successfully parsed.

    If filenames is a string, a bytes object or a path-like object, it is treated as a single filename. ...

    If none of the named files exist, the ConfigParser instance will contain an empty dataset. ...

    A file object is an iterable of strings, so basically the config parser is trying to read each string in the file as a filename. Which is sort of interesting and silly, because if you passed it a file that contained the filename of your actual config...it would work.

    Anyways, you should pass the filename directly to config.read(), i.e. config.read("ini/inifile.ini")

    Or, if you want to use a file descriptor object instead, simply use config.read_file(f). Read the docs for read_file() for more information.


    As an aside, you are duplicating some of the work the context manager is doing for no gain. You can use the with block without creating the object explicitly first or closing it after (it will get closed automatically). Keep it simple:

    with open("path/to/file.txt") as f:
        do_stuff_with_file(f)