Close #18989: enum members will no longer overwrite other attributes, nor be overwritten by them.
diff --git a/Doc/library/enum.rst b/Doc/library/enum.rst
index 236275d..c5076b2 100644
--- a/Doc/library/enum.rst
+++ b/Doc/library/enum.rst
@@ -154,6 +154,12 @@
     >>> Shape(2)
     <Shape.square: 2>
 
+.. note::
+
+    Attempting to create a member with the same name as an already
+    defined attribute (another member, a method, etc.) or attempting to create
+    an attribute with the same name as a member is not allowed.
+
 
 Ensuring unique enumeration values
 ----------------------------------
diff --git a/Lib/enum.py b/Lib/enum.py
index 0d72f3e..40546da 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -29,6 +29,14 @@
         raise AttributeError("can't delete attribute")
 
 
+def _is_descriptor(obj):
+    """Returns True if obj is a descriptor, False otherwise."""
+    return (
+            hasattr(obj, '__get__') or
+            hasattr(obj, '__set__') or
+            hasattr(obj, '__delete__'))
+
+
 def _is_dunder(name):
     """Returns True if a __dunder__ name, False otherwise."""
     return (name[:2] == name[-2:] == '__' and
@@ -50,8 +58,9 @@
     cls.__reduce__ = _break_on_call_reduce
     cls.__module__ = '<unknown>'
 
+
 class _EnumDict(dict):
-    """Keeps track of definition order of the enum items.
+    """Track enum member order and ensure member names are not reused.
 
     EnumMeta will use the names found in self._member_names as the
     enumeration member names.
@@ -62,11 +71,7 @@
         self._member_names = []
 
     def __setitem__(self, key, value):
-        """Changes anything not dundered or that doesn't have __get__.
-
-        If a descriptor is added with the same name as an enum member, the name
-        is removed from _member_names (this may leave a hole in the numerical
-        sequence of values).
+        """Changes anything not dundered or not a descriptor.
 
         If an enum member name is used twice, an error is raised; duplicate
         values are not checked for.
@@ -76,19 +81,20 @@
         """
         if _is_sunder(key):
             raise ValueError('_names_ are reserved for future Enum use')
-        elif _is_dunder(key) or hasattr(value, '__get__'):
-            if key in self._member_names:
-                # overwriting an enum with a method?  then remove the name from
-                # _member_names or it will become an enum anyway when the class
-                # is created
-                self._member_names.remove(key)
-        else:
-            if key in self._member_names:
-                raise TypeError('Attempted to reuse key: %r' % key)
+        elif _is_dunder(key):
+            pass
+        elif key in self._member_names:
+            # descriptor overwriting an enum?
+            raise TypeError('Attempted to reuse key: %r' % key)
+        elif not _is_descriptor(value):
+            if key in self:
+                # enum overwriting a descriptor?
+                raise TypeError('Key already defined as: %r' % self[key])
             self._member_names.append(key)
         super().__setitem__(key, value)
 
 
+
 # Dummy value for Enum as EnumMeta explicitly checks for it, but of course
 # until EnumMeta finishes running the first time the Enum class doesn't exist.
 # This is also why there are checks in EnumMeta like `if Enum is not None`
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 1308003..5d96d6d 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -228,6 +228,32 @@
                 ['FALL', 'ANOTHER_SPRING'],
                 )
 
+    def test_duplicate_name(self):
+        with self.assertRaises(TypeError):
+            class Color(Enum):
+                red = 1
+                green = 2
+                blue = 3
+                red = 4
+
+        with self.assertRaises(TypeError):
+            class Color(Enum):
+                red = 1
+                green = 2
+                blue = 3
+                def red(self):
+                    return 'red'
+
+        with self.assertRaises(TypeError):
+            class Color(Enum):
+                @property
+                def red(self):
+                    return 'redder'
+                red = 1
+                green = 2
+                blue = 3
+
+
     def test_enum_with_value_name(self):
         class Huh(Enum):
             name = 1
@@ -618,17 +644,6 @@
         self.assertIsNot(type(whatever.really), whatever)
         self.assertEqual(whatever.this.really(), 'no, not that')
 
-    def test_overwrite_enums(self):
-        class Why(Enum):
-            question = 1
-            answer = 2
-            propisition = 3
-            def question(self):
-                print(42)
-        self.assertIsNot(type(Why.question), Why)
-        self.assertNotIn(Why.question, Why._member_names_)
-        self.assertNotIn(Why.question, Why)
-
     def test_wrong_inheritance_order(self):
         with self.assertRaises(TypeError):
             class Wrong(Enum, str):