diff options
author | Petr Viktorin <encukou@gmail.com> | 2023-07-11 11:20:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-11 11:20:29 (GMT) |
commit | af5cf1e75136fcef967d4ebe1bc45f29e6dc1bcf (patch) | |
tree | 8f743796c63c2630a762bd7da8fe8d7c39bf2e74 /Doc | |
parent | e5c32a811c248a9b052fc63236da58f81f488b44 (diff) | |
download | cpython-af5cf1e75136fcef967d4ebe1bc45f29e6dc1bcf.zip cpython-af5cf1e75136fcef967d4ebe1bc45f29e6dc1bcf.tar.gz cpython-af5cf1e75136fcef967d4ebe1bc45f29e6dc1bcf.tar.bz2 |
gh-103968: What's New: Add porting hints for PyType_From with metaclasses (GH-105698)
Diffstat (limited to 'Doc')
-rw-r--r-- | Doc/whatsnew/3.12.rst | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst index 766f468..a6d101b 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 <call>` + 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 <sub-interpreter-support>`. This is |