@@ -633,8 +633,8 @@ def __getattr__(self, name):
633
633
if not self ._mock_unsafe :
634
634
if name .startswith (('assert' , 'assret' , 'asert' , 'aseert' , 'assrt' )):
635
635
raise AttributeError (
636
- f"{ name } is not a valid assertion. Use a spec "
637
- f"for the mock if { name } is meant to be an attribute." )
636
+ f"{ name !r } is not a valid assertion. Use a spec "
637
+ f"for the mock if { name !r } is meant to be an attribute." )
638
638
639
639
result = self ._mock_children .get (name )
640
640
if result is _deleted :
@@ -1242,14 +1242,25 @@ def _importer(target):
1242
1242
return thing
1243
1243
1244
1244
1245
+ # _check_spec_arg_typos takes kwargs from commands like patch and checks that
1246
+ # they don't contain common misspellings of arguments related to autospeccing.
1247
+ def _check_spec_arg_typos (kwargs_to_check ):
1248
+ typos = ("autospect" , "auto_spec" , "set_spec" )
1249
+ for typo in typos :
1250
+ if typo in kwargs_to_check :
1251
+ raise RuntimeError (
1252
+ f"{ typo !r} might be a typo; use unsafe=True if this is intended"
1253
+ )
1254
+
1255
+
1245
1256
class _patch (object ):
1246
1257
1247
1258
attribute_name = None
1248
1259
_active_patches = []
1249
1260
1250
1261
def __init__ (
1251
1262
self , getter , attribute , new , spec , create ,
1252
- spec_set , autospec , new_callable , kwargs
1263
+ spec_set , autospec , new_callable , kwargs , * , unsafe = False
1253
1264
):
1254
1265
if new_callable is not None :
1255
1266
if new is not DEFAULT :
@@ -1260,6 +1271,8 @@ def __init__(
1260
1271
raise ValueError (
1261
1272
"Cannot use 'autospec' and 'new_callable' together"
1262
1273
)
1274
+ if not unsafe :
1275
+ _check_spec_arg_typos (kwargs )
1263
1276
1264
1277
self .getter = getter
1265
1278
self .attribute = attribute
@@ -1569,7 +1582,7 @@ def _get_target(target):
1569
1582
def _patch_object (
1570
1583
target , attribute , new = DEFAULT , spec = None ,
1571
1584
create = False , spec_set = None , autospec = None ,
1572
- new_callable = None , ** kwargs
1585
+ new_callable = None , * , unsafe = False , * *kwargs
1573
1586
):
1574
1587
"""
1575
1588
patch the named member (`attribute`) on an object (`target`) with a mock
@@ -1591,7 +1604,7 @@ def _patch_object(
1591
1604
getter = lambda : target
1592
1605
return _patch (
1593
1606
getter , attribute , new , spec , create ,
1594
- spec_set , autospec , new_callable , kwargs
1607
+ spec_set , autospec , new_callable , kwargs , unsafe = unsafe
1595
1608
)
1596
1609
1597
1610
@@ -1646,7 +1659,7 @@ def _patch_multiple(target, spec=None, create=False, spec_set=None,
1646
1659
1647
1660
def patch (
1648
1661
target , new = DEFAULT , spec = None , create = False ,
1649
- spec_set = None , autospec = None , new_callable = None , ** kwargs
1662
+ spec_set = None , autospec = None , new_callable = None , * , unsafe = False , * *kwargs
1650
1663
):
1651
1664
"""
1652
1665
`patch` acts as a function decorator, class decorator or a context
@@ -1708,6 +1721,10 @@ def patch(
1708
1721
use "as" then the patched object will be bound to the name after the
1709
1722
"as"; very useful if `patch` is creating a mock object for you.
1710
1723
1724
+ Patch will raise a `RuntimeError` if passed some common misspellings of
1725
+ the arguments autospec and spec_set. Pass the argument `unsafe` with the
1726
+ value True to disable that check.
1727
+
1711
1728
`patch` takes arbitrary keyword arguments. These will be passed to
1712
1729
`AsyncMock` if the patched object is asynchronous, to `MagicMock`
1713
1730
otherwise or to `new_callable` if specified.
@@ -1718,7 +1735,7 @@ def patch(
1718
1735
getter , attribute = _get_target (target )
1719
1736
return _patch (
1720
1737
getter , attribute , new , spec , create ,
1721
- spec_set , autospec , new_callable , kwargs
1738
+ spec_set , autospec , new_callable , kwargs , unsafe = unsafe
1722
1739
)
1723
1740
1724
1741
@@ -2568,7 +2585,7 @@ def call_list(self):
2568
2585
2569
2586
2570
2587
def create_autospec (spec , spec_set = False , instance = False , _parent = None ,
2571
- _name = None , ** kwargs ):
2588
+ _name = None , * , unsafe = False , * *kwargs ):
2572
2589
"""Create a mock object using another object as a spec. Attributes on the
2573
2590
mock will use the corresponding attribute on the `spec` object as their
2574
2591
spec.
@@ -2584,6 +2601,10 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
2584
2601
spec for an instance object by passing `instance=True`. The returned mock
2585
2602
will only be callable if instances of the mock are callable.
2586
2603
2604
+ `create_autospec` will raise a `RuntimeError` if passed some common
2605
+ misspellings of the arguments autospec and spec_set. Pass the argument
2606
+ `unsafe` with the value True to disable that check.
2607
+
2587
2608
`create_autospec` also takes arbitrary keyword arguments that are passed to
2588
2609
the constructor of the created mock."""
2589
2610
if _is_list (spec ):
@@ -2601,6 +2622,8 @@ def create_autospec(spec, spec_set=False, instance=False, _parent=None,
2601
2622
_kwargs = {}
2602
2623
if _kwargs and instance :
2603
2624
_kwargs ['_spec_as_instance' ] = True
2625
+ if not unsafe :
2626
+ _check_spec_arg_typos (kwargs )
2604
2627
2605
2628
_kwargs .update (kwargs )
2606
2629
0 commit comments