[Python-checkins] [Python-Dev] cpython: Issue #18520: Add a new PyStructSequence_InitType2() function, same than

Benjamin Peterson benjamin at python.org
Tue Jul 23 02:01:46 CEST 2013


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.stinner at 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-checkins at python.org> a
> écrit :
>>
>> http://hg.python.org/cpython/rev/fc718c177ee6
>> changeset:   84793:fc718c177ee6
>> user:        Victor Stinner <victor.stinner at 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, &times_result_desc);
>> +    if (PyStructSequence_InitType2(&TimesResultType, &times_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-checkins at python.org
>> http://mail.python.org/mailman/listinfo/python-checkins
>>
>
> _______________________________________________
> Python-Dev mailing list
> Python-Dev at python.org
> http://mail.python.org/mailman/listinfo/python-dev
> Unsubscribe:
> http://mail.python.org/mailman/options/python-dev/benjamin%40python.org
>



-- 
Regards,
Benjamin


More information about the Python-checkins mailing list