Skip to content

Commit f8773eb

Browse files
authored
Improve unittest.mock stubs (#14421)
* Add `patch()` default arguments. * Forbid certain argument combinations for `patch()`. * Reorder `patch()` overloads. * Add `unsafe` argument. * Add overloads for `path.multiple()`.
1 parent 94fe857 commit f8773eb

File tree

1 file changed

+83
-35
lines changed

1 file changed

+83
-35
lines changed

stdlib/unittest/mock.pyi

Lines changed: 83 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -297,65 +297,80 @@ class _patcher:
297297
# Ideally we'd be able to add an overload for it so that the return type is _patch[MagicMock],
298298
# but that's impossible with the current type system.
299299
@overload
300-
def __call__(
300+
def __call__( # type: ignore[overload-overlap]
301301
self,
302302
target: str,
303303
new: _T,
304-
spec: Any | None = ...,
305-
create: bool = ...,
306-
spec_set: Any | None = ...,
307-
autospec: Any | None = ...,
308-
new_callable: Callable[..., Any] | None = ...,
309-
**kwargs: Any,
304+
spec: Literal[False] | None = None,
305+
create: bool = False,
306+
spec_set: Literal[False] | None = None,
307+
autospec: Literal[False] | None = None,
308+
new_callable: None = None,
309+
*,
310+
unsafe: bool = False,
310311
) -> _patch[_T]: ...
311312
@overload
312313
def __call__(
313314
self,
314315
target: str,
315316
*,
316-
spec: Any | None = ...,
317-
create: bool = ...,
318-
spec_set: Any | None = ...,
319-
autospec: Any | None = ...,
317+
# If not False or None, this is passed to new_callable
318+
spec: Any | Literal[False] | None = None,
319+
create: bool = False,
320+
# If not False or None, this is passed to new_callable
321+
spec_set: Any | Literal[False] | None = None,
322+
autospec: Literal[False] | None = None,
320323
new_callable: Callable[..., _T],
324+
unsafe: bool = False,
325+
# kwargs are passed to new_callable
321326
**kwargs: Any,
322327
) -> _patch_pass_arg[_T]: ...
323328
@overload
324329
def __call__(
325330
self,
326331
target: str,
327332
*,
328-
spec: Any | None = ...,
329-
create: bool = ...,
330-
spec_set: Any | None = ...,
331-
autospec: Any | None = ...,
333+
spec: Any | bool | None = None,
334+
create: bool = False,
335+
spec_set: Any | bool | None = None,
336+
autospec: Any | bool | None = None,
332337
new_callable: None = None,
338+
unsafe: bool = False,
339+
# kwargs are passed to the MagicMock/AsyncMock constructor
333340
**kwargs: Any,
334341
) -> _patch_pass_arg[MagicMock | AsyncMock]: ...
342+
# This overload also covers the case, where new==DEFAULT. In this case, the return type is _patch[Any].
343+
# Ideally we'd be able to add an overload for it so that the return type is _patch[MagicMock],
344+
# but that's impossible with the current type system.
335345
@overload
336346
@staticmethod
337347
def object(
338348
target: Any,
339349
attribute: str,
340350
new: _T,
341-
spec: Any | None = ...,
342-
create: bool = ...,
343-
spec_set: Any | None = ...,
344-
autospec: Any | None = ...,
345-
new_callable: Callable[..., Any] | None = ...,
346-
**kwargs: Any,
351+
spec: Literal[False] | None = None,
352+
create: bool = False,
353+
spec_set: Literal[False] | None = None,
354+
autospec: Literal[False] | None = None,
355+
new_callable: None = None,
356+
*,
357+
unsafe: bool = False,
347358
) -> _patch[_T]: ...
348359
@overload
349360
@staticmethod
350361
def object(
351362
target: Any,
352363
attribute: str,
353364
*,
354-
spec: Any | None = ...,
355-
create: bool = ...,
356-
spec_set: Any | None = ...,
357-
autospec: Any | None = ...,
365+
# If not False or None, this is passed to new_callable
366+
spec: Any | Literal[False] | None = None,
367+
create: bool = False,
368+
# If not False or None, this is passed to new_callable
369+
spec_set: Any | Literal[False] | None = None,
370+
autospec: Literal[False] | None = None,
358371
new_callable: Callable[..., _T],
372+
unsafe: bool = False,
373+
# kwargs are passed to new_callable
359374
**kwargs: Any,
360375
) -> _patch_pass_arg[_T]: ...
361376
@overload
@@ -364,21 +379,54 @@ class _patcher:
364379
target: Any,
365380
attribute: str,
366381
*,
367-
spec: Any | None = ...,
368-
create: bool = ...,
369-
spec_set: Any | None = ...,
370-
autospec: Any | None = ...,
382+
spec: Any | bool | None = None,
383+
create: bool = False,
384+
spec_set: Any | bool | None = None,
385+
autospec: Any | bool | None = None,
371386
new_callable: None = None,
387+
unsafe: bool = False,
388+
# kwargs are passed to the MagicMock/AsyncMock constructor
372389
**kwargs: Any,
373390
) -> _patch_pass_arg[MagicMock | AsyncMock]: ...
391+
@overload
374392
@staticmethod
375393
def multiple(
376-
target: Any,
377-
spec: Any | None = ...,
378-
create: bool = ...,
379-
spec_set: Any | None = ...,
380-
autospec: Any | None = ...,
381-
new_callable: Any | None = ...,
394+
target: Any | str,
395+
# If not False or None, this is passed to new_callable
396+
spec: Any | Literal[False] | None = None,
397+
create: bool = False,
398+
# If not False or None, this is passed to new_callable
399+
spec_set: Any | Literal[False] | None = None,
400+
autospec: Literal[False] | None = None,
401+
*,
402+
new_callable: Callable[..., _T],
403+
# The kwargs must be DEFAULT
404+
**kwargs: Any,
405+
) -> _patch_pass_arg[_T]: ...
406+
@overload
407+
@staticmethod
408+
def multiple(
409+
target: Any | str,
410+
# If not False or None, this is passed to new_callable
411+
spec: Any | Literal[False] | None,
412+
create: bool,
413+
# If not False or None, this is passed to new_callable
414+
spec_set: Any | Literal[False] | None,
415+
autospec: Literal[False] | None,
416+
new_callable: Callable[..., _T],
417+
# The kwargs must be DEFAULT
418+
**kwargs: Any,
419+
) -> _patch_pass_arg[_T]: ...
420+
@overload
421+
@staticmethod
422+
def multiple(
423+
target: Any | str,
424+
spec: Any | bool | None = None,
425+
create: bool = False,
426+
spec_set: Any | bool | None = None,
427+
autospec: Any | bool | None = None,
428+
new_callable: None = None,
429+
# The kwargs are the mock objects or DEFAULT
382430
**kwargs: Any,
383431
) -> _patch[Any]: ...
384432
@staticmethod

0 commit comments

Comments
 (0)