[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#1001422: python-mock: (autopkgtest) needs update for python3.10: InvalidSpecError



Source: python-mock
Version: 4.0.3-2
Severity: serious
X-Debbugs-CC: debian-ci@lists.debian.org
Tags: sid bookworm
User: debian-ci@lists.debian.org
Usertags: needs-update
User: debian-python@lists.debian.org
Usertags: python3.10
Control: affects -1 src:python3-defaults

Dear maintainer(s),

We are in the transition of adding python3.10 to the supported Python versions [0]. With a recent upload of python3-defaults the autopkgtest of python-mock fails in testing when that autopkgtest is run with the binary packages of python3-defaults from unstable. It passes when run with only packages from testing. In tabular form:

                       pass            fail
python3-defaults       from testing    3.9.8-1
python-mock            from testing    4.0.3-2
all others             from testing    from testing

I copied some of the output at the bottom of this report.

Currently this regression is blocking the migration of python3-defaults to testing [1]. https://docs.python.org/3/whatsnew/3.10.html lists what's new in Python3.10, it may help to identify what needs to be updated.

More information about this bug and the reason for filing it can be found on
https://wiki.debian.org/ContinuousIntegration/RegressionEmailInformation

Paul

[0] https://bugs.debian.org/996584
[1] https://qa.debian.org/excuses.php?package=python3-defaults

https://ci.debian.net/data/autopkgtest/testing/amd64/p/python-mock/17420659/log.gz

=================================== FAILURES =================================== _____________ MockTest.test_bool_not_called_when_passing_spec_arg ______________

self = <mock.tests.testmock.MockTest testMethod=test_bool_not_called_when_passing_spec_arg>

    def test_bool_not_called_when_passing_spec_arg(self):
        class Something:
            def __init__(self):
                self.obj_with_bool_func = unittest.mock.MagicMock()
            obj = Something()
      with unittest.mock.patch.object(obj, 'obj_with_bool_func', autospec=True): pass

/usr/lib/python3/dist-packages/mock/tests/testmock.py:2176: _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <unittest.mock._patch object at 0x7fe190485180>

    def __enter__(self):
        """Perform the patch."""
        new, spec, spec_set = self.new, self.spec, self.spec_set
        autospec, kwargs = self.autospec, self.kwargs
        new_callable = self.new_callable
        self.target = self.getter()
            # normalise False to None
        if spec is False:
            spec = None
        if spec_set is False:
            spec_set = None
        if autospec is False:
            autospec = None
            if spec is not None and autospec is not None:
            raise TypeError("Can't specify spec and autospec")
        if ((spec is not None or autospec is not None) and
            spec_set not in (True, None)):
raise TypeError("Can't provide explicit spec_set *and* spec or autospec")
            original, local = self.get_original()
            if new is DEFAULT and autospec is None:
            inherit = False
            if spec is True:
                # set spec to the object we are replacing
                spec = original
                if spec_set is True:
                    spec_set = original
                    spec = None
            elif spec is not None:
                if spec_set is True:
                    spec_set = spec
                    spec = None
            elif spec_set is True:
                spec_set = original
                if spec is not None or spec_set is not None:
                if original is DEFAULT:
                    raise TypeError("Can't use 'spec' with create=True")
                if isinstance(original, type):
                    # If we're patching out a class and there is a spec
                    inherit = True
            if spec is None and _is_async_obj(original):
                Klass = AsyncMock
            else:
                Klass = MagicMock
            _kwargs = {}
            if new_callable is not None:
                Klass = new_callable
            elif spec is not None or spec_set is not None:
                this_spec = spec
                if spec_set is not None:
                    this_spec = spec_set
                if _is_list(this_spec):
                    not_callable = '__call__' not in this_spec
                else:
                    not_callable = not callable(this_spec)
                if _is_async_obj(this_spec):
                    Klass = AsyncMock
                elif not_callable:
                    Klass = NonCallableMagicMock
                if spec is not None:
                _kwargs['spec'] = spec
            if spec_set is not None:
                _kwargs['spec_set'] = spec_set
                # add a name to mocks
            if (isinstance(Klass, type) and
                issubclass(Klass, NonCallableMock) and self.attribute):
                _kwargs['name'] = self.attribute
                _kwargs.update(kwargs)
            new = Klass(**_kwargs)
                if inherit and _is_instance_mock(new):
# we can only tell if the instance should be callable if the
                # spec is not a list
                this_spec = spec
                if spec_set is not None:
                    this_spec = spec_set
                if (not _is_list(this_spec) and not
                    _instance_callable(this_spec)):
                    Klass = NonCallableMagicMock
                    _kwargs.pop('name')
                new.return_value = Klass(_new_parent=new, _new_name='()',
                                         **_kwargs)
        elif autospec is not None:
            # spec is ignored, new *must* be default, spec_set is treated
# as a boolean. Should we check spec is not None and that spec_set
            # is a bool?
            if new is not DEFAULT:
                raise TypeError(
                    "autospec creates the mock for you. Can't specify "
                    "autospec and new."
                )
            if original is DEFAULT:
                raise TypeError("Can't use 'autospec' with create=True")
            spec_set = bool(spec_set)
            if autospec is True:
                autospec = original
                if _is_instance_mock(self.target):
                raise InvalidSpecError(
f'Cannot autospec attr {self.attribute!r} as the patch '
                    f'target has already been mocked out. '
                    f'[target={self.target!r}, attr={autospec!r}]')
            if _is_instance_mock(autospec):
                target_name = getattr(self.target, '__name__', self.target)
              raise InvalidSpecError(
                    f'Cannot autospec attr {self.attribute!r} from target '
                    f'{target_name!r} as it has already been mocked out. '
                    f'[target={self.target!r}, attr={autospec!r}]')
E unittest.mock.InvalidSpecError: Cannot autospec attr 'obj_with_bool_func' from target <mock.tests.testmock.MockTest.test_bool_not_called_when_passing_spec_arg.<locals>.Something object at 0x7fe1903ef9d0> as it has already been mocked out. [target=<mock.tests.testmock.MockTest.test_bool_not_called_when_passing_spec_arg.<locals>.Something object at 0x7fe1903ef9d0>, attr=<MagicMock id='140606764414624'>]

/usr/lib/python3.10/unittest/mock.py:1528: InvalidSpecError

Attachment: OpenPGP_signature
Description: OpenPGP digital signature


Reply to: