summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Sobolev <mail@sobolevn.me>2024-06-02 07:27:20 (GMT)
committerGitHub <noreply@github.com>2024-06-02 07:27:20 (GMT)
commit4aed319a8eb63b205d6007c36713cacdbf1ce8a3 (patch)
tree1e45e41c909d712679b11a8b1efc969991d25935
parentfd6cd621e0cce6ba2e737103d2a62b5ade90f41f (diff)
downloadcpython-4aed319a8eb63b205d6007c36713cacdbf1ce8a3.zip
cpython-4aed319a8eb63b205d6007c36713cacdbf1ce8a3.tar.gz
cpython-4aed319a8eb63b205d6007c36713cacdbf1ce8a3.tar.bz2
gh-119775: Remove ability to create immutable types with mutable bases (#119776)
-rw-r--r--Doc/whatsnew/3.14.rst2
-rw-r--r--Lib/test/test_capi/test_misc.py28
-rw-r--r--Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst2
-rw-r--r--Objects/typeobject.c16
4 files changed, 13 insertions, 35 deletions
diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index d443cf9..45ffb28 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -258,3 +258,5 @@ Deprecated
Removed
-------
+* Creating :c:data:`immutable types <Py_TPFLAGS_IMMUTABLETYPE>` with mutable
+ bases was deprecated since 3.12 and now raises a :exc:`TypeError`.
diff --git a/Lib/test/test_capi/test_misc.py b/Lib/test/test_capi/test_misc.py
index f3d16e4..0dc0b53 100644
--- a/Lib/test/test_capi/test_misc.py
+++ b/Lib/test/test_capi/test_misc.py
@@ -777,33 +777,11 @@ class CAPITest(unittest.TestCase):
with self.assertRaises(SystemError):
_testcapi.create_type_from_repeated_slots(variant)
- @warnings_helper.ignore_warnings(category=DeprecationWarning)
def test_immutable_type_with_mutable_base(self):
- # Add deprecation warning here so it's removed in 3.14
- warnings._deprecated(
- 'creating immutable classes with mutable bases', remove=(3, 14))
-
- class MutableBase:
- def meth(self):
- return 'original'
-
- with self.assertWarns(DeprecationWarning):
- ImmutableSubclass = _testcapi.make_immutable_type_with_base(
- MutableBase)
- instance = ImmutableSubclass()
+ class MutableBase: ...
- 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')
+ with self.assertRaisesRegex(TypeError, 'Creating immutable type'):
+ _testcapi.make_immutable_type_with_base(MutableBase)
def test_pynumber_tobase(self):
from _testcapi import pynumber_tobase
diff --git a/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst b/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst
new file mode 100644
index 0000000..c342a38
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2024-05-30-12-51-21.gh-issue-119775.CBq9IG.rst
@@ -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`.
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index 290306c..0095a79 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -4613,16 +4613,12 @@ _PyType_FromMetaclass_impl(
goto finally;
}
if (!_PyType_HasFeature(b, Py_TPFLAGS_IMMUTABLETYPE)) {
- if (PyErr_WarnFormat(
- PyExc_DeprecationWarning,
- 0,
- "Creating immutable type %s from mutable base %s is "
- "deprecated, and slated to be disallowed in Python 3.14.",
- spec->name,
- b->tp_name))
- {
- goto finally;
- }
+ PyErr_Format(
+ PyExc_TypeError,
+ "Creating immutable type %s from mutable base %N",
+ spec->name, b
+ );
+ goto finally;
}
}
}