Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fddcfa2

Browse files
committed
Closes issue 17660. You no longer need to explicitly pass create=True when patching builtin names.
1 parent fba913f commit fddcfa2

3 files changed

Lines changed: 52 additions & 4 deletions

File tree

Doc/library/unittest.mock.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1031,6 +1031,12 @@ patch
10311031
default because it can be dangerous. With it switched on you can write
10321032
passing tests against APIs that don't actually exist!
10331033

1034+
.. note::
1035+
1036+
.. versionchanged:: 3.5
1037+
If you are patching builtins in a module then you don't
1038+
need to pass `create=True`, it will be added by default.
1039+
10341040
Patch can be used as a `TestCase` class decorator. It works by
10351041
decorating each test method in the class. This reduces the boilerplate
10361042
code when your test methods share a common patchings set. `patch` finds
@@ -1401,6 +1407,21 @@ It is also possible to stop all patches which have been started by using
14011407

14021408
Stop all active patches. Only stops patches started with `start`.
14031409

1410+
.. patch-builtins:
1411+
1412+
patch builtins
1413+
~~~~~~~~~~~~~~~
1414+
You can patch any builtins within a module. The following example patches
1415+
builtin `ord`:
1416+
1417+
>>> @patch('__main__.ord')
1418+
... def test(mock_ord):
1419+
... mock_ord.return_value = 101
1420+
... print(ord('c'))
1421+
...
1422+
>>> test()
1423+
101
1424+
14041425

14051426
TEST_PREFIX
14061427
~~~~~~~~~~~
@@ -2011,7 +2032,7 @@ Mocking context managers with a :class:`MagicMock` is common enough and fiddly
20112032
enough that a helper function is useful.
20122033

20132034
>>> m = mock_open()
2014-
>>> with patch('__main__.open', m, create=True):
2035+
>>> with patch('__main__.open', m):
20152036
... with open('foo', 'w') as h:
20162037
... h.write('some stuff')
20172038
...
@@ -2026,7 +2047,7 @@ enough that a helper function is useful.
20262047

20272048
And for reading files:
20282049

2029-
>>> with patch('__main__.open', mock_open(read_data='bibble'), create=True) as m:
2050+
>>> with patch('__main__.open', mock_open(read_data='bibble')) as m:
20302051
... with open('foo') as h:
20312052
... result = h.read()
20322053
...

Lib/unittest/mock.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,13 @@
2727
import inspect
2828
import pprint
2929
import sys
30+
import builtins
31+
from types import ModuleType
3032
from functools import wraps, partial
3133

3234

35+
_builtins = {name for name in dir(builtins) if not name.startswith('_')}
36+
3337
BaseExceptions = (BaseException,)
3438
if 'java' in sys.platform:
3539
# jython
@@ -1166,6 +1170,9 @@ def get_original(self):
11661170
else:
11671171
local = True
11681172

1173+
if name in _builtins and isinstance(target, ModuleType):
1174+
self.create = True
1175+
11691176
if not self.create and original is DEFAULT:
11701177
raise AttributeError(
11711178
"%s does not have the attribute %r" % (target, name)

Lib/unittest/test/testmock/testpatch.py

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,7 @@ def test():
377377

378378
def test_patchobject_wont_create_by_default(self):
379379
try:
380-
@patch.object(SomeClass, 'frooble', sentinel.Frooble)
380+
@patch.object(SomeClass, 'ord', sentinel.Frooble)
381381
def test():
382382
self.fail('Patching non existent attributes should fail')
383383

@@ -386,7 +386,27 @@ def test():
386386
pass
387387
else:
388388
self.fail('Patching non existent attributes should fail')
389-
self.assertFalse(hasattr(SomeClass, 'frooble'))
389+
self.assertFalse(hasattr(SomeClass, 'ord'))
390+
391+
392+
def test_patch_builtins_without_create(self):
393+
@patch(__name__+'.ord')
394+
def test_ord(mock_ord):
395+
mock_ord.return_value = 101
396+
return ord('c')
397+
398+
@patch(__name__+'.open')
399+
def test_open(mock_open):
400+
m = mock_open.return_value
401+
m.read.return_value = 'abcd'
402+
403+
fobj = open('doesnotexists.txt')
404+
data = fobj.read()
405+
fobj.close()
406+
return data
407+
408+
self.assertEqual(test_ord(), 101)
409+
self.assertEqual(test_open(), 'abcd')
390410

391411

392412
def test_patch_with_static_methods(self):

0 commit comments

Comments
 (0)