From 8091be32f0973d2be95ae309a663d8dad3780cc8 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 9 Apr 2024 19:18:52 -0400 Subject: [PATCH 1/5] Get Iterable from collections.abc. --- Lib/configparser.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index d0326c60e9b907..ca9fef532b8d89 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -143,7 +143,7 @@ between keys and values are surrounded by spaces. """ -from collections.abc import MutableMapping +from collections.abc import Iterable, MutableMapping from collections import ChainMap as _ChainMap import contextlib from dataclasses import dataclass, field @@ -153,7 +153,6 @@ import os import re import sys -from typing import Iterable __all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", From 7de4e0045b9d6574492291be07ef21a5171e2787 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 9 Apr 2024 20:08:49 -0400 Subject: [PATCH 2/5] Replace dataclass with SimpleNamespace. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reduces import time by over 50% (10431µs vs 4350µs on Apple M3 Pro). --- Lib/configparser.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index ca9fef532b8d89..b2b85b7af22586 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -143,16 +143,18 @@ between keys and values are surrounded by spaces. """ +# Do not import dataclasses; overhead is unacceptable (gh-117703) + from collections.abc import Iterable, MutableMapping from collections import ChainMap as _ChainMap import contextlib -from dataclasses import dataclass, field import functools import io import itertools import os import re import sys +import types __all__ = ("NoSectionError", "DuplicateOptionError", "DuplicateSectionError", "NoOptionError", "InterpolationError", "InterpolationDepthError", @@ -537,19 +539,21 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, "found: %r" % (rest,)) -@dataclass -class _ReadState: - elements_added : set[str] = field(default_factory=set) +class _ReadState(types.SimpleNamespace): + elements_added : set[str] cursect : dict[str, str] | None = None sectname : str | None = None optname : str | None = None lineno : int = 0 indent_level : int = 0 - errors : list[ParsingError] = field(default_factory=list) + errors : list[ParsingError] + + def __init__(self): + self.elements_added = set() + self.errors = list() -@dataclass -class _Prefixes: +class _Prefixes(types.SimpleNamespace): full : Iterable[str] inline : Iterable[str] From 11bae33d3d56144368aef8c2213416953a737ace Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Tue, 9 Apr 2024 20:15:47 -0400 Subject: [PATCH 3/5] Add blurb --- .../next/Library/2024-04-09-20-14-44.gh-issue-117348.A2NAAz.rst | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2024-04-09-20-14-44.gh-issue-117348.A2NAAz.rst diff --git a/Misc/NEWS.d/next/Library/2024-04-09-20-14-44.gh-issue-117348.A2NAAz.rst b/Misc/NEWS.d/next/Library/2024-04-09-20-14-44.gh-issue-117348.A2NAAz.rst new file mode 100644 index 00000000000000..2451a4e4f622e4 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-09-20-14-44.gh-issue-117348.A2NAAz.rst @@ -0,0 +1,2 @@ +Largely restored import time performance of configparser by avoiding +dataclasses. From 24c0705c59830c1c490ec481c6f2b8a02be50488 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 14 Apr 2024 06:09:15 -0400 Subject: [PATCH 4/5] Remove SimpleNamespace from _ReadState, as it adds no value. --- Lib/configparser.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index b2b85b7af22586..467f7699b75590 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -539,7 +539,7 @@ def _interpolate_some(self, parser, option, accum, rest, section, map, "found: %r" % (rest,)) -class _ReadState(types.SimpleNamespace): +class _ReadState: elements_added : set[str] cursect : dict[str, str] | None = None sectname : str | None = None From 456de13ccfd911b88ed105fb6b4f131edd9b3f53 Mon Sep 17 00:00:00 2001 From: "Jason R. Coombs" Date: Sun, 14 Apr 2024 06:39:57 -0400 Subject: [PATCH 5/5] Use SimpleNamespace inline. --- Lib/configparser.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/Lib/configparser.py b/Lib/configparser.py index 467f7699b75590..ff7d712bed4afc 100644 --- a/Lib/configparser.py +++ b/Lib/configparser.py @@ -553,17 +553,12 @@ def __init__(self): self.errors = list() -class _Prefixes(types.SimpleNamespace): - full : Iterable[str] - inline : Iterable[str] - - class _Line(str): def __new__(cls, val, *args, **kwargs): return super().__new__(cls, val) - def __init__(self, val, prefixes: _Prefixes): + def __init__(self, val, prefixes): self.prefixes = prefixes @functools.cached_property @@ -656,7 +651,7 @@ def __init__(self, defaults=None, dict_type=_default_dict, else: self._optcre = re.compile(self._OPT_TMPL.format(delim=d), re.VERBOSE) - self._prefixes = _Prefixes( + self._prefixes = types.SimpleNamespace( full=tuple(comment_prefixes or ()), inline=tuple(inline_comment_prefixes or ()), )