summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2021-04-15 13:58:33 (GMT)
committerGitHub <noreply@github.com>2021-04-15 13:58:33 (GMT)
commitec09973f5b21d33550c834ddc89606b0e1c70ffd (patch)
tree21d1545868a0d3be55a76ed88f6514941aab74fc
parent0dca5eb54bd137ed5c6e20012fe8dddb2eadfdd7 (diff)
downloadcpython-ec09973f5b21d33550c834ddc89606b0e1c70ffd.zip
cpython-ec09973f5b21d33550c834ddc89606b0e1c70ffd.tar.gz
cpython-ec09973f5b21d33550c834ddc89606b0e1c70ffd.tar.bz2
bpo-43744: [Enum] fix ``_is_private`` (GH-25349)
``_is_private`` now returns ``False`` instead of raising an exception when enum name matches beginning of class name as used in a private variable
-rw-r--r--Lib/enum.py5
-rw-r--r--Lib/test/test_enum.py25
-rw-r--r--Misc/NEWS.d/next/Library/2021-04-11-20-52-32.bpo-43744.uf0E68.rst2
3 files changed, 30 insertions, 2 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index 9533dd8..17deb4b 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -53,10 +53,11 @@ def _is_sunder(name):
def _is_private(cls_name, name):
# do not use `re` as `re` imports `enum`
pattern = '_%s__' % (cls_name, )
+ pat_len = len(pattern)
if (
- len(name) >= 5
+ len(name) > pat_len
and name.startswith(pattern)
- and name[len(pattern)] != '_'
+ and name[pat_len:pat_len+1] != ['_']
and (name[-1] != '_' or name[-2] != '_')
):
return True
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 5af7cd2..b9d7f96 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -3395,6 +3395,31 @@ class TestUnique(unittest.TestCase):
triple = 3
value = 4
+class TestHelpers(unittest.TestCase):
+
+ sunder_names = '_bad_', '_good_', '_what_ho_'
+ dunder_names = '__mal__', '__bien__', '__que_que__'
+ private_names = '_MyEnum__private', '_MyEnum__still_private'
+ private_and_sunder_names = '_MyEnum__private_', '_MyEnum__also_private_'
+ random_names = 'okay', '_semi_private', '_weird__', '_MyEnum__'
+
+ def test_sunder(self):
+ for name in self.sunder_names + self.private_and_sunder_names:
+ self.assertTrue(enum._is_sunder(name), '%r is a not sunder name?' % name)
+ for name in self.dunder_names + self.private_names + self.random_names:
+ self.assertFalse(enum._is_sunder(name), '%r is a sunder name?' % name)
+
+ def test_dunder(self):
+ for name in self.dunder_names:
+ self.assertTrue(enum._is_dunder(name), '%r is a not dunder name?' % name)
+ for name in self.sunder_names + self.private_names + self.private_and_sunder_names + self.random_names:
+ self.assertFalse(enum._is_dunder(name), '%r is a dunder name?' % name)
+
+ def test_is_private(self):
+ for name in self.private_names + self.private_and_sunder_names:
+ self.assertTrue(enum._is_private('MyEnum', name), '%r is a not private name?')
+ for name in self.sunder_names + self.dunder_names + self.random_names:
+ self.assertFalse(enum._is_private('MyEnum', name), '%r is a private name?')
class TestEnumTypeSubclassing(unittest.TestCase):
pass
diff --git a/Misc/NEWS.d/next/Library/2021-04-11-20-52-32.bpo-43744.uf0E68.rst b/Misc/NEWS.d/next/Library/2021-04-11-20-52-32.bpo-43744.uf0E68.rst
new file mode 100644
index 0000000..7fd74be
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-04-11-20-52-32.bpo-43744.uf0E68.rst
@@ -0,0 +1,2 @@
+fix issue with enum member name matching the start of a private variable
+name