Mario Corchero <marioc...@gmail.com> added the comment:
Right, I believe this is indeed broken. This code: ``` class A: def m(self, a=None): pass from unittest import mock with mock.patch.object(A, "m", autospec=True): A.m.side_effect = print A().m(1) ``` prints: <__main__.A object at 0x7f69cc7dc6a0> 1 Whilst the same code without autospec: ``` class A: def m(self, a=None): pass from unittest import mock with mock.patch.object(A, "m"): A.m.side_effect = print A().m(1) ``` prints: 1 This is a rather tricky issue though, as changing the behaviour to pass self would break too many people (even if it would probably the be "right" fix). You can indeed use autospec or just write a descriptor that does the proper bound method logic: ``` class A: def m(self, a=None): pass def descriptor(self, obj, objtype=None): self._self = obj def _(*args): return self(obj, *args) return _ from unittest import mock with mock.patch.object(A, "m"): A.m.side_effect = print A.m.__get__ = descriptor A().m(1) ``` When patching a method at the class level, today Mock is basically hiding "self" when used without a spec. We should decide whether: - that is OK and we want to "fix" autospec to do the same (remove self) - Leave things as they are, even if not perfect - Pass self, breaking most assertions across the world (sounds like a bad idea initially) - Create some opt-in parameter or a custom thing like PropertyMock to pass self (MethodMock?). TBH, I don't have a good answer :/. I'm subscribing other more insightful people to the issue, maybe this is the way it is intended to work :). ---------- nosy: +cjw296, mariocj89, michael.foord, xtreak _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue42556> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com