mirror of https://github.com/python/cpython
gh-119775: Remove ability to create immutable types with mutable bases (#119776)
This commit is contained in:
parent
fd6cd621e0
commit
4aed319a8e
|
@ -258,3 +258,5 @@ Deprecated
|
||||||
Removed
|
Removed
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
|
||||||
|
bases was deprecated since 3.12 and now raises a :exc:`TypeError`.
|
||||||
|
|
|
@ -777,33 +777,11 @@ class CAPITest(unittest.TestCase):
|
||||||
with self.assertRaises(SystemError):
|
with self.assertRaises(SystemError):
|
||||||
_testcapi.create_type_from_repeated_slots(variant)
|
_testcapi.create_type_from_repeated_slots(variant)
|
||||||
|
|
||||||
@warnings_helper.ignore_warnings(category=DeprecationWarning)
|
|
||||||
def test_immutable_type_with_mutable_base(self):
|
def test_immutable_type_with_mutable_base(self):
|
||||||
# Add deprecation warning here so it's removed in 3.14
|
class MutableBase: ...
|
||||||
warnings._deprecated(
|
|
||||||
'creating immutable classes with mutable bases', remove=(3, 14))
|
|
||||||
|
|
||||||
class MutableBase:
|
with self.assertRaisesRegex(TypeError, 'Creating immutable type'):
|
||||||
def meth(self):
|
_testcapi.make_immutable_type_with_base(MutableBase)
|
||||||
return 'original'
|
|
||||||
|
|
||||||
with self.assertWarns(DeprecationWarning):
|
|
||||||
ImmutableSubclass = _testcapi.make_immutable_type_with_base(
|
|
||||||
MutableBase)
|
|
||||||
instance = ImmutableSubclass()
|
|
||||||
|
|
||||||
self.assertEqual(instance.meth(), 'original')
|
|
||||||
|
|
||||||
# Cannot override the static type's method
|
|
||||||
with self.assertRaisesRegex(
|
|
||||||
TypeError,
|
|
||||||
"cannot set 'meth' attribute of immutable type"):
|
|
||||||
ImmutableSubclass.meth = lambda self: 'overridden'
|
|
||||||
self.assertEqual(instance.meth(), 'original')
|
|
||||||
|
|
||||||
# Can change the method on the mutable base
|
|
||||||
MutableBase.meth = lambda self: 'changed'
|
|
||||||
self.assertEqual(instance.meth(), 'changed')
|
|
||||||
|
|
||||||
def test_pynumber_tobase(self):
|
def test_pynumber_tobase(self):
|
||||||
from _testcapi import pynumber_tobase
|
from _testcapi import pynumber_tobase
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
|
||||||
|
bases was deprecated since 3.12 and now raises a :exc:`TypeError`.
|
|
@ -4613,16 +4613,12 @@ _PyType_FromMetaclass_impl(
|
||||||
goto finally;
|
goto finally;
|
||||||
}
|
}
|
||||||
if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) {
|
if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) {
|
||||||
if (PyErr_WarnFormat(
|
PyErr_Format(
|
||||||
PyExc_DeprecationWarning,
|
PyExc_TypeError,
|
||||||
0,
|
"Creating immutable type %s from mutable base %N",
|
||||||
"Creating immutable type %s from mutable base %s is "
|
spec->name, b
|
||||||
"deprecated, and slated to be disallowed in Python 3.14.",
|
);
|
||||||
spec->name,
|
goto finally;
|
||||||
b->tp_name))
|
|
||||||
{
|
|
||||||
goto finally;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue