Skip to content

Commit e999582

Browse files
committed
Update dynamic module imports in pkg_resources to private alias static imports
Enabled ``attr-defined`` checks in mypy for ``pkg_resources``
1 parent 804ccd2 commit e999582

File tree

5 files changed

+26
-29
lines changed

5 files changed

+26
-29
lines changed

mypy.ini

+2-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,11 @@ exclude = (?x)(
1515
| ^setuptools/_distutils/ # Vendored
1616
| ^setuptools/config/_validate_pyproject/ # Auto-generated
1717
)
18+
1819
# Ignoring attr-defined because setuptools wraps a lot of distutils classes, adding new attributes,
1920
# w/o updating all the attributes and return types from the base classes for type-checkers to understand
2021
# Especially with setuptools.dist.command vs distutils.dist.command vs setuptools._distutils.dist.command
21-
# *.extern modules that actually live in *._vendor will also cause attr-defined issues on import
22+
[mypy-setuptools.*]
2223
disable_error_code = attr-defined
2324

2425
# - Avoid raising issues when importing from "extern" modules, as those are added to path dynamically.

newsfragments/4348.bugfix.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix an error with `UnicodeDecodeError` handling in ``pkg_resources`` when trying to read files in UTF-8 with a fallback -- by :user:`Avasam`

newsfragments/4348.misc.rst

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update dynamic module imports in ``pkg_resources`` to private alias static imports. Enabled ``attr-defined`` checks in mypy for ``pkg_resources`` -- by :user:`Avasam`

pkg_resources/__init__.py

+19-25
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,11 @@
7070
drop_comment,
7171
join_continuation,
7272
)
73-
74-
from pkg_resources.extern import platformdirs
75-
from pkg_resources.extern import packaging
76-
77-
__import__('pkg_resources.extern.packaging.version')
78-
__import__('pkg_resources.extern.packaging.specifiers')
79-
__import__('pkg_resources.extern.packaging.requirements')
80-
__import__('pkg_resources.extern.packaging.markers')
81-
__import__('pkg_resources.extern.packaging.utils')
73+
from pkg_resources.extern.packaging import markers as _packaging_markers
74+
from pkg_resources.extern.packaging import requirements as _packaging_requirements
75+
from pkg_resources.extern.packaging import utils as _packaging_utils
76+
from pkg_resources.extern.packaging import version as _packaging_version
77+
from pkg_resources.extern.platformdirs import user_cache_dir
8278

8379
# declare some globals that will be defined later to
8480
# satisfy the linters.
@@ -116,7 +112,7 @@ class PEP440Warning(RuntimeWarning):
116112
"""
117113

118114

119-
parse_version = packaging.version.Version
115+
parse_version = _packaging_version.Version
120116

121117

122118
_state_vars: Dict[str, str] = {}
@@ -730,7 +726,7 @@ def add(self, dist, entry=None, insert=True, replace=False):
730726
return
731727

732728
self.by_key[dist.key] = dist
733-
normalized_name = packaging.utils.canonicalize_name(dist.key)
729+
normalized_name = _packaging_utils.canonicalize_name(dist.key)
734730
self.normalized_to_canonical_keys[normalized_name] = dist.key
735731
if dist.key not in keys:
736732
keys.append(dist.key)
@@ -1344,9 +1340,7 @@ def get_default_cache():
13441340
or a platform-relevant user cache dir for an app
13451341
named "Python-Eggs".
13461342
"""
1347-
return os.environ.get('PYTHON_EGG_CACHE') or platformdirs.user_cache_dir(
1348-
appname='Python-Eggs'
1349-
)
1343+
return os.environ.get('PYTHON_EGG_CACHE') or user_cache_dir(appname='Python-Eggs')
13501344

13511345

13521346
def safe_name(name):
@@ -1363,8 +1357,8 @@ def safe_version(version):
13631357
"""
13641358
try:
13651359
# normalize the version
1366-
return str(packaging.version.Version(version))
1367-
except packaging.version.InvalidVersion:
1360+
return str(_packaging_version.Version(version))
1361+
except _packaging_version.InvalidVersion:
13681362
version = version.replace(' ', '.')
13691363
return re.sub('[^A-Za-z0-9.]+', '-', version)
13701364

@@ -1441,9 +1435,9 @@ def evaluate_marker(text, extra=None):
14411435
This implementation uses the 'pyparsing' module.
14421436
"""
14431437
try:
1444-
marker = packaging.markers.Marker(text)
1438+
marker = _packaging_markers.Marker(text)
14451439
return marker.evaluate()
1446-
except packaging.markers.InvalidMarker as e:
1440+
except _packaging_markers.InvalidMarker as e:
14471441
raise SyntaxError(e) from e
14481442

14491443

@@ -2695,20 +2689,20 @@ def parsed_version(self):
26952689
if not hasattr(self, "_parsed_version"):
26962690
try:
26972691
self._parsed_version = parse_version(self.version)
2698-
except packaging.version.InvalidVersion as ex:
2692+
except _packaging_version.InvalidVersion as ex:
26992693
info = f"(package: {self.project_name})"
27002694
if hasattr(ex, "add_note"):
27012695
ex.add_note(info) # PEP 678
27022696
raise
2703-
raise packaging.version.InvalidVersion(f"{str(ex)} {info}") from None
2697+
raise _packaging_version.InvalidVersion(f"{str(ex)} {info}") from None
27042698

27052699
return self._parsed_version
27062700

27072701
@property
27082702
def _forgiving_parsed_version(self):
27092703
try:
27102704
return self.parsed_version
2711-
except packaging.version.InvalidVersion as ex:
2705+
except _packaging_version.InvalidVersion as ex:
27122706
self._parsed_version = parse_version(_forgiving_version(self.version))
27132707

27142708
notes = "\n".join(getattr(ex, "__notes__", [])) # PEP 678
@@ -2881,7 +2875,7 @@ def from_filename(cls, filename, metadata=None, **kw):
28812875

28822876
def as_requirement(self):
28832877
"""Return a ``Requirement`` that matches this distribution exactly"""
2884-
if isinstance(self.parsed_version, packaging.version.Version):
2878+
if isinstance(self.parsed_version, _packaging_version.Version):
28852879
spec = "%s==%s" % (self.project_name, self.parsed_version)
28862880
else:
28872881
spec = "%s===%s" % (self.project_name, self.parsed_version)
@@ -3127,11 +3121,11 @@ def parse_requirements(strs):
31273121
return map(Requirement, join_continuation(map(drop_comment, yield_lines(strs))))
31283122

31293123

3130-
class RequirementParseError(packaging.requirements.InvalidRequirement):
3124+
class RequirementParseError(_packaging_requirements.InvalidRequirement):
31313125
"Compatibility wrapper for InvalidRequirement"
31323126

31333127

3134-
class Requirement(packaging.requirements.Requirement):
3128+
class Requirement(_packaging_requirements.Requirement):
31353129
def __init__(self, requirement_string):
31363130
"""DO NOT CALL THIS UNDOCUMENTED METHOD; use Requirement.parse()!"""
31373131
super().__init__(requirement_string)
@@ -3353,6 +3347,6 @@ def _read_utf8_with_fallback(file: str, fallback_encoding=LOCALE_ENCODING) -> st
33533347
"""
33543348
# TODO: Add a deadline?
33553349
# See comment in setuptools.unicode_utils._Utf8EncodingNeeded
3356-
warnings.warns(msg, PkgResourcesDeprecationWarning, stacklevel=2)
3350+
warnings.warn(msg, PkgResourcesDeprecationWarning, stacklevel=2)
33573351
with open(file, "r", encoding=fallback_encoding) as f:
33583352
return f.read()

pkg_resources/tests/test_resources.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import itertools
66

77
import pytest
8-
from pkg_resources.extern import packaging
8+
from pkg_resources.extern.packaging.specifiers import SpecifierSet
99

1010
import pkg_resources
1111
from pkg_resources import (
@@ -567,7 +567,7 @@ def testOptionsAndHashing(self):
567567
assert hash(r1) == hash((
568568
"twisted",
569569
None,
570-
packaging.specifiers.SpecifierSet(">=1.2"),
570+
SpecifierSet(">=1.2"),
571571
frozenset(["foo", "bar"]),
572572
None,
573573
))
@@ -576,7 +576,7 @@ def testOptionsAndHashing(self):
576576
) == hash((
577577
"twisted",
578578
"https://localhost/twisted.zip",
579-
packaging.specifiers.SpecifierSet(),
579+
SpecifierSet(),
580580
frozenset(),
581581
None,
582582
))

0 commit comments

Comments
 (0)