]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.9] bpo-42517: [Enum] deprecate private name members (GH-23722) (GH-23748)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Mon, 14 Dec 2020 23:56:58 +0000 (15:56 -0800)
committerGitHub <noreply@github.com>
Mon, 14 Dec 2020 23:56:58 +0000 (15:56 -0800)
private names will raise a DeprecationWarning; in 3.10 they will become normal attributes

Doc/library/enum.rst
Lib/enum.py
Lib/test/test_enum.py
Misc/NEWS.d/next/Library/2020-12-09-10-59-16.bpo-42517.FKEVcZ.rst [new file with mode: 0644]

index a3c51655576ba5f8000786eadac79ce8f7c7e3dd..4ecca209d87b3dc6cdb6d64c40f3301451324587 100644 (file)
@@ -1121,6 +1121,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 will be normal attributes in Python 3.10 instead of either an error
+or a member (depending on if the name ends with an underscore). Using these names
+in 3.9 will issue a :exc:`DeprecationWarning`.
+
+
 ``Enum`` member type
 """"""""""""""""""""
 
index 35210c993325db326c129346daead2fdfd1159e2..46b5435b7c8e067ff8101824654f83210e04793e 100644 (file)
@@ -41,6 +41,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.
@@ -81,6 +94,14 @@ class _EnumDict(dict):
 
         Single underscore (sunder) names are reserved.
         """
+        if _is_private(self._cls_name, key):
+            import warnings
+            warnings.warn(
+                    "private variables, such as %r, will be normal attributes in 3.10"
+                        % (key, ),
+                    DeprecationWarning,
+                    stacklevel=2,
+                    )
         if _is_sunder(key):
             if key not in (
                     '_order_', '_create_pseudo_member_',
@@ -146,6 +167,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:
index dca668a9046f36191857a21250d5a5a43abc5774..f7f8522bda4f35e2101a5333652092a56afc1ed5 100644 (file)
@@ -1147,6 +1147,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:
@@ -2049,6 +2050,23 @@ class TestEnum(unittest.TestCase):
         exec(code, global_ns, local_ls)
 
 
+    @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
+
+
 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 (file)
index 0000000..e99294d
--- /dev/null
@@ -0,0 +1,2 @@
+Enum: private names will raise a DeprecationWarning; in 3.10 they will
+become normal attributes