Skip to content

Commit e849104

Browse files
author
Gregory Starck
committed
Fix: reload and merge easy-install pth file before save
1 parent 6a2f486 commit e849104

File tree

1 file changed

+52
-31
lines changed

1 file changed

+52
-31
lines changed

setuptools/command/easy_install.py

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,50 +1579,71 @@ def get_exe_prefixes(exe_filename):
15791579
class PthDistributions(Environment):
15801580
"""A .pth file with Distribution paths in it"""
15811581

1582-
dirty = False
1583-
15841582
def __init__(self, filename, sitedirs=()):
15851583
self.filename = filename
15861584
self.sitedirs = list(map(normalize_path, sitedirs))
15871585
self.basedir = normalize_path(os.path.dirname(self.filename))
1588-
self._load()
1586+
self.paths, self.dirty = self._load()
15891587
super().__init__([], None, None)
15901588
for path in yield_lines(self.paths):
15911589
list(map(self.add, find_distributions(path, True)))
15921590

1593-
def _load(self):
1594-
self.paths = []
1595-
saw_import = False
1591+
def _load_raw(self):
1592+
paths = []
1593+
dirty = saw_import = False
15961594
seen = dict.fromkeys(self.sitedirs)
1597-
if os.path.isfile(self.filename):
1598-
f = open(self.filename, 'rt')
1599-
for line in f:
1600-
if line.startswith('import'):
1601-
saw_import = True
1602-
continue
1603-
path = line.rstrip()
1604-
self.paths.append(path)
1605-
if not path.strip() or path.strip().startswith('#'):
1606-
continue
1607-
# skip non-existent paths, in case somebody deleted a package
1608-
# manually, and duplicate paths as well
1609-
path = self.paths[-1] = normalize_path(
1610-
os.path.join(self.basedir, path)
1611-
)
1612-
if not os.path.exists(path) or path in seen:
1613-
self.paths.pop() # skip it
1614-
self.dirty = True # we cleaned up, so we're dirty now :)
1615-
continue
1616-
seen[path] = 1
1617-
f.close()
1595+
f = open(self.filename, 'rt')
1596+
for line in f:
1597+
path = line.rstrip()
1598+
stripped_path = path.strip()
1599+
paths.append(path) # still keep imports and empty/commented lines for formatting
1600+
if line.startswith(('import ', 'from ')):
1601+
saw_import = True
1602+
continue
1603+
if not stripped_path or stripped_path.startswith('#'):
1604+
continue
1605+
# skip non-existent paths, in case somebody deleted a package
1606+
# manually, and duplicate paths as well
1607+
normalized_path = normalize_path(os.path.join(self.basedir, path))
1608+
if not os.path.exists(path) or normalized_path in seen:
1609+
log.debug("cleaned up dirty or duplicated %r", path)
1610+
dirty = True
1611+
paths.pop()
1612+
continue
1613+
seen[normalized_path] = 1
1614+
f.close()
1615+
return paths, dirty or (paths and saw_import)
16181616

1619-
if self.paths and not saw_import:
1620-
self.dirty = True # ensure anything we touch has import wrappers
1621-
while self.paths and not self.paths[-1].strip():
1622-
self.paths.pop()
1617+
def _load(self):
1618+
if os.path.isfile(self.filename):
1619+
paths, dirty = self._load_raw()
1620+
# lights cleaning:
1621+
while paths and not paths[-1].strip():
1622+
paths.pop()
1623+
else:
1624+
paths = []
1625+
dirty = False
1626+
return paths, dirty
16231627

16241628
def save(self):
16251629
"""Write changed .pth file back to disk"""
1630+
last_paths, last_dirty = self._load()
1631+
for path in last_paths[:]:
1632+
if path not in self.paths:
1633+
self.paths.append(path)
1634+
log.info("detected new path %r", path)
1635+
last_dirty = True
1636+
else:
1637+
last_paths.remove(path)
1638+
for path in self.paths[:]:
1639+
if path not in last_paths \
1640+
and not path.startswith(('import ', 'from ')) \
1641+
and not os.path.exists(path):
1642+
self.paths.remove(path)
1643+
log.info("removing now non-existent path %r", path)
1644+
last_dirty = True
1645+
self.dirty |= last_dirty
1646+
16261647
if not self.dirty:
16271648
return
16281649

0 commit comments

Comments
 (0)