Ticket #13201: easy_install_lock.patch

File easy_install_lock.patch, 4.2 KB (added by ohanar, 10 years ago)

new patch applied to setuptools; for review purposes

  • setuptools/command/easy_install.py

    diff --git setuptools/command/easy_install.py setuptools/command/easy_install.py
    index fb0f997..76f4e72 100644
    file, or visit the `EasyInstall home page`__. 
    1010__ http://packages.python.org/distribute/easy_install.html
    1111
    1212"""
    13 import sys, os.path, zipimport, shutil, tempfile, zipfile, re, stat, random
     13import sys, os.path, zipimport, shutil, tempfile, \
     14        zipfile, re, stat, random, fcntl
    1415from glob import glob
    1516from setuptools import Command, _dont_write_bytecode
    1617from setuptools.sandbox import run_setup
    class PthDistributions(Environment): 
    14921493    def __init__(self, filename, sitedirs=()):
    14931494        self.filename = filename; self.sitedirs=map(normalize_path, sitedirs)
    14941495        self.basedir = normalize_path(os.path.dirname(self.filename))
    1495         self._load(); Environment.__init__(self, [], None, None)
    1496         for path in yield_lines(self.paths):
    1497             map(self.add, find_distributions(path, True))
     1496        self.paths = []; self.dist_dict = {}
     1497        Environment.__init__(self, [], None, None); self._load()
    14981498
    14991499    def _load(self):
     1500        old_paths = list(yield_lines(self.paths))
    15001501        self.paths = []
    15011502        saw_import = False
    15021503        seen = dict.fromkeys(self.sitedirs)
    15031504        if os.path.isfile(self.filename):
    15041505            f = open(self.filename,'rt')
     1506            fcntl.flock(f, fcntl.LOCK_SH)
    15051507            for line in f:
    15061508                if line.startswith('import'):
    15071509                    saw_import = True
    class PthDistributions(Environment): 
    15201522                    self.dirty = True   # we cleaned up, so we're dirty now :)
    15211523                    continue
    15221524                seen[path] = 1
     1525            fcntl.flock(f, fcntl.LOCK_UN)
    15231526            f.close()
    15241527
    15251528        if self.paths and not saw_import:
    15261529            self.dirty = True   # ensure anything we touch has import wrappers
    15271530        while self.paths and not self.paths[-1].strip():
    15281531            self.paths.pop()
     1532        for path in old_paths:
     1533            if not os.path.exists(path):
     1534                map(self.remove, self.dist_dict[path])
     1535            elif path not in self.paths:
     1536                self.paths.append(path)
     1537                self.dirty = True
     1538        new_paths = (path for path in self.paths if path not in old_paths)
     1539        for path in yield_lines(new_paths):
     1540            self.dist_dict[path] = find_distributions(path, True)
     1541            map(self.add, self.dist_dict[path])
    15291542
    15301543    def save(self):
    15311544        """Write changed .pth file back to disk"""
     1545        f = open(self.filename,'r+t')
     1546        fcntl.flock(f, fcntl.LOCK_SH)
     1547        self._load()
    15321548        if not self.dirty:
     1549            f.close()
     1550            fcntl.flock(f, fcntl.LOCK_UN)
    15331551            return
    15341552
    15351553        data = '\n'.join(map(self.make_relative,self.paths))
    class PthDistributions(Environment): 
    15441562                " sys.__egginsert = p+len(new)\n"
    15451563            ) % data
    15461564
    1547             if os.path.islink(self.filename):
    1548                 os.unlink(self.filename)
    1549             f = open(self.filename,'wt')
    1550             f.write(data); f.close()
     1565        # overwrite anything extra with whitespace
     1566        data += ' '*(len(open(self.filename,'rt').read())-len(data))
    15511567
    1552         elif os.path.exists(self.filename):
    1553             log.debug("Deleting empty %s", self.filename)
    1554             os.unlink(self.filename)
     1568        fcntl.flock(f, fcntl.LOCK_EX)
     1569        f.write(data)
     1570        fcntl.flock(f, fcntl.LOCK_UN)
     1571        f.close()
    15551572
    15561573        self.dirty = False
    15571574
    class PthDistributions(Environment): 
    15621579                dist.location == os.getcwd() #account for '.' being in PYTHONPATH
    15631580                )):
    15641581            self.paths.append(dist.location)
     1582            self.dist_dict[dist.location] = [dist]
    15651583            self.dirty = True
    15661584        Environment.add(self,dist)
    15671585
    class PthDistributions(Environment): 
    15691587        """Remove `dist` from the distribution map"""
    15701588        while dist.location in self.paths:
    15711589            self.paths.remove(dist.location); self.dirty = True
     1590        if dist.location in self.dist_paths:
     1591            self.dist_dict[dist.location] = None
    15721592        Environment.remove(self,dist)
    15731593
    15741594