Skip to content

ModuleNotFound for editable install of namespace package with two dots #4039

Closed
@mauritsvanrees

Description

@mauritsvanrees

setuptools version

68.1.2, same with main

Python version

3.11.5

OS

MacOS

Additional environment information

Also happening on GitHub-actions on a Linux env.
See also my comment here: plone/meta#172 (comment)

Locally, on Python 3.10 all goes well, on 3.11 not.

Description

I maintain various setuptools/pkg_resources style namespace packages with two dots, for example: plone.app.uuid. Until the beginning of August, an editable install worked fine. Now it fails, because setuptools 68.1.0+ is used:
ModuleNotFoundError: No module named 'plone.app.uuid'

Packages with just one dot seem fine, for example plone.session.

Expected behavior

After pip install -e . of the plone.app.uuid package, I should be able to do import plone.app.uuid.

How to Reproduce

I tried to create a stripped-down copy of plone.app.uuid, but there an import works fine. I suspect it only goes wrong if another plone.app.* package is installed next to it. So use the original repo, but use a branch I created for this issue with minor changes (mainly a much smaller tox.ini):

git clone -b maurits-setuptools-namespace [email protected]:plone/plone.app.uuid.git
cd plone.app.uuid
tox -e test

This can take a few minutes, because it needs lots of packages.

Output

$ git clone -b maurits-setuptools-namespace [email protected]:plone/plone.app.uuid.git
Cloning into 'plone.app.uuid'...
remote: Enumerating objects: 698, done.
remote: Counting objects: 100% (2/2), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 698 (delta 0), reused 0 (delta 0), pack-reused 696
Receiving objects: 100% (698/698), 134.94 KiB | 746.00 KiB/s, done.
Resolving deltas: 100% (353/353), done.
$ cd plone.app.uuid
$ tox -e test
test: install_deps> python -I -m pip install zope.testrunner -c https://dist.plone.org/release/6.0-dev/constraints.txt
.pkg: install_requires> python -I -m pip install 'setuptools>=40.8.0' wheel
.pkg: _optional_hooks> python /Users/maurits/.local/pipx/venvs/tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: get_requires_for_build_sdist> python /Users/maurits/.local/pipx/venvs/tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: get_requires_for_build_editable> python /Users/maurits/.local/pipx/venvs/tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
.pkg: install_requires_for_build_editable> python -I -m pip install wheel
.pkg: build_editable> python /Users/maurits/.local/pipx/venvs/tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
test: install_package_deps> python -I -m pip install Products.CMFCore Products.ZCatalog plone.app.testing plone.dexterity plone.indexer plone.testing plone.uuid setuptools zope.interface zope.publisher -c/Users/maurits/foo/plone.app.uuid/.tox/test/constraints.txt
test: install_package> python -I -m pip install --force-reinstall --no-deps /Users/maurits/foo/plone.app.uuid/.tox/.tmp/package/1/plone.app.uuid-2.2.3.dev0-0.editable-py3-none-any.whl
test: commands[0]> zope-testrunner --all --test-path=/Users/maurits/foo/plone.app.uuid -s plone.app.uuid
Traceback (most recent call last):
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/bin/zope-testrunner", line 8, in <module>
    sys.exit(run())
             ^^^^^
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/__init__.py", line 31, in run
    failed = run_internal(defaults, args, script_parts=script_parts, cwd=cwd,
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/__init__.py", line 55, in run_internal
    runner.run()
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/runner.py", line 179, in run
    feature.global_setup()
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 505, in global_setup
    tests = find_tests(self.runner.options, self.runner.found_suites)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 178, in find_tests
    for suite in found_suites:
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 199, in find_suites
    for fpath, package in find_test_files(options):
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 265, in find_test_files
    for f, package in find_test_files_(options):
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 293, in find_test_files_
    for (p, package) in test_dirs(options, {}):
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 348, in test_dirs
    p = import_name(p)
        ^^^^^^^^^^^^^^
  File "/Users/maurits/foo/plone.app.uuid/.tox/test/lib/python3.11/site-packages/zope/testrunner/find.py", line 423, in import_name
    __import__(name)
ModuleNotFoundError: No module named 'plone.app.uuid'
test: exit 1 (6.56 seconds) /Users/maurits/foo/plone.app.uuid> zope-testrunner --all --test-path=/Users/maurits/foo/plone.app.uuid -s plone.app.uuid pid=38144
.pkg: _exit> python /Users/maurits/.local/pipx/venvs/tox/lib/python3.11/site-packages/pyproject_api/_backend.py True setuptools.build_meta __legacy__
  test: FAIL code 1 (76.97=setup[70.41]+cmd[6.56] seconds)
  evaluation failed :( (77.12 seconds)

The editable install generated this file from a template in setuptools:

$ cd .tox/test
$ cat lib/python3.11/site-packages/__editable___plone_app_uuid_2_2_3_dev0_finder.py 
import sys
from importlib.machinery import ModuleSpec, PathFinder
from importlib.machinery import all_suffixes as module_suffixes
from importlib.util import spec_from_file_location
from itertools import chain
from pathlib import Path

MAPPING = {'plone': '/Users/maurits/foo/plone.app.uuid/plone'}
NAMESPACES = {}
PATH_PLACEHOLDER = '__editable__.plone.app.uuid-2.2.3.dev0.finder' + ".__path_hook__"
...

When I edit MAPPING to the following, and directly call the test command, instead of running tox again, it works:

MAPPING = {
    'plone': '/Users/maurits/foo/plone.app.uuid/plone',
    'plone.app': '/Users/maurits/foo/plone.app.uuid/plone/app',
}

I don't know if that makes any sense, or if the NAMESPACES should be filled.

Workaround: force using an older setuptools, by adding this in pyproject.toml:

[build-system]
# See https://snarky.ca/what-the-heck-is-pyproject-toml/
requires = ["setuptools<68.1.0", "wheel"]
build-backend = "setuptools.build_meta"

I suspect this is a regression caused by PR #3995, so cc @aganders3.
It may need a fix similar to PR #4020.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Needs TriageIssues that need to be evaluated for severity and status.bug

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions