Skip to content

Regression in pytest 8.3.1: AttributeError: 'property' object has no attribute '__code__' on Python 3.11 when combining doctest with property decoration #12650

@lesteve

Description

@lesteve
  • a detailed description of the bug or problem you are having
  • output of pip list from the virtual environment you are using
  • pytest and operating system versions
  • minimal example if possible

This is super edge-casy I am not even sure this is worth fixing but maybe the fix is simple enough? This was originally seen in scikit-learn CI scikit-learn/scikit-learn#29486 (comment)

To reproduce:

pytest --doctest-modules test_deprecation.py
# test_deprecation.py
import functools

class deprecated:
    def __init__(self, reason):
        self.reason = reason

    def __call__(self, prop):
        @property
        @functools.wraps(prop)
        def inner(*args, **kwargs):
            return prop.fget(*args, **kwargs)

        return inner


class MockClass:
    @deprecated("n_features_ is deprecated")
    @property
    def n_features_(self):
        """Number of input features."""
        return 10

Works with pytest 8.2.2 fails with pytest 8.3.1 with the following error:

❯ pytest --doctest-modules /tmp/test_deprecation.py
=================================================================================================================================================== test session starts ===================================================================================================================================================
platform linux -- Python 3.11.9, pytest-8.3.1, pluggy-1.5.0
rootdir: /tmp
plugins: xdist-3.6.1, cov-5.0.0
collected 0 items / 1 error                                                                                                                                                                                                                                                                                               

========================================================================================================================================================= ERRORS ==========================================================================================================================================================
__________________________________________________________________________________________________________________________________________ ERROR collecting test_deprecation.py ___________________________________________________________________________________________________________________________________________
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:942: in find
    self._find(tests, obj, name, module, source_lines, globs, {})
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:1016: in _find
    self._find(tests, val, valname, module, source_lines,
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:1048: in _find
    self._find(tests, val, valname, module, source_lines,
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:1004: in _find
    test = self._get_test(obj, name, module, globs, source_lines)
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:1072: in _get_test
    lineno = self._find_lineno(obj, source_lines)
../../micromamba/envs/scikit-learn-pip-openblas/lib/python3.11/doctest.py:1121: in _find_lineno
    obj = inspect.unwrap(obj).__code__
E   AttributeError: 'property' object has no attribute '__code__'
================================================================================================================================================= short test summary info =================================================================================================================================================
ERROR ../../../../tmp/test_deprecation.py - AttributeError: 'property' object has no attribute '__code__'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
==================================================================================================================================================== 1 error in 0.21s =====================================================================================================================================================

I create the environment like this:

conda create -n bla pytest python=3.11 -y

The conda list output:

$ conda list
# packages in environment at /home/lesteve/micromamba/envs/bla:
#
# Name                    Version                   Build  Channel
_libgcc_mutex             0.1                 conda_forge    conda-forge
_openmp_mutex             4.5                       2_gnu    conda-forge
bzip2                     1.0.8                h4bc722e_7    conda-forge
ca-certificates           2024.7.4             hbcca054_0    conda-forge
colorama                  0.4.6              pyhd8ed1ab_0    conda-forge
exceptiongroup            1.2.2              pyhd8ed1ab_0    conda-forge
iniconfig                 2.0.0              pyhd8ed1ab_0    conda-forge
ld_impl_linux-64          2.40                 hf3520f5_7    conda-forge
libexpat                  2.6.2                h59595ed_0    conda-forge
libffi                    3.4.2                h7f98852_5    conda-forge
libgcc-ng                 14.1.0               h77fa898_0    conda-forge
libgomp                   14.1.0               h77fa898_0    conda-forge
libnsl                    2.0.1                hd590300_0    conda-forge
libsqlite                 3.46.0               hde9e2c9_0    conda-forge
libuuid                   2.38.1               h0b41bf4_0    conda-forge
libxcrypt                 4.4.36               hd590300_1    conda-forge
libzlib                   1.3.1                h4ab18f5_1    conda-forge
ncurses                   6.5                  h59595ed_0    conda-forge
openssl                   3.3.1                h4bc722e_2    conda-forge
packaging                 24.1               pyhd8ed1ab_0    conda-forge
pip                       24.0               pyhd8ed1ab_0    conda-forge
pluggy                    1.5.0              pyhd8ed1ab_0    conda-forge
pytest                    8.3.1              pyhd8ed1ab_0    conda-forge
python                    3.11.9          hb806964_0_cpython    conda-forge
readline                  8.2                  h8228510_1    conda-forge
setuptools                71.0.4             pyhd8ed1ab_0    conda-forge
tk                        8.6.13          noxft_h4845f30_101    conda-forge
tomli                     2.0.1              pyhd8ed1ab_0    conda-forge
tzdata                    2024a                h0c530f3_0    conda-forge
wheel                     0.43.0             pyhd8ed1ab_1    conda-forge
xz                        5.2.6                h166bdaf_0    conda-forge

Metadata

Metadata

Assignees

No one assigned

    Labels

    status: needs informationreporter needs to provide more information; can be closed after 2 or more weeks of inactivitytype: backward compatibilitymight present some backward compatibility issues which should be carefully noted in the changelog

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions