@@ -231,7 +231,11 @@ def _ensure_target_is_callable(theMock: Mock, method_name: str) -> None:
231231 if not was_in_spec and target is None :
232232 return
233233
234- if _should_continue_with_stubbed_invocation (target , allow_classes = True ):
234+ if _should_continue_with_stubbed_invocation (
235+ target ,
236+ allow_classes = True ,
237+ spec = theMock .spec ,
238+ ):
235239 return
236240
237241 raise invocation .InvocationError ("'%s' is not callable." % method_name )
@@ -253,7 +257,7 @@ def _ensure_target_is_not_callable(theMock: Mock, method_name: str) -> None:
253257 else :
254258 return
255259
256- if _should_continue_with_stubbed_invocation (value ):
260+ if _should_continue_with_stubbed_invocation (value , spec = spec ):
257261 raise invocation .InvocationError (
258262 f"expected an invocation of '{ method_name } '"
259263 )
@@ -262,6 +266,7 @@ def _ensure_target_is_not_callable(theMock: Mock, method_name: str) -> None:
262266def _should_continue_with_stubbed_invocation (
263267 value : object ,
264268 allow_classes : bool = False ,
269+ spec : object | None = None ,
265270) -> bool :
266271 if (
267272 inspect .isfunction (value )
@@ -276,12 +281,21 @@ def _should_continue_with_stubbed_invocation(
276281 ):
277282 return True
278283
279- # Generic callable fallback, but keep custom descriptors/property-like
280- # attributes on the property stubbing path.
284+ # For class specs, callable descriptors (objects implementing both
285+ # `__call__` and `__get__`) are generally meant to be stubbed through
286+ # the property path. For non-class specs (e.g. module attributes such as
287+ # `numpy.vstack`), `__get__` should not disqualify callable targets.
288+ treat_callable_descriptors_as_non_callable = inspect .isclass (spec )
289+
290+ # Generic callable fallback, with optional handling for callable
291+ # descriptor-like objects (`__call__` + `__get__`).
281292 return (
282293 callable (value )
283294 and (allow_classes or not inspect .isclass (value ))
284- and not hasattr (value , '__get__' )
295+ and (
296+ not treat_callable_descriptors_as_non_callable
297+ or not hasattr (value , '__get__' )
298+ )
285299 )
286300
287301
0 commit comments