You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
AttributeError when copying flags in the re module. #93820
In CPython 3.11, I've noticed that an attempt to copy (combined) regular expression flags fails with an attribute error; like so:
>>> import copy, re
>>> copy.copy(re.A | re.I)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "lib/python3.11/copy.py", line 102, in copy
return _reconstruct(x, None, *rv)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "lib/python3.11/copy.py", line 265, in _reconstruct
y = func(*args)
^^^^^^^^^^^
File "lib/python3.11/enum.py", line 862, in __getattr__
raise AttributeError(name) from None
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: ASCII|IGNORECASE
Your environment
CPython versions tested on: 3.11.0b3
Operating system and architecture: macOS 10.15.7
Background
This behavior was detected from a CrossHair test failure here, in which we realize possibly symbolic arguments prior to regex compilation. (it's an esoteric use case, and I expect not very high priority)
$ ./python.exe
Python 3.11.0b3+ (heads/3.11:7aa4038a6e, Jun 14 2022, 09:35:10) [Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy, enum
>>> class F(enum.IntFlag):
... a = 2
... b = 4
...
>>> copy.copy(F.a | F.b)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/Users/jelle/py/cpython/Lib/copy.py", line 102, in copy
return _reconstruct(x, None, *rv)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/jelle/py/cpython/Lib/copy.py", line 265, in _reconstruct
y = func(*args)
^^^^^^^^^^^
File "/Users/jelle/py/cpython/Lib/enum.py", line 862, in __getattr__
raise AttributeError(name) from None
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: a|b
It gets a bit tricky when the flags have a residual member, e.g. re.A | re.I | 0x10000. IntFlag supports additional values that are not covered by an enum member.
Activity
JelleZijlstra commentedon Jun 14, 2022
Thanks for reporting! Confirmed that
copy.copy(re.A | re.I)fails on 3.11 but works on 3.10. Marking as a release blocker since this is a regression.cc @ethanfurman for enums
JelleZijlstra commentedon Jun 14, 2022
Also repros with
enum.IntFlagdirectly:dignissimus commentedon Jun 15, 2022
Also occurs on 3.12
tiran commentedon Jun 15, 2022
In 3.11 the
__reduce__and__reduce_ex__methods returns different values:tiran commentedon Jun 15, 2022
I guess the regression was introduced by GH-26658 and commit 62f1d2b .
A quick fix would be to reduce flags by value instead of by name.
dignissimus commentedon Jun 15, 2022
Running the example in 0507303 so works fine, so commit 62f1d2b introduced the issue
dignissimus commentedon Jun 15, 2022
Oh, it looks like we came across it at the same time 😂
tiran commentedon Jun 15, 2022
PR #93876 is a potential fix. Waiting for @ethanfurman to confirm.
gh-93820: Fix copy() regression in enum.Flag (GH-93876)
pythongh-93820: Fix copy() regression in enum.Flag (pythonGH-93876)
serhiy-storchaka commentedon Jun 16, 2022
Ideally,
re.I | re.Ashould be reconstructed asoperator.or_(re.ASCII, re.IGNORECASE).tiran commentedon Jun 16, 2022
It gets a bit tricky when the flags have a residual member, e.g.
re.A | re.I | 0x10000. IntFlag supports additional values that are not covered by an enum member.pythongh-93820: Pickle enum.Flag by name
gh-93820: Fix copy() regression in enum.Flag (GH-93876) (#93886)
Revert 30935 defer bpo45162 to 312 (#94285)
gh-93820: Pickle enum.Flag by name (GH-93891)
[3.11] pythongh-93820: Pickle enum.Flag by name (pythonGH-93891).
[3.11] gh-93820: Pickle enum.Flag by name (GH-93891). (GH-94288)