mirror of
https://github.com/python/cpython.git
synced 2025-07-08 03:45:36 +00:00
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:
parent
b73b5fb9ea
commit
3bb09947ec
13 changed files with 144 additions and 102 deletions
|
@ -2810,56 +2810,35 @@ _PySys_InitCore(PyThreadState *tstate, PyObject *sysdict)
|
|||
|
||||
/* version_info */
|
||||
if (VersionInfoType.tp_name == NULL) {
|
||||
if (PyStructSequence_InitType2(&VersionInfoType,
|
||||
&version_info_desc) < 0) {
|
||||
if (_PyStructSequence_InitType(&VersionInfoType,
|
||||
&version_info_desc,
|
||||
Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
version_info = make_version_info(tstate);
|
||||
SET_SYS("version_info", version_info);
|
||||
/* prevent user from creating new instances */
|
||||
VersionInfoType.tp_init = NULL;
|
||||
VersionInfoType.tp_new = NULL;
|
||||
res = PyDict_DelItemString(VersionInfoType.tp_dict, "__new__");
|
||||
if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
|
||||
/* implementation */
|
||||
SET_SYS("implementation", make_impl_info(version_info));
|
||||
|
||||
// sys.flags: updated in-place later by _PySys_UpdateConfig()
|
||||
if (FlagsType.tp_name == 0) {
|
||||
if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) {
|
||||
if (_PyStructSequence_InitType(&FlagsType, &flags_desc,
|
||||
Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
}
|
||||
SET_SYS("flags", make_flags(tstate->interp));
|
||||
/* prevent user from creating new instances */
|
||||
FlagsType.tp_init = NULL;
|
||||
FlagsType.tp_new = NULL;
|
||||
res = PyDict_DelItemString(FlagsType.tp_dict, "__new__");
|
||||
if (res < 0) {
|
||||
if (!_PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
|
||||
goto err_occurred;
|
||||
}
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
/* getwindowsversion */
|
||||
if (WindowsVersionType.tp_name == 0)
|
||||
if (PyStructSequence_InitType2(&WindowsVersionType,
|
||||
&windows_version_desc) < 0) {
|
||||
if (WindowsVersionType.tp_name == 0) {
|
||||
if (_PyStructSequence_InitType(&WindowsVersionType,
|
||||
&windows_version_desc,
|
||||
Py_TPFLAGS_DISALLOW_INSTANTIATION) < 0) {
|
||||
goto type_init_failed;
|
||||
}
|
||||
/* prevent user from creating new instances */
|
||||
WindowsVersionType.tp_init = NULL;
|
||||
WindowsVersionType.tp_new = NULL;
|
||||
assert(!_PyErr_Occurred(tstate));
|
||||
res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
|
||||
if (res < 0 && _PyErr_ExceptionMatches(tstate, PyExc_KeyError)) {
|
||||
_PyErr_Clear(tstate);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue