[Python-checkins] bpo-40989: PyObject_INIT() becomes an alias to PyObject_Init() (GH-20901)

Victor Stinner webhook-mailer at python.org
Mon Jun 15 19:28:15 EDT 2020


https://github.com/python/cpython/commit/04fc4f2a46b2fd083639deb872c3a3037fdb47d6
commit: 04fc4f2a46b2fd083639deb872c3a3037fdb47d6
branch: master
author: Victor Stinner <vstinner at python.org>
committer: GitHub <noreply at github.com>
date: 2020-06-16T01:28:07+02:00
summary:

bpo-40989: PyObject_INIT() becomes an alias to PyObject_Init() (GH-20901)

The PyObject_INIT() and PyObject_INIT_VAR() macros become aliases to,
respectively, PyObject_Init() and PyObject_InitVar() functions.

Rename _PyObject_INIT() and _PyObject_INIT_VAR() static inline
functions to, respectively, _PyObject_Init() and _PyObject_InitVar(),
and move them to pycore_object.h. Remove their return value:
their return type becomes void.

The _datetime module is now built with the Py_BUILD_CORE_MODULE macro
defined.

Remove an outdated comment on _Py_tracemalloc_config.

files:
A Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst
M Include/cpython/objimpl.h
M Include/internal/pycore_object.h
M Include/internal/pycore_pymem.h
M Include/objimpl.h
M Modules/_datetimemodule.c
M Modules/gcmodule.c
M Objects/bytesobject.c
M Objects/complexobject.c
M Objects/floatobject.c
M Objects/longobject.c
M Objects/object.c
M Objects/tupleobject.c
M Objects/typeobject.c
M Objects/unicodeobject.c
M PC/winreg.c
M setup.py

diff --git a/Include/cpython/objimpl.h b/Include/cpython/objimpl.h
index ca4009bcdb4c1..15999a239f7a9 100644
--- a/Include/cpython/objimpl.h
+++ b/Include/cpython/objimpl.h
@@ -37,8 +37,9 @@
        PyObject *op;
 
        op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
-       if (op == NULL)
-       return PyErr_NoMemory();
+       if (op == NULL) {
+           return PyErr_NoMemory();
+       }
 
        PyObject_Init(op, &YourTypeStruct);
 
@@ -51,40 +52,6 @@
    the 1st step is performed automatically for you, so in a C++ class
    constructor you would start directly with PyObject_Init/InitVar. */
 
-
-/* Inline functions trading binary compatibility for speed:
-   PyObject_INIT() is the fast version of PyObject_Init(), and
-   PyObject_INIT_VAR() is the fast version of PyObject_InitVar().
-
-   These inline functions must not be called with op=NULL. */
-static inline PyObject*
-_PyObject_INIT(PyObject *op, PyTypeObject *typeobj)
-{
-    assert(op != NULL);
-    Py_SET_TYPE(op, typeobj);
-    if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) {
-        Py_INCREF(typeobj);
-    }
-    _Py_NewReference(op);
-    return op;
-}
-
-#define PyObject_INIT(op, typeobj) \
-    _PyObject_INIT(_PyObject_CAST(op), (typeobj))
-
-static inline PyVarObject*
-_PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
-{
-    assert(op != NULL);
-    Py_SET_SIZE(op, size);
-    PyObject_INIT((PyObject *)op, typeobj);
-    return op;
-}
-
-#define PyObject_INIT_VAR(op, typeobj, size) \
-    _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size))
-
-
 /* This function returns the number of allocated memory blocks, regardless of size */
 PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
 
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index 32e86d06db5b4..14444a70ceb01 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -15,6 +15,37 @@ extern "C" {
 PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
 PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
 
+// Fast inlined version of PyType_HasFeature()
+static inline int
+_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
+    return ((type->tp_flags & feature) != 0);
+}
+
+/* Inline functions trading binary compatibility for speed:
+   _PyObject_Init() is the fast version of PyObject_Init(), and
+   _PyObject_InitVar() is the fast version of PyObject_InitVar().
+
+   These inline functions must not be called with op=NULL. */
+static inline void
+_PyObject_Init(PyObject *op, PyTypeObject *typeobj)
+{
+    assert(op != NULL);
+    Py_SET_TYPE(op, typeobj);
+    if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
+        Py_INCREF(typeobj);
+    }
+    _Py_NewReference(op);
+}
+
+static inline void
+_PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
+{
+    assert(op != NULL);
+    Py_SET_SIZE(op, size);
+    _PyObject_Init((PyObject *)op, typeobj);
+}
+
+
 /* Tell the GC to track this object.
  *
  * NB: While the object is tracked by the collector, it must be safe to call the
@@ -96,12 +127,6 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
     return (PyObject **)((char *)op + offset);
 }
 
-// Fast inlined version of PyType_HasFeature()
-static inline int
-_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
-    return ((type->tp_flags & feature) != 0);
-}
-
 // Fast inlined version of PyObject_IS_GC()
 static inline int
 _PyObject_IS_GC(PyObject *obj)
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 3d925e2250d25..e4e35c16ce8ed 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -69,9 +69,6 @@ PyAPI_FUNC(int) _PyMem_GetAllocatorName(
    PYMEM_ALLOCATOR_NOT_SET does nothing. */
 PyAPI_FUNC(int) _PyMem_SetupAllocators(PyMemAllocatorName allocator);
 
-/* bpo-35053: Expose _Py_tracemalloc_config for _Py_NewReference()
-   which access directly _Py_tracemalloc_config.tracing for best
-   performances. */
 struct _PyTraceMalloc_Config {
     /* Module initialized?
        Variable protected by the GIL */
diff --git a/Include/objimpl.h b/Include/objimpl.h
index 030d7eee29723..af537175bfed8 100644
--- a/Include/objimpl.h
+++ b/Include/objimpl.h
@@ -118,7 +118,14 @@ PyAPI_FUNC(void) PyObject_Free(void *ptr);
 /* Functions */
 PyAPI_FUNC(PyObject *) PyObject_Init(PyObject *, PyTypeObject *);
 PyAPI_FUNC(PyVarObject *) PyObject_InitVar(PyVarObject *,
-                                                 PyTypeObject *, Py_ssize_t);
+                                           PyTypeObject *, Py_ssize_t);
+
+#define PyObject_INIT(op, typeobj) \
+    PyObject_Init(_PyObject_CAST(op), (typeobj))
+#define PyObject_INIT_VAR(op, typeobj, size) \
+    PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size))
+
+
 PyAPI_FUNC(PyObject *) _PyObject_New(PyTypeObject *);
 PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t);
 
@@ -136,19 +143,6 @@ PyAPI_FUNC(PyVarObject *) _PyObject_NewVar(PyTypeObject *, Py_ssize_t);
 #define PyObject_NEW_VAR(type, typeobj, n) PyObject_NewVar(type, typeobj, n)
 
 
-#ifdef Py_LIMITED_API
-/* Define PyObject_INIT() and PyObject_INIT_VAR() as aliases to PyObject_Init()
-   and PyObject_InitVar() in the limited C API for compatibility with the
-   CPython C API. */
-#  define PyObject_INIT(op, typeobj) \
-        PyObject_Init(_PyObject_CAST(op), (typeobj))
-#  define PyObject_INIT_VAR(op, typeobj, size) \
-        PyObject_InitVar(_PyVarObject_CAST(op), (typeobj), (size))
-#else
-/* PyObject_INIT() and PyObject_INIT_VAR() are defined in cpython/objimpl.h */
-#endif
-
-
 /*
  * Garbage Collection Support
  * ==========================
diff --git a/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst b/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst
new file mode 100644
index 0000000000000..1be473d142760
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2020-06-15-23-17-51.bpo-40989.tlzG3r.rst	
@@ -0,0 +1,3 @@
+The :c:func:`PyObject_INIT` and :c:func:`PyObject_INIT_VAR` macros become
+aliases to, respectively, :c:func:`PyObject_Init` and
+:c:func:`PyObject_InitVar` functions.
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index acdde83dc845a..74a54e74ae0fe 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -8,6 +8,7 @@
 #define _PY_DATETIME_IMPL
 
 #include "Python.h"
+#include "pycore_object.h"        // _PyObject_Init()
 #include "datetime.h"
 #include "structmember.h"         // PyMemberDef
 
@@ -638,30 +639,24 @@ normalize_datetime(int *year, int *month, int *day,
 static PyObject *
 time_alloc(PyTypeObject *type, Py_ssize_t aware)
 {
-    PyObject *self;
-
-    self = (PyObject *)
-        PyObject_MALLOC(aware ?
-                        sizeof(PyDateTime_Time) :
-                sizeof(_PyDateTime_BaseTime));
-    if (self == NULL)
-        return (PyObject *)PyErr_NoMemory();
-    (void)PyObject_INIT(self, type);
+    size_t size = aware ? sizeof(PyDateTime_Time) : sizeof(_PyDateTime_BaseTime);
+    PyObject *self = (PyObject *)PyObject_Malloc(size);
+    if (self == NULL) {
+        return PyErr_NoMemory();
+    }
+    _PyObject_Init(self, type);
     return self;
 }
 
 static PyObject *
 datetime_alloc(PyTypeObject *type, Py_ssize_t aware)
 {
-    PyObject *self;
-
-    self = (PyObject *)
-        PyObject_MALLOC(aware ?
-                        sizeof(PyDateTime_DateTime) :
-                sizeof(_PyDateTime_BaseDateTime));
-    if (self == NULL)
-        return (PyObject *)PyErr_NoMemory();
-    (void)PyObject_INIT(self, type);
+    size_t size = aware ? sizeof(PyDateTime_DateTime) : sizeof(_PyDateTime_BaseDateTime);
+    PyObject *self = (PyObject *)PyObject_Malloc(size);
+    if (self == NULL) {
+        return PyErr_NoMemory();
+    }
+    _PyObject_Init(self, type);
     return self;
 }
 
diff --git a/Modules/gcmodule.c b/Modules/gcmodule.c
index 444db7b03b4a5..110a48d8cd76f 100644
--- a/Modules/gcmodule.c
+++ b/Modules/gcmodule.c
@@ -2263,8 +2263,10 @@ PyObject *
 _PyObject_GC_New(PyTypeObject *tp)
 {
     PyObject *op = _PyObject_GC_Malloc(_PyObject_SIZE(tp));
-    if (op != NULL)
-        op = PyObject_INIT(op, tp);
+    if (op == NULL) {
+        return NULL;
+    }
+    _PyObject_Init(op, tp);
     return op;
 }
 
@@ -2280,8 +2282,10 @@ _PyObject_GC_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
     }
     size = _PyObject_VAR_SIZE(tp, nitems);
     op = (PyVarObject *) _PyObject_GC_Malloc(size);
-    if (op != NULL)
-        op = PyObject_INIT_VAR(op, tp, nitems);
+    if (op == NULL) {
+        return NULL;
+    }
+    _PyObject_InitVar(op, tp, nitems);
     return op;
 }
 
diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c
index b79c2460409eb..d39721428634f 100644
--- a/Objects/bytesobject.c
+++ b/Objects/bytesobject.c
@@ -79,9 +79,10 @@ _PyBytes_FromSize(Py_ssize_t size, int use_calloc)
         op = (PyBytesObject *)PyObject_Calloc(1, PyBytesObject_SIZE + size);
     else
         op = (PyBytesObject *)PyObject_Malloc(PyBytesObject_SIZE + size);
-    if (op == NULL)
+    if (op == NULL) {
         return PyErr_NoMemory();
-    (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
+    }
+    _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
     op->ob_shash = -1;
     if (!use_calloc)
         op->ob_sval[size] = '\0';
@@ -148,9 +149,10 @@ PyBytes_FromString(const char *str)
 
     /* Inline PyObject_NewVar */
     op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + size);
-    if (op == NULL)
+    if (op == NULL) {
         return PyErr_NoMemory();
-    (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
+    }
+    _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
     op->ob_shash = -1;
     memcpy(op->ob_sval, str, size+1);
     /* share short strings */
@@ -1435,9 +1437,10 @@ bytes_repeat(PyBytesObject *a, Py_ssize_t n)
         return NULL;
     }
     op = (PyBytesObject *)PyObject_MALLOC(PyBytesObject_SIZE + nbytes);
-    if (op == NULL)
+    if (op == NULL) {
         return PyErr_NoMemory();
-    (void)PyObject_INIT_VAR(op, &PyBytes_Type, size);
+    }
+    _PyObject_InitVar((PyVarObject*)op, &PyBytes_Type, size);
     op->ob_shash = -1;
     op->ob_sval[size] = '\0';
     if (Py_SIZE(a) == 1 && n > 0) {
diff --git a/Objects/complexobject.c b/Objects/complexobject.c
index a49037783be77..d983a30901d9e 100644
--- a/Objects/complexobject.c
+++ b/Objects/complexobject.c
@@ -6,8 +6,10 @@
 /* Submitted by Jim Hugunin */
 
 #include "Python.h"
+#include "pycore_object.h"        // _PyObject_Init()
 #include "structmember.h"         // PyMemberDef
 
+
 /*[clinic input]
 class complex "PyComplexObject *" "&PyComplex_Type"
 [clinic start generated code]*/
@@ -229,13 +231,12 @@ complex_subtype_from_c_complex(PyTypeObject *type, Py_complex cval)
 PyObject *
 PyComplex_FromCComplex(Py_complex cval)
 {
-    PyComplexObject *op;
-
     /* Inline PyObject_New */
-    op = (PyComplexObject *) PyObject_MALLOC(sizeof(PyComplexObject));
-    if (op == NULL)
+    PyComplexObject *op = PyObject_MALLOC(sizeof(PyComplexObject));
+    if (op == NULL) {
         return PyErr_NoMemory();
-    (void)PyObject_INIT(op, &PyComplex_Type);
+    }
+    _PyObject_Init((PyObject*)op, &PyComplex_Type);
     op->cval = cval;
     return (PyObject *) op;
 }
diff --git a/Objects/floatobject.c b/Objects/floatobject.c
index 65625fe88cad8..7ffd7eebe5a45 100644
--- a/Objects/floatobject.c
+++ b/Objects/floatobject.c
@@ -4,8 +4,9 @@
    for any kind of float exception without losing portability. */
 
 #include "Python.h"
-#include "pycore_dtoa.h"
+#include "pycore_dtoa.h"          // _Py_dg_dtoa()
 #include "pycore_interp.h"        // _PyInterpreterState.float_state
+#include "pycore_object.h"        // _PyObject_Init()
 #include "pycore_pystate.h"       // _PyInterpreterState_GET()
 
 #include <ctype.h>
@@ -129,7 +130,7 @@ PyFloat_FromDouble(double fval)
             return PyErr_NoMemory();
         }
     }
-    (void)PyObject_INIT(op, &PyFloat_Type);
+    _PyObject_Init((PyObject*)op, &PyFloat_Type);
     op->ob_fval = fval;
     return (PyObject *) op;
 }
diff --git a/Objects/longobject.c b/Objects/longobject.c
index d92a9c56a7208..d00a7a048ddce 100644
--- a/Objects/longobject.c
+++ b/Objects/longobject.c
@@ -5,6 +5,7 @@
 #include "Python.h"
 #include "pycore_bitutils.h"      // _Py_popcount32()
 #include "pycore_interp.h"        // _PY_NSMALLPOSINTS
+#include "pycore_object.h"        // _PyObject_InitVar()
 #include "pycore_pystate.h"       // _Py_IsMainInterpreter()
 #include "longintrepr.h"
 
@@ -146,7 +147,8 @@ _PyLong_New(Py_ssize_t size)
         PyErr_NoMemory();
         return NULL;
     }
-    return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size);
+    _PyObject_InitVar((PyVarObject*)result, &PyLong_Type, size);
+    return result;
 }
 
 PyObject *
diff --git a/Objects/object.c b/Objects/object.c
index 0ab5de28499a8..4481fc91e1db1 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -139,23 +139,23 @@ Py_DecRef(PyObject *o)
 PyObject *
 PyObject_Init(PyObject *op, PyTypeObject *tp)
 {
-    /* Any changes should be reflected in PyObject_INIT() macro */
     if (op == NULL) {
         return PyErr_NoMemory();
     }
 
-    return PyObject_INIT(op, tp);
+    _PyObject_Init(op, tp);
+    return op;
 }
 
 PyVarObject *
 PyObject_InitVar(PyVarObject *op, PyTypeObject *tp, Py_ssize_t size)
 {
-    /* Any changes should be reflected in PyObject_INIT_VAR() macro */
     if (op == NULL) {
         return (PyVarObject *) PyErr_NoMemory();
     }
 
-    return PyObject_INIT_VAR(op, tp, size);
+    _PyObject_InitVar(op, tp, size);
+    return op;
 }
 
 PyObject *
@@ -165,7 +165,7 @@ _PyObject_New(PyTypeObject *tp)
     if (op == NULL) {
         return PyErr_NoMemory();
     }
-    PyObject_INIT(op, tp);
+    _PyObject_Init(op, tp);
     return op;
 }
 
@@ -175,9 +175,11 @@ _PyObject_NewVar(PyTypeObject *tp, Py_ssize_t nitems)
     PyVarObject *op;
     const size_t size = _PyObject_VAR_SIZE(tp, nitems);
     op = (PyVarObject *) PyObject_MALLOC(size);
-    if (op == NULL)
+    if (op == NULL) {
         return (PyVarObject *)PyErr_NoMemory();
-    return PyObject_INIT_VAR(op, tp, nitems);
+    }
+    _PyObject_InitVar(op, tp, nitems);
+    return op;
 }
 
 void
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c
index 8bfa0894a79d4..2ff4c48111fe0 100644
--- a/Objects/tupleobject.c
+++ b/Objects/tupleobject.c
@@ -62,7 +62,7 @@ tuple_alloc(struct _Py_tuple_state *state, Py_ssize_t size)
         assert(size != 0);
         state->free_list[size] = (PyTupleObject *) op->ob_item[0];
         state->numfree[size]--;
-        /* Inline PyObject_InitVar */
+        /* Inlined _PyObject_InitVar() without _PyType_HasFeature() test */
 #ifdef Py_TRACE_REFS
         Py_SET_SIZE(op, size);
         Py_SET_TYPE(op, &PyTuple_Type);
diff --git a/Objects/typeobject.c b/Objects/typeobject.c
index c8f0d2ee45f3c..f0e349ecd2bb9 100644
--- a/Objects/typeobject.c
+++ b/Objects/typeobject.c
@@ -1060,10 +1060,10 @@ PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems)
     memset(obj, '\0', size);
 
     if (type->tp_itemsize == 0) {
-        (void)PyObject_INIT(obj, type);
+        _PyObject_Init(obj, type);
     }
     else {
-        (void) PyObject_INIT_VAR((PyVarObject *)obj, type, nitems);
+        _PyObject_InitVar((PyVarObject *)obj, type, nitems);
     }
 
     if (_PyType_IS_GC(type)) {
diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c
index 7ab0c882db049..c75eb077e0c80 100644
--- a/Objects/unicodeobject.c
+++ b/Objects/unicodeobject.c
@@ -1435,11 +1435,10 @@ PyUnicode_New(Py_ssize_t size, Py_UCS4 maxchar)
      * it's data buffer.
      */
     obj = (PyObject *) PyObject_MALLOC(struct_size + (size + 1) * char_size);
-    if (obj == NULL)
+    if (obj == NULL) {
         return PyErr_NoMemory();
-    obj = PyObject_INIT(obj, &PyUnicode_Type);
-    if (obj == NULL)
-        return NULL;
+    }
+    _PyObject_Init(obj, &PyUnicode_Type);
 
     unicode = (PyCompactUnicodeObject *)obj;
     if (is_ascii)
@@ -8392,9 +8391,11 @@ PyUnicode_BuildEncodingMap(PyObject* string)
     /* Create a three-level trie */
     result = PyObject_MALLOC(sizeof(struct encoding_map) +
                              16*count2 + 128*count3 - 1);
-    if (!result)
+    if (!result) {
         return PyErr_NoMemory();
-    PyObject_Init(result, &EncodingMapType);
+    }
+
+    _PyObject_Init(result, &EncodingMapType);
     mresult = (struct encoding_map*)result;
     mresult->count2 = count2;
     mresult->count3 = count3;
diff --git a/PC/winreg.c b/PC/winreg.c
index 1305b7030fada..7c3b2f4be85c9 100644
--- a/PC/winreg.c
+++ b/PC/winreg.c
@@ -14,6 +14,7 @@
 
 #define PY_SSIZE_T_CLEAN
 #include "Python.h"
+#include "pycore_object.h"        // _PyObject_Init()
 #include "structmember.h"         // PyMemberDef
 #include <windows.h>
 
@@ -457,13 +458,12 @@ clinic_HKEY_converter(PyObject *ob, void *p)
 PyObject *
 PyHKEY_FromHKEY(HKEY h)
 {
-    PyHKEYObject *op;
-
     /* Inline PyObject_New */
-    op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject));
-    if (op == NULL)
+    PyHKEYObject *op = (PyHKEYObject *) PyObject_MALLOC(sizeof(PyHKEYObject));
+    if (op == NULL) {
         return PyErr_NoMemory();
-    PyObject_INIT(op, &PyHKEY_Type);
+    }
+    _PyObject_Init(op, &PyHKEY_Type);
     op->hkey = h;
     return (PyObject *)op;
 }
diff --git a/setup.py b/setup.py
index ef2faf613beec..b220f5279ca63 100644
--- a/setup.py
+++ b/setup.py
@@ -853,7 +853,8 @@ def detect_simple_extensions(self):
         # libm is needed by delta_new() that uses round() and by accum() that
         # uses modf().
         self.add(Extension('_datetime', ['_datetimemodule.c'],
-                           libraries=['m']))
+                           libraries=['m'],
+                           extra_compile_args=['-DPy_BUILD_CORE_MODULE']))
         # zoneinfo module
         self.add(Extension('_zoneinfo', ['_zoneinfo.c'])),
         # random number generator implemented in C



More information about the Python-checkins mailing list