This notebook demonstrates the __path__
attribute. The __path__
attribute is required to import
modules within packages. Having a __path__
in a running notebook will permit relative imports.
The post builds off The Simplest importer for a notebook.
from deathbeds import __The_simplest_path_hook_importer_for_a_notebook as importer
import sys, importlib, pytest
try: del __path__
except: ...
('deathbeds.2018-07-08-The-simplest-path-hook-importer-for-a-notebook', <importnb.loader.Notebook object at 0x00000269C29159C8>) {'origin': 'c:\\users\\deathbeds\\deathbeds.github.io\\deathbeds\\2018-07-08-The-simplest-path-hook-importer-for-a-notebook.ipynb', 'loader_state': None, 'is_package': False}
Typically my notebook is filled with garbage. The snippet below resets the normal sys.path_hooks
behavior.
sys.path_hooks[1] = importlib._bootstrap_external.FileFinder.path_hook(importlib._bootstrap_external._get_supported_file_loaders())
Add the simplest notebook importer as a sys.path_hook
.
importer.new_loader((importer.NotebookLoader, ('.ipynb',)))
Clear the importer cache (forgetting this statement always slips me up) and show the existing importers.
sys.path_importer_cache.clear() or sys.path_hooks[1].__closure__[1].cell_contents
((deathbeds.2018-07-08-The-simplest-path-hook-importer-for-a-notebook.NotebookLoader, ('.ipynb',)), (_frozen_importlib_external.ExtensionFileLoader, ['.cp36-win_amd64.pyd', '.pyd']), (_frozen_importlib_external.SourceFileLoader, ['.py', '.pyw']), (_frozen_importlib_external.SourcelessFileLoader, ['.pyc']))
Force remove the __path__
from the namespace.
if __name__ == '__main__': globals().pop('__path__', None)
Demonstrate that 2018-11-26-Relative-imports
cannot be imported from __main__
.
if __name__ == '__main__':
with pytest.raises(ImportError): importlib.import_module('.2018-11-26-Relative-imports', '__main__')
Add the __path__
back to the namespace.
__path__ = ['.']
Demonstrate that the module maybe imported.
module = importlib.import_module('.2018-11-26-Relative-imports', '__main__')
Test
that module
is a package relative to __main__
and notebook.
class Test:
""">>> assert module.__package__ == '__main__'
>>> assert module.__file__.endswith('.ipynb')"""
if __name__ == '__main__': __import__('doctest').testmod(verbose=True)
Trying: assert module.__package__ == '__main__' Expecting nothing ok Trying: assert module.__file__.endswith('.ipynb') Expecting nothing ok 1 items had no tests: __main__ 1 items passed all tests: 2 tests in __main__.Test 2 tests in 2 items. 2 passed and 0 failed. Test passed.