Skip to content

Commit 6aa2cc7

Browse files
author
Sigrid Tofte Thiis
committed
Initial commit
0 parents  commit 6aa2cc7

8,572 files changed

Lines changed: 1405973 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
import __editable___loop_algorithm_to_python_adaptive_0_0_1_finder; __editable___loop_algorithm_to_python_adaptive_0_0_1_finder.install()
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from __future__ import annotations
2+
import sys
3+
from importlib.machinery import ModuleSpec, PathFinder
4+
from importlib.machinery import all_suffixes as module_suffixes
5+
from importlib.util import spec_from_file_location
6+
from itertools import chain
7+
from pathlib import Path
8+
9+
MAPPING: dict[str, str] = {'loop_to_python_adaptive': 'C:\\Users\\sigridtt\\Documents\\project\\LoopAlgorithmToPythonAdaptive\\loop_to_python_adaptive'}
10+
NAMESPACES: dict[str, list[str]] = {}
11+
PATH_PLACEHOLDER = '__editable__.loop_algorithm_to_python_adaptive-0.0.1.finder' + ".__path_hook__"
12+
13+
14+
class _EditableFinder: # MetaPathFinder
15+
@classmethod
16+
def find_spec(cls, fullname: str, path=None, target=None) -> ModuleSpec | None: # type: ignore
17+
# Top-level packages and modules (we know these exist in the FS)
18+
if fullname in MAPPING:
19+
pkg_path = MAPPING[fullname]
20+
return cls._find_spec(fullname, Path(pkg_path))
21+
22+
# Handle immediate children modules (required for namespaces to work)
23+
# To avoid problems with case sensitivity in the file system we delegate
24+
# to the importlib.machinery implementation.
25+
parent, _, child = fullname.rpartition(".")
26+
if parent and parent in MAPPING:
27+
return PathFinder.find_spec(fullname, path=[MAPPING[parent]])
28+
29+
# Other levels of nesting should be handled automatically by importlib
30+
# using the parent path.
31+
return None
32+
33+
@classmethod
34+
def _find_spec(cls, fullname: str, candidate_path: Path) -> ModuleSpec | None:
35+
init = candidate_path / "__init__.py"
36+
candidates = (candidate_path.with_suffix(x) for x in module_suffixes())
37+
for candidate in chain([init], candidates):
38+
if candidate.exists():
39+
return spec_from_file_location(fullname, candidate)
40+
return None
41+
42+
43+
class _EditableNamespaceFinder: # PathEntryFinder
44+
@classmethod
45+
def _path_hook(cls, path) -> type[_EditableNamespaceFinder]:
46+
if path == PATH_PLACEHOLDER:
47+
return cls
48+
raise ImportError
49+
50+
@classmethod
51+
def _paths(cls, fullname: str) -> list[str]:
52+
paths = NAMESPACES[fullname]
53+
if not paths and fullname in MAPPING:
54+
paths = [MAPPING[fullname]]
55+
# Always add placeholder, for 2 reasons:
56+
# 1. __path__ cannot be empty for the spec to be considered namespace.
57+
# 2. In the case of nested namespaces, we need to force
58+
# import machinery to query _EditableNamespaceFinder again.
59+
return [*paths, PATH_PLACEHOLDER]
60+
61+
@classmethod
62+
def find_spec(cls, fullname: str, target=None) -> ModuleSpec | None: # type: ignore
63+
if fullname in NAMESPACES:
64+
spec = ModuleSpec(fullname, None, is_package=True)
65+
spec.submodule_search_locations = cls._paths(fullname)
66+
return spec
67+
return None
68+
69+
@classmethod
70+
def find_module(cls, _fullname) -> None:
71+
return None
72+
73+
74+
def install():
75+
if not any(finder == _EditableFinder for finder in sys.meta_path):
76+
sys.meta_path.append(_EditableFinder)
77+
78+
if not NAMESPACES:
79+
return
80+
81+
if not any(hook == _EditableNamespaceFinder._path_hook for hook in sys.path_hooks):
82+
# PathEntryFinder is needed to create NamespaceSpec without private APIS
83+
sys.path_hooks.append(_EditableNamespaceFinder._path_hook)
84+
if PATH_PLACEHOLDER not in sys.path:
85+
sys.path.append(PATH_PLACEHOLDER) # Used just to trigger the path hook
425 Bytes
Binary file not shown.
27 KB
Binary file not shown.
Binary file not shown.
Lines changed: 239 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,239 @@
1+
# don't import any costly modules
2+
import os
3+
import sys
4+
5+
report_url = (
6+
"https://github.com/pypa/setuptools/issues/new?template=distutils-deprecation.yml"
7+
)
8+
9+
10+
def warn_distutils_present():
11+
if 'distutils' not in sys.modules:
12+
return
13+
import warnings
14+
15+
warnings.warn(
16+
"Distutils was imported before Setuptools, but importing Setuptools "
17+
"also replaces the `distutils` module in `sys.modules`. This may lead "
18+
"to undesirable behaviors or errors. To avoid these issues, avoid "
19+
"using distutils directly, ensure that setuptools is installed in the "
20+
"traditional way (e.g. not an editable install), and/or make sure "
21+
"that setuptools is always imported before distutils."
22+
)
23+
24+
25+
def clear_distutils():
26+
if 'distutils' not in sys.modules:
27+
return
28+
import warnings
29+
30+
warnings.warn(
31+
"Setuptools is replacing distutils. Support for replacing "
32+
"an already imported distutils is deprecated. In the future, "
33+
"this condition will fail. "
34+
f"Register concerns at {report_url}"
35+
)
36+
mods = [
37+
name
38+
for name in sys.modules
39+
if name == "distutils" or name.startswith("distutils.")
40+
]
41+
for name in mods:
42+
del sys.modules[name]
43+
44+
45+
def enabled():
46+
"""
47+
Allow selection of distutils by environment variable.
48+
"""
49+
which = os.environ.get('SETUPTOOLS_USE_DISTUTILS', 'local')
50+
if which == 'stdlib':
51+
import warnings
52+
53+
warnings.warn(
54+
"Reliance on distutils from stdlib is deprecated. Users "
55+
"must rely on setuptools to provide the distutils module. "
56+
"Avoid importing distutils or import setuptools first, "
57+
"and avoid setting SETUPTOOLS_USE_DISTUTILS=stdlib. "
58+
f"Register concerns at {report_url}"
59+
)
60+
return which == 'local'
61+
62+
63+
def ensure_local_distutils():
64+
import importlib
65+
66+
clear_distutils()
67+
68+
# With the DistutilsMetaFinder in place,
69+
# perform an import to cause distutils to be
70+
# loaded from setuptools._distutils. Ref #2906.
71+
with shim():
72+
importlib.import_module('distutils')
73+
74+
# check that submodules load as expected
75+
core = importlib.import_module('distutils.core')
76+
assert '_distutils' in core.__file__, core.__file__
77+
assert 'setuptools._distutils.log' not in sys.modules
78+
79+
80+
def do_override():
81+
"""
82+
Ensure that the local copy of distutils is preferred over stdlib.
83+
84+
See https://github.com/pypa/setuptools/issues/417#issuecomment-392298401
85+
for more motivation.
86+
"""
87+
if enabled():
88+
warn_distutils_present()
89+
ensure_local_distutils()
90+
91+
92+
class _TrivialRe:
93+
def __init__(self, *patterns) -> None:
94+
self._patterns = patterns
95+
96+
def match(self, string):
97+
return all(pat in string for pat in self._patterns)
98+
99+
100+
class DistutilsMetaFinder:
101+
def find_spec(self, fullname, path, target=None):
102+
# optimization: only consider top level modules and those
103+
# found in the CPython test suite.
104+
if path is not None and not fullname.startswith('test.'):
105+
return None
106+
107+
method_name = 'spec_for_{fullname}'.format(**locals())
108+
method = getattr(self, method_name, lambda: None)
109+
return method()
110+
111+
def spec_for_distutils(self):
112+
if self.is_cpython():
113+
return None
114+
115+
import importlib
116+
import importlib.abc
117+
import importlib.util
118+
119+
try:
120+
mod = importlib.import_module('setuptools._distutils')
121+
except Exception:
122+
# There are a couple of cases where setuptools._distutils
123+
# may not be present:
124+
# - An older Setuptools without a local distutils is
125+
# taking precedence. Ref #2957.
126+
# - Path manipulation during sitecustomize removes
127+
# setuptools from the path but only after the hook
128+
# has been loaded. Ref #2980.
129+
# In either case, fall back to stdlib behavior.
130+
return None
131+
132+
class DistutilsLoader(importlib.abc.Loader):
133+
def create_module(self, spec):
134+
mod.__name__ = 'distutils'
135+
return mod
136+
137+
def exec_module(self, module):
138+
pass
139+
140+
return importlib.util.spec_from_loader(
141+
'distutils', DistutilsLoader(), origin=mod.__file__
142+
)
143+
144+
@staticmethod
145+
def is_cpython():
146+
"""
147+
Suppress supplying distutils for CPython (build and tests).
148+
Ref #2965 and #3007.
149+
"""
150+
return os.path.isfile('pybuilddir.txt')
151+
152+
def spec_for_pip(self):
153+
"""
154+
Ensure stdlib distutils when running under pip.
155+
See pypa/pip#8761 for rationale.
156+
"""
157+
if sys.version_info >= (3, 12) or self.pip_imported_during_build():
158+
return
159+
clear_distutils()
160+
self.spec_for_distutils = lambda: None
161+
162+
@classmethod
163+
def pip_imported_during_build(cls):
164+
"""
165+
Detect if pip is being imported in a build script. Ref #2355.
166+
"""
167+
import traceback
168+
169+
return any(
170+
cls.frame_file_is_setup(frame) for frame, line in traceback.walk_stack(None)
171+
)
172+
173+
@staticmethod
174+
def frame_file_is_setup(frame):
175+
"""
176+
Return True if the indicated frame suggests a setup.py file.
177+
"""
178+
# some frames may not have __file__ (#2940)
179+
return frame.f_globals.get('__file__', '').endswith('setup.py')
180+
181+
def spec_for_sensitive_tests(self):
182+
"""
183+
Ensure stdlib distutils when running select tests under CPython.
184+
185+
python/cpython#91169
186+
"""
187+
clear_distutils()
188+
self.spec_for_distutils = lambda: None
189+
190+
sensitive_tests = (
191+
[
192+
'test.test_distutils',
193+
'test.test_peg_generator',
194+
'test.test_importlib',
195+
]
196+
if sys.version_info < (3, 10)
197+
else [
198+
'test.test_distutils',
199+
]
200+
)
201+
202+
203+
for name in DistutilsMetaFinder.sensitive_tests:
204+
setattr(
205+
DistutilsMetaFinder,
206+
f'spec_for_{name}',
207+
DistutilsMetaFinder.spec_for_sensitive_tests,
208+
)
209+
210+
211+
DISTUTILS_FINDER = DistutilsMetaFinder()
212+
213+
214+
def add_shim():
215+
DISTUTILS_FINDER in sys.meta_path or insert_shim()
216+
217+
218+
class shim:
219+
def __enter__(self) -> None:
220+
insert_shim()
221+
222+
def __exit__(self, exc: object, value: object, tb: object) -> None:
223+
_remove_shim()
224+
225+
226+
def insert_shim():
227+
sys.meta_path.insert(0, DISTUTILS_FINDER)
228+
229+
230+
def _remove_shim():
231+
try:
232+
sys.meta_path.remove(DISTUTILS_FINDER)
233+
except ValueError:
234+
pass
235+
236+
237+
if sys.version_info < (3, 12):
238+
# DistutilsMetaFinder can only be disabled in Python < 3.12 (PEP 632)
239+
remove_shim = _remove_shim
Binary file not shown.
Binary file not shown.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
__import__('_distutils_hack').do_override()

0 commit comments

Comments
 (0)