[Python-checkins] [3.7] bpo-34282: Fix Enum._convert method shadowing members named _convert (GH-9034) (GH-9229)

Ethan Furman webhook-mailer at python.org
Fri Oct 5 23:10:08 EDT 2018


https://github.com/python/cpython/commit/22e86fbbca04d251233fc07515885d2b67945094
commit: 22e86fbbca04d251233fc07515885d2b67945094
branch: 3.6
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: Ethan Furman <ethan at stoneleaf.us>
date: 2018-10-05T20:10:04-07:00
summary:

[3.7] bpo-34282: Fix Enum._convert method shadowing members named _convert (GH-9034) (GH-9229)

* Fix Enum._convert shadowing members named _convert
Co-authored-by: orlnub123 <orlnub123 at gmail.com>

files:
A Misc/NEWS.d/next/Library/2018-09-02-13-33-35.bpo-34282.ztyXH8.rst
M Lib/enum.py
M Lib/test/test_enum.py

diff --git a/Lib/enum.py b/Lib/enum.py
index 112523e998f7..8405fa965d06 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -155,9 +155,11 @@ def __new__(metacls, cls, bases, classdict):
         enum_class._member_map_ = OrderedDict()      # name->value map
         enum_class._member_type_ = member_type
 
-        # save attributes from super classes so we know if we can take
-        # the shortcut of storing members in the class dict
-        base_attributes = {a for b in enum_class.mro() for a in b.__dict__}
+        # save DynamicClassAttribute attributes from super classes so we know
+        # if we can take the shortcut of storing members in the class dict
+        dynamic_attributes = {k for c in enum_class.mro()
+                              for k, v in c.__dict__.items()
+                              if isinstance(v, DynamicClassAttribute)}
 
         # Reverse value->name map for hashable values.
         enum_class._value2member_map_ = {}
@@ -217,7 +219,7 @@ def __new__(metacls, cls, bases, classdict):
                 enum_class._member_names_.append(member_name)
             # performance boost for any member that would not shadow
             # a DynamicClassAttribute
-            if member_name not in base_attributes:
+            if member_name not in dynamic_attributes:
                 setattr(enum_class, member_name, enum_member)
             # now add to _member_map_
             enum_class._member_map_[member_name] = enum_member
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index eaea8ee3abdf..3cecee691626 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -1506,6 +1506,23 @@ class MoreColor(Color):
             yellow = 6
         self.assertEqual(MoreColor.magenta.hex(), '5 hexlified!')
 
+    def test_subclass_duplicate_name(self):
+        class Base(Enum):
+            def test(self):
+                pass
+        class Test(Base):
+            test = 1
+        self.assertIs(type(Test.test), Test)
+
+    def test_subclass_duplicate_name_dynamic(self):
+        from types import DynamicClassAttribute
+        class Base(Enum):
+            @DynamicClassAttribute
+            def test(self):
+                return 'dynamic'
+        class Test(Base):
+            test = 1
+        self.assertEqual(Test.test.test, 'dynamic')
 
     def test_no_duplicates(self):
         class UniqueEnum(Enum):
diff --git a/Misc/NEWS.d/next/Library/2018-09-02-13-33-35.bpo-34282.ztyXH8.rst b/Misc/NEWS.d/next/Library/2018-09-02-13-33-35.bpo-34282.ztyXH8.rst
new file mode 100644
index 000000000000..c1e606ab0ce5
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2018-09-02-13-33-35.bpo-34282.ztyXH8.rst
@@ -0,0 +1 @@
+Fix enum members getting shadowed by parent attributes.



More information about the Python-checkins mailing list