diff options
author | Nikita Sobolev <mail@sobolevn.me> | 2023-06-08 18:40:15 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-08 18:40:15 (GMT) |
commit | 4ff5690e591b7d11cf11e34bf61004e2ea58ab3c (patch) | |
tree | c0b1237ddb98d5327b8b64371e498f94f620a0a7 /Lib/enum.py | |
parent | e822a676f1f3bef6c5413e9b856db481c08ac2a5 (diff) | |
download | cpython-4ff5690e591b7d11cf11e34bf61004e2ea58ab3c.zip cpython-4ff5690e591b7d11cf11e34bf61004e2ea58ab3c.tar.gz cpython-4ff5690e591b7d11cf11e34bf61004e2ea58ab3c.tar.bz2 |
gh-105332: [Enum] Fix unpickling flags in edge-cases (GH-105348)
* revert enum pickling from by-name to by-value
Co-authored-by: Ethan Furman <ethan@stoneleaf.us>
Diffstat (limited to 'Lib/enum.py')
-rw-r--r-- | Lib/enum.py | 30 |
1 files changed, 9 insertions, 21 deletions
diff --git a/Lib/enum.py b/Lib/enum.py index b50fe50..a22bcca 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -12,6 +12,7 @@ __all__ = [ 'FlagBoundary', 'STRICT', 'CONFORM', 'EJECT', 'KEEP', 'global_flag_repr', 'global_enum_repr', 'global_str', 'global_enum', 'EnumCheck', 'CONTINUOUS', 'NAMED_FLAGS', 'UNIQUE', + 'pickle_by_global_name', 'pickle_by_enum_name', ] @@ -913,7 +914,6 @@ class EnumType(type): body['__module__'] = module tmp_cls = type(name, (object, ), body) cls = _simple_enum(etype=cls, boundary=boundary or KEEP)(tmp_cls) - cls.__reduce_ex__ = _reduce_ex_by_global_name if as_global: global_enum(cls) else: @@ -1216,7 +1216,7 @@ class Enum(metaclass=EnumType): return hash(self._name_) def __reduce_ex__(self, proto): - return getattr, (self.__class__, self._name_) + return self.__class__, (self._value_, ) # enum.property is used to provide access to the `name` and # `value` attributes of enum members while keeping some measure of @@ -1283,8 +1283,14 @@ class StrEnum(str, ReprEnum): return name.lower() -def _reduce_ex_by_global_name(self, proto): +def pickle_by_global_name(self, proto): + # should not be used with Flag-type enums return self.name +_reduce_ex_by_global_name = pickle_by_global_name + +def pickle_by_enum_name(self, proto): + # should not be used with Flag-type enums + return getattr, (self.__class__, self._name_) class FlagBoundary(StrEnum): """ @@ -1306,23 +1312,6 @@ class Flag(Enum, boundary=STRICT): Support for flags """ - def __reduce_ex__(self, proto): - cls = self.__class__ - unknown = self._value_ & ~cls._flag_mask_ - member_value = self._value_ & cls._flag_mask_ - if unknown and member_value: - return _or_, (cls(member_value), unknown) - for val in _iter_bits_lsb(member_value): - rest = member_value & ~val - if rest: - return _or_, (cls(rest), cls._value2member_map_.get(val)) - else: - break - if self._name_ is None: - return cls, (self._value_,) - else: - return getattr, (cls, self._name_) - _numeric_repr_ = repr @staticmethod @@ -2049,7 +2038,6 @@ def _old_convert_(etype, name, module, filter, source=None, *, boundary=None): # unless some values aren't comparable, in which case sort by name members.sort(key=lambda t: t[0]) cls = etype(name, members, module=module, boundary=boundary or KEEP) - cls.__reduce_ex__ = _reduce_ex_by_global_name return cls _stdlib_enums = IntEnum, StrEnum, IntFlag |