Discussion:
Using 'with open(...) as ...' together with configparser.ConfigParser.read
(too old to reply)
Loris Bennett
2024-10-29 13:56:01 UTC
Permalink
Hi,

With Python 3.9.18, if I do

try:
with open(args.config_file, 'r') as config_file:
config = configparser.ConfigParser()
config.read(config_file)
print(config.sections())

i.e try to read the configuration with the variable defined via 'with
... as', I get

[]

whereas if I use the file name directly

try:
with open(args.config_file, 'r') as config_file:
config = configparser.ConfigParser()
config.read(args.config_file)
print(config.sections())
I get

['loggers', 'handlers', 'formatters', 'logger_root', 'handler_fileHandler', 'handler_consoleHandler', 'formatter_defaultFormatter']

which is what I expect.

If I print type of 'config_file' I get

<class '_io.TextIOWrapper'>

whereas 'args.config_file' is just

<class 'str'>

Should I be able to use the '_io.TextIOWrapper' object variable here? If so how?

Here

https://docs.python.org/3.9/library/configparser.html

there are examples which use the 'with open ... as' variable for writing
a configuration file, but not for reading one.

Cheers,

Loris
--
This signature is currently under constuction.
Jon Ribbens
2024-10-29 15:33:57 UTC
Permalink
Post by Loris Bennett
Hi,
With Python 3.9.18, if I do
config = configparser.ConfigParser()
config.read(config_file)
print(config.sections())
i.e try to read the configuration with the variable defined via 'with
... as', I get
[]
whereas if I use the file name directly
config = configparser.ConfigParser()
config.read(args.config_file)
print(config.sections())
I get
['loggers', 'handlers', 'formatters', 'logger_root', 'handler_fileHandler', 'handler_consoleHandler', 'formatter_defaultFormatter']
which is what I expect.
If I print type of 'config_file' I get
<class '_io.TextIOWrapper'>
whereas 'args.config_file' is just
<class 'str'>
Should I be able to use the '_io.TextIOWrapper' object variable here? If so how?
Here
https://docs.python.org/3.9/library/configparser.html
there are examples which use the 'with open ... as' variable for writing
a configuration file, but not for reading one.
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
Loris Bennett
2024-10-30 13:03:55 UTC
Permalink
Post by Jon Ribbens
Post by Loris Bennett
Hi,
With Python 3.9.18, if I do
config = configparser.ConfigParser()
config.read(config_file)
print(config.sections())
i.e try to read the configuration with the variable defined via 'with
... as', I get
[]
whereas if I use the file name directly
config = configparser.ConfigParser()
config.read(args.config_file)
print(config.sections())
I get
['loggers', 'handlers', 'formatters', 'logger_root', 'handler_fileHandler', 'handler_consoleHandler', 'formatter_defaultFormatter']
which is what I expect.
If I print type of 'config_file' I get
<class '_io.TextIOWrapper'>
whereas 'args.config_file' is just
<class 'str'>
Should I be able to use the '_io.TextIOWrapper' object variable here? If so how?
Here
https://docs.python.org/3.9/library/configparser.html
there are examples which use the 'with open ... as' variable for writing
a configuration file, but not for reading one.
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.

However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?

Cheers,

Loris
--
This signature is currently under constuction.
Jon Ribbens
2024-10-30 15:41:13 UTC
Permalink
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
Loris Bennett
2024-10-30 15:57:44 UTC
Permalink
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
OK, but is there a common situation might I be obliged to use
'read_file'? I.e. is there some common case where the file name is not
available, only a corresponding file-like object or stream?
--
This signature is currently under constuction.
Jon Ribbens
2024-10-30 17:57:23 UTC
Permalink
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
OK, but is there a common situation might I be obliged to use
'read_file'? I.e. is there some common case where the file name is not
available, only a corresponding file-like object or stream?
Well, sure - any time it's not being read from a file. A bit ironic
that the method to use in that situation is "read_file", of course.
In my view the read() and read_file() methods have their names the
wrong way round. But bear in mind this code is 27 years old, and
the read() function came first.
Loris Bennett
2024-10-31 06:47:17 UTC
Permalink
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
OK, but is there a common situation might I be obliged to use
'read_file'? I.e. is there some common case where the file name is not
available, only a corresponding file-like object or stream?
Well, sure - any time it's not being read from a file. A bit ironic
that the method to use in that situation is "read_file", of course.
In my view the read() and read_file() methods have their names the
wrong way round. But bear in mind this code is 27 years old, and
the read() function came first.
Yes, I suppose history has a lot to answer for :-)

However I didn't make myself clear: I understand that there are
different functions, depending on whether I have a file name or a
stream. Nevertheless, I just can't think of a practical example where I
might just have *only* a stream, especially one containing my
configuration data. I was just interested to know if anyone can give an
example.
--
This signature is currently under constuction.
Jon Ribbens
2024-10-31 08:41:22 UTC
Permalink
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
OK, but is there a common situation might I be obliged to use
'read_file'? I.e. is there some common case where the file name is not
available, only a corresponding file-like object or stream?
Well, sure - any time it's not being read from a file. A bit ironic
that the method to use in that situation is "read_file", of course.
In my view the read() and read_file() methods have their names the
wrong way round. But bear in mind this code is 27 years old, and
the read() function came first.
Yes, I suppose history has a lot to answer for :-)
However I didn't make myself clear: I understand that there are
different functions, depending on whether I have a file name or a
stream. Nevertheless, I just can't think of a practical example where I
might just have *only* a stream, especially one containing my
configuration data. I was just interested to know if anyone can give an
example.
That was answered the first sentence of my reply. It's a bit vague
because in most of the situations I can think of, one of the other
read_*() methods would probably be more appropriate. But again,
the history is that read_file() was added first (originally called
readfp() ) so it had to handle all cases where the data being read
was not coming from a named filesystem file - e.g. it's coming over
a Unix socket, or an HTTP request, or from a database.

It is good practice in general to provide a method that allows your
class to read data as a stream, if that is appropriate for what
you're doing, so that people aren't unnecessarily forced to load
data fully into memory or write it to a file, as well as perhaps a
convenience method thaat will read from a named file for people who
are doing that.
Karsten Hilbert
2024-10-31 16:10:42 UTC
Permalink
Post by Loris Bennett
However I didn't make myself clear: I understand that there are
different functions, depending on whether I have a file name or a
stream. Nevertheless, I just can't think of a practical example where I
might just have *only* a stream, especially one containing my
configuration data. I was just interested to know if anyone can give an
example.
Apart from the fact that any data source can be made into a
file: one might have a stream of data coming in over, say,
http, as in a centralized configuration repository.

Karsten
--
GPG 40BE 5B0E C98E 1713 AFA6 5BC0 3BEA AC80 7D4F C89B
MRAB
2024-10-31 17:06:11 UTC
Permalink
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
Post by Loris Bennett
Post by Jon Ribbens
As per the docs you link to, the read() method only takes filename(s)
as arguments, if you have an already-open file you want to read then
you should use the read_file() method instead.
As you and others have pointed out, this is indeed covered in the docs,
so mea culpa.
However, whereas I can see why you might want to read the config from a
dict or a string, what would be a use case in which I would want to
read from an open file rather than just reading from a file(name)?
The ConfigParser module provides read(), read_file(), read_string(),
and read_dict() methods. I think they were just trying to be
comprehensive. It's a bit non-Pythonic really.
OK, but is there a common situation might I be obliged to use
'read_file'? I.e. is there some common case where the file name is not
available, only a corresponding file-like object or stream?
Well, sure - any time it's not being read from a file. A bit ironic
that the method to use in that situation is "read_file", of course.
In my view the read() and read_file() methods have their names the
wrong way round. But bear in mind this code is 27 years old, and
the read() function came first.
Yes, I suppose history has a lot to answer for :-)
However I didn't make myself clear: I understand that there are
different functions, depending on whether I have a file name or a
stream. Nevertheless, I just can't think of a practical example where I
might just have *only* a stream, especially one containing my
configuration data. I was just interested to know if anyone can give an
example.
What if the config file was inside a zipped folder?

Although I haven't used ConfigParser like that, I have read the contents
of files that are in a zipped folder. It means that I don't have to
extract the file first.

MRAB
2024-10-29 16:10:47 UTC
Permalink
Post by Loris Bennett
Hi,
With Python 3.9.18, if I do
config = configparser.ConfigParser()
config.read(config_file)
print(config.sections())
i.e try to read the configuration with the variable defined via 'with
... as', I get
[]
whereas if I use the file name directly
config = configparser.ConfigParser()
config.read(args.config_file)
print(config.sections())
I get
['loggers', 'handlers', 'formatters', 'logger_root', 'handler_fileHandler', 'handler_consoleHandler', 'formatter_defaultFormatter']
which is what I expect.
If I print type of 'config_file' I get
<class '_io.TextIOWrapper'>
whereas 'args.config_file' is just
<class 'str'>
Should I be able to use the '_io.TextIOWrapper' object variable here? If so how?
Here
https://docs.python.org/3.9/library/configparser.html
there are examples which use the 'with open ... as' variable for writing
a configuration file, but not for reading one.
Cheers,
Loris
'config.read' expects a path or paths. If you give it a file handle, it
treats it as an iterable. (It might be reading the line as paths of
files, but I haven't tested it).

If you want to read from an open file, use 'config.read_file' instead.
Lawrence D'Oliveiro
2024-10-30 00:10:14 UTC
Permalink
I never bother with putting files into context managers. This is not a
good idea for files open for writing, but even for read-only files (as
here), CPython will close the file when the object goes out of scope
anyway.
Loading...