-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
WIP direct module load shims #2964
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,6 +74,9 @@ def do_override(): | |
|
||
|
||
class DistutilsMetaFinder: | ||
# for forensic purposes, since we may not be able to get at the module object easily | ||
_fromfile = __file__ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe accessing |
||
|
||
def find_spec(self, fullname, path, target=None): | ||
if path is not None: | ||
return | ||
|
@@ -86,8 +89,16 @@ def spec_for_distutils(self): | |
import importlib.abc | ||
import importlib.util | ||
|
||
class DistutilsLoader(importlib.abc.Loader): | ||
st = importlib.import_module('setuptools') | ||
if os.path.dirname(st.__file__) != os.path.dirname(__file__): | ||
# no-op; the setuptools we imported was from a foreign site-packages dir, remove self from meta_path | ||
remove_shim() | ||
return None | ||
else: | ||
# we're a sibling of the setuptools that actually got imported; kill any other shims | ||
remove_foreign_shims() | ||
|
||
class DistutilsLoader(importlib.abc.Loader): | ||
def create_module(self, spec): | ||
return importlib.import_module('setuptools._distutils') | ||
|
||
|
@@ -130,7 +141,8 @@ def frame_file_is_setup(frame): | |
|
||
|
||
def ensure_shim(): | ||
DISTUTILS_FINDER in sys.meta_path or add_shim() | ||
if not (any(s for s in sys.meta_path if type(s).__name__ == 'DistutilsMetaFinder' and getattr(s, '_fromfile', None) == DistutilsMetaFinder._fromfile)): | ||
add_shim() | ||
Comment on lines
+144
to
+145
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh, this is unfortunate. Because the shim might be invoked independently several times, it has to detect different instances of the same name and origin. This complexity is one argument for keeping _distutils_hack as a top-level module in order to rely on import semantics to resolve exactly one instance of the module/finder per origin. I'd like to explore an approach that doesn't require touching some many different aspects of the implementation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was the point though- since the requirements for the shim are certainly a moving target, the only sure way to get the right shim behavior for any given version of setuptools is to let each setuptools load its own locally, then clean up the others when one actually "fires". It's definitely "icky", but given the restrictions of what you can actually do in a |
||
|
||
|
||
@contextlib.contextmanager | ||
|
@@ -151,3 +163,15 @@ def remove_shim(): | |
sys.meta_path.remove(DISTUTILS_FINDER) | ||
except ValueError: | ||
pass | ||
|
||
|
||
def remove_foreign_shims(): | ||
""" | ||
Remove setuptools metapath shims that might've been installed by other installations on sys.path | ||
""" | ||
try: | ||
foreign_shims = [l for l in sys.meta_path if type(l).__name__ == 'DistutilsMetaFinder' and l is not DISTUTILS_FINDER] | ||
for shim in foreign_shims: | ||
sys.meta_path.remove(shim) | ||
except Exception: | ||
pass |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introducing imperative code ahead of imports is going to cause flake8 errors on all the subsequent imports. I'd suggest to just keep the previous technique where the shim is a package and a module of the package can be imported to invoke the behavior. i.e.
mv _distutils_hack setuptools/_distutils_shim
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This one's easy to solve any number of ways since it's a real import (I was just lazy with the PoC), but I think you're already starting to see the problems that the extra top-level package can cause (eg, d0da014)