The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*.
which may result in incomplete initialization.
Creating classes whose metaclass overrides
- :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it
- will be no longer allowed.
+ :c:member:`~PyTypeObject.tp_new` is deprecated.
+
+ .. versionchanged:: 3.14
+
+ Creating classes whose metaclass overrides
+ :c:member:`~PyTypeObject.tp_new` is no longer allowed.
.. c:function:: PyObject* PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*.
which may result in incomplete initialization.
Creating classes whose metaclass overrides
- :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it
- will be no longer allowed.
+ :c:member:`~PyTypeObject.tp_new` is deprecated.
+
+ .. versionchanged:: 3.14
+
+ Creating classes whose metaclass overrides
+ :c:member:`~PyTypeObject.tp_new` is no longer allowed.
.. c:function:: PyObject* PyType_FromSpec(PyType_Spec *spec)
The :c:member:`~PyTypeObject.tp_new` of the metaclass is *ignored*.
which may result in incomplete initialization.
Creating classes whose metaclass overrides
- :c:member:`~PyTypeObject.tp_new` is deprecated and in Python 3.14+ it
- will be no longer allowed.
+ :c:member:`~PyTypeObject.tp_new` is deprecated.
+
+ .. versionchanged:: 3.14
+
+ Creating classes whose metaclass overrides
+ :c:member:`~PyTypeObject.tp_new` is no longer allowed.
.. raw:: html
with self.assertRaisesRegex(TypeError, msg):
t = _testcapi.pytype_fromspec_meta(metaclass)
- def test_heaptype_with_custom_metaclass_deprecation(self):
+ def test_heaptype_base_with_custom_metaclass(self):
metaclass = _testcapi.HeapCTypeMetaclassCustomNew
- # gh-103968: a metaclass with custom tp_new is deprecated, but still
- # allowed for functions that existed in 3.11
- # (PyType_FromSpecWithBases is used here).
class Base(metaclass=metaclass):
pass
# Class creation from C
- with warnings_helper.check_warnings(
- ('.* _testcapi.Subclass .* custom tp_new.*in Python 3.14.*', DeprecationWarning),
- ):
+ msg = "Metaclasses with custom tp_new are not supported."
+ with self.assertRaisesRegex(TypeError, msg):
sub = _testcapi.make_type_with_base(Base)
- self.assertTrue(issubclass(sub, Base))
- self.assertIsInstance(sub, metaclass)
def test_multiple_inheritance_ctypes_with_weakref_or_dict(self):
for weakref_cls in (_testcapi.HeapCTypeWithWeakref,
--- /dev/null
+:c:func:`PyType_FromSpec`, :c:func:`PyType_FromSpecWithBases` and
+:c:func:`PyType_FromModuleAndSpec` will now fail if the metaclass of the new
+type has custom :c:member:`~PyTypeObject.tp_new`.
return -1;
}
-static PyObject *
-_PyType_FromMetaclass_impl(
+PyObject *
+PyType_FromMetaclass(
PyTypeObject *metaclass, PyObject *module,
- PyType_Spec *spec, PyObject *bases_in, int _allow_tp_new)
+ PyType_Spec *spec, PyObject *bases_in)
{
/* Invariant: A non-NULL value in one of these means this function holds
* a strong reference or owns allocated memory.
goto finally;
}
if (metaclass->tp_new && metaclass->tp_new != PyType_Type.tp_new) {
- if (_allow_tp_new) {
- if (PyErr_WarnFormat(
- PyExc_DeprecationWarning, 1,
- "Type %s uses PyType_Spec with a metaclass that has custom "
- "tp_new. This is deprecated and will no longer be allowed in "
- "Python 3.14.", spec->name) < 0) {
- goto finally;
- }
- }
- else {
- PyErr_SetString(
- PyExc_TypeError,
- "Metaclasses with custom tp_new are not supported.");
- goto finally;
- }
+ PyErr_SetString(
+ PyExc_TypeError,
+ "Metaclasses with custom tp_new are not supported.");
+ goto finally;
}
/* Calculate best base, and check that all bases are type objects */
return (PyObject*)res;
}
-PyObject *
-PyType_FromMetaclass(PyTypeObject *metaclass, PyObject *module,
- PyType_Spec *spec, PyObject *bases_in)
-{
- return _PyType_FromMetaclass_impl(metaclass, module, spec, bases_in, 0);
-}
-
PyObject *
PyType_FromModuleAndSpec(PyObject *module, PyType_Spec *spec, PyObject *bases)
{
- return _PyType_FromMetaclass_impl(NULL, module, spec, bases, 1);
+ return PyType_FromMetaclass(NULL, module, spec, bases);
}
PyObject *
PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
{
- return _PyType_FromMetaclass_impl(NULL, NULL, spec, bases, 1);
+ return PyType_FromMetaclass(NULL, NULL, spec, bases);
}
PyObject *
PyType_FromSpec(PyType_Spec *spec)
{
- return _PyType_FromMetaclass_impl(NULL, NULL, spec, NULL, 1);
+ return PyType_FromMetaclass(NULL, NULL, spec, NULL);
}
PyObject *