Skip to content

Commit

Permalink
Allow tests to build pkgutil legacy namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
abravalheri committed Sep 6, 2023
1 parent d651344 commit 88cc6c5
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
37 changes: 25 additions & 12 deletions setuptools/tests/namespaces.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import ast
import json
import textwrap


Expand All @@ -7,33 +9,44 @@ def iter_namespace_pkgs(namespace):
yield ".".join(parts[:i+1])


def build_namespace_package(tmpdir, name, version="1.0"):
def build_namespace_package(tmpdir, name, version="1.0", impl="pkg_resources"):
src_dir = tmpdir / name
src_dir.mkdir()
setup_py = src_dir / 'setup.py'
namespace, _, rest = name.rpartition('.')
namespaces = list(iter_namespace_pkgs(namespace))
setup_args = {
"name": name,
"version": version,
"packages": namespaces,
}

if impl == "pkg_resources":
tmpl = '__import__("pkg_resources").declare_namespace(__name__)'
setup_args["namespace_packages"] = namespaces
elif impl == "pkgutil":
tmpl = '__path__ = __import__("pkgutil").extend_path(__path__, __name__)'
else:
raise ValueError(f"Cannot recognise {impl=} when creating namespaces")

args = json.dumps(setup_args, indent=4)
assert ast.literal_eval(args) # ensure it is valid Python

script = textwrap.dedent(
"""
"""\
import setuptools
setuptools.setup(
name={name!r},
version={version!r},
namespace_packages={namespaces!r},
packages={namespaces!r},
)
args = {args}
setuptools.setup(**args)
"""
).format(**locals())
).format(args=args)
setup_py.write_text(script, encoding='utf-8')

ns_pkg_dir = src_dir / namespace.replace(".", "/")
ns_pkg_dir.mkdir(parents=True)

for ns in namespaces:
pkg_init = src_dir / ns.replace(".", "/") / '__init__.py'
tmpl = '__import__("pkg_resources").declare_namespace(__name__)'
decl = tmpl.format(**locals())
pkg_init.write_text(decl, encoding='utf-8')
pkg_init.write_text(tmpl, encoding='utf-8')

pkg_mod = ns_pkg_dir / (rest + '.py')
some_functionality = 'name = {rest!r}'.format(**locals())
Expand Down
15 changes: 12 additions & 3 deletions setuptools/tests/test_editable_install.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,17 @@ def test_nspkg_file_is_unique(self, tmp_path, monkeypatch):
files = list(installation_dir.glob("*-nspkg.pth"))
assert len(files) == len(examples)

@pytest.mark.parametrize(
"impl",
(
"pkg_resources",
# "pkgutil", => does not work
)
)
@pytest.mark.parametrize("ns", ("myns.n",))
def test_namespace_package_importable(self, venv, tmp_path, ns, editable_opts):
def test_namespace_package_importable(
self, venv, tmp_path, ns, impl, editable_opts
):
"""
Installing two packages sharing the same namespace, one installed
naturally using pip or `--single-version-externally-managed`
Expand All @@ -275,8 +284,8 @@ def test_namespace_package_importable(self, venv, tmp_path, ns, editable_opts):
requires = ["setuptools"]
build-backend = "setuptools.build_meta"
"""
pkg_A = namespaces.build_namespace_package(tmp_path, f"{ns}.pkgA")
pkg_B = namespaces.build_namespace_package(tmp_path, f"{ns}.pkgB")
pkg_A = namespaces.build_namespace_package(tmp_path, f"{ns}.pkgA", impl=impl)
pkg_B = namespaces.build_namespace_package(tmp_path, f"{ns}.pkgB", impl=impl)
(pkg_A / "pyproject.toml").write_text(build_system, encoding="utf-8")
(pkg_B / "pyproject.toml").write_text(build_system, encoding="utf-8")
# use pip to install to the target directory
Expand Down

0 comments on commit 88cc6c5

Please sign in to comment.