summaryrefslogtreecommitdiff
path: root/pkg_resources/__init__.py
diff options
context:
space:
mode:
authorJason R. Coombs <jaraco@jaraco.com>2022-05-09 10:42:04 -0400
committerJason R. Coombs <jaraco@jaraco.com>2022-05-09 10:42:56 -0400
commit9116c7eb52504bec77d26881d2c28e427dc52143 (patch)
tree6becb88401eb15bdff6fc924211894e6d9c277d1 /pkg_resources/__init__.py
parent8d12d6196c369c7cf0164a1202e968dd68a2cb6c (diff)
parente009a87b5578cb16099b697ba8395c8f6bdd70f3 (diff)
downloadpython-setuptools-git-debt/remove-easy-install.tar.gz
Merge branch 'main' into debt/remove-easy-installdebt/remove-easy-install
Diffstat (limited to 'pkg_resources/__init__.py')
-rw-r--r--pkg_resources/__init__.py70
1 files changed, 32 insertions, 38 deletions
diff --git a/pkg_resources/__init__.py b/pkg_resources/__init__.py
index 42129d5b..d59226af 100644
--- a/pkg_resources/__init__.py
+++ b/pkg_resources/__init__.py
@@ -71,12 +71,19 @@ try:
except ImportError:
importlib_machinery = None
+from pkg_resources.extern.jaraco.text import (
+ yield_lines,
+ drop_comment,
+ join_continuation,
+)
+
from pkg_resources.extern import appdirs
from pkg_resources.extern import packaging
__import__('pkg_resources.extern.packaging.version')
__import__('pkg_resources.extern.packaging.specifiers')
__import__('pkg_resources.extern.packaging.requirements')
__import__('pkg_resources.extern.packaging.markers')
+__import__('pkg_resources.extern.packaging.utils')
if sys.version_info < (3, 5):
raise RuntimeError("Python 3.5 or later is required")
@@ -548,6 +555,7 @@ class WorkingSet:
self.entries = []
self.entry_keys = {}
self.by_key = {}
+ self.normalized_to_canonical_keys = {}
self.callbacks = []
if entries is None:
@@ -628,6 +636,14 @@ class WorkingSet:
is returned.
"""
dist = self.by_key.get(req.key)
+
+ if dist is None:
+ canonical_key = self.normalized_to_canonical_keys.get(req.key)
+
+ if canonical_key is not None:
+ req.key = canonical_key
+ dist = self.by_key.get(canonical_key)
+
if dist is not None and dist not in req:
# XXX add more info
raise VersionConflict(dist, req)
@@ -696,6 +712,8 @@ class WorkingSet:
return
self.by_key[dist.key] = dist
+ normalized_name = packaging.utils.canonicalize_name(dist.key)
+ self.normalized_to_canonical_keys[normalized_name] = dist.key
if dist.key not in keys:
keys.append(dist.key)
if dist.key not in keys2:
@@ -916,14 +934,15 @@ class WorkingSet:
def __getstate__(self):
return (
self.entries[:], self.entry_keys.copy(), self.by_key.copy(),
- self.callbacks[:]
+ self.normalized_to_canonical_keys.copy(), self.callbacks[:]
)
- def __setstate__(self, e_k_b_c):
- entries, keys, by_key, callbacks = e_k_b_c
+ def __setstate__(self, e_k_b_n_c):
+ entries, keys, by_key, normalized_to_canonical_keys, callbacks = e_k_b_n_c
self.entries = entries[:]
self.entry_keys = keys.copy()
self.by_key = by_key.copy()
+ self.normalized_to_canonical_keys = normalized_to_canonical_keys.copy()
self.callbacks = callbacks[:]
@@ -1581,7 +1600,7 @@ class EggProvider(NullProvider):
"""Provider based on a virtual filesystem"""
def __init__(self, module):
- NullProvider.__init__(self, module)
+ super().__init__(module)
self._setup_prefix()
def _setup_prefix(self):
@@ -1701,7 +1720,7 @@ class ZipProvider(EggProvider):
_zip_manifests = MemoizedZipManifests()
def __init__(self, module):
- EggProvider.__init__(self, module)
+ super().__init__(module)
self.zip_pre = self.loader.archive + os.sep
def _zipinfo_name(self, fspath):
@@ -2205,12 +2224,14 @@ def _handle_ns(packageName, path_item):
# use find_spec (PEP 451) and fall-back to find_module (PEP 302)
try:
- loader = importer.find_spec(packageName).loader
+ spec = importer.find_spec(packageName)
except AttributeError:
# capture warnings due to #1111
with warnings.catch_warnings():
warnings.simplefilter("ignore")
loader = importer.find_module(packageName)
+ else:
+ loader = spec.loader if spec else None
if loader is None:
return None
@@ -2396,20 +2417,6 @@ def _set_parent_ns(packageName):
setattr(sys.modules[parent], name, sys.modules[packageName])
-def yield_lines(strs):
- """Yield non-empty/non-comment lines of a string or sequence"""
- if isinstance(strs, str):
- for s in strs.splitlines():
- s = s.strip()
- # skip blank lines/comments
- if s and not s.startswith('#'):
- yield s
- else:
- for ss in strs:
- for s in yield_lines(ss):
- yield s
-
-
MODULE = re.compile(r"\w+(\.\w+)*$").match
EGG_NAME = re.compile(
r"""
@@ -3046,12 +3053,12 @@ class DistInfoDistribution(Distribution):
if not req.marker or req.marker.evaluate({'extra': extra}):
yield req
- common = frozenset(reqs_for_extra(None))
+ common = types.MappingProxyType(dict.fromkeys(reqs_for_extra(None)))
dm[None].extend(common)
for extra in self._parsed_pkg_info.get_all('Provides-Extra') or []:
s_extra = safe_extra(extra.strip())
- dm[s_extra] = list(frozenset(reqs_for_extra(extra)) - common)
+ dm[s_extra] = [r for r in reqs_for_extra(extra) if r not in common]
return dm
@@ -3077,25 +3084,12 @@ def issue_warning(*args, **kw):
def parse_requirements(strs):
- """Yield ``Requirement`` objects for each specification in `strs`
+ """
+ Yield ``Requirement`` objects for each specification in `strs`.
`strs` must be a string, or a (possibly-nested) iterable thereof.
"""
- # create a steppable iterator, so we can handle \-continuations
- lines = iter(yield_lines(strs))
-
- for line in lines:
- # Drop comments -- a hash without a space may be in a URL.
- if ' #' in line:
- line = line[:line.find(' #')]
- # If there is a line continuation, drop it, and append the next line.
- if line.endswith('\\'):
- line = line[:-2].strip()
- try:
- line += next(lines)
- except StopIteration:
- return
- yield Requirement(line)
+ return map(Requirement, join_continuation(map(drop_comment, yield_lines(strs))))
class RequirementParseError(packaging.requirements.InvalidRequirement):