bpo-43916: Add Py_TPFLAGS_DISALLOW_INSTANTIATION type flag (GH-25721)

Add a new Py_TPFLAGS_DISALLOW_INSTANTIATION type flag to disallow
creating type instances: set tp_new to NULL and don't create the
"__new__" key in the type dictionary.

The flag is set automatically on static types if tp_base is NULL or
&PyBaseObject_Type and tp_new is NULL.

Use the flag on the following types:

* _curses.ncurses_version type
* _curses_panel.panel
* _tkinter.Tcl_Obj
* _tkinter.tkapp
* _tkinter.tktimertoken
* _xxsubinterpretersmodule.ChannelID
* sys.flags type
* sys.getwindowsversion() type
* sys.version_info type

Update MyStr example in the C API documentation to use
Py_TPFLAGS_DISALLOW_INSTANTIATION.

Add _PyStructSequence_InitType() function to create a structseq type
with the Py_TPFLAGS_DISALLOW_INSTANTIATION flag set.

type_new() calls _PyType_CheckConsistency() at exit.
This commit is contained in:
Victor Stinner 2021-04-30 12:46:15 +02:00 committed by GitHub
parent b73b5fb9ea
commit 3bb09947ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 144 additions and 102 deletions

View file

@ -1199,6 +1199,25 @@ and :c:type:`PyType_Type` effectively act as defaults.)
.. versionadded:: 3.10
.. data:: Py_TPFLAGS_DISALLOW_INSTANTIATION
Disallow creating instances of the type: set
:c:member:`~PyTypeObject.tp_new` to NULL and don't create the ``__new__``
key in the type dictionary.
The flag must be set before creating the type, not after. For example, it
must be set before :c:func:`PyType_Ready` is called on the type.
The flag is set automatically on :ref:`static types <static-types>` if
:c:member:`~PyTypeObject.tp_base` is NULL or ``&PyBaseObject_Type`` and
:c:member:`~PyTypeObject.tp_new` is NULL.
**Inheritance:**
This flag is not inherited.
.. versionadded:: 3.10
.. c:member:: const char* PyTypeObject.tp_doc
@ -1761,6 +1780,9 @@ and :c:type:`PyType_Type` effectively act as defaults.)
in :c:member:`~PyTypeObject.tp_new`, while for mutable types, most initialization should be
deferred to :c:member:`~PyTypeObject.tp_init`.
Set the :const:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag to disallow creating
instances of the type in Python.
**Inheritance:**
This field is inherited by subtypes, except it is not inherited by
@ -2596,7 +2618,8 @@ A type that supports weakrefs, instance dicts, and hashing::
};
A str subclass that cannot be subclassed and cannot be called
to create instances (e.g. uses a separate factory func)::
to create instances (e.g. uses a separate factory func) using
:c:data:`Py_TPFLAGS_DISALLOW_INSTANTIATION` flag::
typedef struct {
PyUnicodeObject raw;
@ -2609,8 +2632,7 @@ to create instances (e.g. uses a separate factory func)::
.tp_basicsize = sizeof(MyStr),
.tp_base = NULL, // set to &PyUnicode_Type in module init
.tp_doc = "my custom str",
.tp_flags = Py_TPFLAGS_DEFAULT,
.tp_new = NULL,
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_DISALLOW_INSTANTIATION,
.tp_repr = (reprfunc)myobj_repr,
};