Skip to content

Commit

Permalink
Ensure that pkg_resources.working_set (.entries) load lazily
Browse files Browse the repository at this point in the history
Fixes pypa#510
Fixes pypa#711
Fixes pypa#926
  • Loading branch information
Alphadelta14 committed Sep 23, 2020
1 parent df51e62 commit c2943fa
Showing 1 changed file with 39 additions and 18 deletions.
57 changes: 39 additions & 18 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -555,16 +555,17 @@ class WorkingSet:

def __init__(self, entries=None):
"""Create working set from list of path entries (default=sys.path)"""
self.entries = []
self.entry_keys = {}
self.by_key = {}

self._entries = None
self._by_key = None
self._entry_keys = None

self.callbacks = []

if entries is None:
entries = sys.path

for entry in entries:
self.add_entry(entry)
self.paths = entries

@classmethod
def _build_master(cls):
Expand Down Expand Up @@ -618,11 +619,41 @@ def add_entry(self, entry):
once, and the ``.entries`` of the ``sys.path`` WorkingSet should always
equal ``sys.path``.)
"""
self.entry_keys.setdefault(entry, [])
self.entries.append(entry)
self._entry_keys.setdefault(entry, [])
self._entries.append(entry)
for dist in find_distributions(entry, True):
self.add(dist, entry, False)

def _load_entries(self):
"""Force entries to be loaded from self.paths."""
self._by_key = {}
self._entries = []
self._entry_keys = {}

for entry in self.paths:
self.add_entry(entry)

@property
def entries(self):
"""Lazy access to path entries."""
if self._entries is None:
self._load_entries()
return self._entries

@property
def by_key(self):
"""Lazy access to path entries."""
if self._by_key is None:
self._load_entries()
return self._by_key

@property
def entry_keys(self):
"""Lazy access to path entries."""
if self._entry_keys is None:
self._load_entries()
return self._entry_keys

def __contains__(self, dist):
"""True if `dist` is the active distribution for its project"""
return self.by_key.get(dist.key) == dist
Expand Down Expand Up @@ -3270,21 +3301,11 @@ def _initialize_master_working_set():
run_script = working_set.run_script
# backward compatibility
run_main = run_script
# Activate all distributions already on sys.path with replace=False and
# ensure that all distributions added to the working set in the future
# (e.g. by calling ``require()``) will get activated as well,
# with higher priority (replace=True).
tuple(
dist.activate(replace=False)
for dist in working_set
)

add_activation_listener(
lambda dist: dist.activate(replace=True),
existing=False,
)
working_set.entries = []
# match order
list(map(working_set.add_entry, sys.path))
globals().update(locals())

class PkgResourcesDeprecationWarning(Warning):
Expand Down

0 comments on commit c2943fa

Please sign in to comment.