diff options
author | Ethan Furman <ethan@stoneleaf.us> | 2021-04-15 13:58:33 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-15 13:58:33 (GMT) |
commit | ec09973f5b21d33550c834ddc89606b0e1c70ffd (patch) | |
tree | 21d1545868a0d3be55a76ed88f6514941aab74fc | |
parent | 0dca5eb54bd137ed5c6e20012fe8dddb2eadfdd7 (diff) | |
download | cpython-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.py | 5 | ||||
-rw-r--r-- | Lib/test/test_enum.py | 25 | ||||
-rw-r--r-- | Misc/NEWS.d/next/Library/2021-04-11-20-52-32.bpo-43744.uf0E68.rst | 2 |
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 |