Skip to content

Commit

Permalink
Merge branch '3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
jaraco committed Jul 8, 2023
2 parents 02603ad + 39617ac commit 1266b06
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 197 deletions.
87 changes: 34 additions & 53 deletions configparser.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,17 @@ can be customized by end users easily.

.. seealso::

Module :mod:`tomllib`
TOML is a well-specified format for application configuration files.
It is specifically designed to be an improved version of INI.

Module :mod:`shlex`
Support for creating Unix shell-like mini-languages which can be used as
an alternate format for application configuration files.
Support for creating Unix shell-like mini-languages which can also
be used for application configuration files.

Module :mod:`json`
The json module implements a subset of JavaScript syntax which can also
be used for this purpose.
The ``json`` module implements a subset of JavaScript syntax which is
sometimes used for configuration, but does not support comments.


.. testsetup::
Expand All @@ -65,10 +69,10 @@ Let's take a very basic configuration file that looks like this:
CompressionLevel = 9
ForwardX11 = yes
[bitbucket.org]
[forge.example]
User = hg
[topsecret.server.com]
[topsecret.server.example]
Port = 50022
ForwardX11 = no
Expand All @@ -85,10 +89,10 @@ creating the above configuration file programmatically.
>>> config['DEFAULT'] = {'ServerAliveInterval': '45',
... 'Compression': 'yes',
... 'CompressionLevel': '9'}
>>> config['bitbucket.org'] = {}
>>> config['bitbucket.org']['User'] = 'hg'
>>> config['topsecret.server.com'] = {}
>>> topsecret = config['topsecret.server.com']
>>> config['forge.example'] = {}
>>> config['forge.example']['User'] = 'hg'
>>> config['topsecret.server.example'] = {}
>>> topsecret = config['topsecret.server.example']
>>> topsecret['Port'] = '50022' # mutates the parser
>>> topsecret['ForwardX11'] = 'no' # same here
>>> config['DEFAULT']['ForwardX11'] = 'yes'
Expand All @@ -111,28 +115,28 @@ back and explore the data it holds.
>>> config.read('example.ini')
['example.ini']
>>> config.sections()
['bitbucket.org', 'topsecret.server.com']
>>> 'bitbucket.org' in config
['forge.example', 'topsecret.server.example']
>>> 'forge.example' in config
True
>>> 'bytebong.com' in config
>>> 'python.org' in config
False
>>> config['bitbucket.org']['User']
>>> config['forge.example']['User']
'hg'
>>> config['DEFAULT']['Compression']
'yes'
>>> topsecret = config['topsecret.server.com']
>>> topsecret = config['topsecret.server.example']
>>> topsecret['ForwardX11']
'no'
>>> topsecret['Port']
'50022'
>>> for key in config['bitbucket.org']: # doctest: +SKIP
>>> for key in config['forge.example']: # doctest: +SKIP
... print(key)
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config['bitbucket.org']['ForwardX11']
>>> config['forge.example']['ForwardX11']
'yes'

As we can see above, the API is pretty straightforward. The only bit of magic
Expand All @@ -150,15 +154,15 @@ configuration while the previously existing keys are retained.
>>> another_config = configparser.ConfigParser()
>>> another_config.read('example.ini')
['example.ini']
>>> another_config['topsecret.server.com']['Port']
>>> another_config['topsecret.server.example']['Port']
'50022'
>>> another_config.read_string("[topsecret.server.com]\nPort=48484")
>>> another_config['topsecret.server.com']['Port']
>>> another_config.read_string("[topsecret.server.example]\nPort=48484")
>>> another_config['topsecret.server.example']['Port']
'48484'
>>> another_config.read_dict({"topsecret.server.com": {"Port": 21212}})
>>> another_config['topsecret.server.com']['Port']
>>> another_config.read_dict({"topsecret.server.example": {"Port": 21212}})
>>> another_config['topsecret.server.example']['Port']
'21212'
>>> another_config['topsecret.server.com']['ForwardX11']
>>> another_config['topsecret.server.example']['ForwardX11']
'no'

This behaviour is equivalent to a :meth:`ConfigParser.read` call with several
Expand Down Expand Up @@ -191,9 +195,9 @@ recognizes Boolean values from ``'yes'``/``'no'``, ``'on'``/``'off'``,

>>> topsecret.getboolean('ForwardX11')
False
>>> config['bitbucket.org'].getboolean('ForwardX11')
>>> config['forge.example'].getboolean('ForwardX11')
True
>>> config.getboolean('bitbucket.org', 'Compression')
>>> config.getboolean('forge.example', 'Compression')
True

Apart from :meth:`~ConfigParser.getboolean`, config parsers also
Expand All @@ -220,7 +224,7 @@ provide fallback values:
Please note that default values have precedence over fallback values.
For instance, in our example the ``'CompressionLevel'`` key was
specified only in the ``'DEFAULT'`` section. If we try to get it from
the section ``'topsecret.server.com'``, we will always get the default,
the section ``'topsecret.server.example'``, we will always get the default,
even if we specify a fallback:

.. doctest::
Expand All @@ -235,7 +239,7 @@ the ``fallback`` keyword-only argument:

.. doctest::

>>> config.get('bitbucket.org', 'monster',
>>> config.get('forge.example', 'monster',
... fallback='No such things as monsters')
'No such things as monsters'

Expand Down Expand Up @@ -1206,28 +1210,6 @@ ConfigParser Objects
names is stripped before :meth:`optionxform` is called.


.. method:: readfp(fp, filename=None)

.. deprecated:: 3.2
Use :meth:`read_file` instead.

.. versionchanged:: 3.2
:meth:`readfp` now iterates on *fp* instead of calling ``fp.readline()``.

For existing code calling :meth:`readfp` with arguments which don't
support iteration, the following generator may be used as a wrapper
around the file-like object::

def readline_generator(fp):
line = fp.readline()
while line:
yield line
line = fp.readline()

Instead of ``parser.readfp(fp)`` use
``parser.read_file(readline_generator(fp))``.


.. data:: MAX_INTERPOLATION_DEPTH

The maximum depth for recursive interpolation for :meth:`get` when the *raw*
Expand Down Expand Up @@ -1361,10 +1343,9 @@ Exceptions

Exception raised when errors occur attempting to parse a file.

.. versionchanged:: 3.2
The ``filename`` attribute and :meth:`__init__` argument were renamed to
``source`` for consistency.

.. versionchanged:: 3.12
The ``filename`` attribute and :meth:`__init__` constructor argument were
removed. They have been available using the name ``source`` since 3.2.

.. rubric:: Footnotes

Expand Down
1 change: 1 addition & 0 deletions newsfragments/+eca10a5c.removal.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Synced with CPython 3.12.0b2. Removes ``SafeConfigParser`` and ``filename`` parameter.
Loading

0 comments on commit 1266b06

Please sign in to comment.