Commit 91213fb2 authored by Jason R. Coombs's avatar Jason R. Coombs Committed by GitHub

Merge pull request #2166 from pypa/bugfix/2165-remove-site-py

Remove site.py hack
parents 78d2a3bf d9a3b57c
Setuptools no longer installs a site.py file during easy_install or develop installs. As a result, .eggs on PYTHONPATH will no longer take precedence over other packages on sys.path. If this issue affects your production environment, please reach out to the maintainers at #2165.
...@@ -139,7 +139,6 @@ class develop(namespaces.DevelopInstaller, easy_install): ...@@ -139,7 +139,6 @@ class develop(namespaces.DevelopInstaller, easy_install):
self.reinitialize_command('build_ext', inplace=1) self.reinitialize_command('build_ext', inplace=1)
self.run_command('build_ext') self.run_command('build_ext')
self.install_site_py() # ensure that target dir is site-safe
if setuptools.bootstrap_install_from: if setuptools.bootstrap_install_from:
self.easy_install(setuptools.bootstrap_install_from) self.easy_install(setuptools.bootstrap_install_from)
setuptools.bootstrap_install_from = None setuptools.bootstrap_install_from = None
......
...@@ -205,7 +205,6 @@ class easy_install(Command): ...@@ -205,7 +205,6 @@ class easy_install(Command):
self.pth_file = self.always_copy_from = None self.pth_file = self.always_copy_from = None
self.site_dirs = None self.site_dirs = None
self.installed_projects = {} self.installed_projects = {}
self.sitepy_installed = False
# Always read easy_install options, even if we are subclassed, or have # Always read easy_install options, even if we are subclassed, or have
# an independent instance created. This ensures that defaults will # an independent instance created. This ensures that defaults will
# always come from the standard configuration file(s)' "easy_install" # always come from the standard configuration file(s)' "easy_install"
...@@ -494,12 +493,8 @@ class easy_install(Command): ...@@ -494,12 +493,8 @@ class easy_install(Command):
else: else:
self.pth_file = None self.pth_file = None
if instdir not in map(normalize_path, _pythonpath()): if self.multi_version and not os.path.exists(pth_file):
# only PYTHONPATH dirs need a site.py, so pretend it's there self.pth_file = None # don't create a .pth file
self.sitepy_installed = True
elif self.multi_version and not os.path.exists(pth_file):
self.sitepy_installed = True # don't need site.py in this case
self.pth_file = None # and don't create a .pth file
self.install_dir = instdir self.install_dir = instdir
__cant_write_msg = textwrap.dedent(""" __cant_write_msg = textwrap.dedent("""
...@@ -656,9 +651,6 @@ class easy_install(Command): ...@@ -656,9 +651,6 @@ class easy_install(Command):
os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir)) os.path.exists(tmpdir) and rmtree(rmtree_safe(tmpdir))
def easy_install(self, spec, deps=False): def easy_install(self, spec, deps=False):
if not self.editable:
self.install_site_py()
with self._tmpdir() as tmpdir: with self._tmpdir() as tmpdir:
if not isinstance(spec, Requirement): if not isinstance(spec, Requirement):
if URL_SCHEME(spec): if URL_SCHEME(spec):
...@@ -1317,38 +1309,6 @@ class easy_install(Command): ...@@ -1317,38 +1309,6 @@ class easy_install(Command):
Please make the appropriate changes for your system and try again. Please make the appropriate changes for your system and try again.
""").strip() """).strip()
def install_site_py(self):
"""Make sure there's a site.py in the target dir, if needed"""
if self.sitepy_installed:
return # already did it, or don't need to
sitepy = os.path.join(self.install_dir, "site.py")
source = resource_string("setuptools", "site-patch.py")
source = source.decode('utf-8')
current = ""
if os.path.exists(sitepy):
log.debug("Checking existing site.py in %s", self.install_dir)
with io.open(sitepy) as strm:
current = strm.read()
if not current.startswith('def __boot():'):
raise DistutilsError(
"%s is not a setuptools-generated site.py; please"
" remove it." % sitepy
)
if current != source:
log.info("Creating %s", sitepy)
if not self.dry_run:
ensure_directory(sitepy)
with io.open(sitepy, 'w', encoding='utf-8') as strm:
strm.write(source)
self.byte_compile([sitepy])
self.sitepy_installed = True
def create_home_path(self): def create_home_path(self):
"""Create directories under ~.""" """Create directories under ~."""
if not self.user: if not self.user:
......
def __boot():
import sys
import os
PYTHONPATH = os.environ.get('PYTHONPATH')
if PYTHONPATH is None or (sys.platform == 'win32' and not PYTHONPATH):
PYTHONPATH = []
else:
PYTHONPATH = PYTHONPATH.split(os.pathsep)
pic = getattr(sys, 'path_importer_cache', {})
stdpath = sys.path[len(PYTHONPATH):]
mydir = os.path.dirname(__file__)
for item in stdpath:
if item == mydir or not item:
continue # skip if current dir. on Windows, or my own directory
importer = pic.get(item)
if importer is not None:
loader = importer.find_module('site')
if loader is not None:
# This should actually reload the current module
loader.load_module('site')
break
else:
try:
import imp # Avoid import loop in Python 3
stream, path, descr = imp.find_module('site', [item])
except ImportError:
continue
if stream is None:
continue
try:
# This should actually reload the current module
imp.load_module('site', stream, path, descr)
finally:
stream.close()
break
else:
raise ImportError("Couldn't find the real 'site' module")
# 2.2 comp
known_paths = dict([(
makepath(item)[1], 1) for item in sys.path]) # noqa
oldpos = getattr(sys, '__egginsert', 0) # save old insertion position
sys.__egginsert = 0 # and reset the current one
for item in PYTHONPATH:
addsitedir(item) # noqa
sys.__egginsert += oldpos # restore effective old position
d, nd = makepath(stdpath[0]) # noqa
insert_at = None
new_path = []
for item in sys.path:
p, np = makepath(item) # noqa
if np == nd and insert_at is None:
# We've hit the first 'system' path entry, so added entries go here
insert_at = len(new_path)
if np in known_paths or insert_at is None:
new_path.append(item)
else:
# new path after the insert point, back-insert it
new_path.insert(insert_at, item)
insert_at += 1
sys.path[:] = new_path
if __name__ == 'site':
__boot()
del __boot
...@@ -62,14 +62,6 @@ SETUP_PY = DALS(""" ...@@ -62,14 +62,6 @@ SETUP_PY = DALS("""
class TestEasyInstallTest: class TestEasyInstallTest:
def test_install_site_py(self, tmpdir):
dist = Distribution()
cmd = ei.easy_install(dist)
cmd.sitepy_installed = False
cmd.install_dir = str(tmpdir)
cmd.install_site_py()
assert (tmpdir / 'site.py').exists()
def test_get_script_args(self): def test_get_script_args(self):
header = ei.CommandSpec.best().from_environment().as_header() header = ei.CommandSpec.best().from_environment().as_header()
dist = FakeDist() dist = FakeDist()
......
...@@ -7,8 +7,6 @@ envlist=python ...@@ -7,8 +7,6 @@ envlist=python
minversion = 3.2 minversion = 3.2
requires = requires =
tox-pip-version >= 0.0.6 tox-pip-version >= 0.0.6
# workaround for #1998
virtualenv < 20; python_version=="2.7"
[helpers] [helpers]
# Custom pip behavior # Custom pip behavior
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment