Skip to content

Commit f341e7f

Browse files
committed
Fixed problem with enum internal functions removed in Python 3.11
1 parent c14e026 commit f341e7f

File tree

3 files changed

+54
-2
lines changed

3 files changed

+54
-2
lines changed

docs/changelog.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
Changelog
33
#########
44

5+
Version 1.4.3
6+
=============
7+
8+
* `~firebird.base.types` module:
9+
10+
- Added internal functions `_decompose` and `_power_of_two` from stdlib `.enum` module,
11+
because they were removed in Python 3.11.
12+
513
Version 1.4.2
614
=============
715

firebird/base/config.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@
5555
from decimal import Decimal, DecimalException
5656
from configparser import ConfigParser, DEFAULTSECT
5757
from inspect import signature, Signature, Parameter
58-
from enum import Enum, Flag, _decompose
58+
from enum import Enum, Flag
5959
import os
6060
from .config_pb2 import ConfigProto
61-
from .types import Error, MIME, ZMQAddress, PyExpr, PyCode, PyCallable
61+
from .types import Error, MIME, ZMQAddress, PyExpr, PyCode, PyCallable, _decompose
6262
from .strconv import get_convertor, convert_to_str, Convertor
6363

6464
PROTO_CONFIG = 'firebird.base.ConfigProto'

firebird/base/types.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,3 +475,47 @@ def load(spec: str) -> Any:
475475
for item in name.split('.'):
476476
result = getattr(result, item)
477477
return result
478+
479+
# Next two functions are copied from stdlib enum module, as they were removed in Python 3.11
480+
481+
def _decompose(flag, value):
482+
"""
483+
Extract all members from the value.
484+
"""
485+
# _decompose is only called if the value is not named
486+
not_covered = value
487+
negative = value < 0
488+
# issue29167: wrap accesses to _value2member_map_ in a list to avoid race
489+
# conditions between iterating over it and having more pseudo-
490+
# members added to it
491+
if negative:
492+
# only check for named flags
493+
flags_to_check = [
494+
(m, v)
495+
for v, m in list(flag._value2member_map_.items())
496+
if m.name is not None
497+
]
498+
else:
499+
# check for named flags and powers-of-two flags
500+
flags_to_check = [
501+
(m, v)
502+
for v, m in list(flag._value2member_map_.items())
503+
if m.name is not None or _power_of_two(v)
504+
]
505+
members = []
506+
for member, member_value in flags_to_check:
507+
if member_value and member_value & value == member_value:
508+
members.append(member)
509+
not_covered &= ~member_value
510+
if not members and value in flag._value2member_map_:
511+
members.append(flag._value2member_map_[value])
512+
members.sort(key=lambda m: m._value_, reverse=True)
513+
if len(members) > 1 and members[0].value == value:
514+
# we have the breakdown, don't need the value member itself
515+
members.pop(0)
516+
return members, not_covered
517+
518+
def _power_of_two(value):
519+
if value < 1:
520+
return False
521+
return value == 2 ** (value.bit_length() - 1)

0 commit comments

Comments
 (0)