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

Skip to content

Commit 2da9504

Browse files
committed
Close issue20653: improve functional API docs; minor code changes
1 parent adb2e2a commit 2da9504

2 files changed

Lines changed: 61 additions & 12 deletions

File tree

Doc/library/enum.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,9 @@ from that module.
374374
With pickle protocol version 4 it is possible to easily pickle enums
375375
nested in other classes.
376376

377+
It is possible to modify how Enum members are pickled/unpickled by defining
378+
:meth:`__reduce_ex__` in the enumeration class.
379+
377380

378381
Functional API
379382
--------------
@@ -420,13 +423,44 @@ The solution is to specify the module name explicitly as follows::
420423

421424
>>> Animals = Enum('Animals', 'ant bee cat dog', module=__name__)
422425

426+
.. warning::
427+
428+
If :param module: is not supplied, and Enum cannot determine what it is,
429+
the new Enum members will not be unpicklable; to keep errors closer to
430+
the source, pickling will be disabled.
431+
423432
The new pickle protocol 4 also, in some circumstances, relies on
424433
:attr:`__qualname__` being set to the location where pickle will be able
425434
to find the class. For example, if the class was made available in class
426435
SomeData in the global scope::
427436

428437
>>> Animals = Enum('Animals', 'ant bee cat dog', qualname='SomeData.Animals')
429438

439+
The complete signature is::
440+
441+
Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=<mixed-in class>)
442+
443+
:param value: What the new Enum class will record as its name.
444+
445+
:param names: The Enum members. This can be a whitespace or comma seperated
446+
string::
447+
448+
'red green blue', 'red,green,blue', 'red, green, blue'
449+
450+
(values will start at 1), or an iterator of name, value pairs::
451+
452+
[('cyan', 4), ('magenta', 5), ('yellow', 6)]
453+
454+
or a mapping::
455+
456+
{'chartruese': 7, 'sea_green': 11, 'rosemary': 42}
457+
458+
:param module: name of module where new Enum class can be found.
459+
460+
:param qualname: where in module new Enum class can be found.
461+
462+
:param type: type to mix in to new Enum class.
463+
430464

431465
Derived Enumerations
432466
--------------------

Lib/enum.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -115,14 +115,21 @@ def __new__(metacls, cls, bases, classdict):
115115
# Reverse value->name map for hashable values.
116116
enum_class._value2member_map_ = {}
117117

118-
# check for a supported pickle protocols, and if not present sabotage
119-
# pickling, since it won't work anyway.
120-
# if new class implements its own __reduce_ex__, do not sabotage
121-
if classdict.get('__reduce_ex__') is None:
118+
# If a custom type is mixed into the Enum, and it does not know how
119+
# to pickle itself, pickle.dumps will succeed but pickle.loads will
120+
# fail. Rather than have the error show up later and possibly far
121+
# from the source, sabotage the pickle protocol for this class so
122+
# that pickle.dumps also fails.
123+
#
124+
# However, if the new class implements its own __reduce_ex__, do not
125+
# sabotage -- it's on them to make sure it works correctly. We use
126+
# __reduce_ex__ instead of any of the others as it is preferred by
127+
# pickle over __reduce__, and it handles all pickle protocols.
128+
if '__reduce_ex__' not in classdict:
122129
if member_type is not object:
123130
methods = ('__getnewargs_ex__', '__getnewargs__',
124131
'__reduce_ex__', '__reduce__')
125-
if not any(map(member_type.__dict__.get, methods)):
132+
if not any(m in member_type.__dict__ for m in methods):
126133
_make_class_unpicklable(enum_class)
127134

128135
# instantiate them, checking for duplicates as we go
@@ -193,14 +200,22 @@ def __call__(cls, value, names=None, *, module=None, qualname=None, type=None):
193200
to an enumeration member (i.e. Color(3)) and for the functional API
194201
(i.e. Color = Enum('Color', names='red green blue')).
195202
196-
When used for the functional API: `module`, if set, will be stored in
197-
the new class' __module__ attribute; `qualname`, if set, will be stored
198-
in the new class' __qualname__ attribute; `type`, if set, will be mixed
199-
in as the first base class.
203+
When used for the functional API:
200204
201-
Note: if `module` is not set this routine will attempt to discover the
202-
calling module by walking the frame stack; if this is unsuccessful
203-
the resulting class will not be pickleable.
205+
`value` will be the name of the new class.
206+
207+
`names` should be either a string of white-space/comma delimited names
208+
(values will start at 1), or an iterator/mapping of name, value pairs.
209+
210+
`module` should be set to the module this class is being created in;
211+
if it is not set, an attempt to find that module will be made, but if
212+
it fails the class will not be picklable.
213+
214+
`qualname` should be set to the actual location this class can be found
215+
at in its module; by default it is set to the global scope. If this is
216+
not correct, unpickling will fail in some circumstances.
217+
218+
`type`, if set, will be mixed in as the first base class.
204219
205220
"""
206221
if names is None: # simple value lookup

0 commit comments

Comments
 (0)