55from collections import OrderedDict
66from enum import Enum , IntEnum , EnumMeta , unique
77from io import StringIO
8- from pickle import dumps , loads , PicklingError
8+ from pickle import dumps , loads , PicklingError , HIGHEST_PROTOCOL
99
1010# for pickle tests
1111try :
@@ -61,6 +61,16 @@ class Fruit(Enum):
6161except Exception :
6262 pass
6363
64+ def test_pickle_dump_load (assertion , source , target = None ):
65+ if target is None :
66+ target = source
67+ for protocol in range (2 , HIGHEST_PROTOCOL + 1 ):
68+ assertion (loads (dumps (source , protocol = protocol )), target )
69+
70+ def test_pickle_exception (assertion , exception , obj ):
71+ for protocol in range (2 , HIGHEST_PROTOCOL + 1 ):
72+ with assertion (exception ):
73+ dumps (obj , protocol = protocol )
6474
6575class TestHelpers (unittest .TestCase ):
6676 # _is_descriptor, _is_sunder, _is_dunder
@@ -503,41 +513,40 @@ class WeekDay(IntEnum):
503513 def test_pickle_enum (self ):
504514 if isinstance (Stooges , Exception ):
505515 raise Stooges
506- self .assertIs ( Stooges . CURLY , loads ( dumps ( Stooges .CURLY )) )
507- self .assertIs ( Stooges , loads ( dumps ( Stooges )) )
516+ test_pickle_dump_load ( self .assertIs , Stooges .CURLY )
517+ test_pickle_dump_load ( self .assertIs , Stooges )
508518
509519 def test_pickle_int (self ):
510520 if isinstance (IntStooges , Exception ):
511521 raise IntStooges
512- self .assertIs ( IntStooges . CURLY , loads ( dumps ( IntStooges .CURLY )) )
513- self .assertIs ( IntStooges , loads ( dumps ( IntStooges )) )
522+ test_pickle_dump_load ( self .assertIs , IntStooges .CURLY )
523+ test_pickle_dump_load ( self .assertIs , IntStooges )
514524
515525 def test_pickle_float (self ):
516526 if isinstance (FloatStooges , Exception ):
517527 raise FloatStooges
518- self .assertIs ( FloatStooges . CURLY , loads ( dumps ( FloatStooges .CURLY )) )
519- self .assertIs ( FloatStooges , loads ( dumps ( FloatStooges )) )
528+ test_pickle_dump_load ( self .assertIs , FloatStooges .CURLY )
529+ test_pickle_dump_load ( self .assertIs , FloatStooges )
520530
521531 def test_pickle_enum_function (self ):
522532 if isinstance (Answer , Exception ):
523533 raise Answer
524- self .assertIs ( Answer . him , loads ( dumps ( Answer .him )) )
525- self .assertIs ( Answer , loads ( dumps ( Answer )) )
534+ test_pickle_dump_load ( self .assertIs , Answer .him )
535+ test_pickle_dump_load ( self .assertIs , Answer )
526536
527537 def test_pickle_enum_function_with_module (self ):
528538 if isinstance (Question , Exception ):
529539 raise Question
530- self .assertIs ( Question . who , loads ( dumps ( Question .who )) )
531- self .assertIs ( Question , loads ( dumps ( Question )) )
540+ test_pickle_dump_load ( self .assertIs , Question .who )
541+ test_pickle_dump_load ( self .assertIs , Question )
532542
533543 def test_exploding_pickle (self ):
534544 BadPickle = Enum ('BadPickle' , 'dill sweet bread-n-butter' )
535- enum . _make_class_unpicklable ( BadPickle )
545+ BadPickle . __qualname__ = ' BadPickle' # needed for pickle protocol 4
536546 globals ()['BadPickle' ] = BadPickle
537- with self .assertRaises (TypeError ):
538- dumps (BadPickle .dill )
539- with self .assertRaises (PicklingError ):
540- dumps (BadPickle )
547+ enum ._make_class_unpicklable (BadPickle ) # will overwrite __qualname__
548+ test_pickle_exception (self .assertRaises , TypeError , BadPickle .dill )
549+ test_pickle_exception (self .assertRaises , PicklingError , BadPickle )
541550
542551 def test_string_enum (self ):
543552 class SkillLevel (str , Enum ):
@@ -690,7 +699,7 @@ def test_subclassing(self):
690699 self .assertEqual (Name .BDFL , 'Guido van Rossum' )
691700 self .assertTrue (Name .BDFL , Name ('Guido van Rossum' ))
692701 self .assertIs (Name .BDFL , getattr (Name , 'BDFL' ))
693- self .assertIs ( Name . BDFL , loads ( dumps ( Name .BDFL )) )
702+ test_pickle_dump_load ( self .assertIs , Name .BDFL )
694703
695704 def test_extending (self ):
696705 class Color (Enum ):
@@ -864,6 +873,7 @@ class TestAutoInt(AutoIntEnum):
864873
865874 def test_subclasses_with_getnewargs (self ):
866875 class NamedInt (int ):
876+ __qualname__ = 'NamedInt' # needed for pickle protocol 4
867877 def __new__ (cls , * args ):
868878 _args = args
869879 name , * args = args
@@ -902,6 +912,7 @@ def __add__(self, other):
902912 return temp
903913
904914 class NEI (NamedInt , Enum ):
915+ __qualname__ = 'NEI' # needed for pickle protocol 4
905916 x = ('the-x' , 1 )
906917 y = ('the-y' , 2 )
907918
@@ -912,12 +923,13 @@ class NEI(NamedInt, Enum):
912923 globals ()['NEI' ] = NEI
913924 NI5 = NamedInt ('test' , 5 )
914925 self .assertEqual (NI5 , 5 )
915- self .assertEqual ( loads ( dumps ( NI5 )) , 5 )
926+ test_pickle_dump_load ( self .assertEqual , NI5 , 5 )
916927 self .assertEqual (NEI .y .value , 2 )
917- self .assertIs ( loads ( dumps ( NEI . y )) , NEI .y )
928+ test_pickle_dump_load ( self .assertIs , NEI .y )
918929
919930 def test_subclasses_without_getnewargs (self ):
920931 class NamedInt (int ):
932+ __qualname__ = 'NamedInt'
921933 def __new__ (cls , * args ):
922934 _args = args
923935 name , * args = args
@@ -954,6 +966,7 @@ def __add__(self, other):
954966 return temp
955967
956968 class NEI (NamedInt , Enum ):
969+ __qualname__ = 'NEI'
957970 x = ('the-x' , 1 )
958971 y = ('the-y' , 2 )
959972
@@ -964,21 +977,20 @@ class NEI(NamedInt, Enum):
964977 NI5 = NamedInt ('test' , 5 )
965978 self .assertEqual (NI5 , 5 )
966979 self .assertEqual (NEI .y .value , 2 )
967- with self .assertRaises (TypeError ):
968- dumps (NEI .x )
969- with self .assertRaises (PicklingError ):
970- dumps (NEI )
980+ test_pickle_exception (self .assertRaises , TypeError , NEI .x )
981+ test_pickle_exception (self .assertRaises , PicklingError , NEI )
971982
972983 def test_tuple_subclass (self ):
973984 class SomeTuple (tuple , Enum ):
985+ __qualname__ = 'SomeTuple' # needed for pickle protocol 4
974986 first = (1 , 'for the money' )
975987 second = (2 , 'for the show' )
976988 third = (3 , 'for the music' )
977989 self .assertIs (type (SomeTuple .first ), SomeTuple )
978990 self .assertIsInstance (SomeTuple .second , tuple )
979991 self .assertEqual (SomeTuple .third , (3 , 'for the music' ))
980992 globals ()['SomeTuple' ] = SomeTuple
981- self .assertIs ( loads ( dumps ( SomeTuple . first )) , SomeTuple .first )
993+ test_pickle_dump_load ( self .assertIs , SomeTuple .first )
982994
983995 def test_duplicate_values_give_unique_enum_items (self ):
984996 class AutoNumber (Enum ):
0 commit comments