forked from pypa/virtualenv
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
use import hooks to patch distutils/setuptools (pypa#1688)
- Loading branch information
1 parent
c310a95
commit caae48b
Showing
10 changed files
with
119 additions
and
98 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Having `distutils configuration <https://docs.python.org/3/install/index.html#distutils-configuration-files>`_ | ||
files that set ``prefix`` and ``install_scripts`` cause installation of packages in the wrong location - | ||
by :user:`gaborbernat`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fix startup on Python 2 is slower for virtualenv - this was due to setuptools calculating it's working set distribution | ||
- by :user:`gaborbernat`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
Fix entry points are not populated for editable installs on Python 2 due to setuptools working set being calculated | ||
before ``easy_install.pth`` runs - by :user:`gaborbernat`. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Fix ``attr:`` import fails for setuptools - by :user:`gaborbernat`. |
49 changes: 0 additions & 49 deletions
49
src/virtualenv/create/via_global_ref/_distutils_patch_virtualenv.py
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
"""Patches that are applied at runtime to the virtual environment""" | ||
# -*- coding: utf-8 -*- | ||
|
||
import os | ||
import sys | ||
|
||
VIRTUALENV_PATCH_FILE = os.path.join(__file__) | ||
|
||
|
||
def patch_dist(dist): | ||
""" | ||
Distutils allows user to configure some arguments via a configuration file: | ||
https://docs.python.org/3/install/index.html#distutils-configuration-files | ||
Some of this arguments though don't make sense in context of the virtual environment files, let's fix them up. | ||
""" | ||
# we cannot allow some install config as that would get packages installed outside of the virtual environment | ||
old_parse_config_files = dist.Distribution.parse_config_files | ||
|
||
def parse_config_files(self, *args, **kwargs): | ||
result = old_parse_config_files(self, *args, **kwargs) | ||
install = self.get_option_dict("install") | ||
|
||
if "prefix" in install: # the prefix governs where to install the libraries | ||
install["prefix"] = VIRTUALENV_PATCH_FILE, os.path.abspath(sys.prefix) | ||
|
||
if "install_scripts" in install: # the install_scripts governs where to generate console scripts | ||
script_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "__SCRIPT_DIR__")) | ||
install["install_scripts"] = VIRTUALENV_PATCH_FILE, script_path | ||
|
||
return result | ||
|
||
dist.Distribution.parse_config_files = parse_config_files | ||
|
||
|
||
# Import hook that patches some modules to ignore configuration values that break package installation in case | ||
# of virtual environments. | ||
_DISTUTILS_PATCH = "distutils.dist", "setuptools.dist" | ||
if sys.version_info > (3, 4): | ||
# https://docs.python.org/3/library/importlib.html#setting-up-an-importer | ||
from importlib.abc import MetaPathFinder | ||
from importlib.util import find_spec | ||
from threading import Lock | ||
|
||
class _Finder(MetaPathFinder): | ||
"""A meta path finder that allows patching the imported distutils modules""" | ||
|
||
fullname = None | ||
lock = Lock() | ||
|
||
def find_spec(self, fullname, path, target=None): | ||
if fullname in _DISTUTILS_PATCH and self.fullname is None: | ||
with self.lock: | ||
self.fullname = fullname | ||
try: | ||
spec = find_spec(fullname, path) | ||
if spec is not None: | ||
old = spec.loader.exec_module | ||
|
||
def exec_module(module): | ||
old(module) | ||
patch_dist(module) | ||
|
||
spec.loader.exec_module = exec_module | ||
return spec | ||
finally: | ||
self.fullname = None | ||
|
||
sys.meta_path.insert(0, _Finder()) | ||
else: | ||
# https://www.python.org/dev/peps/pep-0302/ | ||
from imp import find_module | ||
from pkgutil import ImpImporter, ImpLoader | ||
|
||
class _VirtualenvImporter(object, ImpImporter): | ||
def __init__(self, path=None): | ||
object.__init__(self) | ||
ImpImporter.__init__(self, path) | ||
|
||
def find_module(self, fullname, path=None): | ||
if fullname in _DISTUTILS_PATCH: | ||
try: | ||
return _VirtualenvLoader(fullname, *find_module(fullname.split(".")[-1], path)) | ||
except ImportError: | ||
pass | ||
return None | ||
|
||
class _VirtualenvLoader(object, ImpLoader): | ||
def __init__(self, fullname, file, filename, etc): | ||
object.__init__(self) | ||
ImpLoader.__init__(self, fullname, file, filename, etc) | ||
|
||
def load_module(self, fullname): | ||
module = super(_VirtualenvLoader, self).load_module(fullname) | ||
patch_dist(module) | ||
module.__loader__ = None # distlib fallback | ||
return module | ||
|
||
sys.meta_path.append(_VirtualenvImporter()) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters