[Python-checkins] bpo-43795: Generate python3dll.c and doc data from manifest (PEP 652) (GH-25315)

encukou webhook-mailer at python.org
Thu Apr 29 05:33:24 EDT 2021


https://github.com/python/cpython/commit/f6ee4dad589c0953283dacb577a2d808fda7aae9
commit: f6ee4dad589c0953283dacb577a2d808fda7aae9
branch: master
author: Petr Viktorin <encukou at gmail.com>
committer: encukou <encukou at gmail.com>
date: 2021-04-29T11:33:14+02:00
summary:

bpo-43795: Generate python3dll.c and doc data from manifest (PEP 652) (GH-25315)

files:
A Misc/NEWS.d/next/C API/2021-04-09-18-19-07.bpo-43795.l0yobT.rst
A Misc/stable_abi.txt
M Doc/data/stable_abi.dat
M Makefile.pre.in
M PC/python3dll.c
M Tools/scripts/README
M Tools/scripts/stable_abi.py

diff --git a/Doc/data/stable_abi.dat b/Doc/data/stable_abi.dat
index 491a5fbb96f5a5..833228f7fd755d 100644
--- a/Doc/data/stable_abi.dat
+++ b/Doc/data/stable_abi.dat
@@ -1,5 +1,13 @@
-# File generated by 'make regen-limited-abi'
-# This is NOT an authoritative list of stable ABI symbols
+# Generated by Tools/scripts/stable_abi.py
+
+METH_CLASS
+METH_COEXIST
+METH_FASTCALL
+METH_METHOD
+METH_NOARGS
+METH_O
+METH_STATIC
+METH_VARARGS
 PyAiter_Check
 PyArg_Parse
 PyArg_ParseTuple
@@ -33,6 +41,8 @@ PyBytes_FromStringAndSize
 PyBytes_Repr
 PyBytes_Size
 PyBytes_Type
+PyCFunction
+PyCFunctionWithKeywords
 PyCFunction_Call
 PyCFunction_GetFlags
 PyCFunction_GetFunction
@@ -44,6 +54,7 @@ PyCMethod_New
 PyCallIter_New
 PyCallIter_Type
 PyCallable_Check
+PyCapsule_Destructor
 PyCapsule_GetContext
 PyCapsule_GetDestructor
 PyCapsule_GetName
@@ -138,11 +149,17 @@ PyErr_PrintEx
 PyErr_ProgramText
 PyErr_ResourceWarning
 PyErr_Restore
+PyErr_SetExcFromWindowsErr
+PyErr_SetExcFromWindowsErrWithFilename
+PyErr_SetExcFromWindowsErrWithFilenameObject
+PyErr_SetExcFromWindowsErrWithFilenameObjects
 PyErr_SetExcInfo
 PyErr_SetFromErrno
 PyErr_SetFromErrnoWithFilename
 PyErr_SetFromErrnoWithFilenameObject
 PyErr_SetFromErrnoWithFilenameObjects
+PyErr_SetFromWindowsErr
+PyErr_SetFromWindowsErrWithFilename
 PyErr_SetImportError
 PyErr_SetImportErrorSubclass
 PyErr_SetInterrupt
@@ -243,6 +260,7 @@ PyExc_UnicodeWarning
 PyExc_UserWarning
 PyExc_ValueError
 PyExc_Warning
+PyExc_WindowsError
 PyExc_ZeroDivisionError
 PyExceptionClass_Name
 PyException_GetCause
@@ -274,6 +292,8 @@ PyGC_IsEnabled
 PyGILState_Ensure
 PyGILState_GetThisThreadState
 PyGILState_Release
+PyGILState_STATE
+PyGetSetDef
 PyGetSetDescr_Type
 PyImport_AddModule
 PyImport_AddModuleObject
@@ -296,6 +316,7 @@ PyImport_ImportModuleLevelObject
 PyImport_ImportModuleNoBlock
 PyImport_ReloadModule
 PyIndex_Check
+PyInterpreterState
 PyInterpreterState_Clear
 PyInterpreterState_Delete
 PyInterpreterState_Get
@@ -319,6 +340,7 @@ PyList_SetSlice
 PyList_Size
 PyList_Sort
 PyList_Type
+PyLongObject
 PyLongRangeIter_Type
 PyLong_AsDouble
 PyLong_AsLong
@@ -358,12 +380,16 @@ PyMem_Calloc
 PyMem_Free
 PyMem_Malloc
 PyMem_Realloc
+PyMemberDef
 PyMemberDescr_Type
 PyMemoryView_FromMemory
 PyMemoryView_FromObject
 PyMemoryView_GetContiguous
 PyMemoryView_Type
+PyMethodDef
 PyMethodDescr_Type
+PyModuleDef
+PyModuleDef_Base
 PyModuleDef_Init
 PyModuleDef_Type
 PyModule_AddFunctions
@@ -427,18 +453,22 @@ PyOS_AfterFork
 PyOS_AfterFork_Child
 PyOS_AfterFork_Parent
 PyOS_BeforeFork
+PyOS_CheckStack
 PyOS_FSPath
+PyOS_InputHook
 PyOS_InterruptOccurred
 PyOS_double_to_string
 PyOS_getsig
 PyOS_mystricmp
 PyOS_mystrnicmp
 PyOS_setsig
+PyOS_sighandler_t
 PyOS_snprintf
 PyOS_string_to_double
 PyOS_strtol
 PyOS_strtoul
 PyOS_vsnprintf
+PyObject
 PyObject_ASCII
 PyObject_AsFileDescriptor
 PyObject_Bytes
@@ -537,6 +567,8 @@ PySlice_Unpack
 PyState_AddModule
 PyState_FindModule
 PyState_RemoveModule
+PyStructSequence_Desc
+PyStructSequence_Field
 PyStructSequence_GetItem
 PyStructSequence_New
 PyStructSequence_NewType
@@ -557,6 +589,7 @@ PySys_SetObject
 PySys_SetPath
 PySys_WriteStderr
 PySys_WriteStdout
+PyThreadState
 PyThreadState_Clear
 PyThreadState_Delete
 PyThreadState_Get
@@ -604,6 +637,7 @@ PyTuple_Pack
 PyTuple_SetItem
 PyTuple_Size
 PyTuple_Type
+PyTypeObject
 PyType_ClearCache
 PyType_FromModuleAndSpec
 PyType_FromSpec
@@ -617,6 +651,8 @@ PyType_GetSlot
 PyType_IsSubtype
 PyType_Modified
 PyType_Ready
+PyType_Slot
+PyType_Spec
 PyType_Type
 PyUnicodeDecodeError_Create
 PyUnicodeDecodeError_GetEncoding
@@ -653,6 +689,7 @@ PyUnicode_AsEncodedObject
 PyUnicode_AsEncodedString
 PyUnicode_AsEncodedUnicode
 PyUnicode_AsLatin1String
+PyUnicode_AsMBCSString
 PyUnicode_AsRawUnicodeEscapeString
 PyUnicode_AsUCS4
 PyUnicode_AsUCS4Copy
@@ -672,11 +709,14 @@ PyUnicode_Count
 PyUnicode_Decode
 PyUnicode_DecodeASCII
 PyUnicode_DecodeCharmap
+PyUnicode_DecodeCodePageStateful
 PyUnicode_DecodeFSDefault
 PyUnicode_DecodeFSDefaultAndSize
 PyUnicode_DecodeLatin1
 PyUnicode_DecodeLocale
 PyUnicode_DecodeLocaleAndSize
+PyUnicode_DecodeMBCS
+PyUnicode_DecodeMBCSStateful
 PyUnicode_DecodeRawUnicodeEscape
 PyUnicode_DecodeUTF16
 PyUnicode_DecodeUTF16Stateful
@@ -687,6 +727,7 @@ PyUnicode_DecodeUTF7Stateful
 PyUnicode_DecodeUTF8
 PyUnicode_DecodeUTF8Stateful
 PyUnicode_DecodeUnicodeEscape
+PyUnicode_EncodeCodePage
 PyUnicode_EncodeFSDefault
 PyUnicode_EncodeLocale
 PyUnicode_FSConverter
@@ -724,6 +765,8 @@ PyUnicode_Tailmatch
 PyUnicode_Translate
 PyUnicode_Type
 PyUnicode_WriteChar
+PyVarObject
+PyWeakReference
 PyWeakref_GetObject
 PyWeakref_NewProxy
 PyWeakref_NewRef
@@ -732,11 +775,14 @@ PyWrapper_New
 PyZip_Type
 Py_AddPendingCall
 Py_AtExit
+Py_BEGIN_ALLOW_THREADS
+Py_BLOCK_THREADS
 Py_BuildValue
 Py_BytesMain
 Py_CompileString
 Py_DecRef
 Py_DecodeLocale
+Py_END_ALLOW_THREADS
 Py_EncodeLocale
 Py_EndInterpreter
 Py_EnterRecursiveCall
@@ -781,6 +827,127 @@ Py_SetPath
 Py_SetProgramName
 Py_SetPythonHome
 Py_SetRecursionLimit
+Py_TPFLAGS_BASETYPE
+Py_TPFLAGS_DEFAULT
+Py_TPFLAGS_HAVE_GC
+Py_TPFLAGS_METHOD_DESCRIPTOR
+Py_UCS4
+Py_UNBLOCK_THREADS
 Py_UTF8Mode
 Py_VaBuildValue
 Py_XNewRef
+Py_am_aiter
+Py_am_anext
+Py_am_await
+Py_am_send
+Py_intptr_t
+Py_mp_ass_subscript
+Py_mp_length
+Py_mp_subscript
+Py_nb_absolute
+Py_nb_add
+Py_nb_and
+Py_nb_bool
+Py_nb_divmod
+Py_nb_float
+Py_nb_floor_divide
+Py_nb_index
+Py_nb_inplace_add
+Py_nb_inplace_and
+Py_nb_inplace_floor_divide
+Py_nb_inplace_lshift
+Py_nb_inplace_matrix_multiply
+Py_nb_inplace_multiply
+Py_nb_inplace_or
+Py_nb_inplace_power
+Py_nb_inplace_remainder
+Py_nb_inplace_rshift
+Py_nb_inplace_subtract
+Py_nb_inplace_true_divide
+Py_nb_inplace_xor
+Py_nb_int
+Py_nb_invert
+Py_nb_lshift
+Py_nb_matrix_multiply
+Py_nb_multiply
+Py_nb_negative
+Py_nb_or
+Py_nb_positive
+Py_nb_power
+Py_nb_remainder
+Py_nb_rshift
+Py_nb_subtract
+Py_nb_true_divide
+Py_nb_xor
+Py_sq_ass_item
+Py_sq_concat
+Py_sq_contains
+Py_sq_inplace_concat
+Py_sq_inplace_repeat
+Py_sq_item
+Py_sq_length
+Py_sq_repeat
+Py_ssize_t
+Py_tp_alloc
+Py_tp_base
+Py_tp_bases
+Py_tp_call
+Py_tp_clear
+Py_tp_dealloc
+Py_tp_del
+Py_tp_descr_get
+Py_tp_descr_set
+Py_tp_doc
+Py_tp_finalize
+Py_tp_free
+Py_tp_getattr
+Py_tp_getattro
+Py_tp_getset
+Py_tp_hash
+Py_tp_init
+Py_tp_is_gc
+Py_tp_iter
+Py_tp_iternext
+Py_tp_members
+Py_tp_methods
+Py_tp_new
+Py_tp_repr
+Py_tp_richcompare
+Py_tp_setattr
+Py_tp_setattro
+Py_tp_str
+Py_tp_traverse
+Py_uintptr_t
+_frame
+_node
+allocfunc
+binaryfunc
+descrgetfunc
+descrsetfunc
+destructor
+getattrfunc
+getattrofunc
+getiterfunc
+getter
+hashfunc
+initproc
+inquiry
+iternextfunc
+lenfunc
+newfunc
+objobjargproc
+objobjproc
+reprfunc
+richcmpfunc
+setattrfunc
+setattrofunc
+setter
+ssizeargfunc
+ssizeobjargproc
+ssizessizeargfunc
+ssizessizeobjargproc
+symtable
+ternaryfunc
+traverseproc
+unaryfunc
+visitproc
diff --git a/Makefile.pre.in b/Makefile.pre.in
index 4d9b760863ad59..72ccbcf7c2a091 100644
--- a/Makefile.pre.in
+++ b/Makefile.pre.in
@@ -752,10 +752,7 @@ regen-importlib: Programs/_freeze_importlib
 
 
 regen-limited-abi: all
-	@$(MKDIR_P) $(srcdir)/Doc/data/
-	$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py generate $(srcdir)/Doc/data/stable_abi.dat.new
-	$(UPDATE_FILE) $(srcdir)/Doc/data/stable_abi.dat \
-	$(srcdir)/Doc/data/stable_abi.dat.new
+	$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --generate-all $(srcdir)/Misc/stable_abi.txt
 
 
 ############################################################################
@@ -1983,7 +1980,7 @@ patchcheck: @DEF_MAKE_RULE@
 	$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/patchcheck.py
 
 check-limited-abi: all
-	$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py check $(srcdir)/Doc/data/stable_abi.dat
+	$(RUNSHARED) ./$(BUILDPYTHON) $(srcdir)/Tools/scripts/stable_abi.py --all $(srcdir)/Misc/stable_abi.txt
 
 # Dependencies
 
diff --git a/Misc/NEWS.d/next/C API/2021-04-09-18-19-07.bpo-43795.l0yobT.rst b/Misc/NEWS.d/next/C API/2021-04-09-18-19-07.bpo-43795.l0yobT.rst
new file mode 100644
index 00000000000000..5153c336777187
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2021-04-09-18-19-07.bpo-43795.l0yobT.rst	
@@ -0,0 +1,2 @@
+Stable ABI and limited API definitions are generated from a central manifest
+(:pep:`652`).
diff --git a/Misc/stable_abi.txt b/Misc/stable_abi.txt
new file mode 100644
index 00000000000000..efb2731f595a22
--- /dev/null
+++ b/Misc/stable_abi.txt
@@ -0,0 +1,2144 @@
+# This file lists the contents of the Limited API and Stable ABI.
+# Please append new items at the end.
+
+# The syntax of this file is not fixed.
+# It is designed to be read only by Tools/stable_abi.py, which can change
+# without notice.
+
+# For the history of the stable ABI prior to this file,
+# see the history of PC/python3dll.c and before that, PC/python3.def,
+# and PC/pythonXYstub.def
+
+
+# Mentioned in PEP 384:
+
+struct PyObject
+    added 3.2
+struct PyVarObject
+    added 3.2
+struct PyMethodDef
+    added 3.2
+struct PyMemberDef
+    added 3.2
+struct PyGetSetDef
+    added 3.2
+struct PyModuleDef_Base
+    added 3.2
+struct PyModuleDef
+    added 3.2
+struct PyStructSequence_Field
+    added 3.2
+struct PyStructSequence_Desc
+    added 3.2
+struct PyType_Slot
+    added 3.2
+struct PyType_Spec
+    added 3.2
+struct PyThreadState
+    added 3.2
+struct PyInterpreterState
+    added 3.2
+struct _frame
+    added 3.2
+struct symtable
+    added 3.2
+struct _node
+    added 3.2
+struct PyWeakReference
+    added 3.2
+struct PyLongObject
+    added 3.2
+struct PyTypeObject
+    added 3.2
+
+function PyType_FromSpec
+    added 3.2
+
+const Py_tp_dealloc
+    added 3.2
+const Py_tp_getattr
+    added 3.2
+const Py_tp_setattr
+    added 3.2
+const Py_tp_repr
+    added 3.2
+const Py_tp_hash
+    added 3.2
+const Py_tp_call
+    added 3.2
+const Py_tp_str
+    added 3.2
+const Py_tp_getattro
+    added 3.2
+const Py_tp_setattro
+    added 3.2
+const Py_tp_doc
+    added 3.2
+const Py_tp_traverse
+    added 3.2
+const Py_tp_clear
+    added 3.2
+const Py_tp_richcompare
+    added 3.2
+const Py_tp_iter
+    added 3.2
+const Py_tp_iternext
+    added 3.2
+const Py_tp_methods
+    added 3.2
+const Py_tp_base
+    added 3.2
+const Py_tp_descr_get
+    added 3.2
+const Py_tp_descr_set
+    added 3.2
+const Py_tp_init
+    added 3.2
+const Py_tp_alloc
+    added 3.2
+const Py_tp_new
+    added 3.2
+const Py_tp_members
+    added 3.2
+const Py_tp_getset
+    added 3.2
+const Py_tp_free
+    added 3.2
+const Py_tp_is_gc
+    added 3.2
+const Py_tp_bases
+    added 3.2
+const Py_tp_del
+    added 3.2
+const Py_nb_add
+    added 3.2
+const Py_nb_subtract
+    added 3.2
+const Py_nb_multiply
+    added 3.2
+const Py_nb_remainder
+    added 3.2
+const Py_nb_divmod
+    added 3.2
+const Py_nb_power
+    added 3.2
+const Py_nb_negative
+    added 3.2
+const Py_nb_positive
+    added 3.2
+const Py_nb_absolute
+    added 3.2
+const Py_nb_bool
+    added 3.2
+const Py_nb_invert
+    added 3.2
+const Py_nb_lshift
+    added 3.2
+const Py_nb_rshift
+    added 3.2
+const Py_nb_and
+    added 3.2
+const Py_nb_xor
+    added 3.2
+const Py_nb_or
+    added 3.2
+const Py_nb_int
+    added 3.2
+const Py_nb_float
+    added 3.2
+const Py_nb_inplace_add
+    added 3.2
+const Py_nb_inplace_subtract
+    added 3.2
+const Py_nb_inplace_multiply
+    added 3.2
+const Py_nb_inplace_remainder
+    added 3.2
+const Py_nb_inplace_power
+    added 3.2
+const Py_nb_inplace_lshift
+    added 3.2
+const Py_nb_inplace_rshift
+    added 3.2
+const Py_nb_inplace_and
+    added 3.2
+const Py_nb_inplace_xor
+    added 3.2
+const Py_nb_inplace_or
+    added 3.2
+const Py_nb_floor_divide
+    added 3.2
+const Py_nb_true_divide
+    added 3.2
+const Py_nb_inplace_floor_divide
+    added 3.2
+const Py_nb_inplace_true_divide
+    added 3.2
+const Py_nb_index
+    added 3.2
+const Py_sq_length
+    added 3.2
+const Py_sq_concat
+    added 3.2
+const Py_sq_repeat
+    added 3.2
+const Py_sq_item
+    added 3.2
+const Py_sq_ass_item
+    added 3.2
+const Py_sq_contains
+    added 3.2
+const Py_sq_inplace_concat
+    added 3.2
+const Py_sq_inplace_repeat
+    added 3.2
+const Py_mp_length
+    added 3.2
+const Py_mp_subscript
+    added 3.2
+const Py_mp_ass_subscript
+    added 3.2
+
+typedef Py_uintptr_t
+    added 3.2
+typedef Py_intptr_t
+    added 3.2
+typedef Py_ssize_t
+    added 3.2
+typedef unaryfunc
+    added 3.2
+typedef binaryfunc
+    added 3.2
+typedef ternaryfunc
+    added 3.2
+typedef inquiry
+    added 3.2
+typedef lenfunc
+    added 3.2
+typedef ssizeargfunc
+    added 3.2
+typedef ssizessizeargfunc
+    added 3.2
+typedef ssizeobjargproc
+    added 3.2
+typedef ssizessizeobjargproc
+    added 3.2
+typedef objobjargproc
+    added 3.2
+typedef objobjproc
+    added 3.2
+typedef visitproc
+    added 3.2
+typedef traverseproc
+    added 3.2
+typedef destructor
+    added 3.2
+typedef getattrfunc
+    added 3.2
+typedef getattrofunc
+    added 3.2
+typedef setattrfunc
+    added 3.2
+typedef setattrofunc
+    added 3.2
+typedef reprfunc
+    added 3.2
+typedef hashfunc
+    added 3.2
+typedef richcmpfunc
+    added 3.2
+typedef getiterfunc
+    added 3.2
+typedef iternextfunc
+    added 3.2
+typedef descrgetfunc
+    added 3.2
+typedef descrsetfunc
+    added 3.2
+typedef initproc
+    added 3.2
+typedef newfunc
+    added 3.2
+typedef allocfunc
+    added 3.2
+struct PyCFunction
+    added 3.2
+struct PyCFunctionWithKeywords
+    added 3.2
+struct PyCapsule_Destructor
+    added 3.2
+typedef getter
+    added 3.2
+typedef setter
+    added 3.2
+typedef PyOS_sighandler_t
+    added 3.2
+typedef PyGILState_STATE
+    added 3.2
+typedef Py_UCS4
+    added 3.2
+
+macro Py_BEGIN_ALLOW_THREADS
+    added 3.2
+macro Py_BLOCK_THREADS
+    added 3.2
+macro Py_UNBLOCK_THREADS
+    added 3.2
+macro Py_END_ALLOW_THREADS
+    added 3.2
+
+# The following were added in PC/python3.def in the intial stable ABI commit,
+# 4d0d471a8031de90a2b1ce99c4ac4780e60b3bc9,
+# and later amendments in 3.2:
+# 0d012f284be829c6217f60523db0e1671b7db9d9
+# c83bc3c1fbed14d27a5de3032e24d2cf006a7c4b
+
+function PyArg_Parse
+    added 3.2
+function PyArg_ParseTuple
+    added 3.2
+function PyArg_ParseTupleAndKeywords
+    added 3.2
+function PyArg_UnpackTuple
+    added 3.2
+function PyArg_VaParse
+    added 3.2
+function PyArg_VaParseTupleAndKeywords
+    added 3.2
+function PyArg_ValidateKeywordArguments
+    added 3.2
+data PyBaseObject_Type
+    added 3.2
+function PyBool_FromLong
+    added 3.2
+data PyBool_Type
+    added 3.2
+data PyByteArrayIter_Type
+    added 3.2
+function PyByteArray_AsString
+    added 3.2
+function PyByteArray_Concat
+    added 3.2
+function PyByteArray_FromObject
+    added 3.2
+function PyByteArray_FromStringAndSize
+    added 3.2
+function PyByteArray_Resize
+    added 3.2
+function PyByteArray_Size
+    added 3.2
+data PyByteArray_Type
+    added 3.2
+data PyBytesIter_Type
+    added 3.2
+function PyBytes_AsString
+    added 3.2
+function PyBytes_AsStringAndSize
+    added 3.2
+function PyBytes_Concat
+    added 3.2
+function PyBytes_ConcatAndDel
+    added 3.2
+function PyBytes_DecodeEscape
+    added 3.2
+function PyBytes_FromFormat
+    added 3.2
+function PyBytes_FromFormatV
+    added 3.2
+function PyBytes_FromObject
+    added 3.2
+function PyBytes_FromString
+    added 3.2
+function PyBytes_FromStringAndSize
+    added 3.2
+function PyBytes_Repr
+    added 3.2
+function PyBytes_Size
+    added 3.2
+data PyBytes_Type
+    added 3.2
+function PyCFunction_Call
+    added 3.2
+function PyCFunction_GetFlags
+    added 3.2
+function PyCFunction_GetFunction
+    added 3.2
+function PyCFunction_GetSelf
+    added 3.2
+function PyCFunction_NewEx
+    added 3.2
+data PyCFunction_Type
+    added 3.2
+function PyCallIter_New
+    added 3.2
+data PyCallIter_Type
+    added 3.2
+function PyCallable_Check
+    added 3.2
+function PyCapsule_GetContext
+    added 3.2
+function PyCapsule_GetDestructor
+    added 3.2
+function PyCapsule_GetName
+    added 3.2
+function PyCapsule_GetPointer
+    added 3.2
+function PyCapsule_Import
+    added 3.2
+function PyCapsule_IsValid
+    added 3.2
+function PyCapsule_New
+    added 3.2
+function PyCapsule_SetContext
+    added 3.2
+function PyCapsule_SetDestructor
+    added 3.2
+function PyCapsule_SetName
+    added 3.2
+function PyCapsule_SetPointer
+    added 3.2
+data PyCapsule_Type
+    added 3.2
+data PyClassMethodDescr_Type
+    added 3.2
+function PyCodec_BackslashReplaceErrors
+    added 3.2
+function PyCodec_Decode
+    added 3.2
+function PyCodec_Decoder
+    added 3.2
+function PyCodec_Encode
+    added 3.2
+function PyCodec_Encoder
+    added 3.2
+function PyCodec_IgnoreErrors
+    added 3.2
+function PyCodec_IncrementalDecoder
+    added 3.2
+function PyCodec_IncrementalEncoder
+    added 3.2
+function PyCodec_KnownEncoding
+    added 3.2
+function PyCodec_LookupError
+    added 3.2
+function PyCodec_Register
+    added 3.2
+function PyCodec_RegisterError
+    added 3.2
+function PyCodec_ReplaceErrors
+    added 3.2
+function PyCodec_StreamReader
+    added 3.2
+function PyCodec_StreamWriter
+    added 3.2
+function PyCodec_StrictErrors
+    added 3.2
+function PyCodec_XMLCharRefReplaceErrors
+    added 3.2
+function PyComplex_FromDoubles
+    added 3.2
+function PyComplex_ImagAsDouble
+    added 3.2
+function PyComplex_RealAsDouble
+    added 3.2
+data PyComplex_Type
+    added 3.2
+function PyDescr_NewClassMethod
+    added 3.2
+function PyDescr_NewGetSet
+    added 3.2
+function PyDescr_NewMember
+    added 3.2
+function PyDescr_NewMethod
+    added 3.2
+data PyDictItems_Type
+    added 3.2
+data PyDictIterItem_Type
+    added 3.2
+data PyDictIterKey_Type
+    added 3.2
+data PyDictIterValue_Type
+    added 3.2
+data PyDictKeys_Type
+    added 3.2
+function PyDictProxy_New
+    added 3.2
+data PyDictProxy_Type
+    added 3.2
+data PyDictValues_Type
+    added 3.2
+function PyDict_Clear
+    added 3.2
+function PyDict_Contains
+    added 3.2
+function PyDict_Copy
+    added 3.2
+function PyDict_DelItem
+    added 3.2
+function PyDict_DelItemString
+    added 3.2
+function PyDict_GetItem
+    added 3.2
+function PyDict_GetItemString
+    added 3.2
+function PyDict_GetItemWithError
+    added 3.2
+function PyDict_Items
+    added 3.2
+function PyDict_Keys
+    added 3.2
+function PyDict_Merge
+    added 3.2
+function PyDict_MergeFromSeq2
+    added 3.2
+function PyDict_New
+    added 3.2
+function PyDict_Next
+    added 3.2
+function PyDict_SetItem
+    added 3.2
+function PyDict_SetItemString
+    added 3.2
+function PyDict_Size
+    added 3.2
+data PyDict_Type
+    added 3.2
+function PyDict_Update
+    added 3.2
+function PyDict_Values
+    added 3.2
+data PyEllipsis_Type
+    added 3.2
+data PyEnum_Type
+    added 3.2
+function PyErr_BadArgument
+    added 3.2
+function PyErr_BadInternalCall
+    added 3.2
+function PyErr_CheckSignals
+    added 3.2
+function PyErr_Clear
+    added 3.2
+function PyErr_Display
+    added 3.2
+function PyErr_ExceptionMatches
+    added 3.2
+function PyErr_Fetch
+    added 3.2
+function PyErr_Format
+    added 3.2
+function PyErr_GivenExceptionMatches
+    added 3.2
+function PyErr_NewException
+    added 3.2
+function PyErr_NewExceptionWithDoc
+    added 3.2
+function PyErr_NoMemory
+    added 3.2
+function PyErr_NormalizeException
+    added 3.2
+function PyErr_Occurred
+    added 3.2
+function PyErr_Print
+    added 3.2
+function PyErr_PrintEx
+    added 3.2
+function PyErr_ProgramText
+    added 3.2
+function PyErr_Restore
+    added 3.2
+function PyErr_SetFromErrno
+    added 3.2
+function PyErr_SetFromErrnoWithFilename
+    added 3.2
+function PyErr_SetFromErrnoWithFilenameObject
+    added 3.2
+function PyErr_SetInterrupt
+    added 3.2
+function PyErr_SetNone
+    added 3.2
+function PyErr_SetObject
+    added 3.2
+function PyErr_SetString
+    added 3.2
+function PyErr_SyntaxLocation
+    added 3.2
+function PyErr_WarnEx
+    added 3.2
+function PyErr_WarnExplicit
+    added 3.2
+function PyErr_WarnFormat
+    added 3.2
+function PyErr_WriteUnraisable
+    added 3.2
+function PyEval_AcquireLock
+    added 3.2
+function PyEval_AcquireThread
+    added 3.2
+function PyEval_CallFunction
+    added 3.2
+function PyEval_CallMethod
+    added 3.2
+function PyEval_CallObjectWithKeywords
+    added 3.2
+function PyEval_EvalCode
+    added 3.2
+function PyEval_EvalCodeEx
+    added 3.2
+function PyEval_EvalFrame
+    added 3.2
+function PyEval_EvalFrameEx
+    added 3.2
+function PyEval_GetBuiltins
+    added 3.2
+function PyEval_GetFrame
+    added 3.2
+function PyEval_GetFuncDesc
+    added 3.2
+function PyEval_GetFuncName
+    added 3.2
+function PyEval_GetGlobals
+    added 3.2
+function PyEval_GetLocals
+    added 3.2
+function PyEval_InitThreads
+    added 3.2
+function PyEval_ReleaseLock
+    added 3.2
+function PyEval_ReleaseThread
+    added 3.2
+function PyEval_RestoreThread
+    added 3.2
+function PyEval_SaveThread
+    added 3.2
+function PyEval_ThreadsInitialized
+    added 3.2
+data PyExc_ArithmeticError
+    added 3.2
+data PyExc_AssertionError
+    added 3.2
+data PyExc_AttributeError
+    added 3.2
+data PyExc_BaseException
+    added 3.2
+data PyExc_BufferError
+    added 3.2
+data PyExc_BytesWarning
+    added 3.2
+data PyExc_DeprecationWarning
+    added 3.2
+data PyExc_EOFError
+    added 3.2
+data PyExc_EnvironmentError
+    added 3.2
+data PyExc_Exception
+    added 3.2
+data PyExc_FloatingPointError
+    added 3.2
+data PyExc_FutureWarning
+    added 3.2
+data PyExc_GeneratorExit
+    added 3.2
+data PyExc_IOError
+    added 3.2
+data PyExc_ImportError
+    added 3.2
+data PyExc_ImportWarning
+    added 3.2
+data PyExc_IndentationError
+    added 3.2
+data PyExc_IndexError
+    added 3.2
+data PyExc_KeyError
+    added 3.2
+data PyExc_KeyboardInterrupt
+    added 3.2
+data PyExc_LookupError
+    added 3.2
+data PyExc_MemoryError
+    added 3.2
+data PyExc_NameError
+    added 3.2
+data PyExc_NotImplementedError
+    added 3.2
+data PyExc_OSError
+    added 3.2
+data PyExc_OverflowError
+    added 3.2
+data PyExc_PendingDeprecationWarning
+    added 3.2
+data PyExc_ReferenceError
+    added 3.2
+data PyExc_RuntimeError
+    added 3.2
+data PyExc_RuntimeWarning
+    added 3.2
+data PyExc_StopIteration
+    added 3.2
+data PyExc_SyntaxError
+    added 3.2
+data PyExc_SyntaxWarning
+    added 3.2
+data PyExc_SystemError
+    added 3.2
+data PyExc_SystemExit
+    added 3.2
+data PyExc_TabError
+    added 3.2
+data PyExc_TypeError
+    added 3.2
+data PyExc_UnboundLocalError
+    added 3.2
+data PyExc_UnicodeDecodeError
+    added 3.2
+data PyExc_UnicodeEncodeError
+    added 3.2
+data PyExc_UnicodeError
+    added 3.2
+data PyExc_UnicodeTranslateError
+    added 3.2
+data PyExc_UnicodeWarning
+    added 3.2
+data PyExc_UserWarning
+    added 3.2
+data PyExc_ValueError
+    added 3.2
+data PyExc_Warning
+    added 3.2
+data PyExc_ZeroDivisionError
+    added 3.2
+function PyException_GetCause
+    added 3.2
+function PyException_GetContext
+    added 3.2
+function PyException_GetTraceback
+    added 3.2
+function PyException_SetCause
+    added 3.2
+function PyException_SetContext
+    added 3.2
+function PyException_SetTraceback
+    added 3.2
+function PyFile_FromFd
+    added 3.2
+function PyFile_GetLine
+    added 3.2
+function PyFile_WriteObject
+    added 3.2
+function PyFile_WriteString
+    added 3.2
+data PyFilter_Type
+    added 3.2
+function PyFloat_AsDouble
+    added 3.2
+function PyFloat_FromDouble
+    added 3.2
+function PyFloat_FromString
+    added 3.2
+function PyFloat_GetInfo
+    added 3.2
+function PyFloat_GetMax
+    added 3.2
+function PyFloat_GetMin
+    added 3.2
+data PyFloat_Type
+    added 3.2
+function PyFrozenSet_New
+    added 3.2
+data PyFrozenSet_Type
+    added 3.2
+function PyGC_Collect
+    added 3.2
+function PyGILState_Ensure
+    added 3.2
+function PyGILState_GetThisThreadState
+    added 3.2
+function PyGILState_Release
+    added 3.2
+data PyGetSetDescr_Type
+    added 3.2
+function PyImport_AddModule
+    added 3.2
+function PyImport_AppendInittab
+    added 3.2
+function PyImport_ExecCodeModule
+    added 3.2
+function PyImport_ExecCodeModuleEx
+    added 3.2
+function PyImport_ExecCodeModuleWithPathnames
+    added 3.2
+function PyImport_GetImporter
+    added 3.2
+function PyImport_GetMagicNumber
+    added 3.2
+function PyImport_GetMagicTag
+    added 3.2
+function PyImport_GetModuleDict
+    added 3.2
+function PyImport_Import
+    added 3.2
+function PyImport_ImportFrozenModule
+    added 3.2
+function PyImport_ImportModule
+    added 3.2
+function PyImport_ImportModuleLevel
+    added 3.2
+function PyImport_ImportModuleNoBlock
+    added 3.2
+function PyImport_ReloadModule
+    added 3.2
+function PyInterpreterState_Clear
+    added 3.2
+function PyInterpreterState_Delete
+    added 3.2
+function PyInterpreterState_New
+    added 3.2
+function PyIter_Next
+    added 3.2
+data PyListIter_Type
+    added 3.2
+data PyListRevIter_Type
+    added 3.2
+function PyList_Append
+    added 3.2
+function PyList_AsTuple
+    added 3.2
+function PyList_GetItem
+    added 3.2
+function PyList_GetSlice
+    added 3.2
+function PyList_Insert
+    added 3.2
+function PyList_New
+    added 3.2
+function PyList_Reverse
+    added 3.2
+function PyList_SetItem
+    added 3.2
+function PyList_SetSlice
+    added 3.2
+function PyList_Size
+    added 3.2
+function PyList_Sort
+    added 3.2
+data PyList_Type
+    added 3.2
+data PyLongRangeIter_Type
+    added 3.2
+function PyLong_AsDouble
+    added 3.2
+function PyLong_AsLong
+    added 3.2
+function PyLong_AsLongAndOverflow
+    added 3.2
+function PyLong_AsLongLong
+    added 3.2
+function PyLong_AsLongLongAndOverflow
+    added 3.2
+function PyLong_AsSize_t
+    added 3.2
+function PyLong_AsSsize_t
+    added 3.2
+function PyLong_AsUnsignedLong
+    added 3.2
+function PyLong_AsUnsignedLongLong
+    added 3.2
+function PyLong_AsUnsignedLongLongMask
+    added 3.2
+function PyLong_AsUnsignedLongMask
+    added 3.2
+function PyLong_AsVoidPtr
+    added 3.2
+function PyLong_FromDouble
+    added 3.2
+function PyLong_FromLong
+    added 3.2
+function PyLong_FromLongLong
+    added 3.2
+function PyLong_FromSize_t
+    added 3.2
+function PyLong_FromSsize_t
+    added 3.2
+function PyLong_FromString
+    added 3.2
+function PyLong_FromUnsignedLong
+    added 3.2
+function PyLong_FromUnsignedLongLong
+    added 3.2
+function PyLong_FromVoidPtr
+    added 3.2
+function PyLong_GetInfo
+    added 3.2
+data PyLong_Type
+    added 3.2
+data PyMap_Type
+    added 3.2
+function PyMapping_Check
+    added 3.2
+function PyMapping_GetItemString
+    added 3.2
+function PyMapping_HasKey
+    added 3.2
+function PyMapping_HasKeyString
+    added 3.2
+function PyMapping_Items
+    added 3.2
+function PyMapping_Keys
+    added 3.2
+function PyMapping_Length
+    added 3.2
+function PyMapping_SetItemString
+    added 3.2
+function PyMapping_Size
+    added 3.2
+function PyMapping_Values
+    added 3.2
+function PyMem_Free
+    added 3.2
+function PyMem_Malloc
+    added 3.2
+function PyMem_Realloc
+    added 3.2
+data PyMemberDescr_Type
+    added 3.2
+function PyMemoryView_FromObject
+    added 3.2
+function PyMemoryView_GetContiguous
+    added 3.2
+data PyMemoryView_Type
+    added 3.2
+data PyMethodDescr_Type
+    added 3.2
+function PyModule_AddIntConstant
+    added 3.2
+function PyModule_AddObject
+    added 3.2
+function PyModule_AddStringConstant
+    added 3.2
+function PyModule_Create2
+    added 3.2
+function PyModule_GetDef
+    added 3.2
+function PyModule_GetDict
+    added 3.2
+function PyModule_GetFilename
+    added 3.2
+function PyModule_GetFilenameObject
+    added 3.2
+function PyModule_GetName
+    added 3.2
+function PyModule_GetState
+    added 3.2
+function PyModule_New
+    added 3.2
+data PyModule_Type
+    added 3.2
+function PyNumber_Absolute
+    added 3.2
+function PyNumber_Add
+    added 3.2
+function PyNumber_And
+    added 3.2
+function PyNumber_AsSsize_t
+    added 3.2
+function PyNumber_Check
+    added 3.2
+function PyNumber_Divmod
+    added 3.2
+function PyNumber_Float
+    added 3.2
+function PyNumber_FloorDivide
+    added 3.2
+function PyNumber_InPlaceAdd
+    added 3.2
+function PyNumber_InPlaceAnd
+    added 3.2
+function PyNumber_InPlaceFloorDivide
+    added 3.2
+function PyNumber_InPlaceLshift
+    added 3.2
+function PyNumber_InPlaceMultiply
+    added 3.2
+function PyNumber_InPlaceOr
+    added 3.2
+function PyNumber_InPlacePower
+    added 3.2
+function PyNumber_InPlaceRemainder
+    added 3.2
+function PyNumber_InPlaceRshift
+    added 3.2
+function PyNumber_InPlaceSubtract
+    added 3.2
+function PyNumber_InPlaceTrueDivide
+    added 3.2
+function PyNumber_InPlaceXor
+    added 3.2
+function PyNumber_Index
+    added 3.2
+function PyNumber_Invert
+    added 3.2
+function PyNumber_Long
+    added 3.2
+function PyNumber_Lshift
+    added 3.2
+function PyNumber_Multiply
+    added 3.2
+function PyNumber_Negative
+    added 3.2
+function PyNumber_Or
+    added 3.2
+function PyNumber_Positive
+    added 3.2
+function PyNumber_Power
+    added 3.2
+function PyNumber_Remainder
+    added 3.2
+function PyNumber_Rshift
+    added 3.2
+function PyNumber_Subtract
+    added 3.2
+function PyNumber_ToBase
+    added 3.2
+function PyNumber_TrueDivide
+    added 3.2
+function PyNumber_Xor
+    added 3.2
+function PyOS_AfterFork
+    added 3.2
+    ifdef HAVE_FORK
+data PyOS_InputHook
+    added 3.2
+function PyOS_InterruptOccurred
+    added 3.2
+function PyOS_double_to_string
+    added 3.2
+function PyOS_getsig
+    added 3.2
+function PyOS_mystricmp
+    added 3.2
+function PyOS_mystrnicmp
+    added 3.2
+function PyOS_setsig
+    added 3.2
+function PyOS_snprintf
+    added 3.2
+function PyOS_string_to_double
+    added 3.2
+function PyOS_strtol
+    added 3.2
+function PyOS_strtoul
+    added 3.2
+function PyOS_vsnprintf
+    added 3.2
+function PyObject_ASCII
+    added 3.2
+function PyObject_AsFileDescriptor
+    added 3.2
+function PyObject_Bytes
+    added 3.2
+function PyObject_Call
+    added 3.2
+function PyObject_CallFunction
+    added 3.2
+function PyObject_CallFunctionObjArgs
+    added 3.2
+function PyObject_CallMethod
+    added 3.2
+function PyObject_CallMethodObjArgs
+    added 3.2
+function PyObject_CallObject
+    added 3.2
+function PyObject_ClearWeakRefs
+    added 3.2
+function PyObject_DelItem
+    added 3.2
+function PyObject_DelItemString
+    added 3.2
+function PyObject_Dir
+    added 3.2
+function PyObject_Format
+    added 3.2
+function PyObject_Free
+    added 3.2
+function PyObject_GC_Del
+    added 3.2
+function PyObject_GC_Track
+    added 3.2
+function PyObject_GC_UnTrack
+    added 3.2
+function PyObject_GenericGetAttr
+    added 3.2
+function PyObject_GenericSetAttr
+    added 3.2
+function PyObject_GetAttr
+    added 3.2
+function PyObject_GetAttrString
+    added 3.2
+function PyObject_GetItem
+    added 3.2
+function PyObject_GetIter
+    added 3.2
+function PyObject_HasAttr
+    added 3.2
+function PyObject_HasAttrString
+    added 3.2
+function PyObject_Hash
+    added 3.2
+function PyObject_HashNotImplemented
+    added 3.2
+function PyObject_Init
+    added 3.2
+function PyObject_InitVar
+    added 3.2
+function PyObject_IsInstance
+    added 3.2
+function PyObject_IsSubclass
+    added 3.2
+function PyObject_IsTrue
+    added 3.2
+function PyObject_Length
+    added 3.2
+function PyObject_Malloc
+    added 3.2
+function PyObject_Not
+    added 3.2
+function PyObject_Realloc
+    added 3.2
+function PyObject_Repr
+    added 3.2
+function PyObject_RichCompare
+    added 3.2
+function PyObject_RichCompareBool
+    added 3.2
+function PyObject_SelfIter
+    added 3.2
+function PyObject_SetAttr
+    added 3.2
+function PyObject_SetAttrString
+    added 3.2
+function PyObject_SetItem
+    added 3.2
+function PyObject_Size
+    added 3.2
+function PyObject_Str
+    added 3.2
+function PyObject_Type
+    added 3.2
+data PyProperty_Type
+    added 3.2
+data PyRangeIter_Type
+    added 3.2
+data PyRange_Type
+    added 3.2
+data PyReversed_Type
+    added 3.2
+function PySeqIter_New
+    added 3.2
+data PySeqIter_Type
+    added 3.2
+function PySequence_Check
+    added 3.2
+function PySequence_Concat
+    added 3.2
+function PySequence_Contains
+    added 3.2
+function PySequence_Count
+    added 3.2
+function PySequence_DelItem
+    added 3.2
+function PySequence_DelSlice
+    added 3.2
+function PySequence_Fast
+    added 3.2
+function PySequence_GetItem
+    added 3.2
+function PySequence_GetSlice
+    added 3.2
+function PySequence_In
+    added 3.2
+function PySequence_InPlaceConcat
+    added 3.2
+function PySequence_InPlaceRepeat
+    added 3.2
+function PySequence_Index
+    added 3.2
+function PySequence_Length
+    added 3.2
+function PySequence_List
+    added 3.2
+function PySequence_Repeat
+    added 3.2
+function PySequence_SetItem
+    added 3.2
+function PySequence_SetSlice
+    added 3.2
+function PySequence_Size
+    added 3.2
+function PySequence_Tuple
+    added 3.2
+data PySetIter_Type
+    added 3.2
+function PySet_Add
+    added 3.2
+function PySet_Clear
+    added 3.2
+function PySet_Contains
+    added 3.2
+function PySet_Discard
+    added 3.2
+function PySet_New
+    added 3.2
+function PySet_Pop
+    added 3.2
+function PySet_Size
+    added 3.2
+data PySet_Type
+    added 3.2
+function PySlice_GetIndices
+    added 3.2
+function PySlice_GetIndicesEx
+    added 3.2
+function PySlice_New
+    added 3.2
+data PySlice_Type
+    added 3.2
+function PyState_FindModule
+    added 3.2
+function PyStructSequence_GetItem
+    added 3.2
+function PyStructSequence_New
+    added 3.2
+function PyStructSequence_NewType
+    added 3.2
+function PyStructSequence_SetItem
+    added 3.2
+data PySuper_Type
+    added 3.2
+function PySys_AddWarnOption
+    added 3.2
+function PySys_AddWarnOptionUnicode
+    added 3.2
+function PySys_FormatStderr
+    added 3.2
+function PySys_FormatStdout
+    added 3.2
+function PySys_GetObject
+    added 3.2
+function PySys_HasWarnOptions
+    added 3.2
+function PySys_ResetWarnOptions
+    added 3.2
+function PySys_SetArgv
+    added 3.2
+function PySys_SetArgvEx
+    added 3.2
+function PySys_SetObject
+    added 3.2
+function PySys_SetPath
+    added 3.2
+function PySys_WriteStderr
+    added 3.2
+function PySys_WriteStdout
+    added 3.2
+function PyThreadState_Clear
+    added 3.2
+function PyThreadState_Delete
+    added 3.2
+function PyThreadState_DeleteCurrent
+    added 3.2
+    abi_only
+function PyThreadState_Get
+    added 3.2
+function PyThreadState_GetDict
+    added 3.2
+function PyThreadState_New
+    added 3.2
+function PyThreadState_SetAsyncExc
+    added 3.2
+function PyThreadState_Swap
+    added 3.2
+function PyTraceBack_Here
+    added 3.2
+function PyTraceBack_Print
+    added 3.2
+data PyTraceBack_Type
+    added 3.2
+data PyTupleIter_Type
+    added 3.2
+function PyTuple_GetItem
+    added 3.2
+function PyTuple_GetSlice
+    added 3.2
+function PyTuple_New
+    added 3.2
+function PyTuple_Pack
+    added 3.2
+function PyTuple_SetItem
+    added 3.2
+function PyTuple_Size
+    added 3.2
+data PyTuple_Type
+    added 3.2
+function PyType_ClearCache
+    added 3.2
+function PyType_GenericAlloc
+    added 3.2
+function PyType_GenericNew
+    added 3.2
+function PyType_GetFlags
+    added 3.2
+function PyType_IsSubtype
+    added 3.2
+function PyType_Modified
+    added 3.2
+function PyType_Ready
+    added 3.2
+data PyType_Type
+    added 3.2
+function PyUnicodeDecodeError_Create
+    added 3.2
+function PyUnicodeDecodeError_GetEncoding
+    added 3.2
+function PyUnicodeDecodeError_GetEnd
+    added 3.2
+function PyUnicodeDecodeError_GetObject
+    added 3.2
+function PyUnicodeDecodeError_GetReason
+    added 3.2
+function PyUnicodeDecodeError_GetStart
+    added 3.2
+function PyUnicodeDecodeError_SetEnd
+    added 3.2
+function PyUnicodeDecodeError_SetReason
+    added 3.2
+function PyUnicodeDecodeError_SetStart
+    added 3.2
+function PyUnicodeEncodeError_GetEncoding
+    added 3.2
+function PyUnicodeEncodeError_GetEnd
+    added 3.2
+function PyUnicodeEncodeError_GetObject
+    added 3.2
+function PyUnicodeEncodeError_GetReason
+    added 3.2
+function PyUnicodeEncodeError_GetStart
+    added 3.2
+function PyUnicodeEncodeError_SetEnd
+    added 3.2
+function PyUnicodeEncodeError_SetReason
+    added 3.2
+function PyUnicodeEncodeError_SetStart
+    added 3.2
+data PyUnicodeIter_Type
+    added 3.2
+function PyUnicodeTranslateError_GetEnd
+    added 3.2
+function PyUnicodeTranslateError_GetObject
+    added 3.2
+function PyUnicodeTranslateError_GetReason
+    added 3.2
+function PyUnicodeTranslateError_GetStart
+    added 3.2
+function PyUnicodeTranslateError_SetEnd
+    added 3.2
+function PyUnicodeTranslateError_SetReason
+    added 3.2
+function PyUnicodeTranslateError_SetStart
+    added 3.2
+function PyUnicode_Append
+    added 3.2
+function PyUnicode_AppendAndDel
+    added 3.2
+function PyUnicode_AsASCIIString
+    added 3.2
+function PyUnicode_AsCharmapString
+    added 3.2
+function PyUnicode_AsDecodedObject
+    added 3.2
+function PyUnicode_AsDecodedUnicode
+    added 3.2
+function PyUnicode_AsEncodedObject
+    added 3.2
+function PyUnicode_AsEncodedString
+    added 3.2
+function PyUnicode_AsEncodedUnicode
+    added 3.2
+function PyUnicode_AsLatin1String
+    added 3.2
+function PyUnicode_AsRawUnicodeEscapeString
+    added 3.2
+function PyUnicode_AsUTF16String
+    added 3.2
+function PyUnicode_AsUTF32String
+    added 3.2
+function PyUnicode_AsUTF8String
+    added 3.2
+function PyUnicode_AsUnicodeEscapeString
+    added 3.2
+function PyUnicode_AsWideChar
+    added 3.2
+function PyUnicode_Compare
+    added 3.2
+function PyUnicode_Concat
+    added 3.2
+function PyUnicode_Contains
+    added 3.2
+function PyUnicode_Count
+    added 3.2
+function PyUnicode_Decode
+    added 3.2
+function PyUnicode_DecodeASCII
+    added 3.2
+function PyUnicode_DecodeCharmap
+    added 3.2
+function PyUnicode_DecodeFSDefault
+    added 3.2
+function PyUnicode_DecodeFSDefaultAndSize
+    added 3.2
+function PyUnicode_DecodeLatin1
+    added 3.2
+function PyUnicode_DecodeRawUnicodeEscape
+    added 3.2
+function PyUnicode_DecodeUTF16
+    added 3.2
+function PyUnicode_DecodeUTF16Stateful
+    added 3.2
+function PyUnicode_DecodeUTF32
+    added 3.2
+function PyUnicode_DecodeUTF32Stateful
+    added 3.2
+function PyUnicode_DecodeUTF8
+    added 3.2
+function PyUnicode_DecodeUTF8Stateful
+    added 3.2
+function PyUnicode_DecodeUnicodeEscape
+    added 3.2
+function PyUnicode_FSConverter
+    added 3.2
+function PyUnicode_FSDecoder
+    added 3.2
+function PyUnicode_Find
+    added 3.2
+function PyUnicode_Format
+    added 3.2
+function PyUnicode_FromEncodedObject
+    added 3.2
+function PyUnicode_FromFormat
+    added 3.2
+function PyUnicode_FromFormatV
+    added 3.2
+function PyUnicode_FromObject
+    added 3.2
+function PyUnicode_FromOrdinal
+    added 3.2
+function PyUnicode_FromString
+    added 3.2
+function PyUnicode_FromStringAndSize
+    added 3.2
+function PyUnicode_FromWideChar
+    added 3.2
+function PyUnicode_GetDefaultEncoding
+    added 3.2
+function PyUnicode_GetSize
+    added 3.2
+function PyUnicode_IsIdentifier
+    added 3.2
+function PyUnicode_Join
+    added 3.2
+function PyUnicode_Partition
+    added 3.2
+function PyUnicode_RPartition
+    added 3.2
+function PyUnicode_RSplit
+    added 3.2
+function PyUnicode_Replace
+    added 3.2
+function PyUnicode_Resize
+    added 3.2
+function PyUnicode_RichCompare
+    added 3.2
+function PyUnicode_Split
+    added 3.2
+function PyUnicode_Splitlines
+    added 3.2
+function PyUnicode_Tailmatch
+    added 3.2
+function PyUnicode_Translate
+    added 3.2
+function PyUnicode_BuildEncodingMap
+    added 3.2
+function PyUnicode_CompareWithASCIIString
+    added 3.2
+function PyUnicode_DecodeUTF7
+    added 3.2
+function PyUnicode_DecodeUTF7Stateful
+    added 3.2
+function PyUnicode_EncodeFSDefault
+    added 3.2
+function PyUnicode_InternFromString
+    added 3.2
+function PyUnicode_InternImmortal
+    added 3.2
+function PyUnicode_InternInPlace
+    added 3.2
+data PyUnicode_Type
+    added 3.2
+function PyWeakref_GetObject
+    added 3.2
+function PyWeakref_NewProxy
+    added 3.2
+function PyWeakref_NewRef
+    added 3.2
+data PyWrapperDescr_Type
+    added 3.2
+function PyWrapper_New
+    added 3.2
+data PyZip_Type
+    added 3.2
+function Py_AddPendingCall
+    added 3.2
+function Py_AtExit
+    added 3.2
+function Py_BuildValue
+    added 3.2
+function Py_CompileString
+    added 3.2
+function Py_DecRef
+    added 3.2
+function Py_EndInterpreter
+    added 3.2
+function Py_Exit
+    added 3.2
+function Py_FatalError
+    added 3.2
+data Py_FileSystemDefaultEncoding
+    added 3.2
+function Py_Finalize
+    added 3.2
+function Py_GetBuildInfo
+    added 3.2
+function Py_GetCompiler
+    added 3.2
+function Py_GetCopyright
+    added 3.2
+function Py_GetExecPrefix
+    added 3.2
+function Py_GetPath
+    added 3.2
+function Py_GetPlatform
+    added 3.2
+function Py_GetPrefix
+    added 3.2
+function Py_GetProgramFullPath
+    added 3.2
+function Py_GetProgramName
+    added 3.2
+function Py_GetPythonHome
+    added 3.2
+function Py_GetRecursionLimit
+    added 3.2
+function Py_GetVersion
+    added 3.2
+data Py_HasFileSystemDefaultEncoding
+    added 3.2
+function Py_IncRef
+    added 3.2
+function Py_Initialize
+    added 3.2
+function Py_InitializeEx
+    added 3.2
+function Py_IsInitialized
+    added 3.2
+function Py_Main
+    added 3.2
+function Py_MakePendingCalls
+    added 3.2
+function Py_NewInterpreter
+    added 3.2
+function Py_ReprEnter
+    added 3.2
+function Py_ReprLeave
+    added 3.2
+function Py_SetProgramName
+    added 3.2
+function Py_SetPythonHome
+    added 3.2
+function Py_SetRecursionLimit
+    added 3.2
+function Py_VaBuildValue
+    added 3.2
+
+function _PyErr_BadInternalCall
+    added 3.2
+    abi_only
+function _PyObject_CallFunction_SizeT
+    added 3.2
+    abi_only
+function _PyObject_CallMethod_SizeT
+    added 3.2
+    abi_only
+function _PyObject_GC_Malloc
+    added 3.2
+    abi_only
+function _PyObject_GC_New
+    added 3.2
+    abi_only
+function _PyObject_GC_NewVar
+    added 3.2
+    abi_only
+function _PyObject_GC_Resize
+    added 3.2
+    abi_only
+function _PyObject_New
+    added 3.2
+    abi_only
+function _PyObject_NewVar
+    added 3.2
+    abi_only
+function _PyState_AddModule
+    added 3.2
+    abi_only
+function _PyThreadState_Init
+    added 3.2
+    abi_only
+function _PyThreadState_Prealloc
+    added 3.2
+    abi_only
+function _PyTrash_deposit_object
+    added 3.2
+    abi_only
+function _PyTrash_destroy_chain
+    added 3.2
+    abi_only
+data _PyWeakref_CallableProxyType
+    added 3.2
+    abi_only
+data _PyWeakref_ProxyType
+    added 3.2
+    abi_only
+data _PyWeakref_RefType
+    added 3.2
+    abi_only
+function _Py_BuildValue_SizeT
+    added 3.2
+    abi_only
+function _Py_CheckRecursiveCall
+    added 3.2
+    abi_only
+function _Py_Dealloc
+    added 3.2
+    abi_only
+data _Py_EllipsisObject
+    added 3.2
+    abi_only
+data _Py_FalseStruct
+    added 3.2
+    abi_only
+data _Py_NoneStruct
+    added 3.2
+    abi_only
+data _Py_NotImplementedStruct
+    added 3.2
+    abi_only
+data _Py_SwappedOp
+    added 3.2
+    abi_only
+data _Py_TrueStruct
+    added 3.2
+    abi_only
+function _Py_VaBuildValue_SizeT
+    added 3.2
+    abi_only
+
+# Flags are implicitly part of the ABI:
+
+const Py_TPFLAGS_DEFAULT
+    added 3.2
+const Py_TPFLAGS_BASETYPE
+    added 3.2
+const Py_TPFLAGS_HAVE_GC
+    added 3.2
+
+const METH_VARARGS
+    added 3.2
+const METH_NOARGS
+    added 3.2
+const METH_O
+    added 3.2
+const METH_CLASS
+    added 3.2
+const METH_STATIC
+    added 3.2
+const METH_COEXIST
+    added 3.2
+# METH_STACKLESS is undocumented
+# METH_FASTCALL is not part of limited API.
+
+# The following are defined in private headers, but historically
+# they were exported as part of the stable ABI.
+function PyMarshal_ReadObjectFromString
+    added 3.2
+    abi_only
+function PyMarshal_WriteObjectToString
+    added 3.2
+    abi_only
+function PyMember_GetOne
+    added 3.2
+    abi_only
+function PyMember_SetOne
+    added 3.2
+    abi_only
+
+# TLS api is deprecated; superseded by TSS API
+
+function PyThread_ReInitTLS
+    added 3.2
+function PyThread_create_key
+    added 3.2
+function PyThread_delete_key
+    added 3.2
+function PyThread_set_key_value
+    added 3.2
+function PyThread_get_key_value
+    added 3.2
+function PyThread_delete_key_value
+    added 3.2
+function PyThread_acquire_lock
+    added 3.2
+function PyThread_acquire_lock_timed
+    added 3.2
+function PyThread_allocate_lock
+    added 3.2
+function PyThread_exit_thread
+    added 3.2
+function PyThread_free_lock
+    added 3.2
+function PyThread_get_stacksize
+    added 3.2
+function PyThread_get_thread_ident
+    added 3.2
+function PyThread_get_thread_native_id
+    added 3.2
+function PyThread_init_thread
+    added 3.2
+function PyThread_release_lock
+    added 3.2
+function PyThread_set_stacksize
+    added 3.2
+function PyThread_start_new_thread
+    added 3.2
+
+# The following were added in PC/python3.def in Python 3.3:
+# 7800f75827b1be557be16f3b18f5170fbf9fae08
+# 9c56409d3353b8cd4cfc19e0467bbe23fd34fc92
+# 75aeaa9b18667219bbacbc58ba6efecccef9dfbd
+
+function PyState_AddModule
+    added 3.3
+function PyState_RemoveModule
+    added 3.3
+function PyType_FromSpecWithBases
+    added 3.3
+function _PyArg_Parse_SizeT
+    added 3.3
+    abi_only
+function _PyArg_ParseTuple_SizeT
+    added 3.3
+    abi_only
+function _PyArg_ParseTupleAndKeywords_SizeT
+    added 3.3
+    abi_only
+function _PyArg_VaParse_SizeT
+    added 3.3
+    abi_only
+function _PyArg_VaParseTupleAndKeywords_SizeT
+    added 3.3
+    abi_only
+function PyThread_GetInfo
+    added 3.3
+
+# The following were added in PC/python3.def in Python 3.4:
+# 3ba3a3ee56c142e93d6bbe20ff6bf939212a30f0
+
+function PyCFunction_New
+    added 3.4
+function PyType_GetSlot
+    added 3.4
+
+# The following were added in PC/python3.def in Python 3.5:
+# 11d7b1423fc44d764eba7065ea5eba58ed748b21
+# f3b73ad51da3097d7915796fdc62608b1ab90c0a
+
+function PyErr_FormatV
+    added 3.5
+function PyModuleDef_Init
+    added 3.5
+data PyModuleDef_Type
+    added 3.5
+
+# New slots in 3.5:
+# d51374ed78a3e3145911a16cdf3b9b84b3ba7d15 - Matrix multiplication (PEP 465)
+# 7544508f0245173bff5866aa1598c8f6cce1fc5f - Async iterators (PEP 492)
+# 0969a9f8abcf98bb43ea77b1dd050426adcfb4f7 - tp_finalize
+
+const Py_nb_matrix_multiply
+    added 3.5
+const Py_nb_inplace_matrix_multiply
+    added 3.5
+const Py_am_await
+    added 3.5
+const Py_am_aiter
+    added 3.5
+const Py_am_anext
+    added 3.5
+const Py_tp_finalize
+    added 3.5
+
+# The following were added in PC/python3.def in Python 3.6:
+
+function Py_FinalizeEx
+    added 3.6
+
+function PyOS_FSPath
+    added 3.6
+function PyErr_ResourceWarning
+    added 3.6
+function PyErr_SetImportErrorSubclass
+    added 3.6
+data PyExc_ModuleNotFoundError
+    added 3.6
+
+# The following were added in PC/python3.def in Python 3.6.1 and 3.5.3/3.5.4:
+
+function PyCodec_NameReplaceErrors
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyErr_GetExcInfo
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyErr_SetExcInfo
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyErr_SetFromErrnoWithFilenameObjects
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyErr_SetImportError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyErr_SyntaxLocationEx
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_BlockingIOError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_BrokenPipeError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ChildProcessError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ConnectionAbortedError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ConnectionError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ConnectionRefusedError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ConnectionResetError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_FileExistsError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_FileNotFoundError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_InterruptedError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_IsADirectoryError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_NotADirectoryError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_PermissionError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ProcessLookupError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_RecursionError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_ResourceWarning
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_StopAsyncIteration
+    added 3.7  # (and 3.6.1 and 3.5.3)
+data PyExc_TimeoutError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyImport_AddModuleObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyImport_ExecCodeModuleObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyImport_ImportFrozenModuleObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyImport_ImportModuleLevelObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyMem_Calloc
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyMemoryView_FromMemory
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_AddFunctions
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_ExecDef
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_FromDefAndSpec2
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_GetNameObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_NewObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyModule_SetDocString
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyNumber_InPlaceMatrixMultiply
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyNumber_MatrixMultiply
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyObject_Calloc
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyObject_GenericSetDict
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PySys_AddXOption
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PySys_GetXOptions
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_AsUCS4
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_AsUCS4Copy
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_AsWideCharString
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_DecodeLocale
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_DecodeLocaleAndSize
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_EncodeLocale
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_FindChar
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_GetLength
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_ReadChar
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_Substring
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function PyUnicode_WriteChar
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function Py_DecodeLocale
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function Py_EncodeLocale
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function Py_SetPath
+    added 3.7  # (and 3.6.1 and 3.5.3)
+function _PyTrash_thread_deposit_object
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    abi_only
+function _PyTrash_thread_destroy_chain
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    abi_only
+function PyErr_SetExcFromWindowsErr
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyErr_SetExcFromWindowsErrWithFilename
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyErr_SetExcFromWindowsErrWithFilenameObject
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyErr_SetExcFromWindowsErrWithFilenameObjects
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyErr_SetFromWindowsErr
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyErr_SetFromWindowsErrWithFilename
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+data PyExc_WindowsError
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyOS_CheckStack
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef USE_STACKCHECK
+function PyUnicode_AsMBCSString
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyUnicode_DecodeCodePageStateful
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyUnicode_DecodeMBCS
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyUnicode_DecodeMBCSStateful
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+function PyUnicode_EncodeCodePage
+    added 3.7  # (and 3.6.1 and 3.5.3)
+    ifdef MS_WINDOWS
+
+# 3.5.4:
+function PySlice_AdjustIndices
+    added 3.7  # (and 3.6.1 and 3.5.4)
+function PySlice_Unpack
+    added 3.7  # (and 3.6.1 and 3.5.4)
+
+# The following were added in PC/python3.def in Python 3.7:
+
+function PyInterpreterState_GetID
+    added 3.7
+function PyThread_tss_alloc
+    added 3.7
+function PyThread_tss_create
+    added 3.7
+function PyThread_tss_delete
+    added 3.7
+function PyThread_tss_free
+    added 3.7
+function PyThread_tss_get
+    added 3.7
+function PyThread_tss_is_created
+    added 3.7
+function PyThread_tss_set
+    added 3.7
+function PyOS_BeforeFork
+    added 3.7
+    ifdef HAVE_FORK
+function PyOS_AfterFork_Parent
+    added 3.7
+    ifdef HAVE_FORK
+function PyOS_AfterFork_Child
+    added 3.7
+    ifdef HAVE_FORK
+
+# New method flags in 3.7 (PEP 590):
+
+const METH_FASTCALL
+    added 3.7
+const METH_METHOD
+    added 3.7
+
+# The following were added in PC/python3.def in Python 3.8:
+
+function PyImport_GetModule
+    added 3.8
+data Py_UTF8Mode
+    added 3.8
+function PyExceptionClass_Name
+    added 3.8
+function PyIndex_Check
+    added 3.8
+function PyIter_Check
+    added 3.8
+data PyDictRevIterItem_Type
+    added 3.8
+data PyDictRevIterKey_Type
+    added 3.8
+data PyDictRevIterValue_Type
+    added 3.8
+function PyInterpreterState_GetDict
+    added 3.8
+function Py_BytesMain
+    added 3.8
+
+# New type flag (PEP 590):
+
+const Py_TPFLAGS_METHOD_DESCRIPTOR
+    added 3.8
+
+# The following were added in PC/python3.def in Python 3.9:
+
+function Py_EnterRecursiveCall
+    added 3.9
+function Py_LeaveRecursiveCall
+    added 3.9
+function Py_GenericAlias
+    added 3.9
+function Py_GenericAliasType
+    added 3.9
+function PyCMethod_New
+    added 3.9  # Windows: 3.10 & 3.9.2 -- https://bugs.python.org/issue43155
+function PyInterpreterState_Get
+    added 3.9
+function PyObject_GC_IsFinalized
+    added 3.9
+function PyObject_GC_IsTracked
+    added 3.9
+
+# The following were added in PC/python3.def in Python 3.10:
+
+function Py_GetArgcArgv
+    added 3.10
+    abi_only
+function PyIter_Send
+    added 3.10
+function PyUnicode_AsUTF8AndSize
+    added 3.10
+function PyObject_GenericGetDict
+    added 3.10
+function Py_NewRef
+    added 3.10
+function Py_XNewRef
+    added 3.10
+function PyModule_AddType
+    added 3.10
+function PyType_FromModuleAndSpec
+    added 3.10
+function PyType_GetModule
+    added 3.10
+function PyType_GetModuleState
+    added 3.10
+function Py_FrozenMain
+    added 3.10
+function PyFrame_GetLineNumber
+    added 3.10
+function PyFrame_GetCode
+    added 3.10
+function PyObject_CallNoArgs
+    added 3.10
+function PyThreadState_GetFrame
+    added 3.10
+function PyThreadState_GetID
+    added 3.10
+function PyThreadState_GetInterpreter
+    added 3.10
+function PyModule_AddObjectRef
+    added 3.10
+data Py_FileSystemDefaultEncodeErrors
+    added 3.10
+data PyCodec_Unregister
+    added 3.10
+function PyErr_SetInterruptEx
+    added 3.10
+function Py_Is
+    added 3.10
+function Py_IsTrue
+    added 3.10
+function Py_IsFalse
+    added 3.10
+function Py_IsNone
+    added 3.10
+function _Py_IncRef
+    added 3.10
+    abi_only
+function _Py_DecRef
+    added 3.10
+    abi_only
+function PyAiter_Check
+    added 3.10
+function PyObject_GetAiter
+    added 3.10
+data PyExc_EncodingWarning
+    added 3.10
+
+# Support for Stable ABI in debug builds
+
+data _Py_RefTotal
+    added 3.10
+    abi_only
+    ifdef Py_REF_DEBUG
+function _Py_NegativeRefcount
+    added 3.10
+    abi_only
+    ifdef Py_REF_DEBUG
+
+# New slots in 3.10:
+
+const Py_am_send
+    added 3.10
+
+
+# (Detailed comments aren't really needed for further entries: from here on
+#  we can use version control logs.)
+
diff --git a/PC/python3dll.c b/PC/python3dll.c
old mode 100644
new mode 100755
index e5a21ed7c022e7..a53ec63e038f9f
--- a/PC/python3dll.c
+++ b/PC/python3dll.c
@@ -1,4 +1,7 @@
-/* Re-export stable Python API */
+
+/* Re-export stable Python ABI */
+
+/* Generated by Tools/scripts/stable_abi.py */
 
 #ifdef _M_IX86
 #define DECORATE "_"
@@ -41,6 +44,7 @@ EXPORT_FUNC(_PyTrash_thread_destroy_chain)
 EXPORT_FUNC(Py_AddPendingCall)
 EXPORT_FUNC(Py_AtExit)
 EXPORT_FUNC(Py_BuildValue)
+EXPORT_FUNC(Py_BytesMain)
 EXPORT_FUNC(Py_CompileString)
 EXPORT_FUNC(Py_DecodeLocale)
 EXPORT_FUNC(Py_DecRef)
@@ -70,7 +74,11 @@ EXPORT_FUNC(Py_GetVersion)
 EXPORT_FUNC(Py_IncRef)
 EXPORT_FUNC(Py_Initialize)
 EXPORT_FUNC(Py_InitializeEx)
+EXPORT_FUNC(Py_Is)
+EXPORT_FUNC(Py_IsFalse)
 EXPORT_FUNC(Py_IsInitialized)
+EXPORT_FUNC(Py_IsNone)
+EXPORT_FUNC(Py_IsTrue)
 EXPORT_FUNC(Py_LeaveRecursiveCall)
 EXPORT_FUNC(Py_Main)
 EXPORT_FUNC(Py_MakePendingCalls)
@@ -84,6 +92,7 @@ EXPORT_FUNC(Py_SetPythonHome)
 EXPORT_FUNC(Py_SetRecursionLimit)
 EXPORT_FUNC(Py_VaBuildValue)
 EXPORT_FUNC(Py_XNewRef)
+EXPORT_FUNC(PyAiter_Check)
 EXPORT_FUNC(PyArg_Parse)
 EXPORT_FUNC(PyArg_ParseTuple)
 EXPORT_FUNC(PyArg_ParseTupleAndKeywords)
@@ -230,14 +239,12 @@ EXPORT_FUNC(PyEval_EvalCodeEx)
 EXPORT_FUNC(PyEval_EvalFrame)
 EXPORT_FUNC(PyEval_EvalFrameEx)
 EXPORT_FUNC(PyEval_GetBuiltins)
-EXPORT_FUNC(PyEval_GetCallStats)
 EXPORT_FUNC(PyEval_GetFrame)
 EXPORT_FUNC(PyEval_GetFuncDesc)
 EXPORT_FUNC(PyEval_GetFuncName)
 EXPORT_FUNC(PyEval_GetGlobals)
 EXPORT_FUNC(PyEval_GetLocals)
 EXPORT_FUNC(PyEval_InitThreads)
-EXPORT_FUNC(PyEval_ReInitThreads)
 EXPORT_FUNC(PyEval_ReleaseLock)
 EXPORT_FUNC(PyEval_ReleaseThread)
 EXPORT_FUNC(PyEval_RestoreThread)
@@ -270,7 +277,6 @@ EXPORT_FUNC(PyGILState_Release)
 EXPORT_FUNC(PyImport_AddModule)
 EXPORT_FUNC(PyImport_AddModuleObject)
 EXPORT_FUNC(PyImport_AppendInittab)
-EXPORT_FUNC(PyImport_Cleanup)
 EXPORT_FUNC(PyImport_ExecCodeModule)
 EXPORT_FUNC(PyImport_ExecCodeModuleEx)
 EXPORT_FUNC(PyImport_ExecCodeModuleObject)
@@ -291,6 +297,8 @@ EXPORT_FUNC(PyImport_ReloadModule)
 EXPORT_FUNC(PyIndex_Check)
 EXPORT_FUNC(PyInterpreterState_Clear)
 EXPORT_FUNC(PyInterpreterState_Delete)
+EXPORT_FUNC(PyInterpreterState_Get)
+EXPORT_FUNC(PyInterpreterState_GetDict)
 EXPORT_FUNC(PyInterpreterState_GetID)
 EXPORT_FUNC(PyInterpreterState_New)
 EXPORT_FUNC(PyIter_Check)
@@ -339,10 +347,14 @@ EXPORT_FUNC(PyMapping_Length)
 EXPORT_FUNC(PyMapping_SetItemString)
 EXPORT_FUNC(PyMapping_Size)
 EXPORT_FUNC(PyMapping_Values)
+EXPORT_FUNC(PyMarshal_ReadObjectFromString)
+EXPORT_FUNC(PyMarshal_WriteObjectToString)
 EXPORT_FUNC(PyMem_Calloc)
 EXPORT_FUNC(PyMem_Free)
 EXPORT_FUNC(PyMem_Malloc)
 EXPORT_FUNC(PyMem_Realloc)
+EXPORT_FUNC(PyMember_GetOne)
+EXPORT_FUNC(PyMember_SetOne)
 EXPORT_FUNC(PyMemoryView_FromMemory)
 EXPORT_FUNC(PyMemoryView_FromObject)
 EXPORT_FUNC(PyMemoryView_GetContiguous)
@@ -421,12 +433,15 @@ EXPORT_FUNC(PyObject_Dir)
 EXPORT_FUNC(PyObject_Format)
 EXPORT_FUNC(PyObject_Free)
 EXPORT_FUNC(PyObject_GC_Del)
+EXPORT_FUNC(PyObject_GC_IsFinalized)
+EXPORT_FUNC(PyObject_GC_IsTracked)
 EXPORT_FUNC(PyObject_GC_Track)
 EXPORT_FUNC(PyObject_GC_UnTrack)
 EXPORT_FUNC(PyObject_GenericGetAttr)
 EXPORT_FUNC(PyObject_GenericGetDict)
 EXPORT_FUNC(PyObject_GenericSetAttr)
 EXPORT_FUNC(PyObject_GenericSetDict)
+EXPORT_FUNC(PyObject_GetAiter)
 EXPORT_FUNC(PyObject_GetAttr)
 EXPORT_FUNC(PyObject_GetAttrString)
 EXPORT_FUNC(PyObject_GetItem)
@@ -454,11 +469,6 @@ EXPORT_FUNC(PyObject_SetItem)
 EXPORT_FUNC(PyObject_Size)
 EXPORT_FUNC(PyObject_Str)
 EXPORT_FUNC(PyObject_Type)
-EXPORT_FUNC(PyODict_DelItem)
-EXPORT_FUNC(PyODict_New)
-EXPORT_FUNC(PyODict_SetItem)
-EXPORT_FUNC(PyOS_AfterFork)
-EXPORT_FUNC(PyOS_CheckStack)
 EXPORT_FUNC(PyOS_double_to_string)
 EXPORT_FUNC(PyOS_FSPath)
 EXPORT_FUNC(PyOS_getsig)
@@ -471,9 +481,6 @@ EXPORT_FUNC(PyOS_string_to_double)
 EXPORT_FUNC(PyOS_strtol)
 EXPORT_FUNC(PyOS_strtoul)
 EXPORT_FUNC(PyOS_vsnprintf)
-EXPORT_FUNC(PyParser_SimpleParseFileFlags)
-EXPORT_FUNC(PyParser_SimpleParseStringFlags)
-EXPORT_FUNC(PyParser_SimpleParseStringFlagsFilename)
 EXPORT_FUNC(PySeqIter_New)
 EXPORT_FUNC(PySequence_Check)
 EXPORT_FUNC(PySequence_Concat)
@@ -529,6 +536,25 @@ EXPORT_FUNC(PySys_SetObject)
 EXPORT_FUNC(PySys_SetPath)
 EXPORT_FUNC(PySys_WriteStderr)
 EXPORT_FUNC(PySys_WriteStdout)
+EXPORT_FUNC(PyThread_acquire_lock)
+EXPORT_FUNC(PyThread_acquire_lock_timed)
+EXPORT_FUNC(PyThread_allocate_lock)
+EXPORT_FUNC(PyThread_create_key)
+EXPORT_FUNC(PyThread_delete_key)
+EXPORT_FUNC(PyThread_delete_key_value)
+EXPORT_FUNC(PyThread_exit_thread)
+EXPORT_FUNC(PyThread_free_lock)
+EXPORT_FUNC(PyThread_get_key_value)
+EXPORT_FUNC(PyThread_get_stacksize)
+EXPORT_FUNC(PyThread_get_thread_ident)
+EXPORT_FUNC(PyThread_get_thread_native_id)
+EXPORT_FUNC(PyThread_GetInfo)
+EXPORT_FUNC(PyThread_init_thread)
+EXPORT_FUNC(PyThread_ReInitTLS)
+EXPORT_FUNC(PyThread_release_lock)
+EXPORT_FUNC(PyThread_set_key_value)
+EXPORT_FUNC(PyThread_set_stacksize)
+EXPORT_FUNC(PyThread_start_new_thread)
 EXPORT_FUNC(PyThread_tss_alloc)
 EXPORT_FUNC(PyThread_tss_create)
 EXPORT_FUNC(PyThread_tss_delete)
@@ -688,8 +714,6 @@ EXPORT_DATA(_Py_NoneStruct)
 EXPORT_DATA(_Py_NotImplementedStruct)
 EXPORT_DATA(_Py_SwappedOp)
 EXPORT_DATA(_Py_TrueStruct)
-EXPORT_DATA(_PyTrash_delete_later)
-EXPORT_DATA(_PyTrash_delete_nesting)
 EXPORT_DATA(_PyWeakref_CallableProxyType)
 EXPORT_DATA(_PyWeakref_ProxyType)
 EXPORT_DATA(_PyWeakref_RefType)
@@ -707,6 +731,7 @@ EXPORT_DATA(PyCallIter_Type)
 EXPORT_DATA(PyCapsule_Type)
 EXPORT_DATA(PyCFunction_Type)
 EXPORT_DATA(PyClassMethodDescr_Type)
+EXPORT_DATA(PyCodec_Unregister)
 EXPORT_DATA(PyComplex_Type)
 EXPORT_DATA(PyDict_Type)
 EXPORT_DATA(PyDictItems_Type)
@@ -715,6 +740,9 @@ EXPORT_DATA(PyDictIterKey_Type)
 EXPORT_DATA(PyDictIterValue_Type)
 EXPORT_DATA(PyDictKeys_Type)
 EXPORT_DATA(PyDictProxy_Type)
+EXPORT_DATA(PyDictRevIterItem_Type)
+EXPORT_DATA(PyDictRevIterKey_Type)
+EXPORT_DATA(PyDictRevIterValue_Type)
 EXPORT_DATA(PyDictValues_Type)
 EXPORT_DATA(PyEllipsis_Type)
 EXPORT_DATA(PyEnum_Type)
@@ -801,12 +829,6 @@ EXPORT_DATA(PyMemoryView_Type)
 EXPORT_DATA(PyMethodDescr_Type)
 EXPORT_DATA(PyModule_Type)
 EXPORT_DATA(PyModuleDef_Type)
-EXPORT_DATA(PyNullImporter_Type)
-EXPORT_DATA(PyODict_Type)
-EXPORT_DATA(PyODictItems_Type)
-EXPORT_DATA(PyODictIter_Type)
-EXPORT_DATA(PyODictKeys_Type)
-EXPORT_DATA(PyODictValues_Type)
 EXPORT_DATA(PyOS_InputHook)
 EXPORT_DATA(PyProperty_Type)
 EXPORT_DATA(PyRange_Type)
@@ -816,7 +838,6 @@ EXPORT_DATA(PySeqIter_Type)
 EXPORT_DATA(PySet_Type)
 EXPORT_DATA(PySetIter_Type)
 EXPORT_DATA(PySlice_Type)
-EXPORT_DATA(PySortWrapper_Type)
 EXPORT_DATA(PySuper_Type)
 EXPORT_DATA(PyTraceBack_Type)
 EXPORT_DATA(PyTuple_Type)
diff --git a/Tools/scripts/README b/Tools/scripts/README
index 7fc51a10ee902c..ba0f662c45f0c5 100644
--- a/Tools/scripts/README
+++ b/Tools/scripts/README
@@ -58,6 +58,7 @@ reindent-rst.py           Fix-up reStructuredText file whitespace
 rgrep.py                  Reverse grep through a file (useful for big logfiles)
 run_tests.py              Run the test suite with more sensible default options
 serve.py                  Small wsgiref-based web server, used in make serve in Doc
+stable_abi.py             Stable ABI checks and file generators.
 suff.py                   Sort a list of files by suffix
 texi2html.py              Convert GNU texinfo files into HTML
 untabify.py               Replace tabs with spaces in argument files
diff --git a/Tools/scripts/stable_abi.py b/Tools/scripts/stable_abi.py
index 1690cfce1727d7..399153db81c254 100755
--- a/Tools/scripts/stable_abi.py
+++ b/Tools/scripts/stable_abi.py
@@ -1,13 +1,28 @@
-#!/usr/bin/env python
+"""Check the stable ABI manifest or generate files from it
 
+By default, the tool only checks existing files/libraries.
+Pass --generate to recreate auto-generated files instead.
+
+For actions that take a FILENAME, the filename can be left out to use a default
+(relative to the manifest file, as they appear in the CPython codebase).
+"""
+
+from functools import partial
+from pathlib import Path
+import dataclasses
+import subprocess
+import sysconfig
 import argparse
-import glob
+import textwrap
+import difflib
+import shutil
+import sys
+import os
 import os.path
-import pathlib
+import io
 import re
-import subprocess
-import sys
-import sysconfig
+
+MISSING = object()
 
 EXCLUDED_HEADERS = {
     "bytes_methods.h",
@@ -27,10 +42,303 @@
     "token.h",
     "ucnhash.h",
 }
-
 MACOS = (sys.platform == "darwin")
+UNIXY = MACOS or (sys.platform == "linux")  # XXX should this be "not Windows"?
+
+
+# The stable ABI manifest (Misc/stable_abi.txt) exists only to fill the
+# following dataclasses.
+# Feel free to change its syntax (and the `parse_manifest` function)
+# to better serve that purpose (while keeping it human-readable).
+
+ at dataclasses.dataclass
+class Manifest:
+    """Collection of `ABIItem`s forming the stable ABI/limited API."""
+
+    kind = 'manifest'
+    contents: dict = dataclasses.field(default_factory=dict)
+
+    def add(self, item):
+        if item.name in self.contents:
+            # We assume that stable ABI items do not share names,
+            # even if they're diferent kinds (e.g. function vs. macro).
+            raise ValueError(f'duplicate ABI item {item.name}')
+        self.contents[item.name] = item
+
+    @property
+    def feature_defines(self):
+        """Return all feature defines which affect what's available
+
+        These are e.g. HAVE_FORK and MS_WINDOWS.
+        """
+        return set(item.ifdef for item in self.contents.values()) - {None}
+
+    def select(self, kinds, *, include_abi_only=True, ifdef=None):
+        """Yield selected items of the manifest
+
+        kinds: set of requested kinds, e.g. {'function', 'macro'}
+        include_abi_only: if True (default), include all items of the
+            stable ABI.
+            If False, include only items from the limited API
+            (i.e. items people should use today)
+        ifdef: set of feature defines (e.g. {'HAVE_FORK', 'MS_WINDOWS'}).
+            If None (default), items are not filtered by this. (This is
+            different from the empty set, which filters out all such
+            conditional items.)
+        """
+        for name, item in sorted(self.contents.items()):
+            if item.kind not in kinds:
+                continue
+            if item.abi_only and not include_abi_only:
+                continue
+            if (ifdef is not None
+                    and item.ifdef is not None
+                    and item.ifdef not in ifdef):
+                continue
+            yield item
+
+    def dump(self):
+        """Yield lines to recreate the manifest file (sans comments/newlines)"""
+        # Recursive in preparation for struct member & function argument nodes
+        for item in self.contents.values():
+            yield from item.dump(indent=0)
+
+ at dataclasses.dataclass
+class ABIItem:
+    """Information on one item (function, macro, struct, etc.)"""
+
+    kind: str
+    name: str
+    added: str = None
+    contents: list = dataclasses.field(default_factory=list)
+    abi_only: bool = False
+    ifdef: str = None
+
+    KINDS = frozenset({
+        'struct', 'function', 'macro', 'data', 'const', 'typedef',
+    })
+
+    def dump(self, indent=0):
+        yield f"{'    ' * indent}{self.kind} {self.name}"
+        if self.added:
+            yield f"{'    ' * (indent+1)}added {self.added}"
+        if self.ifdef:
+            yield f"{'    ' * (indent+1)}ifdef {self.ifdef}"
+        if self.abi_only:
+            yield f"{'    ' * (indent+1)}abi_only"
+
+def parse_manifest(file):
+    """Parse the given file (iterable of lines) to a Manifest"""
+
+    LINE_RE = re.compile('(?P<indent>[ ]*)(?P<kind>[^ ]+)[ ]*(?P<content>.*)')
+    manifest = Manifest()
+
+    # parents of currently processed line, each with its indentation level
+    levels = [(manifest, -1)]
+
+    def raise_error(msg):
+        raise SyntaxError(f'line {lineno}: {msg}')
+
+    for lineno, line in enumerate(file, start=1):
+        line, sep, comment = line.partition('#')
+        line = line.rstrip()
+        if not line:
+            continue
+        match = LINE_RE.fullmatch(line)
+        if not match:
+            raise_error(f'invalid syntax: {line}')
+        level = len(match['indent'])
+        kind = match['kind']
+        content = match['content']
+        while level <= levels[-1][1]:
+            levels.pop()
+        parent = levels[-1][0]
+        entry = None
+        if kind in ABIItem.KINDS:
+            if parent.kind not in {'manifest'}:
+                raise_error(f'{kind} cannot go in {parent.kind}')
+            entry = ABIItem(kind, content)
+            parent.add(entry)
+        elif kind in {'added', 'ifdef'}:
+            if parent.kind not in ABIItem.KINDS:
+                raise_error(f'{kind} cannot go in {parent.kind}')
+            setattr(parent, kind, content)
+        elif kind in {'abi_only'}:
+            if parent.kind not in {'function', 'data'}:
+                raise_error(f'{kind} cannot go in {parent.kind}')
+            parent.abi_only = True
+        else:
+            raise_error(f"unknown kind {kind!r}")
+        levels.append((entry, level))
+    return manifest
+
+# The tool can run individual "actions".
+# Most actions are "generators", which generate a single file from the
+# manifest. (Checking works by generating a temp file & comparing.)
+# Other actions, like "--unixy-check", don't work on a single file.
+
+generators = []
+def generator(var_name, default_path):
+    """Decorates a file generator: function that writes to a file"""
+    def _decorator(func):
+        func.var_name = var_name
+        func.arg_name = '--' + var_name.replace('_', '-')
+        func.default_path = default_path
+        generators.append(func)
+        return func
+    return _decorator
+
+
+ at generator("python3dll", 'PC/python3dll.c')
+def gen_python3dll(manifest, args, outfile):
+    """Generate/check the source for the Windows stable ABI library"""
+    write = partial(print, file=outfile)
+    write(textwrap.dedent(r"""
+        /* Re-export stable Python ABI */
+
+        /* Generated by Tools/scripts/stable_abi.py */
+
+        #ifdef _M_IX86
+        #define DECORATE "_"
+        #else
+        #define DECORATE
+        #endif
+
+        #define EXPORT_FUNC(name) \
+            __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name))
+        #define EXPORT_DATA(name) \
+            __pragma(comment(linker, "/EXPORT:" DECORATE #name "=" PYTHON_DLL_NAME "." #name ",DATA"))
+    """))
+
+    def sort_key(item):
+        return item.name.lower()
+
+    for item in sorted(
+            manifest.select(
+                {'function'}, include_abi_only=True, ifdef={'MS_WINDOWS'}),
+            key=sort_key):
+        write(f'EXPORT_FUNC({item.name})')
+
+    write()
+
+    for item in sorted(
+            manifest.select(
+                {'data'}, include_abi_only=True, ifdef={'MS_WINDOWS'}),
+            key=sort_key):
+        write(f'EXPORT_DATA({item.name})')
+
+
+ at generator("doc_list", 'Doc/data/stable_abi.dat')
+def gen_doc_annotations(manifest, args, outfile):
+    """Generate/check the stable ABI list for documentation annotations"""
+    write = partial(print, file=outfile)
+    write("# Generated by Tools/scripts/stable_abi.py")
+    write()
+    for item in manifest.select(ABIItem.KINDS, include_abi_only=False):
+        write(item.name)
+
+
+def generate_or_check(manifest, args, path, func):
+    """Generate/check a file with a single generator
+
+    Return True if successful; False if a comparison failed.
+    """
+
+    outfile = io.StringIO()
+    func(manifest, args, outfile)
+    generated = outfile.getvalue()
+    existing = path.read_text()
+
+    if generated != existing:
+        if args.generate:
+            path.write_text(generated)
+        else:
+            print(f'File {path} differs from expected!')
+            diff = difflib.unified_diff(
+                generated.splitlines(), existing.splitlines(),
+                str(path), '<expected>',
+                lineterm='',
+            )
+            for line in diff:
+                print(line)
+            return False
+    return True
+
+
+def do_unixy_check(manifest, args):
+    """Check headers & library using "Unixy" tools (GCC/clang, binutils)"""
+    okay = True
 
-def get_exported_symbols(library, dynamic=False):
+    # Get all macros first: we'll need feature macros like HAVE_FORK and
+    # MS_WINDOWS for everything else
+    present_macros = gcc_get_limited_api_macros(['Include/Python.h'])
+    feature_defines = manifest.feature_defines & present_macros
+
+    # Check that we have all neded macros
+    expected_macros = set(
+        item.name for item in manifest.select({'macro'})
+    )
+    missing_macros = expected_macros - present_macros
+    okay &= _report_unexpected_items(
+        missing_macros,
+        'Some macros from are not defined from "Include/Python.h"'
+        + 'with Py_LIMITED_API:')
+
+    expected_symbols = set(item.name for item in manifest.select(
+        {'function', 'data'}, include_abi_only=True, ifdef=feature_defines,
+    ))
+
+    # Check the static library (*.a)
+    LIBRARY = sysconfig.get_config_var("LIBRARY")
+    if not LIBRARY:
+        raise Exception("failed to get LIBRARY variable from sysconfig")
+    if os.path.exists(LIBRARY):
+        okay &= binutils_check_library(
+            manifest, LIBRARY, expected_symbols, dynamic=False)
+
+    # Check the dynamic library (*.so)
+    LDLIBRARY = sysconfig.get_config_var("LDLIBRARY")
+    if not LDLIBRARY:
+        raise Exception("failed to get LDLIBRARY variable from sysconfig")
+    okay &= binutils_check_library(
+            manifest, LDLIBRARY, expected_symbols, dynamic=False)
+
+    # Check definitions in the header files
+    expected_defs = set(item.name for item in manifest.select(
+        {'function', 'data'}, include_abi_only=False, ifdef=feature_defines,
+    ))
+    found_defs = gcc_get_limited_api_definitions(['Include/Python.h'])
+    missing_defs = expected_defs - found_defs
+    okay &= _report_unexpected_items(
+        missing_defs,
+        'Some expected declarations were not declared in '
+        + '"Include/Python.h" with Py_LIMITED_API:')
+
+    # Some Limited API macros are defined in terms of private symbols.
+    # These are not part of Limited API (even though they're defined with
+    # Py_LIMITED_API). They must be part of the Stable ABI, though.
+    private_symbols = {n for n in expected_symbols if n.startswith('_')}
+    extra_defs = found_defs - expected_defs - private_symbols
+    okay &= _report_unexpected_items(
+        extra_defs,
+        'Some extra declarations were found in "Include/Python.h" '
+        + 'with Py_LIMITED_API:')
+
+    return okay
+
+
+def _report_unexpected_items(items, msg):
+    """If there are any `items`, report them using "msg" and return false"""
+    if items:
+        print(msg, file=sys.stderr)
+        for item in sorted(items):
+            print(' -', item, file=sys.stderr)
+        return False
+    return True
+
+
+def binutils_get_exported_symbols(library, dynamic=False):
+    """Retrieve exported symbols using the nm(1) tool from binutils"""
     # Only look at dynamic symbols
     args = ["nm", "--no-sort"]
     if dynamic:
@@ -61,86 +369,89 @@ def get_exported_symbols(library, dynamic=False):
             yield symbol
 
 
-def check_library(stable_abi_file, library, abi_funcs, dynamic=False):
-    available_symbols = set(get_exported_symbols(library, dynamic))
-    missing_symbols = abi_funcs - available_symbols
+def binutils_check_library(manifest, library, expected_symbols, dynamic):
+    """Check that library exports all expected_symbols"""
+    available_symbols = set(binutils_get_exported_symbols(library, dynamic))
+    missing_symbols = expected_symbols - available_symbols
     if missing_symbols:
-        raise Exception(
-            f"""\
-Some symbols from the limited API are missing: {', '.join(missing_symbols)}
+        print(textwrap.dedent(f"""\
+            Some symbols from the limited API are missing from {library}:
+                {', '.join(missing_symbols)}
 
-This error means that there are some missing symbols among the ones exported
-in the Python library ("libpythonx.x.a" or "libpythonx.x.so"). This normally
-means that some symbol, function implementation or a prototype, belonging to
-a symbol in the limited API has been deleted or is missing.
+            This error means that there are some missing symbols among the
+            ones exported in the library.
+            This normally means that some symbol, function implementation or
+            a prototype belonging to a symbol in the limited API has been
+            deleted or is missing.
+        """), file=sys.stderr)
+        return False
+    return True
 
-Check if this was a mistake and if not, update the file containing the limited
-API symbols. This file is located at:
 
-{stable_abi_file}
+def gcc_get_limited_api_macros(headers):
+    """Get all limited API macros from headers.
 
-You can read more about the limited API and its contracts at:
-
-https://docs.python.org/3/c-api/stable.html
-
-And in PEP 384:
-
-https://www.python.org/dev/peps/pep-0384/
-"""
-        )
+    Runs the preprocesor over all the header files in "Include" setting
+    "-DPy_LIMITED_API" to the correct value for the running version of the
+    interpreter and extracting all macro definitions (via adding -dM to the
+    compiler arguments).
 
+    Requires Python built with a GCC-compatible compiler. (clang might work)
+    """
 
-def generate_limited_api_symbols(args):
-    library = sysconfig.get_config_var("LIBRARY")
-    ldlibrary = sysconfig.get_config_var("LDLIBRARY")
-    if ldlibrary != library:
-        raise Exception("Limited ABI symbols can only be generated from a static build")
-    available_symbols = {
-        symbol for symbol in get_exported_symbols(library) if symbol.startswith("Py")
-    }
+    api_hexversion = sys.version_info.major << 24 | sys.version_info.minor << 16
 
-    headers = [
-        file
-        for file in pathlib.Path("Include").glob("*.h")
-        if file.name not in EXCLUDED_HEADERS
-    ]
-    stable_data, stable_exported_data, stable_functions = get_limited_api_definitions(
-        headers
+    preprocesor_output_with_macros = subprocess.check_output(
+        sysconfig.get_config_var("CC").split()
+        + [
+            # Prevent the expansion of the exported macros so we can
+            # capture them later
+            "-DSIZEOF_WCHAR_T=4",  # The actual value is not important
+            f"-DPy_LIMITED_API={api_hexversion}",
+            "-I.",
+            "-I./Include",
+            "-dM",
+            "-E",
+        ]
+        + [str(file) for file in headers],
+        text=True,
     )
 
-    stable_symbols = {
-        symbol
-        for symbol in (stable_functions | stable_exported_data | stable_data)
-        if symbol.startswith("Py") and symbol in available_symbols
-    }
-    with open(args.output_file, "w") as output_file:
-        output_file.write(f"# File generated by 'make regen-limited-abi'\n")
-        output_file.write(
-            f"# This is NOT an authoritative list of stable ABI symbols\n"
+    return {
+        target
+        for target in re.findall(
+            r"#define (\w+)", preprocesor_output_with_macros
         )
-        for symbol in sorted(stable_symbols):
-            output_file.write(f"{symbol}\n")
+    }
 
 
-def get_limited_api_definitions(headers):
-    """Run the preprocesor over all the header files in "Include" setting
-    "-DPy_LIMITED_API" to the correct value for the running version of the interpreter.
+def gcc_get_limited_api_definitions(headers):
+    """Get all limited API definitions from headers.
 
-    The limited API symbols will be extracted from the output of this command as it includes
-    the prototypes and definitions of all the exported symbols that are in the limited api.
+    Run the preprocesor over all the header files in "Include" setting
+    "-DPy_LIMITED_API" to the correct value for the running version of the
+    interpreter.
+
+    The limited API symbols will be extracted from the output of this command
+    as it includes the prototypes and definitions of all the exported symbols
+    that are in the limited api.
 
     This function does *NOT* extract the macros defined on the limited API
+
+    Requires Python built with a GCC-compatible compiler. (clang might work)
     """
+    api_hexversion = sys.version_info.major << 24 | sys.version_info.minor << 16
     preprocesor_output = subprocess.check_output(
         sysconfig.get_config_var("CC").split()
         + [
-            # Prevent the expansion of the exported macros so we can capture them later
+            # Prevent the expansion of the exported macros so we can capture
+            # them later
             "-DPyAPI_FUNC=__PyAPI_FUNC",
             "-DPyAPI_DATA=__PyAPI_DATA",
             "-DEXPORT_DATA=__EXPORT_DATA",
             "-D_Py_NO_RETURN=",
             "-DSIZEOF_WCHAR_T=4",  # The actual value is not important
-            f"-DPy_LIMITED_API={sys.version_info.major << 24 | sys.version_info.minor << 16}",
+            f"-DPy_LIMITED_API={api_hexversion}",
             "-I.",
             "-I./Include",
             "-E",
@@ -156,64 +467,126 @@ def get_limited_api_definitions(headers):
         re.findall(r"__EXPORT_DATA\((.*?)\)", preprocesor_output)
     )
     stable_data = set(
-        re.findall(r"__PyAPI_DATA\(.*?\)\s*\(?(.*?)\)?\s*;", preprocesor_output)
+        re.findall(r"__PyAPI_DATA\(.*?\)[\s\*\(]*([^);]*)\)?.*;", preprocesor_output)
     )
-    return stable_data, stable_exported_data, stable_functions
-
-
-def check_symbols(parser_args):
-    with open(parser_args.stable_abi_file, "r") as filename:
-        abi_funcs = {
-            symbol
-            for symbol in filename.read().splitlines()
-            if symbol and not symbol.startswith("#")
-        }
-
-    try:
-        # static library
-        LIBRARY = sysconfig.get_config_var("LIBRARY")
-        if not LIBRARY:
-            raise Exception("failed to get LIBRARY variable from sysconfig")
-        if os.path.exists(LIBRARY):
-            check_library(parser_args.stable_abi_file, LIBRARY, abi_funcs)
-
-        # dynamic library
-        LDLIBRARY = sysconfig.get_config_var("LDLIBRARY")
-        if not LDLIBRARY:
-            raise Exception("failed to get LDLIBRARY variable from sysconfig")
-        if LDLIBRARY != LIBRARY:
-            check_library(
-                parser_args.stable_abi_file, LDLIBRARY, abi_funcs, dynamic=True
-            )
-    except Exception as e:
-        print(e, file=sys.stderr)
-        sys.exit(1)
+    return stable_data | stable_exported_data | stable_functions
 
 
 def main():
-    parser = argparse.ArgumentParser(description="Process some integers.")
-    subparsers = parser.add_subparsers()
-    check_parser = subparsers.add_parser(
-        "check", help="Check the exported symbols against a given ABI file"
+    parser = argparse.ArgumentParser(
+        description=__doc__,
+        formatter_class=argparse.RawDescriptionHelpFormatter,
+    )
+    parser.add_argument(
+        "file", type=Path, metavar='FILE',
+        help="file with the stable abi manifest",
     )
-    check_parser.add_argument(
-        "stable_abi_file", type=str, help="File with the stable abi functions"
+    parser.add_argument(
+        "--generate", action='store_true',
+        help="generate file(s), rather than just checking them",
     )
-    check_parser.set_defaults(func=check_symbols)
-    generate_parser = subparsers.add_parser(
-        "generate",
-        help="Generate symbols from the header files and the exported symbols",
+    parser.add_argument(
+        "--generate-all", action='store_true',
+        help="as --generate, but generate all file(s) using default filenames."
+            + " (unlike --all, does not run any extra checks)",
     )
-    generate_parser.add_argument(
-        "output_file", type=str, help="File to dump the symbols to"
+    parser.add_argument(
+        "-a", "--all", action='store_true',
+        help="run all available checks using default filenames",
+    )
+    parser.add_argument(
+        "-l", "--list", action='store_true',
+        help="list available generators and their default filenames; then exit",
+    )
+    parser.add_argument(
+        "--dump", action='store_true',
+        help="dump the manifest contents (used for debugging the parser)",
+    )
+
+    actions_group = parser.add_argument_group('actions')
+    for gen in generators:
+        actions_group.add_argument(
+            gen.arg_name, dest=gen.var_name,
+            type=str, nargs="?", default=MISSING,
+            metavar='FILENAME',
+            help=gen.__doc__,
+        )
+    actions_group.add_argument(
+        '--unixy-check', action='store_true',
+        help=do_unixy_check.__doc__,
     )
-    generate_parser.set_defaults(func=generate_limited_api_symbols)
     args = parser.parse_args()
-    if "func" not in args:
-        parser.error("Either 'check' or 'generate' must be used")
-        sys.exit(1)
 
-    args.func(args)
+    base_path = args.file.parent.parent
+
+    if args.list:
+        for gen in generators:
+            print(f'{gen.arg_name}: {base_path / gen.default_path}')
+        sys.exit(0)
+
+    run_all_generators = args.generate_all
+
+    if args.generate_all:
+        args.generate = True
+
+    if args.all:
+        run_all_generators = True
+        args.unixy_check = True
+
+    with args.file.open() as file:
+        manifest = parse_manifest(file)
+
+    # Remember results of all actions (as booleans).
+    # At the end we'll check that at least one action was run,
+    # and also fail if any are false.
+    results = {}
+
+    if args.dump:
+        for line in manifest.dump():
+            print(line)
+        results['dump'] = True
+
+    for gen in generators:
+        filename = getattr(args, gen.var_name)
+        if filename is None or (run_all_generators and filename is MISSING):
+            filename = base_path / gen.default_path
+        elif filename is MISSING:
+            continue
+
+        results[gen.var_name] = generate_or_check(manifest, args, filename, gen)
+
+    if args.unixy_check:
+        results['unixy_check'] = do_unixy_check(manifest, args)
+
+    if not results:
+        if args.generate:
+            parser.error('No file specified. Use --help for usage.')
+        parser.error('No check specified. Use --help for usage.')
+
+    failed_results = [name for name, result in results.items() if not result]
+
+    if failed_results:
+        raise Exception(f"""
+        These checks related to the stable ABI did not succeed:
+            {', '.join(failed_results)}
+
+        If you see diffs in the output, files derived from the stable
+        ABI manifest the were not regenerated.
+        Run `make regen-limited-abi` to fix this.
+
+        Otherwise, see the error(s) above.
+
+        The stable ABI manifest is at: {args.file}
+        Note that there is a process to follow when modifying it.
+
+        You can read more about the limited API and its contracts at:
+
+        https://docs.python.org/3/c-api/stable.html
+
+        And in PEP 384:
+
+        https://www.python.org/dev/peps/pep-0384/
+        """)
 
 
 if __name__ == "__main__":



More information about the Python-checkins mailing list