bpo-40864: Fetch instance variables for spec

This commit is contained in:
Evan Fagerberg 2020-10-05 20:11:38 -04:00
parent 91e3339066
commit 444925d2b1
2 changed files with 26 additions and 2 deletions

View File

@ -487,8 +487,13 @@ class NonCallableMock(Base):
_spec_class = None
_spec_signature = None
_spec_asyncs = []
try:
_members = inspect.getmembers(spec)
except Exception:
# Fallback to dir if for some reason we cannot inspect members
_members = [(elem, None) for elem in dir(spec)]
for attr in dir(spec):
for attr, _ in _members:
if iscoroutinefunction(getattr(spec, attr, None)):
_spec_asyncs.append(attr)
@ -501,7 +506,11 @@ class NonCallableMock(Base):
_spec_as_instance, _eat_self)
_spec_signature = res and res[1]
spec = dir(spec)
spec = []
for member_k, member_v in _members:
spec.append(member_k)
if member_k == '__init__' and hasattr(member_v, '__code__'):
spec.extend(member_v.__code__.co_names)
__dict__ = self.__dict__
__dict__['_spec_class'] = _spec_class

View File

@ -1,4 +1,5 @@
import copy
import inspect
import re
import sys
import tempfile
@ -868,6 +869,20 @@ class MockTest(unittest.TestCase):
self.assertRaises(AttributeError, set_attr)
def test_finds_attrs_set_in__init__(self):
class X(object):
y = 3
def __init__(self, z):
self.z = self.__get_z()
def __get_z(self): return 'Z'
mock = Mock(spec=X)
self.assertTrue(hasattr(mock, 'y'))
self.assertTrue(hasattr(mock, 'z'))
def test_copy(self):
current = sys.getrecursionlimit()
self.addCleanup(sys.setrecursionlimit, current)