This is a follow up of 2 previous discussions in the Python discourse and an issue in pypa/packaging-problems:
Summary
One of the popular ways of implementing PEP 660 is via import hooks (since other alternatives like symlinking package folders are not available in all platforms).
However the reference implementation editables currently does not support namespaces.
Specifically the dynamic path computation aspect of PEP 420 is a challenge.
After inspecting the implementation for importlib._bootstrap_external, I may have managed to find 2 solutions for this problem, described in the detail in this discourse post and demonstrated as a PoC in this gist:
- Solution A: Create a custom "path class" that tries to emulate the
_NamespacePath behaviour.
- Solution B: Create a custom
PathEntryFinder and add a “bogus” entry to sys.path just to trigger it (implicitly relying that importlib.machinery.PathFinder will take care of setting __path__ to _NamespacePath object under the hood).
However, the problem is that I don't know if these approaches are reliable in the long run and in accordance with the language specification.
Open Questions
Questions like the following are still not clear to me:
- Is there a chance that an internal check for namespace packages will fail if
__path__ uses a custom class instead of _NamespacePath even if the behaviour described in PEP 420 is observed?
- Can we rely on the fact that the import machinery will automatically set the namespace loader for specs in the form of
ModuleSpec("name", None, is_package=True)?
- Is
pkgutil (and particularly pkgutil.extend_path) still considered first class citizen of the standard library or is it better to avoid it when writing new code?
- Can we rely on the behaviour of
sys.path_hooks + importlib.machinery.PathFinder to create ModuleSpec objects for namespaces that will automatically perform dynamic path computation? Or is this an internal implementation detail that can change in the future?
If the discussed approaches are not recommended, how can we support namespace packages using import hooks and deliver a complete solution for PEP 660?
This is a follow up of 2 previous discussions in the Python discourse and an issue in
pypa/packaging-problems:Summary
One of the popular ways of implementing PEP 660 is via import hooks (since other alternatives like
symlinkingpackage folders are not available in all platforms).However the reference implementation
editablescurrently does not support namespaces.Specifically the dynamic path computation aspect of PEP 420 is a challenge.
After inspecting the implementation for
importlib._bootstrap_external, I may have managed to find 2 solutions for this problem, described in the detail in this discourse post and demonstrated as a PoC in this gist:_NamespacePathbehaviour.PathEntryFinderand add a “bogus” entry tosys.pathjust to trigger it (implicitly relying thatimportlib.machinery.PathFinderwill take care of setting__path__to_NamespacePathobject under the hood).However, the problem is that I don't know if these approaches are reliable in the long run and in accordance with the language specification.
Open Questions
Questions like the following are still not clear to me:
__path__uses a custom class instead of_NamespacePatheven if the behaviour described in PEP 420 is observed?ModuleSpec("name", None, is_package=True)?pkgutil(and particularlypkgutil.extend_path) still considered first class citizen of the standard library or is it better to avoid it when writing new code?sys.path_hooks+importlib.machinery.PathFinderto createModuleSpecobjects for namespaces that will automatically perform dynamic path computation? Or is this an internal implementation detail that can change in the future?If the discussed approaches are not recommended, how can we support namespace packages using import hooks and deliver a complete solution for PEP 660?