Skip to content

Commit 14a0e16

Browse files
bpo-36548: Improve the repr of re flags. (GH-12715)
1 parent 65fb2c0 commit 14a0e16

File tree

3 files changed

+45
-16
lines changed

3 files changed

+45
-16
lines changed

Lib/re.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,24 +141,40 @@
141141
__version__ = "2.2.1"
142142

143143
class RegexFlag(enum.IntFlag):
144-
ASCII = sre_compile.SRE_FLAG_ASCII # assume ascii "locale"
145-
IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case
146-
LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
147-
UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale"
148-
MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
149-
DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline
150-
VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
151-
A = ASCII
152-
I = IGNORECASE
153-
L = LOCALE
154-
U = UNICODE
155-
M = MULTILINE
156-
S = DOTALL
157-
X = VERBOSE
144+
ASCII = A = sre_compile.SRE_FLAG_ASCII # assume ascii "locale"
145+
IGNORECASE = I = sre_compile.SRE_FLAG_IGNORECASE # ignore case
146+
LOCALE = L = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale
147+
UNICODE = U = sre_compile.SRE_FLAG_UNICODE # assume unicode "locale"
148+
MULTILINE = M = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline
149+
DOTALL = S = sre_compile.SRE_FLAG_DOTALL # make dot match newline
150+
VERBOSE = X = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments
158151
# sre extensions (experimental, don't rely on these)
159-
TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
160-
T = TEMPLATE
152+
TEMPLATE = T = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking
161153
DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation
154+
155+
def __repr__(self):
156+
if self._name_ is not None:
157+
return f're.{self._name_}'
158+
value = self._value_
159+
members = []
160+
negative = value < 0
161+
if negative:
162+
value = ~value
163+
for m in self.__class__:
164+
if value & m._value_:
165+
value &= ~m._value_
166+
members.append(f're.{m._name_}')
167+
if value:
168+
members.append(hex(value))
169+
res = '|'.join(members)
170+
if negative:
171+
if len(members) > 1:
172+
res = f'~({res})'
173+
else:
174+
res = f'~{res}'
175+
return res
176+
__str__ = object.__str__
177+
162178
globals().update(RegexFlag.__members__)
163179

164180
# sre exception

Lib/test/test_re.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,18 @@ def test_long_pattern(self):
21702170
self.assertEqual(r[:30], "re.compile('Very long long lon")
21712171
self.assertEqual(r[-16:], ", re.IGNORECASE)")
21722172

2173+
def test_flags_repr(self):
2174+
self.assertEqual(repr(re.I), "re.IGNORECASE")
2175+
self.assertEqual(repr(re.I|re.S|re.X),
2176+
"re.IGNORECASE|re.DOTALL|re.VERBOSE")
2177+
self.assertEqual(repr(re.I|re.S|re.X|(1<<20)),
2178+
"re.IGNORECASE|re.DOTALL|re.VERBOSE|0x100000")
2179+
self.assertEqual(repr(~re.I), "~re.IGNORECASE")
2180+
self.assertEqual(repr(~(re.I|re.S|re.X)),
2181+
"~(re.IGNORECASE|re.DOTALL|re.VERBOSE)")
2182+
self.assertEqual(repr(~(re.I|re.S|re.X|(1<<20))),
2183+
"~(re.IGNORECASE|re.DOTALL|re.VERBOSE|0x100000)")
2184+
21732185

21742186
class ImplementationTest(unittest.TestCase):
21752187
"""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improved the repr of regular expression flags.

0 commit comments

Comments
 (0)