aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Lib/enum.py18
-rw-r--r--Lib/test/test_enum.py23
-rw-r--r--Misc/NEWS.d/next/Library/2021-02-08-16-27-00.bpo-43162.t-W7h3.rst2
3 files changed, 39 insertions, 4 deletions
diff --git a/Lib/enum.py b/Lib/enum.py
index d4b11521ab2..55299c57882 100644
--- a/Lib/enum.py
+++ b/Lib/enum.py
@@ -139,12 +139,22 @@ class property(DynamicClassAttribute):
return ownerclass._member_map_[self.name]
except KeyError:
raise AttributeError(
- '%s: no attribute %r' % (ownerclass.__name__, self.name)
+ '%s: no class attribute %r' % (ownerclass.__name__, self.name)
)
else:
if self.fget is None:
+ # check for member
+ if self.name in ownerclass._member_map_:
+ import warnings
+ warnings.warn(
+ "accessing one member from another is not supported, "
+ " and will be disabled in 3.11",
+ DeprecationWarning,
+ stacklevel=2,
+ )
+ return ownerclass._member_map_[self.name]
raise AttributeError(
- '%s: no attribute %r' % (ownerclass.__name__, self.name)
+ '%s: no instance attribute %r' % (ownerclass.__name__, self.name)
)
else:
return self.fget(instance)
@@ -152,7 +162,7 @@ class property(DynamicClassAttribute):
def __set__(self, instance, value):
if self.fset is None:
raise AttributeError(
- "%s: cannot set attribute %r" % (self.clsname, self.name)
+ "%s: cannot set instance attribute %r" % (self.clsname, self.name)
)
else:
return self.fset(instance, value)
@@ -160,7 +170,7 @@ class property(DynamicClassAttribute):
def __delete__(self, instance):
if self.fdel is None:
raise AttributeError(
- "%s: cannot delete attribute %r" % (self.clsname, self.name)
+ "%s: cannot delete instance attribute %r" % (self.clsname, self.name)
)
else:
return self.fdel(instance)
diff --git a/Lib/test/test_enum.py b/Lib/test/test_enum.py
index 96de878faf7..3982d1d6430 100644
--- a/Lib/test/test_enum.py
+++ b/Lib/test/test_enum.py
@@ -2185,6 +2185,29 @@ class TestEnum(unittest.TestCase):
self.assertEqual(Private._Private__corporal, 'Radar')
self.assertEqual(Private._Private__major_, 'Hoolihan')
+ @unittest.skipUnless(
+ sys.version_info[:2] == (3, 10),
+ 'member-member access now raises an exception',
+ )
+ def test_warning_for_member_from_member_access(self):
+ with self.assertWarns(DeprecationWarning):
+ class Di(Enum):
+ YES = 1
+ NO = 0
+ nope = Di.YES.NO
+ self.assertIs(Di.NO, nope)
+
+ @unittest.skipUnless(
+ sys.version_info[:2] > (3, 10),
+ 'member-member access currently issues a warning',
+ )
+ def test_exception_for_member_from_member_access(self):
+ with self.assertRaisesRegex(AttributeError, "Di: no instance attribute .NO."):
+ class Di(Enum):
+ YES = 1
+ NO = 0
+ nope = Di.YES.NO
+
def test_strenum_auto(self):
class Strings(StrEnum):
ONE = auto()
diff --git a/Misc/NEWS.d/next/Library/2021-02-08-16-27-00.bpo-43162.t-W7h3.rst b/Misc/NEWS.d/next/Library/2021-02-08-16-27-00.bpo-43162.t-W7h3.rst
new file mode 100644
index 00000000000..fef5915e762
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2021-02-08-16-27-00.bpo-43162.t-W7h3.rst
@@ -0,0 +1,2 @@
+deprecate unsupported ability to access enum members as attributes of other
+enum members