From f5047660c281e1f10620e6cb569d8b7b67eeb096 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google]" Date: Sun, 8 May 2022 18:51:21 +0000 Subject: [PATCH 1/6] gh-89336: Remove configparser 3.12 deprecations. --- Doc/library/configparser.rst | 26 ------------ Lib/configparser.py | 42 ------------------- ...2-05-08-18-51-14.gh-issue-89336.TL6ip7.rst | 3 ++ 3 files changed, 3 insertions(+), 68 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index 72aa20d73d8bd3..f695badeb947d2 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -1206,28 +1206,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* @@ -1361,10 +1339,6 @@ 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. - .. rubric:: Footnotes diff --git a/Lib/configparser.py b/Lib/configparser.py index de9ee537ac1884..38e53a9e7bd1ec 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -312,26 +312,6 @@ def __init__(self, source=None, filename=None): self.errors = [] self.args = (source, ) - @property - def filename(self): - """Deprecated, use `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - return self.source - - @filename.setter - def filename(self, value): - """Deprecated, user `source'.""" - warnings.warn( - "The 'filename' attribute will be removed in Python 3.12. " - "Use 'source' instead.", - DeprecationWarning, stacklevel=2 - ) - self.source = value - def append(self, lineno, line): self.errors.append((lineno, line)) self.message += '\n\t[line %2d]: %s' % (lineno, line) @@ -768,15 +748,6 @@ def read_dict(self, dictionary, source=''): elements_added.add((section, key)) self.set(section, key, value) - def readfp(self, fp, filename=None): - """Deprecated, use read_file instead.""" - warnings.warn( - "This method will be removed in Python 3.12. " - "Use 'parser.read_file()' instead.", - DeprecationWarning, stacklevel=2 - ) - self.read_file(fp, source=filename) - def get(self, section, option, *, raw=False, vars=None, fallback=_UNSET): """Get an option value for a given section. @@ -1239,19 +1210,6 @@ def _read_defaults(self, defaults): self._interpolation = hold_interpolation -class SafeConfigParser(ConfigParser): - """ConfigParser alias for backwards compatibility purposes.""" - - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - warnings.warn( - "The SafeConfigParser class has been renamed to ConfigParser " - "in Python 3.2. This alias will be removed in Python 3.12." - " Use ConfigParser directly instead.", - DeprecationWarning, stacklevel=2 - ) - - class SectionProxy(MutableMapping): """A proxy for a single section from a parser.""" diff --git a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst new file mode 100644 index 00000000000000..b1d6bd139bfc3e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst @@ -0,0 +1,3 @@ +The ``configparser`` module APIs deprecated to be removed in 3.12 have been +removed: The ``SafeConfigParser`` class alias, the ``ParsingError.filename`` +property, and the ``ConfigParser.readfp`` method have all been removed. From d22fac1ec73b0a3f7f71127f3aab1db044e986de Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google]" Date: Sun, 8 May 2022 19:07:18 +0000 Subject: [PATCH 2/6] Fix the tests, further cleanup. --- Lib/configparser.py | 19 +++++----------- Lib/test/test_configparser.py | 42 +++++------------------------------ 2 files changed, 10 insertions(+), 51 deletions(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index 38e53a9e7bd1ec..f98e6fb01f97cc 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -148,14 +148,14 @@ import sys import warnings -__all__ = ["NoSectionError", "DuplicateOptionError", "DuplicateSectionError", +__all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", "InterpolationMissingOptionError", "InterpolationSyntaxError", "ParsingError", "MissingSectionHeaderError", - "ConfigParser", "SafeConfigParser", "RawConfigParser", + "ConfigParser", "RawConfigParser", "Interpolation", "BasicInterpolation", "ExtendedInterpolation", "LegacyInterpolation", "SectionProxy", "ConverterMapping", - "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH"] + "DEFAULTSECT", "MAX_INTERPOLATION_DEPTH") _default_dict = dict DEFAULTSECT = "DEFAULT" @@ -297,17 +297,8 @@ def __init__(self, option, section, rawval): class ParsingError(Error): """Raised when a configuration file does not follow legal syntax.""" - def __init__(self, source=None, filename=None): - # Exactly one of `source'/`filename' arguments has to be given. - # `filename' kept for compatibility. - if filename and source: - raise ValueError("Cannot specify both `filename' and `source'. " - "Use `source'.") - elif not filename and not source: - raise ValueError("Required argument `source' not given.") - elif filename: - source = filename - Error.__init__(self, 'Source contains parsing errors: %r' % source) + def __init__(self, source): + super().__init__(f'Source contains parsing errors: {source!r}') self.source = source self.errors = [] self.args = (source, ) diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 59c4b275cb46d7..5e2715a96b9943 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -1612,23 +1612,12 @@ def test_interpolation_depth_error(self): self.assertEqual(error.section, 'section') def test_parsing_error(self): - with self.assertRaises(ValueError) as cm: + with self.assertRaises(TypeError) as cm: configparser.ParsingError() - self.assertEqual(str(cm.exception), "Required argument `source' not " - "given.") - with self.assertRaises(ValueError) as cm: - configparser.ParsingError(source='source', filename='filename') - self.assertEqual(str(cm.exception), "Cannot specify both `filename' " - "and `source'. Use `source'.") - error = configparser.ParsingError(filename='source') + error = configparser.ParsingError(source='source') + self.assertEqual(error.source, 'source') + error = configparser.ParsingError('source') self.assertEqual(error.source, 'source') - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - self.assertEqual(error.filename, 'source') - error.filename = 'filename' - self.assertEqual(error.source, 'filename') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) def test_interpolation_validation(self): parser = configparser.ConfigParser() @@ -1647,27 +1636,6 @@ def test_interpolation_validation(self): self.assertEqual(str(cm.exception), "bad interpolation variable " "reference '%(()'") - def test_readfp_deprecation(self): - sio = io.StringIO(""" - [section] - option = value - """) - parser = configparser.ConfigParser() - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser.readfp(sio, filename='StringIO') - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - self.assertEqual(len(parser), 2) - self.assertEqual(parser['section']['option'], 'value') - - def test_safeconfigparser_deprecation(self): - with warnings.catch_warnings(record=True) as w: - warnings.simplefilter("always", DeprecationWarning) - parser = configparser.SafeConfigParser() - for warning in w: - self.assertTrue(warning.category is DeprecationWarning) - def test_legacyinterpolation_deprecation(self): with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always", DeprecationWarning) @@ -1841,7 +1809,7 @@ def test_parsingerror(self): self.assertEqual(e1.source, e2.source) self.assertEqual(e1.errors, e2.errors) self.assertEqual(repr(e1), repr(e2)) - e1 = configparser.ParsingError(filename='filename') + e1 = configparser.ParsingError('filename') e1.append(1, 'line1') e1.append(2, 'line2') e1.append(3, 'line3') From 06dfe8118d79814e72af06941d9ebe66d67c73bf Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith [Google]" Date: Sun, 8 May 2022 21:47:34 +0000 Subject: [PATCH 3/6] Add whatsnew and a versionchanged note. --- Doc/library/configparser.rst | 3 +++ Doc/whatsnew/3.12.rst | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/Doc/library/configparser.rst b/Doc/library/configparser.rst index f695badeb947d2..bf49f2bfbe1b43 100644 --- a/Doc/library/configparser.rst +++ b/Doc/library/configparser.rst @@ -1339,6 +1339,9 @@ Exceptions Exception raised when errors occur attempting to parse a file. +.. 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 diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index b73c3db040019e..8ab3d898896c31 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -107,6 +107,14 @@ Deprecated Removed ======= +:class:`configparser.ParsingError` no longer has a ``filename`` attribute or +constructor argument. Use the ``source`` attribute and argument name instead. + +:mod:`configparser` no longer has a ``SafeConfigParser`` class, use the shorter +:class:`~configparser.ConfigParser` name instead. + +:class:`configparser.ConfigParser` no longer has a ``readfp`` method, use +:meth:`~configparser.ConfigParser.read_file` instead. Porting to Python 3.12 From 65f391bf63c9fa2fee85718dd56c2e7a3dac6f6c Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 9 May 2022 14:44:15 -0700 Subject: [PATCH 4/6] Update Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst Co-authored-by: Hugo van Kemenade --- .../Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst index b1d6bd139bfc3e..6efc3d5893f7f1 100644 --- a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst +++ b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst @@ -1,3 +1,3 @@ -The ``configparser`` module APIs deprecated to be removed in 3.12 have been -removed: The ``SafeConfigParser`` class alias, the ``ParsingError.filename`` -property, and the ``ConfigParser.readfp`` method have all been removed. +Removed ``configparser`` module APIs: +the ``SafeConfigParser`` class alias, the ``ParsingError.filename`` +property, and the ``ConfigParser.readfp`` method, deprecated since Python 3.2. From 1850ab68f35785439d71ac431eb99dac96e78935 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 9 May 2022 14:53:32 -0700 Subject: [PATCH 5/6] Update 2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst --- .../next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst index 6efc3d5893f7f1..e03f4cef67dcc6 100644 --- a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst +++ b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst @@ -1,3 +1,3 @@ -Removed ``configparser`` module APIs: +Removed ``configparser`` module APIs: the ``SafeConfigParser`` class alias, the ``ParsingError.filename`` property, and the ``ConfigParser.readfp`` method, deprecated since Python 3.2. From 9fc3ae15081202714a9820b172f6a84dbff78882 Mon Sep 17 00:00:00 2001 From: "Gregory P. Smith" Date: Mon, 9 May 2022 14:55:00 -0700 Subject: [PATCH 6/6] Update 2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst --- .../Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst index e03f4cef67dcc6..b4c58c0e48b25e 100644 --- a/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst +++ b/Misc/NEWS.d/next/Library/2022-05-08-18-51-14.gh-issue-89336.TL6ip7.rst @@ -1,3 +1,4 @@ -Removed ``configparser`` module APIs: +Removed :mod:`configparser` module APIs: the ``SafeConfigParser`` class alias, the ``ParsingError.filename`` -property, and the ``ConfigParser.readfp`` method, deprecated since Python 3.2. +property and parameter, and the ``ConfigParser.readfp`` method, all +of which were deprecated since Python 3.2.