diff options
author | HongWeipeng <961365124@qq.com> | 2019-11-26 22:36:02 (GMT) |
---|---|---|
committer | Ethan Furman <ethan@stoneleaf.us> | 2019-11-26 22:36:02 (GMT) |
commit | 0b41a922f95f62b620d5a197b9f2ed8e4bb70730 (patch) | |
tree | d9db36ebe3acbb32ae944e5cffd291232a1e0687 /Lib/enum.py | |
parent | e563a155be60fc0757914f87c8138f10de00bb16 (diff) | |
download | cpython-0b41a922f95f62b620d5a197b9f2ed8e4bb70730.zip cpython-0b41a922f95f62b620d5a197b9f2ed8e4bb70730.tar.gz cpython-0b41a922f95f62b620d5a197b9f2ed8e4bb70730.tar.bz2 |
bpo-38045: Improve the performance of _decompose() in enum.py (GH-16483)
* Improve the performance of _decompose() in enum.py
Co-Authored-By: Brandt Bucher <brandtbucher@gmail.com>
Diffstat (limited to 'Lib/enum.py')
-rw-r--r-- | Lib/enum.py | 33 |
1 files changed, 10 insertions, 23 deletions
diff --git a/Lib/enum.py b/Lib/enum.py index 06f42a9..0be1b60 100644 --- a/Lib/enum.py +++ b/Lib/enum.py @@ -861,28 +861,20 @@ def _decompose(flag, value): # _decompose is only called if the value is not named not_covered = value negative = value < 0 - # issue29167: wrap accesses to _value2member_map_ in a list to avoid race - # conditions between iterating over it and having more pseudo- - # members added to it - if negative: - # only check for named flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None - ] - else: - # check for named flags and powers-of-two flags - flags_to_check = [ - (m, v) - for v, m in list(flag._value2member_map_.items()) - if m.name is not None or _power_of_two(v) - ] members = [] - for member, member_value in flags_to_check: + for member in flag: + member_value = member.value if member_value and member_value & value == member_value: members.append(member) not_covered &= ~member_value + if not negative: + tmp = not_covered + while tmp: + flag_value = 2 ** _high_bit(tmp) + if flag_value in flag._value2member_map_: + members.append(flag._value2member_map_[flag_value]) + not_covered &= ~flag_value + tmp &= ~flag_value if not members and value in flag._value2member_map_: members.append(flag._value2member_map_[value]) members.sort(key=lambda m: m._value_, reverse=True) @@ -890,8 +882,3 @@ def _decompose(flag, value): # we have the breakdown, don't need the value member itself members.pop(0) return members, not_covered - -def _power_of_two(value): - if value < 1: - return False - return value == 2 ** _high_bit(value) |