configparser.ConfigParser().write(...) creates 2 empty lines at the end of my file

I have created a config.ini file by using configparser.ConfigParser. The contents (i.e., the config items) have been written to the config.ini file using the write() method of configparser.ConfigParser.

I am very pedantic and I dislike the fact that there are 2 empty lines at the end of my config.ini file instead of just 1 empty line.

How can I remedy that?

Do you guys also get this strange behavior when you use write() of configparser.ConfigParser?

Hi Bostjan,
Just read the file as text and use .strip should do it :wink:
Nacho

To note, if you take that approach, you’ll want to make sure to add back a single end of file newline.

Also, to avoid an extra read and write from the file, you could write to a StringIO object, then strip and + "\n" the string, then write that to an actual file on disk.

My 2 cents: YAGNI. “Practicality beats purity.”

Thanks for your input, but still – why does the write() method of configparser.ConfigParser do this? Is it a possible bug in this particular method?

1 Like

Python’s source code is usually very readable: cpython/configparser.py at bad86a621af61f383b9f06fe4a08f66245df99e2 · python/cpython · GitHub

As you can see there, write just calls self._write_section for each section. As you can check, _write_section prints each line ending with "\n", and then finally prints an extra "\n" so we can have one empty line between each section.

Definetely not a “bug”, though I agree it would be better if the file didn’t end with "\n\n". Personally, I would remove the final write("\n") from _write_section, and then refactor this simple loop:

for section in self._sections:
    self._write_section(section)

into something like this:

it = iter(self._sections)
first_section = next(it)
self._write_section(first_section)
for section in it:  # for each remaining section
    write("\n")
    self._write_section(section)

Actually, this wouldn’t play well with with the (conditional) printing of the DEFAULTS section that comes before that loop. Maybe something like this?

print_linefeed = False

if self._defaults:
    self._write_section(self.default_section)
    print_linefeed = True

for section in self._sections:
    if print_linefeed:
        write("\n")
    self._write_section(section)
    print_linefeed = True