How does the import machinery handle relative imports?

Adam Preble adam.preble at gmail.com
Thu Apr 23 02:12:06 EDT 2020


I'm fussing over some details of relative imports while trying to mimic Python module loading in my personal project. This is getting more into corner cases, but I can spare time to talk about it while working on more normal stuff.

I first found this place:
https://manikos.github.io/how-pythons-import-machinery-works

And eventually just started looking at PEP 451. Neither is really explaining relative imports. I decided to try this garbage:

from importlib.util import spec_from_loader, module_from_spec
from importlib.machinery import SourceFileLoader
spec = spec_from_loader("..import_star", SourceFileLoader("package_test.import_star", r"C:\coding\random_python_projects\package_test\import_star.py"))
print(spec)
mod = module_from_spec(spec)
print(mod)
spec.loader.exec_module(mod)

...exec_module ultimately fails to do the job. Note the syntax so that I can actually perform a relative import hahaha:

C:\Python36\python.exe -m package_test.second_level.import_upwards
ModuleSpec(name='..import_star', loader=<_frozen_importlib_external.SourceFileLoader object at 0x00000226E914B080>, origin='<unknown>')
<module '..import_star' from '<unknown>'>
Traceback (most recent call last):
  File "C:\Python36\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "C:\Python36\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "C:\coding\random_python_projects\package_test\second_level\import_upwards.py", line 15, in <module>
    spec.loader.exec_module(mod)
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 750, in get_code
  File "<frozen importlib._bootstrap_external>", line 398, in _check_name_wrapper
ImportError: loader for package_test.import_star cannot handle ..import_star


Yeah I don't think I'm doing this right! At this point I'm just trying to figure out where I feed in the relative path. Is that all deduced in advance of creating finding the spec? Can I even give the finders a relative path like that?


More information about the Python-list mailing list