From 3c5af7383a75b076fa2575b4a543b37b31f6ff2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Tue, 28 May 2024 17:12:23 +0100 Subject: [PATCH 1/9] GH-119668: expose importlib.NamespacePath MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Lib/importlib/_bootstrap_external.py | 15 +++++++++------ Lib/importlib/machinery.py | 1 + 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 30c91801212374..8ce9e98841ca23 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1346,7 +1346,7 @@ def get_filename(self, fullname): return self.path -class _NamespacePath: +class NamespacePath: """Represents a namespace package's path. It uses the module name to find its parent module, and from there it looks up the parent's __path__. When this changes, the module's own path is recomputed, @@ -1405,7 +1405,7 @@ def __len__(self): return len(self._recalculate()) def __repr__(self): - return f'_NamespacePath({self._path!r})' + return f'NamespacePath({self._path!r})' def __contains__(self, item): return item in self._recalculate() @@ -1414,12 +1414,15 @@ def append(self, item): self._path.append(item) +_NamespacePath = NamespacePath # for backwards compatibility + + # This class is actually exposed publicly in a namespace package's __loader__ # attribute, so it should be available through a non-private name. # https://github.com/python/cpython/issues/92054 class NamespaceLoader: def __init__(self, name, path, path_finder): - self._path = _NamespacePath(name, path, path_finder) + self._path = NamespacePath(name, path, path_finder) def is_package(self, fullname): return True @@ -1474,9 +1477,9 @@ def invalidate_caches(): del sys.path_importer_cache[name] elif hasattr(finder, 'invalidate_caches'): finder.invalidate_caches() - # Also invalidate the caches of _NamespacePaths + # Also invalidate the caches of NamespacePaths # https://bugs.python.org/issue45703 - _NamespacePath._epoch += 1 + NamespacePath._epoch += 1 from importlib.metadata import MetadataPathFinder MetadataPathFinder.invalidate_caches() @@ -1562,7 +1565,7 @@ def find_spec(cls, fullname, path=None, target=None): # We found at least one namespace path. Return a spec which # can create the namespace package. spec.origin = None - spec.submodule_search_locations = _NamespacePath(fullname, namespace_path, cls._get_spec) + spec.submodule_search_locations = NamespacePath(fullname, namespace_path, cls._get_spec) return spec else: return None diff --git a/Lib/importlib/machinery.py b/Lib/importlib/machinery.py index fbd30b159fb752..8809b8ec1e1cef 100644 --- a/Lib/importlib/machinery.py +++ b/Lib/importlib/machinery.py @@ -14,6 +14,7 @@ from ._bootstrap_external import ExtensionFileLoader from ._bootstrap_external import AppleFrameworkLoader from ._bootstrap_external import NamespaceLoader +from ._bootstrap_external import NamespacePath def all_suffixes(): From 668b8ff5fbb0abccbdb9450c54c394d6e64a8a7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Tue, 28 May 2024 17:14:35 +0100 Subject: [PATCH 2/9] add news MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- .../next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst diff --git a/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst new file mode 100644 index 00000000000000..cb49c819b22f40 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst @@ -0,0 +1 @@ +Expose :py:class:`importlib.NamespacePath`. From 02ceeb5390bdaa3c335b02068ba4075dc5b1f8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Tue, 28 May 2024 17:17:24 +0100 Subject: [PATCH 3/9] add to docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Doc/library/importlib.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 2ec15dd171c18a..c8f53c49843b1c 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1006,6 +1006,14 @@ find and load modules. :exc:`ImportError` is raised. +.. class:: NamespacePath(name, path, path_finder) + + Represents a namespace package's path. It uses the module name to find its + parent module, and from there it looks up the parent's ``__path__``. When + this changes, the module's own path is recomputed, using path_finder. For + top-level modules, the parent module's path is :py:data:`sys.path`. + + .. class:: SourceFileLoader(fullname, path) A concrete implementation of :class:`importlib.abc.SourceLoader` by From 29df08fba99483c2cb7b60c8ddba4586d093f9cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 21 Jul 2024 21:08:52 +0100 Subject: [PATCH 4/9] Apply suggestions from code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com> --- Doc/library/importlib.rst | 6 +++--- .../Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index c8f53c49843b1c..5e70b0953632ce 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -1008,10 +1008,10 @@ find and load modules. .. class:: NamespacePath(name, path, path_finder) - Represents a namespace package's path. It uses the module name to find its + Represents a namespace package's path. It uses the module *name* to find its parent module, and from there it looks up the parent's ``__path__``. When - this changes, the module's own path is recomputed, using path_finder. For - top-level modules, the parent module's path is :py:data:`sys.path`. + this changes, the module's own path is recomputed, using *path_finder*. For + top-level modules, the parent module's path is :data:`sys.path`. .. class:: SourceFileLoader(fullname, path) diff --git a/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst index cb49c819b22f40..7ad8dd03d8679d 100644 --- a/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst +++ b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst @@ -1 +1 @@ -Expose :py:class:`importlib.NamespacePath`. +Expose :class:`importlib.NamespacePath`. From 0dd0520a351493b4ada8a1b2b9480c08d30f3842 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 17 Nov 2024 03:38:34 +0000 Subject: [PATCH 5/9] Fix news (importlib.NamespacePath > importlib.machinery.NamespacePath) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- .../next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst index 7ad8dd03d8679d..69d9858ce186e0 100644 --- a/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst +++ b/Misc/NEWS.d/next/Library/2024-05-28-17-14-30.gh-issue-119668.RrIGpn.rst @@ -1 +1 @@ -Expose :class:`importlib.NamespacePath`. +Expose :class:`importlib.machinery.NamespacePath`. From 06b89067b00c8431c51a422bd60c07a670060725 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 17 Nov 2024 03:46:37 +0000 Subject: [PATCH 6/9] Link to module.__path__ in NamespacePath docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Doc/library/importlib.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index ebfb2604621c7a..eafad46632d358 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -988,9 +988,10 @@ find and load modules. .. class:: NamespacePath(name, path, path_finder) Represents a namespace package's path. It uses the module *name* to find its - parent module, and from there it looks up the parent's ``__path__``. When - this changes, the module's own path is recomputed, using *path_finder*. For - top-level modules, the parent module's path is :data:`sys.path`. + parent module, and from there it looks up the parent's + :attr:`module.__path__`. When this changes, the module's own path is + recomputed, using *path_finder*. For top-level modules, the parent module's + path is :data:`sys.path`. .. class:: SourceFileLoader(fullname, path) From cd506a4ccb277556d7548370bd4c3b1274ec7fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 17 Nov 2024 03:57:00 +0000 Subject: [PATCH 7/9] Mention the path argument in the documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Doc/library/importlib.rst | 13 ++++++++----- Lib/importlib/_bootstrap_external.py | 13 ++++++++----- 2 files changed, 16 insertions(+), 10 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index eafad46632d358..649e71d9228b7a 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -987,11 +987,14 @@ find and load modules. .. class:: NamespacePath(name, path, path_finder) - Represents a namespace package's path. It uses the module *name* to find its - parent module, and from there it looks up the parent's - :attr:`module.__path__`. When this changes, the module's own path is - recomputed, using *path_finder*. For top-level modules, the parent module's - path is :data:`sys.path`. + Represents a namespace package's path. + + It uses the module *name* to find its parent module, and from there it looks + up the parent's :attr:`module.__path__`. When this changes, the module's own + path is recomputed, using *path_finder*. The initial package path value is + set to *path*. + + For top-level modules, the parent module's path is :data:`sys.path`. .. class:: SourceFileLoader(fullname, path) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 24d7afc502eaa6..b5768e8c5966d4 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1080,11 +1080,14 @@ def get_filename(self, fullname): class NamespacePath: - """Represents a namespace package's path. It uses the module name - to find its parent module, and from there it looks up the parent's - __path__. When this changes, the module's own path is recomputed, - using path_finder. For top-level modules, the parent module's path - is sys.path.""" + """Represents a namespace package's path. + + It uses the module name to find its parent module, and from there it looks + up the parent's __path__. When this changes, the module's own path is + recomputed, using path_finder. The initial package path value is set to path. + + For top-level modules, the parent module's path is sys.path. + """ # When invalidate_caches() is called, this epoch is incremented # https://bugs.python.org/issue45703 From 6f441c4462b9c0968113a0409d29955d6c50ccd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 17 Nov 2024 03:58:39 +0000 Subject: [PATCH 8/9] Simplify docs text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Doc/library/importlib.rst | 3 +-- Lib/importlib/_bootstrap_external.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Doc/library/importlib.rst b/Doc/library/importlib.rst index 649e71d9228b7a..2b38ab81e201b1 100644 --- a/Doc/library/importlib.rst +++ b/Doc/library/importlib.rst @@ -991,8 +991,7 @@ find and load modules. It uses the module *name* to find its parent module, and from there it looks up the parent's :attr:`module.__path__`. When this changes, the module's own - path is recomputed, using *path_finder*. The initial package path value is - set to *path*. + path is recomputed, using *path_finder*. The initial value is set to *path*. For top-level modules, the parent module's path is :data:`sys.path`. diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index b5768e8c5966d4..4a87f1cf0e8a32 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1084,7 +1084,7 @@ class NamespacePath: It uses the module name to find its parent module, and from there it looks up the parent's __path__. When this changes, the module's own path is - recomputed, using path_finder. The initial package path value is set to path. + recomputed, using path_finder. The initial value is set to path. For top-level modules, the parent module's path is sys.path. """ From 137652a97d8153e7833f3aaae7dc7300becf5d57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Filipe=20La=C3=ADns?= Date: Sun, 17 Nov 2024 04:00:15 +0000 Subject: [PATCH 9/9] Highlight argument names in docs text MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Filipe Laíns --- Lib/importlib/_bootstrap_external.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 4a87f1cf0e8a32..0ebcf381cf2789 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -1082,9 +1082,9 @@ def get_filename(self, fullname): class NamespacePath: """Represents a namespace package's path. - It uses the module name to find its parent module, and from there it looks + It uses the module *name* to find its parent module, and from there it looks up the parent's __path__. When this changes, the module's own path is - recomputed, using path_finder. The initial value is set to path. + recomputed, using *path_finder*. The initial value is set to *path*. For top-level modules, the parent module's path is sys.path. """