From af5cf1e75136fcef967d4ebe1bc45f29e6dc1bcf Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 11 Jul 2023 13:20:29 +0200 Subject: [PATCH] gh-103968: What's New: Add porting hints for PyType_From with metaclasses (GH-105698) --- Doc/whatsnew/3.12.rst | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 766f468cf9cfbc..a6d101bdb9f7a8 100644 --- a/Doc/whatsnew/3.12.rst +++ b/Doc/whatsnew/3.12.rst @@ -1837,7 +1837,31 @@ Porting to Python 3.12 allowing incomplete initialization. Note that :c:func:`PyType_FromMetaclass` (added in Python 3.12) - already disallows creating classes whose metaclass overrides ``tp_new``. + already disallows creating classes whose metaclass overrides ``tp_new`` + (:meth:`~object.__new__` in Python). + + Since ``tp_new`` overrides almost everything ``PyType_From*`` functions do, + the two are incompatible with each other. + The existing behavior -- ignoring the metaclass for several steps + of type creation -- is unsafe in general, since (meta)classes assume that + ``tp_new`` was called. + There is no simple general workaround. One of the following may work for you: + + - If you control the metaclass, avoid using ``tp_new`` in it: + + - If initialization can be skipped, it can be done in + :c:member:`~PyTypeObject.tp_init` instead. + - If the metaclass doesn't need to be instantiated from Python, + set its ``tp_new`` to ``NULL`` using + the :const:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag. + This makes it acceptable for ``PyType_From*`` functions. + + - Avoid ``PyType_From*`` functions: if you don't need C-specific features + (slots or setting the instance size), create types by :ref:`calling ` + the metaclass. + + - If you *know* the ``tp_new`` can be skipped safely, filter the deprecation + warning out using :func:`warnings.catch_warnings` from Python. * :c:var:`PyOS_InputHook` and :c:var:`PyOS_ReadlineFunctionPointer` are no longer called in :ref:`subinterpreters `. This is