@@ -182,12 +182,12 @@ def _instance_callable(obj):
182182 return False
183183
184184
185- def _set_signature (mock , original , instance = False ):
185+ def _set_signature (mock , original , instance = False , skipfirst = False ):
186186 # creates a function with signature (*args, **kwargs) that delegates to a
187187 # mock. It still does signature checking by calling a lambda with the same
188188 # signature as the original.
189189
190- skipfirst = isinstance (original , type )
190+ skipfirst = skipfirst or isinstance (original , type )
191191 result = _get_signature_object (original , instance , skipfirst )
192192 if result is None :
193193 return mock
@@ -200,28 +200,41 @@ def checksig(*args, **kwargs):
200200 if not name .isidentifier ():
201201 name = 'funcopy'
202202 context = {'_checksig_' : checksig , 'mock' : mock }
203- src = """def %s(*args, **kwargs):
203+ if skipfirst :
204+ src = """def %s(_mock_self, /, *args, **kwargs):
205+ _checksig_(*args, **kwargs)
206+ return mock(*args, **kwargs)""" % name
207+ else :
208+ src = """def %s(*args, **kwargs):
204209 _checksig_(*args, **kwargs)
205210 return mock(*args, **kwargs)""" % name
206211 exec (src , context )
207212 funcopy = context [name ]
208213 _setup_func (funcopy , mock , sig )
209214 return funcopy
210215
211- def _set_async_signature (mock , original , instance = False , is_async_mock = False ):
216+ def _set_async_signature (mock , original , instance = False , is_async_mock = False , skipfirst = False ):
212217 # creates an async function with signature (*args, **kwargs) that delegates to a
213218 # mock. It still does signature checking by calling a lambda with the same
214219 # signature as the original.
215220
216- skipfirst = isinstance (original , type )
217- func , sig = _get_signature_object (original , instance , skipfirst )
221+ skipfirst = skipfirst or isinstance (original , type )
222+ result = _get_signature_object (original , instance , skipfirst )
223+ if result is None :
224+ return mock
225+ func , sig = result
218226 def checksig (* args , ** kwargs ):
219227 sig .bind (* args , ** kwargs )
220228 _copy_func_details (func , checksig )
221229
222230 name = original .__name__
223231 context = {'_checksig_' : checksig , 'mock' : mock }
224- src = """async def %s(*args, **kwargs):
232+ if skipfirst :
233+ src = """async def %s(_mock_self, /, *args, **kwargs):
234+ _checksig_(*args, **kwargs)
235+ return await mock(*args, **kwargs)""" % name
236+ else :
237+ src = """async def %s(*args, **kwargs):
225238 _checksig_(*args, **kwargs)
226239 return await mock(*args, **kwargs)""" % name
227240 exec (src , context )
@@ -1593,7 +1606,10 @@ def __enter__(self):
15931606 raise TypeError ("Can't use 'autospec' with create=True" )
15941607 spec_set = bool (spec_set )
15951608 if autospec is True :
1596- autospec = original
1609+ if isinstance (self .target , type ):
1610+ autospec = getattr (self .target , self .attribute , original )
1611+ else :
1612+ autospec = original
15971613
15981614 if _is_instance_mock (self .target ):
15991615 raise InvalidSpecError (
@@ -1607,8 +1623,14 @@ def __enter__(self):
16071623 f'{ target_name !r} as it has already been mocked out. '
16081624 f'[target={ self .target !r} , attr={ autospec !r} ]' )
16091625
1626+ # For regular methods on classes, self is passed by the descriptor
1627+ # protocol but should not be recorded in mock call args.
1628+ _eat_self = _must_skip (
1629+ self .target , self .attribute , isinstance (self .target , type )
1630+ )
16101631 new = create_autospec (autospec , spec_set = spec_set ,
1611- _name = self .attribute , ** kwargs )
1632+ _name = self .attribute , _eat_self = _eat_self ,
1633+ ** kwargs )
16121634 elif kwargs :
16131635 # can't set keyword args when we aren't creating the mock
16141636 # XXXX If new is a Mock we could call new.configure_mock(**kwargs)
@@ -2746,7 +2768,7 @@ def call_list(self):
27462768
27472769
27482770def create_autospec (spec , spec_set = False , instance = False , _parent = None ,
2749- _name = None , * , unsafe = False , ** kwargs ):
2771+ _name = None , * , unsafe = False , _eat_self = False , ** kwargs ):
27502772 """Create a mock object using another object as a spec. Attributes on the
27512773 mock will use the corresponding attribute on the `spec` object as their
27522774 spec.
@@ -2823,17 +2845,17 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
28232845 Klass = NonCallableMagicMock
28242846
28252847 mock = Klass (parent = _parent , _new_parent = _parent , _new_name = _new_name ,
2826- name = _name , ** _kwargs )
2848+ name = _name , _eat_self = _eat_self or None , ** _kwargs )
28272849 if is_dataclass_spec :
28282850 mock ._mock_extend_spec_methods (dataclass_spec_list )
28292851
28302852 if isinstance (spec , FunctionTypes ):
28312853 # should only happen at the top level because we don't
28322854 # recurse for functions
28332855 if is_async_func :
2834- mock = _set_async_signature (mock , spec )
2856+ mock = _set_async_signature (mock , spec , skipfirst = _eat_self )
28352857 else :
2836- mock = _set_signature (mock , spec )
2858+ mock = _set_signature (mock , spec , skipfirst = _eat_self )
28372859 else :
28382860 _check_signature (spec , mock , is_type , instance )
28392861
0 commit comments