|
41 | 41 | # For debugging purposes
|
42 | 42 | from rich.console import Console
|
43 | 43 |
|
| 44 | +from scalene.get_module_details import _get_module_details |
44 | 45 | from scalene.find_browser import find_browser
|
45 | 46 |
|
46 |
| -console = Console(style="white on blue") |
47 |
| -def nada(*args): |
48 |
| - pass |
49 |
| -# Assigning to `nada` disables any console.log commands. |
50 |
| -console.log = nada |
51 |
| - |
52 | 47 | from collections import defaultdict
|
53 | 48 | from importlib.abc import SourceLoader
|
54 | 49 | from importlib.machinery import ModuleSpec
|
@@ -95,6 +90,12 @@ def nada(*args):
|
95 | 90 | from scalene.scalene_parseargs import ScaleneParseArgs, StopJupyterExecution
|
96 | 91 | from scalene.scalene_sigqueue import ScaleneSigQueue
|
97 | 92 |
|
| 93 | +console = Console(style="white on blue") |
| 94 | +# Assigning to `nada` disables any console.log commands. |
| 95 | +def nada(*args: Any) -> None: |
| 96 | + pass |
| 97 | +console.log = nada |
| 98 | + |
98 | 99 | MINIMUM_PYTHON_VERSION_MAJOR = 3
|
99 | 100 | MINIMUM_PYTHON_VERSION_MINOR = 8
|
100 | 101 |
|
@@ -160,84 +161,7 @@ def start() -> None:
|
160 | 161 | def stop() -> None:
|
161 | 162 | """Stop profiling."""
|
162 | 163 | Scalene.stop()
|
163 |
| - |
164 |
| - |
165 |
| -def _get_module_details( |
166 |
| - mod_name: str, |
167 |
| - error: Type[Exception] = ImportError, |
168 |
| -) -> Tuple[str, ModuleSpec, CodeType]: |
169 |
| - """Copy of `runpy._get_module_details`, but not private.""" |
170 |
| - if mod_name.startswith("."): |
171 |
| - raise error("Relative module names not supported") |
172 |
| - pkg_name, _, _ = mod_name.rpartition(".") |
173 |
| - if pkg_name: |
174 |
| - # Try importing the parent to avoid catching initialization errors |
175 |
| - try: |
176 |
| - __import__(pkg_name) |
177 |
| - except ImportError as e: |
178 |
| - # If the parent or higher ancestor package is missing, let the |
179 |
| - # error be raised by find_spec() below and then be caught. But do |
180 |
| - # not allow other errors to be caught. |
181 |
| - if e.name is None or ( |
182 |
| - e.name != pkg_name and not pkg_name.startswith(e.name + ".") |
183 |
| - ): |
184 |
| - raise |
185 |
| - # Warn if the module has already been imported under its normal name |
186 |
| - existing = sys.modules.get(mod_name) |
187 |
| - if existing is not None and not hasattr(existing, "__path__"): |
188 |
| - from warnings import warn |
189 |
| - |
190 |
| - msg = ( |
191 |
| - "{mod_name!r} found in sys.modules after import of " |
192 |
| - "package {pkg_name!r}, but prior to execution of " |
193 |
| - "{mod_name!r}; this may result in unpredictable " |
194 |
| - "behaviour".format(mod_name=mod_name, pkg_name=pkg_name) |
195 |
| - ) |
196 |
| - warn(RuntimeWarning(msg)) |
197 |
| - |
198 |
| - try: |
199 |
| - spec = importlib.util.find_spec(mod_name) |
200 |
| - except (ImportError, AttributeError, TypeError, ValueError) as ex: |
201 |
| - # This hack fixes an impedance mismatch between pkgutil and |
202 |
| - # importlib, where the latter raises other errors for cases where |
203 |
| - # pkgutil previously raised ImportError |
204 |
| - msg = "Error while finding module specification for {!r} ({}: {})" |
205 |
| - if mod_name.endswith(".py"): |
206 |
| - msg += ( |
207 |
| - f". Try using '{mod_name[:-3]}' instead of " |
208 |
| - f"'{mod_name}' as the module name." |
209 |
| - ) |
210 |
| - raise error(msg.format(mod_name, type(ex).__name__, ex)) from ex |
211 |
| - if spec is None: |
212 |
| - raise error("No module named %s" % mod_name) |
213 |
| - if spec.submodule_search_locations is not None: |
214 |
| - if mod_name == "__main__" or mod_name.endswith(".__main__"): |
215 |
| - raise error("Cannot use package as __main__ module") |
216 |
| - try: |
217 |
| - pkg_main_name = mod_name + ".__main__" |
218 |
| - return _get_module_details(pkg_main_name, error) |
219 |
| - except error as e: |
220 |
| - if mod_name not in sys.modules: |
221 |
| - raise # No module loaded; being a package is irrelevant |
222 |
| - raise error( |
223 |
| - ("%s; %r is a package and cannot " + "be directly executed") |
224 |
| - % (e, mod_name) |
225 |
| - ) |
226 |
| - loader = spec.loader |
227 |
| - # use isinstance instead of `is None` to placate mypy |
228 |
| - if not isinstance(loader, SourceLoader): |
229 |
| - raise error( |
230 |
| - "%r is a namespace package and cannot be executed" % mod_name |
231 |
| - ) |
232 |
| - try: |
233 |
| - code = loader.get_code(mod_name) |
234 |
| - except ImportError as e: |
235 |
| - raise error(format(e)) from e |
236 |
| - if code is None: |
237 |
| - raise error("No code object available for %s" % mod_name) |
238 |
| - return mod_name, spec, code |
239 |
| - |
240 |
| - |
| 164 | + |
241 | 165 | class Scalene:
|
242 | 166 | """The Scalene profiler itself."""
|
243 | 167 |
|
|
0 commit comments