diff -r a30cdf366c02 Lib/unittest/mock.py --- a/Lib/unittest/mock.py Tue Jan 10 11:30:44 2017 +0800 +++ b/Lib/unittest/mock.py Tue Jan 10 22:09:52 2017 +0200 @@ -238,6 +238,9 @@ class _SentinelObject(object): def __repr__(self): return 'sentinel.%s' % self.name + def __reduce__(self): + return 'sentinel.%s' % self.name + class _Sentinel(object): """Access attributes to return a named object, usable as a sentinel.""" @@ -250,6 +253,9 @@ class _Sentinel(object): raise AttributeError return self._sentinels.setdefault(name, _SentinelObject(name)) + def __reduce__(self): + return 'sentinel' + sentinel = _Sentinel() diff -r a30cdf366c02 Lib/unittest/test/testmock/testsentinel.py --- a/Lib/unittest/test/testmock/testsentinel.py Tue Jan 10 11:30:44 2017 +0800 +++ b/Lib/unittest/test/testmock/testsentinel.py Tue Jan 10 22:09:52 2017 +0200 @@ -1,4 +1,6 @@ import unittest +import copy +import pickle from unittest.mock import sentinel, DEFAULT @@ -23,6 +25,17 @@ class SentinelTest(unittest.TestCase): # If this doesn't raise an AttributeError then help(mock) is broken 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__': unittest.main()