File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -1831,6 +1831,10 @@ sentinel
18311831 the same attribute will always return the same object. The objects
18321832 returned have a sensible repr so that test failure messages are readable.
18331833
1834+ .. versionchanged :: 3.7
1835+ The ``sentinel `` attributes now preserve their identity when they are
1836+ :mod: `copied <copy> ` or :mod: `pickled <pickle> `.
1837+
18341838Sometimes when testing you need to test that a specific object is passed as an
18351839argument to another method, or returned. It can be common to create named
18361840sentinel objects to test this. :data: `sentinel ` provides a convenient way of
Original file line number Diff line number Diff line change @@ -93,6 +93,13 @@ New Modules
9393Improved Modules
9494================
9595
96+ unittest.mock
97+ -------------
98+
99+ The :const: `~unittest.mock.sentinel ` attributes now preserve their identity
100+ when they are :mod: `copied <copy> ` or :mod: `pickled <pickle> `.
101+ (Contributed by Serhiy Storchaka in :issue: `20804 `.)
102+
96103
97104Optimizations
98105=============
Original file line number Diff line number Diff line change @@ -238,6 +238,9 @@ def __init__(self, name):
238238 def __repr__ (self ):
239239 return 'sentinel.%s' % self .name
240240
241+ def __reduce__ (self ):
242+ return 'sentinel.%s' % self .name
243+
241244
242245class _Sentinel (object ):
243246 """Access attributes to return a named object, usable as a sentinel."""
@@ -250,6 +253,9 @@ def __getattr__(self, name):
250253 raise AttributeError
251254 return self ._sentinels .setdefault (name , _SentinelObject (name ))
252255
256+ def __reduce__ (self ):
257+ return 'sentinel'
258+
253259
254260sentinel = _Sentinel ()
255261
Original file line number Diff line number Diff line change 11import unittest
2+ import copy
3+ import pickle
24from unittest .mock import sentinel , DEFAULT
35
46
@@ -23,6 +25,17 @@ def testBases(self):
2325 # If this doesn't raise an AttributeError then help(mock) is broken
2426 self .assertRaises (AttributeError , lambda : sentinel .__bases__ )
2527
28+ def testPickle (self ):
29+ for proto in range (pickle .HIGHEST_PROTOCOL + 1 ):
30+ with self .subTest (protocol = proto ):
31+ pickled = pickle .dumps (sentinel .whatever , proto )
32+ unpickled = pickle .loads (pickled )
33+ self .assertIs (unpickled , sentinel .whatever )
34+
35+ def testCopy (self ):
36+ self .assertIs (copy .copy (sentinel .whatever ), sentinel .whatever )
37+ self .assertIs (copy .deepcopy (sentinel .whatever ), sentinel .whatever )
38+
2639
2740if __name__ == '__main__' :
2841 unittest .main ()
Original file line number Diff line number Diff line change @@ -212,6 +212,9 @@ Core and Builtins
212212Library
213213-------
214214
215+ - Issue #20804: The unittest.mock.sentinel attributes now preserve their
216+ identity when they are copied or pickled.
217+
215218- Issue #29142: In urllib.request, suffixes in no_proxy environment variable with
216219 leading dots could match related hostnames again (e.g. .b.c matches a.b.c).
217220 Patch by Milan Oberkirch.
You can’t perform that action at this time.
0 commit comments