Skip to content

Commit

Permalink
Merge pull request #1402 from daa/pkg-resources-always-handle-namespa…
Browse files Browse the repository at this point in the history
…ce-package-path

Improved handling of  module __path__ attribute for namespace packages, fixes #1321
  • Loading branch information
jaraco committed Sep 16, 2018
2 parents 9e23b6d + ec1a8f6 commit 5c8ff5a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 13 deletions.
2 changes: 2 additions & 0 deletions changelog.d/1402.change.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Fixed a bug with namespace packages under python-3.6 when one package in
current directory hides another which is installed.
11 changes: 6 additions & 5 deletions pkg_resources/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2144,12 +2144,13 @@ def position_in_sys_path(path):
parts = path_parts[:-module_parts]
return safe_sys_path_index(_normalize_cached(os.sep.join(parts)))

if not isinstance(orig_path, list):
# Is this behavior useful when module.__path__ is not a list?
return
new_path = sorted(orig_path, key=position_in_sys_path)
new_path = [_normalize_cached(p) for p in new_path]

orig_path.sort(key=position_in_sys_path)
module.__path__[:] = [_normalize_cached(p) for p in orig_path]
if isinstance(module.__path__, list):
module.__path__[:] = new_path
else:
module.__path__ = new_path


def declare_namespace(packageName):
Expand Down
41 changes: 33 additions & 8 deletions setuptools/tests/test_namespaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

class TestNamespaces:

@pytest.mark.xfail(sys.version_info < (3, 5),
reason="Requires importlib.util.module_from_spec")
@pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
reason="https://github.com/pypa/setuptools/issues/851")
@pytest.mark.xfail(
sys.version_info < (3, 5),
reason="Requires importlib.util.module_from_spec",
)
def test_mixed_site_and_non_site(self, tmpdir):
"""
Installing two packages sharing the same namespace, one installed
Expand Down Expand Up @@ -55,8 +55,6 @@ def test_mixed_site_and_non_site(self, tmpdir):
with test.test.paths_on_pythonpath(map(str, targets)):
subprocess.check_call(try_import)

@pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
reason="https://github.com/pypa/setuptools/issues/851")
def test_pkg_resources_import(self, tmpdir):
"""
Ensure that a namespace package doesn't break on import
Expand All @@ -81,8 +79,6 @@ def test_pkg_resources_import(self, tmpdir):
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(try_import)

@pytest.mark.skipif(bool(os.environ.get("APPVEYOR")),
reason="https://github.com/pypa/setuptools/issues/851")
def test_namespace_package_installed_and_cwd(self, tmpdir):
"""
Installing a namespace packages but also having it in the current
Expand All @@ -109,3 +105,32 @@ def test_namespace_package_installed_and_cwd(self, tmpdir):
]
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(pkg_resources_imp, cwd=str(pkg_A))

def test_packages_in_the_same_namespace_installed_and_cwd(self, tmpdir):
"""
Installing one namespace package and also have another in the same
namespace in the current working directory, both of them must be
importable.
"""
pkg_A = namespaces.build_namespace_package(tmpdir, 'myns.pkgA')
pkg_B = namespaces.build_namespace_package(tmpdir, 'myns.pkgB')
target = tmpdir / 'packages'
# use pip to install to the target directory
install_cmd = [
sys.executable,
'-m',
'pip.__main__',
'install',
str(pkg_A),
'-t', str(target),
]
subprocess.check_call(install_cmd)
namespaces.make_site_dir(target)

# ensure that all packages import and pkg_resources imports
pkg_resources_imp = [
sys.executable,
'-c', 'import pkg_resources; import myns.pkgA; import myns.pkgB',
]
with test.test.paths_on_pythonpath([str(target)]):
subprocess.check_call(pkg_resources_imp, cwd=str(pkg_B))

0 comments on commit 5c8ff5a

Please sign in to comment.