Commit d9c956fb authored by Serhiy Storchaka's avatar Serhiy Storchaka

Issue #20804: The unittest.mock.sentinel attributes now preserve their

identity when they are copied or pickled.
parent d4f5001b
...@@ -1831,6 +1831,10 @@ sentinel ...@@ -1831,6 +1831,10 @@ sentinel
the same attribute will always return the same object. The objects the same attribute will always return the same object. The objects
returned have a sensible repr so that test failure messages are readable. returned have a sensible repr so that test failure messages are readable.
.. versionchanged:: 3.7
The ``sentinel`` attributes now preserve their identity when they are
:mod:`copied <copy>` or :mod:`pickled <pickle>`.
Sometimes when testing you need to test that a specific object is passed as an Sometimes when testing you need to test that a specific object is passed as an
argument to another method, or returned. It can be common to create named argument to another method, or returned. It can be common to create named
sentinel objects to test this. :data:`sentinel` provides a convenient way of sentinel objects to test this. :data:`sentinel` provides a convenient way of
......
...@@ -93,6 +93,13 @@ New Modules ...@@ -93,6 +93,13 @@ New Modules
Improved Modules Improved Modules
================ ================
unittest.mock
-------------
The :const:`~unittest.mock.sentinel` attributes now preserve their identity
when they are :mod:`copied <copy>` or :mod:`pickled <pickle>`.
(Contributed by Serhiy Storchaka in :issue:`20804`.)
Optimizations Optimizations
============= =============
......
...@@ -238,6 +238,9 @@ class _SentinelObject(object): ...@@ -238,6 +238,9 @@ class _SentinelObject(object):
def __repr__(self): def __repr__(self):
return 'sentinel.%s' % self.name return 'sentinel.%s' % self.name
def __reduce__(self):
return 'sentinel.%s' % self.name
class _Sentinel(object): class _Sentinel(object):
"""Access attributes to return a named object, usable as a sentinel.""" """Access attributes to return a named object, usable as a sentinel."""
...@@ -250,6 +253,9 @@ class _Sentinel(object): ...@@ -250,6 +253,9 @@ class _Sentinel(object):
raise AttributeError raise AttributeError
return self._sentinels.setdefault(name, _SentinelObject(name)) return self._sentinels.setdefault(name, _SentinelObject(name))
def __reduce__(self):
return 'sentinel'
sentinel = _Sentinel() sentinel = _Sentinel()
......
import unittest import unittest
import copy
import pickle
from unittest.mock import sentinel, DEFAULT from unittest.mock import sentinel, DEFAULT
...@@ -23,6 +25,17 @@ class SentinelTest(unittest.TestCase): ...@@ -23,6 +25,17 @@ class SentinelTest(unittest.TestCase):
# If this doesn't raise an AttributeError then help(mock) is broken # If this doesn't raise an AttributeError then help(mock) is broken
self.assertRaises(AttributeError, lambda: sentinel.__bases__) self.assertRaises(AttributeError, lambda: sentinel.__bases__)
def testPickle(self):
for proto in range(pickle.HIGHEST_PROTOCOL+1):
with self.subTest(protocol=proto):
pickled = pickle.dumps(sentinel.whatever, proto)
unpickled = pickle.loads(pickled)
self.assertIs(unpickled, sentinel.whatever)
def testCopy(self):
self.assertIs(copy.copy(sentinel.whatever), sentinel.whatever)
self.assertIs(copy.deepcopy(sentinel.whatever), sentinel.whatever)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()
...@@ -212,6 +212,9 @@ Core and Builtins ...@@ -212,6 +212,9 @@ Core and Builtins
Library Library
------- -------
- Issue #20804: The unittest.mock.sentinel attributes now preserve their
identity when they are copied or pickled.
- Issue #29142: In urllib.request, suffixes in no_proxy environment variable with - Issue #29142: In urllib.request, suffixes in no_proxy environment variable with
leading dots could match related hostnames again (e.g. .b.c matches a.b.c). leading dots could match related hostnames again (e.g. .b.c matches a.b.c).
Patch by Milan Oberkirch. Patch by Milan Oberkirch.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment