We've cheerfully broken the ABI before on minor releases, though if it's part of the stable ABI, we can't be cavaliar about that anymore.
2013/7/22 Victor Stinner <victor.stin...@gmail.com>: > "Add a new PyStructSequence_InitType2()" > > I added a new function because I guess that it would break the API (and ABI) > to change the return type of a function in a minor release. > > Tell me if you have a better name than PyStructSequence_InitType2() ;-) > > "Ex" suffix is usually used when parameters are added. It is not the case > here. > > Victor > > Le 22 juil. 2013 23:59, "victor.stinner" <python-check...@python.org> a > écrit : >> >> http://hg.python.org/cpython/rev/fc718c177ee6 >> changeset: 84793:fc718c177ee6 >> user: Victor Stinner <victor.stin...@gmail.com> >> date: Mon Jul 22 22:24:54 2013 +0200 >> summary: >> Issue #18520: Add a new PyStructSequence_InitType2() function, same than >> PyStructSequence_InitType() except that it has a return value (0 on >> success, >> -1 on error). >> >> * PyStructSequence_InitType2() now raises MemoryError on memory >> allocation failure >> * Fix also some calls to PyDict_SetItemString(): handle error >> >> files: >> Include/pythonrun.h | 2 +- >> Include/structseq.h | 2 + >> Misc/NEWS | 4 +++ >> Modules/_lsprof.c | 10 ++++--- >> Modules/grpmodule.c | 11 ++++++-- >> Modules/posixmodule.c | 24 ++++++++++++------ >> Modules/pwdmodule.c | 5 ++- >> Modules/resource.c | 9 ++++-- >> Modules/signalmodule.c | 7 +++-- >> Modules/spwdmodule.c | 8 ++++-- >> Modules/timemodule.c | 5 ++- >> Objects/floatobject.c | 9 ++++-- >> Objects/longobject.c | 6 +++- >> Objects/structseq.c | 37 +++++++++++++++++++++-------- >> Python/pythonrun.c | 3 +- >> Python/sysmodule.c | 23 ++++++++++++----- >> Python/thread.c | 6 +++- >> 17 files changed, 117 insertions(+), 54 deletions(-) >> >> >> diff --git a/Include/pythonrun.h b/Include/pythonrun.h >> --- a/Include/pythonrun.h >> +++ b/Include/pythonrun.h >> @@ -197,7 +197,7 @@ >> PyAPI_FUNC(void) _PyExc_Init(PyObject * bltinmod); >> PyAPI_FUNC(void) _PyImportHooks_Init(void); >> PyAPI_FUNC(int) _PyFrame_Init(void); >> -PyAPI_FUNC(void) _PyFloat_Init(void); >> +PyAPI_FUNC(int) _PyFloat_Init(void); >> PyAPI_FUNC(int) PyByteArray_Init(void); >> PyAPI_FUNC(void) _PyRandom_Init(void); >> #endif >> diff --git a/Include/structseq.h b/Include/structseq.h >> --- a/Include/structseq.h >> +++ b/Include/structseq.h >> @@ -24,6 +24,8 @@ >> #ifndef Py_LIMITED_API >> PyAPI_FUNC(void) PyStructSequence_InitType(PyTypeObject *type, >> PyStructSequence_Desc *desc); >> +PyAPI_FUNC(int) PyStructSequence_InitType2(PyTypeObject *type, >> + PyStructSequence_Desc *desc); >> #endif >> PyAPI_FUNC(PyTypeObject*) PyStructSequence_NewType(PyStructSequence_Desc >> *desc); >> >> diff --git a/Misc/NEWS b/Misc/NEWS >> --- a/Misc/NEWS >> +++ b/Misc/NEWS >> @@ -10,6 +10,10 @@ >> Core and Builtins >> ----------------- >> >> +- Issue #18520: Add a new PyStructSequence_InitType2() function, same >> than >> + PyStructSequence_InitType() except that it has a return value (0 on >> success, >> + -1 on error). >> + >> - Issue #15905: Fix theoretical buffer overflow in handling of >> sys.argv[0], >> prefix and exec_prefix if the operation system does not obey >> MAXPATHLEN. >> >> diff --git a/Modules/_lsprof.c b/Modules/_lsprof.c >> --- a/Modules/_lsprof.c >> +++ b/Modules/_lsprof.c >> @@ -884,10 +884,12 @@ >> PyDict_SetItemString(d, "Profiler", (PyObject *)&PyProfiler_Type); >> >> if (!initialized) { >> - PyStructSequence_InitType(&StatsEntryType, >> - &profiler_entry_desc); >> - PyStructSequence_InitType(&StatsSubEntryType, >> - &profiler_subentry_desc); >> + if (PyStructSequence_InitType2(&StatsEntryType, >> + &profiler_entry_desc) < 0) >> + return NULL; >> + if (PyStructSequence_InitType2(&StatsSubEntryType, >> + &profiler_subentry_desc) < 0) >> + return NULL; >> } >> Py_INCREF((PyObject*) &StatsEntryType); >> Py_INCREF((PyObject*) &StatsSubEntryType); >> diff --git a/Modules/grpmodule.c b/Modules/grpmodule.c >> --- a/Modules/grpmodule.c >> +++ b/Modules/grpmodule.c >> @@ -210,9 +210,14 @@ >> if (m == NULL) >> return NULL; >> d = PyModule_GetDict(m); >> - if (!initialized) >> - PyStructSequence_InitType(&StructGrpType, >> &struct_group_type_desc); >> - PyDict_SetItemString(d, "struct_group", (PyObject *) &StructGrpType); >> + if (!initialized) { >> + if (PyStructSequence_InitType2(&StructGrpType, >> + &struct_group_type_desc) < 0) >> + return NULL; >> + } >> + if (PyDict_SetItemString(d, "struct_group", >> + (PyObject *)&StructGrpType) < 0) >> + return NULL; >> initialized = 1; >> return m; >> } >> diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c >> --- a/Modules/posixmodule.c >> +++ b/Modules/posixmodule.c >> @@ -11518,19 +11518,23 @@ >> if (!initialized) { >> #if defined(HAVE_WAITID) && !defined(__APPLE__) >> waitid_result_desc.name = MODNAME ".waitid_result"; >> - PyStructSequence_InitType(&WaitidResultType, >> &waitid_result_desc); >> + if (PyStructSequence_InitType2(&WaitidResultType, >> &waitid_result_desc) < 0) >> + return NULL; >> #endif >> >> stat_result_desc.name = MODNAME ".stat_result"; >> stat_result_desc.fields[7].name = PyStructSequence_UnnamedField; >> stat_result_desc.fields[8].name = PyStructSequence_UnnamedField; >> stat_result_desc.fields[9].name = PyStructSequence_UnnamedField; >> - PyStructSequence_InitType(&StatResultType, &stat_result_desc); >> + if (PyStructSequence_InitType2(&StatResultType, >> &stat_result_desc) < 0) >> + return NULL; >> structseq_new = StatResultType.tp_new; >> StatResultType.tp_new = statresult_new; >> >> statvfs_result_desc.name = MODNAME ".statvfs_result"; >> - PyStructSequence_InitType(&StatVFSResultType, >> &statvfs_result_desc); >> + if (PyStructSequence_InitType2(&StatVFSResultType, >> + &statvfs_result_desc) < 0) >> + return NULL; >> #ifdef NEED_TICKS_PER_SECOND >> # if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK) >> ticks_per_second = sysconf(_SC_CLK_TCK); >> @@ -11543,12 +11547,15 @@ >> >> #if defined(HAVE_SCHED_SETPARAM) || defined(HAVE_SCHED_SETSCHEDULER) >> sched_param_desc.name = MODNAME ".sched_param"; >> - PyStructSequence_InitType(&SchedParamType, &sched_param_desc); >> + if (PyStructSequence_InitType2(&SchedParamType, >> &sched_param_desc) < 0) >> + return NULL; >> SchedParamType.tp_new = sched_param_new; >> #endif >> >> /* initialize TerminalSize_info */ >> - PyStructSequence_InitType(&TerminalSizeType, &TerminalSize_desc); >> + if (PyStructSequence_InitType2(&TerminalSizeType, >> + &TerminalSize_desc) < 0) >> + return NULL; >> } >> #if defined(HAVE_WAITID) && !defined(__APPLE__) >> Py_INCREF((PyObject*) &WaitidResultType); >> @@ -11566,11 +11573,13 @@ >> #endif >> >> times_result_desc.name = MODNAME ".times_result"; >> - PyStructSequence_InitType(&TimesResultType, ×_result_desc); >> + if (PyStructSequence_InitType2(&TimesResultType, ×_result_desc) >> < 0) >> + return NULL; >> PyModule_AddObject(m, "times_result", (PyObject *)&TimesResultType); >> >> uname_result_desc.name = MODNAME ".uname_result"; >> - PyStructSequence_InitType(&UnameResultType, &uname_result_desc); >> + if (PyStructSequence_InitType2(&UnameResultType, &uname_result_desc) >> < 0) >> + return NULL; >> PyModule_AddObject(m, "uname_result", (PyObject *)&UnameResultType); >> >> #ifdef __APPLE__ >> @@ -11648,7 +11657,6 @@ >> initialized = 1; >> >> return m; >> - >> } >> >> #ifdef __cplusplus >> diff --git a/Modules/pwdmodule.c b/Modules/pwdmodule.c >> --- a/Modules/pwdmodule.c >> +++ b/Modules/pwdmodule.c >> @@ -216,8 +216,9 @@ >> return NULL; >> >> if (!initialized) { >> - PyStructSequence_InitType(&StructPwdType, >> - &struct_pwd_type_desc); >> + if (PyStructSequence_InitType2(&StructPwdType, >> + &struct_pwd_type_desc) < 0) >> + return NULL; >> initialized = 1; >> } >> Py_INCREF((PyObject *) &StructPwdType); >> diff --git a/Modules/resource.c b/Modules/resource.c >> --- a/Modules/resource.c >> +++ b/Modules/resource.c >> @@ -263,9 +263,12 @@ >> /* Add some symbolic constants to the module */ >> Py_INCREF(PyExc_OSError); >> PyModule_AddObject(m, "error", PyExc_OSError); >> - if (!initialized) >> - PyStructSequence_InitType(&StructRUsageType, >> - &struct_rusage_desc); >> + if (!initialized) { >> + if (PyStructSequence_InitType2(&StructRUsageType, >> + &struct_rusage_desc) < 0) >> + return NULL; >> + } >> + >> Py_INCREF(&StructRUsageType); >> PyModule_AddObject(m, "struct_rusage", >> (PyObject*) &StructRUsageType); >> diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c >> --- a/Modules/signalmodule.c >> +++ b/Modules/signalmodule.c >> @@ -978,9 +978,10 @@ >> return NULL; >> >> #if defined(HAVE_SIGWAITINFO) || defined(HAVE_SIGTIMEDWAIT) >> - if (!initialized) >> - PyStructSequence_InitType(&SiginfoType, &struct_siginfo_desc); >> - >> + if (!initialized) { >> + if (PyStructSequence_InitType2(&SiginfoType, >> &struct_siginfo_desc) < 0) >> + return NULL; >> + } >> Py_INCREF((PyObject*) &SiginfoType); >> PyModule_AddObject(m, "struct_siginfo", (PyObject*) &SiginfoType); >> initialized = 1; >> diff --git a/Modules/spwdmodule.c b/Modules/spwdmodule.c >> --- a/Modules/spwdmodule.c >> +++ b/Modules/spwdmodule.c >> @@ -196,9 +196,11 @@ >> m=PyModule_Create(&spwdmodule); >> if (m == NULL) >> return NULL; >> - if (!initialized) >> - PyStructSequence_InitType(&StructSpwdType, >> - &struct_spwd_type_desc); >> + if (!initialized) { >> + if (PyStructSequence_InitType2(&StructSpwdType, >> + &struct_spwd_type_desc) < 0) >> + return NULL; >> + } >> Py_INCREF((PyObject *) &StructSpwdType); >> PyModule_AddObject(m, "struct_spwd", (PyObject *) &StructSpwdType); >> initialized = 1; >> diff --git a/Modules/timemodule.c b/Modules/timemodule.c >> --- a/Modules/timemodule.c >> +++ b/Modules/timemodule.c >> @@ -1476,8 +1476,9 @@ >> PyInit_timezone(m); >> >> if (!initialized) { >> - PyStructSequence_InitType(&StructTimeType, >> - &struct_time_type_desc); >> + if (PyStructSequence_InitType2(&StructTimeType, >> + &struct_time_type_desc) < 0) >> + return NULL; >> >> #ifdef MS_WINDOWS >> winver.dwOSVersionInfoSize = sizeof(winver); >> diff --git a/Objects/floatobject.c b/Objects/floatobject.c >> --- a/Objects/floatobject.c >> +++ b/Objects/floatobject.c >> @@ -1853,7 +1853,7 @@ >> float_new, /* tp_new */ >> }; >> >> -void >> +int >> _PyFloat_Init(void) >> { >> /* We attempt to determine if this machine is using IEEE >> @@ -1903,8 +1903,11 @@ >> float_format = detected_float_format; >> >> /* Init float info */ >> - if (FloatInfoType.tp_name == 0) >> - PyStructSequence_InitType(&FloatInfoType, &floatinfo_desc); >> + if (FloatInfoType.tp_name == NULL) { >> + if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < >> 0) >> + return 0; >> + } >> + return 1; >> } >> >> int >> diff --git a/Objects/longobject.c b/Objects/longobject.c >> --- a/Objects/longobject.c >> +++ b/Objects/longobject.c >> @@ -5059,8 +5059,10 @@ >> } >> #endif >> /* initialize int_info */ >> - if (Int_InfoType.tp_name == 0) >> - PyStructSequence_InitType(&Int_InfoType, &int_info_desc); >> + if (Int_InfoType.tp_name == NULL) { >> + if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < >> 0) >> + return 0; >> + } >> >> return 1; >> } >> diff --git a/Objects/structseq.c b/Objects/structseq.c >> --- a/Objects/structseq.c >> +++ b/Objects/structseq.c >> @@ -320,12 +320,13 @@ >> structseq_new, /* tp_new */ >> }; >> >> -void >> -PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc >> *desc) >> +int >> +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc >> *desc) >> { >> PyObject *dict; >> PyMemberDef* members; >> int n_members, n_unnamed_members, i, k; >> + PyObject *v; >> >> #ifdef Py_TRACE_REFS >> /* if the type object was chained, unchain it first >> @@ -347,8 +348,10 @@ >> type->tp_doc = desc->doc; >> >> members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1); >> - if (members == NULL) >> - return; >> + if (members == NULL) { >> + PyErr_NoMemory(); >> + return -1; >> + } >> >> for (i = k = 0; i < n_members; ++i) { >> if (desc->fields[i].name == PyStructSequence_UnnamedField) >> @@ -366,22 +369,33 @@ >> type->tp_members = members; >> >> if (PyType_Ready(type) < 0) >> - return; >> + return -1; >> Py_INCREF(type); >> >> dict = type->tp_dict; >> #define SET_DICT_FROM_INT(key, value) \ >> do { \ >> - PyObject *v = PyLong_FromLong((long) value); \ >> - if (v != NULL) { \ >> - PyDict_SetItemString(dict, key, v); \ >> + v = PyLong_FromLong((long) value); \ >> + if (v == NULL) \ >> + return -1; \ >> + if (PyDict_SetItemString(dict, key, v) < 0) { \ >> Py_DECREF(v); \ >> + return -1; \ >> } \ >> + Py_DECREF(v); \ >> } while (0) >> >> SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence); >> SET_DICT_FROM_INT(real_length_key, n_members); >> SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); >> + >> + return 0; >> +} >> + >> +void >> +PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc >> *desc) >> +{ >> + (void)PyStructSequence_InitType2(type, desc); >> } >> >> PyTypeObject* >> @@ -390,8 +404,11 @@ >> PyTypeObject *result; >> >> result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); >> - if (result != NULL) { >> - PyStructSequence_InitType(result, desc); >> + if (result == NULL) >> + return NULL; >> + if (PyStructSequence_InitType2(result, desc) < 0) { >> + Py_DECREF(result); >> + return NULL; >> } >> return result; >> } >> diff --git a/Python/pythonrun.c b/Python/pythonrun.c >> --- a/Python/pythonrun.c >> +++ b/Python/pythonrun.c >> @@ -328,7 +328,8 @@ >> if (!PyByteArray_Init()) >> Py_FatalError("Py_Initialize: can't init bytearray"); >> >> - _PyFloat_Init(); >> + if (!_PyFloat_Init()) >> + Py_FatalError("Py_Initialize: can't init float"); >> >> interp->modules = PyDict_New(); >> if (interp->modules == NULL) >> diff --git a/Python/sysmodule.c b/Python/sysmodule.c >> --- a/Python/sysmodule.c >> +++ b/Python/sysmodule.c >> @@ -1634,8 +1634,10 @@ >> SET_SYS_FROM_STRING("int_info", >> PyLong_GetInfo()); >> /* initialize hash_info */ >> - if (Hash_InfoType.tp_name == 0) >> - PyStructSequence_InitType(&Hash_InfoType, &hash_info_desc); >> + if (Hash_InfoType.tp_name == NULL) { >> + if (PyStructSequence_InitType2(&Hash_InfoType, &hash_info_desc) < >> 0) >> + return NULL; >> + } >> SET_SYS_FROM_STRING("hash_info", >> get_hash_info()); >> SET_SYS_FROM_STRING("maxunicode", >> @@ -1676,8 +1678,11 @@ >> } >> >> /* version_info */ >> - if (VersionInfoType.tp_name == 0) >> - PyStructSequence_InitType(&VersionInfoType, &version_info_desc); >> + if (VersionInfoType.tp_name == NULL) { >> + if (PyStructSequence_InitType2(&VersionInfoType, >> + &version_info_desc) < 0) >> + return NULL; >> + } >> version_info = make_version_info(); >> SET_SYS_FROM_STRING("version_info", version_info); >> /* prevent user from creating new instances */ >> @@ -1688,8 +1693,10 @@ >> SET_SYS_FROM_STRING("implementation", make_impl_info(version_info)); >> >> /* flags */ >> - if (FlagsType.tp_name == 0) >> - PyStructSequence_InitType(&FlagsType, &flags_desc); >> + if (FlagsType.tp_name == 0) { >> + if (PyStructSequence_InitType2(&FlagsType, &flags_desc) < 0) >> + return NULL; >> + } >> SET_SYS_FROM_STRING("flags", make_flags()); >> /* prevent user from creating new instances */ >> FlagsType.tp_init = NULL; >> @@ -1699,7 +1706,9 @@ >> #if defined(MS_WINDOWS) >> /* getwindowsversion */ >> if (WindowsVersionType.tp_name == 0) >> - PyStructSequence_InitType(&WindowsVersionType, >> &windows_version_desc); >> + if (PyStructSequence_InitType2(&WindowsVersionType, >> + &windows_version_desc) < 0) >> + return NULL; >> /* prevent user from creating new instances */ >> WindowsVersionType.tp_init = NULL; >> WindowsVersionType.tp_new = NULL; >> diff --git a/Python/thread.c b/Python/thread.c >> --- a/Python/thread.c >> +++ b/Python/thread.c >> @@ -399,8 +399,10 @@ >> int len; >> #endif >> >> - if (ThreadInfoType.tp_name == 0) >> - PyStructSequence_InitType(&ThreadInfoType, &threadinfo_desc); >> + if (ThreadInfoType.tp_name == 0) { >> + if (PyStructSequence_InitType2(&ThreadInfoType, &threadinfo_desc) >> < 0) >> + return NULL; >> + } >> >> threadinfo = PyStructSequence_New(&ThreadInfoType); >> if (threadinfo == NULL) >> >> -- >> Repository URL: http://hg.python.org/cpython >> >> _______________________________________________ >> Python-checkins mailing list >> python-check...@python.org >> http://mail.python.org/mailman/listinfo/python-checkins >> > > _______________________________________________ > Python-Dev mailing list > Python-Dev@python.org > http://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > http://mail.python.org/mailman/options/python-dev/benjamin%40python.org > -- Regards, Benjamin _______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com