Author Adrian Wielgosik
Recipients Adrian Wielgosik
Date 2018-12-09.16:35:30
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1544373330.85.0.788709270274.issue35448@psf.upfronthosting.co.za>
In-reply-to
Content
Documentation of ConfigParser says:

> If a file named in filenames cannot be opened, that file will be ignored. This is designed so that you can specify an iterable of potential configuration file locations (for example, the current directory, the user’s home directory, and some system-wide directory), and all existing configuration files in the iterable will be read.

While this is a useful property, it can also be a footgun. The first read() example in the Quick Start section contains just a single file read:

>>> config.read('example.ini')

I would expect that this basic usage is very popular. If the file doesn't exist, the normal usage pattern fails in a confusing way:

 from configparser import ConfigParser
 config = ConfigParser()
 config.read('config.txt')
 value = config.getint('section', 'option')
---> configparser.NoSectionError: No section: 'section'

In my opinion, this error isn't very obvious to understand and debug, unless you have read that piece of .read() documentation.

This behavior did also bite me even more, with another usage pattern I've found in a project I maintain:
> config.read('global.txt')
> config.read('local.txt')
Here, both files are expected to exist, with the latter one extending or updating configuration from the first file. If one of the files doesn't exist (eg mistake during deployment), there's no obvious error, but the program will be configured in different way than intended.

Now, I'm aware that all of this can be avoided by simply using `read_file()`:
> with open('file.txt') as f:
>    config.read_file(f)
But again, `.read()` is the one usually mentioned first in both the official documentation, and most independent guides, so it's easy to get wrong.

Due to this, I propose adding an extra parameter to .read():
read(filenames, encoding=None, check_exist=False)
that, when manually set to True, will throw exception if any of input files doesn't exist; and to use this parameter by default in Quick Start section of ConfigParser documentation.
If this is a reasonable idea, I could try and make a PR.

For comparison, the `toml` Python library has the following behavior:
- if argument is a single filename and file doesn't exist, it throws
- if argument is a list of filenames and none exist, it throws
- if argument is a list of filenames and at least one exists, it works, but prints a warning for each nonexistent file.

For the record, seems like this issue was also mentioned in https://bugs.python.org/issue490399
History
Date User Action Args
2018-12-09 16:35:30Adrian Wielgosiksetrecipients: + Adrian Wielgosik
2018-12-09 16:35:30Adrian Wielgosiksetmessageid: <1544373330.85.0.788709270274.issue35448@psf.upfronthosting.co.za>
2018-12-09 16:35:30Adrian Wielgosiklinkissue35448 messages
2018-12-09 16:35:30Adrian Wielgosikcreate