Feature or enhancement
Proposal:
Lib/configparser.py and Lib/test/test_configparser.py still carry a fair
amount of pre-f-string formatting (% formatting and str.format() calls) plus
a handful of constructs that have since acquired simpler spellings. Linting the
two modules with Ruff's current default rule set reports 72 violations:
35 UP032 f-string
17 UP031 printf-string-formatting
3 UP030 format-literals
3 RUF012 mutable-class-default
2 SIM102 collapsible-if
2 C414 unnecessary-double-cast-or-process
1 C408 unnecessary-collection-call
1 C405 unnecessary-literal-set
1 C901 complex-structure
1 F841 unused-variable
1 I001 unsorted-imports
1 ISC004 implicit-string-concatenation-in-collection-literal
1 RUF019 unnecessary-key-check
1 RUF022 unsorted-dunder-all
1 RUF059 unused-unpacked-variable
1 SIM117 multiple-with-statements
None of these are bugs, and CPython's own Ruff configuration only selects F401
and F811 for Lib/, so nothing here is failing today. The proposal is simply
to modernize the two modules: convert the %/.format() call sites to
f-strings, and apply the small set of simplifications above.
Two of the reports need more than a mechanical fix:
-
C901 on ExtendedInterpolation._interpolate_some is a complexity metric,
not a defect. Splitting that parser loop up would be a much larger and
riskier change, so I propose an explicit # noqa: C901 # gh-159686. The
issue reference rides along in the directive rather than in a comment above
it, so the suppression carries its own trail without adding prose to the
method; configparser: ExtendedInterpolation._interpolate_some exceeds common complexity limits #159686 records why the complexity is inherent to the
interpolation grammar and what a refactoring might look like.
-
RUF012 wants the mutable class attributes annotated ClassVar, and the
obvious spelling of that would import typing at runtime, which this module
deliberately avoids (cf. the gh-117703 note above the imports). Adding
from __future__ import annotations and importing ClassVar only under
TYPE_CHECKING keeps typing out of the import graph, as tomllib and
importlib.metadata already do. -X importtime confirms typing is still
not imported. A side benefit is that Iterable['ParsingError'] can lose its
quotes (UP037).
This does make TYPE_CHECKING a module-level name, so it needs adding to
not_exported in the check__all__ test.
Motivation
Two reasons:
-
These are the usual readability wins. The error paths in particular read
better as f-strings, e.g.
- Error.__init__(self, 'No section: %r' % (section,))
+ Error.__init__(self, f'No section: {section!r}')
-
configparser is backported to PyPI as
backports.configparser, whose
module is merged from CPython periodically. That project lints with the
default rule set and currently has to carry a per-file exemption for the
CPython-derived files (jaraco/configparser#73). Landing the changes here
lets the backport drop the exemption and keeps the two copies converging
rather than diverging.
I have this working locally as four reviewable commits (the f-string
conversion, the simplifications, the handful of % sites Ruff will not
autofix, and the import/__all__/ClassVar changes above), and I am happy to
put up the PR. With all of it applied, both CPython's own Ruff configuration
and the default rule set report no findings for either file, and
test_configparser, test_logging, test_collections, test___all__ and
test_pydoc all pass.
Has this already been discussed elsewhere?
No response given
Links to previous discussion of this feature:
jaraco/configparser#73
Linked PRs