monkeypatch.syspath_prepend: Skip fixup_namespace_packages if pkg_resources not imported

Calling pkg_resources.fixup_namespace_packages() is only needed for packages
that use pkg_resources.declare_namespace() and hence they already imported
pkg_resources. When pkg_resources is not imported, we don't need to use it.

This avoids an unneeded runtime dependency on setuptools.
The code is tested by test_syspath_prepend_with_namespace_packages,
behavior should remain unchanged, hence no new test was added.

When people drop pkg_resources from sys.modules, they are on their own.
If someone has a actual use case making this valid to support,
they can come in and provide a test, a reference and a fix.
This commit is contained in:
Miro Hrončok 2021-04-01 17:21:45 +02:00
parent 0061ec5555
commit 778d2b2499
2 changed files with 9 additions and 2 deletions

View File

@ -0,0 +1,4 @@
:meth:`pytest.MonkeyPatch.syspath_prepend` no longer fails when
``setuptools`` is not installed.
It now only calls :func:`pkg_resources.fixup_namespace_packages` if
``pkg_resources`` was previously imported, because it is not needed otherwise.

View File

@ -312,14 +312,17 @@ class MonkeyPatch:
def syspath_prepend(self, path) -> None: def syspath_prepend(self, path) -> None:
"""Prepend ``path`` to ``sys.path`` list of import locations.""" """Prepend ``path`` to ``sys.path`` list of import locations."""
from pkg_resources import fixup_namespace_packages
if self._savesyspath is None: if self._savesyspath is None:
self._savesyspath = sys.path[:] self._savesyspath = sys.path[:]
sys.path.insert(0, str(path)) sys.path.insert(0, str(path))
# https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171 # https://github.com/pypa/setuptools/blob/d8b901bc/docs/pkg_resources.txt#L162-L171
fixup_namespace_packages(str(path)) # this is only needed when pkg_resources was already loaded by the namespace package
if "pkg_resources" in sys.modules:
from pkg_resources import fixup_namespace_packages
fixup_namespace_packages(str(path))
# A call to syspathinsert() usually means that the caller wants to # A call to syspathinsert() usually means that the caller wants to
# import some dynamically created files, thus with python3 we # import some dynamically created files, thus with python3 we