Skip to content

monkeypatch.setattr started failing in Pytest 8.1.2 (setuptools CI) #12254

Open
@abravalheri

Description

@abravalheri
  • a detailed description of the bug or problem you are having

Prior to 8.1.2 the following statement executed without raising an exception (8.0.2) in the setuptools CI, but now it started failing (8.1.2):

    def test_get_output_mapping_with_stub(self, tmpdir_cwd, monkeypatch):
        monkeypatch.setenv('SETUPTOOLS_EXT_SUFFIX', '.mp3')  # make test OS-independent
>       monkeypatch.setattr('setuptools.command.build_ext.use_stubs', True)

/home/runner/work/setuptools/setuptools/setuptools/tests/test_build_ext.py:141

The error message does not make much sense to me:

obj = <module 'setuptools.command' from '/home/runner/work/setuptools/setuptools/setuptools/command/__init__.py'>
name = 'build_ext', ann = 'setuptools.command.build_ext'

    def annotated_getattr(obj: object, name: str, ann: str) -> object:
        try:
>           obj = getattr(obj, name)
E           AttributeError: module 'setuptools.command' has no attribute 'build_ext'

/home/runner/work/setuptools/setuptools/.tox/py/lib/python3.11/site-packages/_pytest/monkeypatch.py:91: AttributeError

The above exception was the direct cause of the following exception:

self = <setuptools.tests.test_build_ext.TestBuildExt object at 0x7f41b3f86a50>
tmpdir_cwd = local('/home/runner/work/setuptools/setuptools')
monkeypatch = <_pytest.monkeypatch.MonkeyPatch object at 0x7f41b1dfe5d0>

    def test_get_outputs(self, tmpdir_cwd, monkeypatch):
        monkeypatch.setenv('SETUPTOOLS_EXT_SUFFIX', '.mp3')  # make test OS-independent
>       monkeypatch.setattr('setuptools.command.build_ext.use_stubs', False)

/home/runner/work/setuptools/setuptools/setuptools/tests/test_build_ext.py:109: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/home/runner/work/setuptools/setuptools/.tox/py/lib/python3.11/site-packages/_pytest/monkeypatch.py:103: in derive_importpath
    target = resolve(module)
/home/runner/work/setuptools/setuptools/.tox/py/lib/python3.11/site-packages/_pytest/monkeypatch.py:[85](https://github.com/pypa/setuptools/actions/runs/8853717171/job/24315188999#step:9:86): in resolve
    found = annotated_getattr(found, part, used)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

obj = <module 'setuptools.command' from '/home/runner/work/setuptools/setuptools/setuptools/command/__init__.py'>
name = 'build_ext', ann = 'setuptools.command.build_ext'

    def annotated_getattr(obj: object, name: str, ann: str) -> object:
        try:
            obj = getattr(obj, name)
        except AttributeError as e:
>           raise AttributeError(
                f"{type(obj).__name__!r} object at {ann} has no attribute {name!r}"
            ) from e
E           AttributeError: 'module' object at setuptools.command.build_ext has no attribute 'build_ext'

/home/runner/work/setuptools/setuptools/.tox/py/lib/python3.11/site-packages/_pytest/monkeypatch.py:[93](https://github.com/pypa/setuptools/actions/runs/8853717171/job/24315188999#step:9:94): AttributeError

Because:

  1. setuptools.command.build_ext is defined as a module, not an attribute of setuptools.command
  2. setuptools.command.build_ext module does define a build_ext class. But also setuptools.command.build_ext.build_ext should have nothing to do with monkeypatching setuptools.command.build_ext.use_stubs...

In the same workflow run, we also have other similar errors (e.g. AttributeError: module 'setuptools.command' has no attribute 'build_clib')


- [x] output of `pip list` from the virtual environment you are using

For the tox output:

alabaster==0.7.16
attrs==23.2.0
autocommand==2.2.2
Babel==2.14.0
backports.tarfile==1.1.1
build==1.2.1
cachetools==5.3.3
certifi==2024.2.2
cffi==1.16.0
chardet==5.2.0
charset-normalizer==3.3.2
colorama==0.4.6
ConfigUpdater==3.2
coverage==7.5.0
cryptography==42.0.5
distlib==0.3.8
docutils==0.21.2
domdf-python-tools==3.8.0.post2
execnet==2.1.1
filelock==3.13.4
idna==3.7
imagesize==1.4.1
importlib_metadata==7.1.0
importlib_resources==6.4.0
inflect==7.2.1
ini2toml==0.14
iniconfig==2.0.0
jaraco.classes==3.4.0
jaraco.context==5.3.0
jaraco.develop==8.13.0
jaraco.env==1.0.0
jaraco.envs==2.6.0
jaraco.functools==4.0.1
jaraco.packaging==10.1.0
jaraco.path==3.7.0
jaraco.text==3.12.0
jaraco.ui==2.3.0
jaraco.vcs==2.2.0
jaraco.versioning==1.1.0
jeepney==0.8.0
Jinja2==3.1.3
keyring==25.2.0
MarkupSafe==2.1.5
more-itertools==10.2.0
mypy==1.9.0
mypy-extensions==1.0.0
natsort==8.4.0
packaging==24.0
path==16.14.0
pip==24.0
pip-run==12.6.1
platformdirs==4.2.1
pluggy==1.5.0
pycparser==2.22
Pygments==2.17.2
PyNaCl==1.5.0
pyproject-api==1.6.1
pyproject_hooks==1.0.0
pytest==8.1.2
pytest-checkdocs==2.12.0
pytest-cov==5.0.0
pytest-enabler==3.1.1
pytest-home==0.5.1
pytest-mypy==0.10.3
pytest-perf==0.14.0
pytest-ruff==0.3.1
pytest-timeout==2.3.1
pytest-xdist==3.5.0
python-dateutil==2.9.0.post0
pytz==2024.1
requests==2.31.0
requests-file==2.0.0
requests-toolbelt==1.0.0
ruff==0.4.2
SecretStorage==3.3.3
setuptools @ file:///home/runner/work/setuptools/setuptools/.tox/.tmp/package/1/setuptools-69.5.1.post20240426-0.editable-py3-none-any.whl#sha256=c45586b1cbdcef78ac5a07ff798e095fc4a634e8f28286d1144ed343e1f94bd2
six==1.16.0
snowballstemmer==2.2.0
Sphinx==7.3.7
sphinxcontrib-applehelp==1.0.8
sphinxcontrib-devhelp==1.0.6
sphinxcontrib-htmlhelp==2.0.5
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.7
sphinxcontrib-serializinghtml==1.1.10
subprocess-tee==0.4.1
tempora==5.5.1
toml==0.10.2
tomli==2.0.1
tomli_w==1.0.0
tomlkit==0.12.4
tox==4.15.0
typeguard==4.2.1
typing_extensions==4.11.0
urllib3==2.2.1
virtualenv==20.26.0
wheel==0.43.0
zipp==3.18.1

  • pytest and operating system versions
ubuntu-latest (Github Actions) - Ubuntu 22.04 LTS
CPython 3.11.9

pytest==8.1.2
pytest-checkdocs==2.12.0
pytest-cov==5.0.0
pytest-enabler==3.1.1
pytest-home==0.5.1
pytest-mypy==0.10.3
pytest-perf==0.14.0
pytest-ruff==0.3.1
pytest-timeout==2.3.1
pytest-xdist==3.5.0

  • minimal example if possible

Unfortunately I was not able to simplify the reproducer.
I tried to create a minimal example with monkeypatch and nested modules but all works fine:

docker run --rm -it python:3.11-bookworm /bin/bash

cd /tmp
python3 -m venv .venv
.venv/bin/python -m pip install 'pytest==8.1.2'

mkdir -p pkg/a/b
cat <<EOF > pkg/a/b/__init__.py
def f():
    from . import c
    return c.y()
EOF
cat <<EOF > pkg/a/b/c.py
x = 37

def y(): return x
EOF


cat <<EOF > test_monkeypatch.py
from pkg.a import b

def test_monkeypatch(monkeypatch):
    monkeypatch.setattr('pkg.a.b.c.x', 42)

    assert b.f() == 42
EOF

.venv/bin/pytest test_monkeypatch.py  # ==> this works fine...

Metadata

Metadata

Assignees

No one assigned

    Labels

    plugin: monkeypatchrelated to the monkeypatch builtin plugintype: bugproblem that needs to be addressed

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions