summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEthan Furman <ethan@stoneleaf.us>2020-12-10 01:12:11 (GMT)
committerGitHub <noreply@github.com>2020-12-10 01:12:11 (GMT)
commit7cf0aad96d1d20f07d7f0e374885f327c2d5ff27 (patch)
treebabeef9e57bf228cf1714462dfdf7ca1bce97870
parent6bd94de168b58ac9358277ed6f200490ab26c174 (diff)
downloadcpython-7cf0aad96d1d20f07d7f0e374885f327c2d5ff27.zip
cpython-7cf0aad96d1d20f07d7f0e374885f327c2d5ff27.tar.gz
cpython-7cf0aad96d1d20f07d7f0e374885f327c2d5ff27.tar.bz2
bpo-42517: [Enum] do not convert private names into members (GH-23722)
private names, such as `_Color__hue` and `_Color__hue_` are now normal attributes, and do not become members nor raise exceptions
-rw-r--r--Doc/library/enum.rst9
-rw-r--r--Lib/enum.py19
-rw-r--r--Lib/test/test_enum.py25
-rw-r--r--Misc/NEWS.d/next/Library/2020-12-09-10-59-16.bpo-42517.FKEVcZ.rst2
4 files changed, 54 insertions, 1 deletions
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index 118002b..a9584b9 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -1164,6 +1164,15 @@ and raise an error if the two do not match::
In Python 2 code the :attr:`_order_` attribute is necessary as definition
order is lost before it can be recorded.
+
+_Private__names
+"""""""""""""""
+
+Private names are not converted to Enum members, but remain normal attributes.
+
+.. versionchanged:: 3.10
+
+
``Enum`` member type
""""""""""""""""""""
diff --git a/Lib/enum.py b/Lib/enum.py
index 83e050e..74318c3 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -49,6 +49,19 @@ def _is_sunder(name):
name[-2:-1] != '_'
)
+def _is_private(cls_name, name):
+ # do not use `re` as `re` imports `enum`
+ pattern = '_%s__' % (cls_name, )
+ if (
+ len(name) >= 5
+ and name.startswith(pattern)
+ and name[len(pattern)] != '_'
+ and (name[-1] != '_' or name[-2] != '_')
+ ):
+ return True
+ else:
+ return False
+
def _make_class_unpicklable(cls):
"""
Make the given class un-picklable.
@@ -89,7 +102,10 @@ class _EnumDict(dict):
Single underscore (sunder) names are reserved.
"""
- if _is_sunder(key):
+ if _is_private(self._cls_name, key):
+ # do nothing, name will be a normal attribute
+ pass
+ elif _is_sunder(key):
if key not in (
'_order_', '_create_pseudo_member_',
'_generate_next_value_', '_missing_', '_ignore_',
@@ -157,6 +173,7 @@ class EnumMeta(type):
metacls._check_for_existing_members(cls, bases)
# create the namespace dict
enum_dict = _EnumDict()
+ enum_dict._cls_name = cls
# inherit previous flags and _generate_next_value_ function
member_type, first_enum = metacls._get_mixins_(cls, bases)
if first_enum is not None:
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 20bc5b3..7ca54e9 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -1149,6 +1149,7 @@ class TestEnum(unittest.TestCase):
class auto_enum(type(Enum)):
def __new__(metacls, cls, bases, classdict):
temp = type(classdict)()
+ temp._cls_name = cls
names = set(classdict._member_names)
i = 0
for k in classdict._member_names:
@@ -2155,6 +2156,30 @@ class TestEnum(unittest.TestCase):
self.assertFalse(NeverEnum.__dict__.get('_test2', False))
+ @unittest.skipUnless(
+ sys.version_info[:2] == (3, 9),
+ 'private variables are now normal attributes',
+ )
+ def test_warning_for_private_variables(self):
+ with self.assertWarns(DeprecationWarning):
+ class Private(Enum):
+ __corporal = 'Radar'
+ self.assertEqual(Private._Private__corporal.value, 'Radar')
+ try:
+ with self.assertWarns(DeprecationWarning):
+ class Private(Enum):
+ __major_ = 'Hoolihan'
+ except ValueError:
+ pass
+
+ def test_private_variable_is_normal_attribute(self):
+ class Private(Enum):
+ __corporal = 'Radar'
+ __major_ = 'Hoolihan'
+ self.assertEqual(Private._Private__corporal, 'Radar')
+ self.assertEqual(Private._Private__major_, 'Hoolihan')
+
+
class TestOrder(unittest.TestCase):
def test_same_members(self):
diff --git a/Misc/NEWS.d/next/Library/2020-12-09-10-59-16.bpo-42517.FKEVcZ.rst b/Misc/NEWS.d/next/Library/2020-12-09-10-59-16.bpo-42517.FKEVcZ.rst
new file mode 100644
index 0000000..813139d
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2020-12-09-10-59-16.bpo-42517.FKEVcZ.rst
@@ -0,0 +1,2 @@
+Enum: private names do not become members / do not generate errors -- they
+remain normal attributes