[PATCH 1/3] Fix Python 3.8 problems
authorChristian Tismer <tismer@stackless.com>
Tue, 26 Nov 2019 10:54:37 +0000 (11:54 +0100)
committerKurt Kremitzki <kurt@kwk.systems>
Mon, 18 May 2020 01:27:01 +0000 (02:27 +0100)
This patch fixes some refcounting problems with Python 3.8 .
One incompatible change was announced in the what's new
document, but actually there were two more problems which
were not explicitly mentioned but took much time to sort out.

The patch is compatible with the limited API changes
(tested with debug build and API error disabled).
It is also independent of the Python version which is
full Limited API support.

For more info, see the documentation mentioned below.

The flag error is circumvented now! We either find a better
solution or leave it as it is. For now this is ok.

Fixes: PYSIDE-939
Change-Id: Iff4a9816857a6ebe86efd4b654d8921e4e464939
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Cristian Maureira-Fredes <cristian.maureira-fredes@qt.io>
Gbp-Pq: Name 0002-Fix-Python-3.8-problems.patch

17 files changed:
sources/pyside2/PySide2/QtQml/pysideqmlregistertype.cpp
sources/pyside2/libpyside/pysideclassinfo.cpp
sources/pyside2/libpyside/pysidemetafunction.cpp
sources/pyside2/libpyside/pysideproperty.cpp
sources/pyside2/libpyside/pysideqflags.cpp
sources/pyside2/libpyside/pysidesignal.cpp
sources/pyside2/libpyside/pysideslot.cpp
sources/pyside2/libpyside/pysideweakref.cpp
sources/pyside2/tests/signals/bug_79.py
sources/shiboken2/generator/shiboken2/cppgenerator.cpp
sources/shiboken2/libshiboken/basewrapper.cpp
sources/shiboken2/libshiboken/basewrapper.h
sources/shiboken2/libshiboken/pep384impl.cpp
sources/shiboken2/libshiboken/pep384impl.h
sources/shiboken2/libshiboken/sbkenum.cpp
sources/shiboken2/libshiboken/typespec.cpp
sources/shiboken2/libshiboken/voidptr.cpp

index 6427e5198e87b639f0728c6673fc3c165c563d7c..fb9a5a0cf7ac39ce8df02ada91b5950add6de56d 100644 (file)
@@ -236,7 +236,7 @@ void propListTpFree(void *self)
 static PyType_Slot PropertyListType_slots[] = {
     {Py_tp_init, (void *)propListTpInit},
     {Py_tp_free, (void *)propListTpFree},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PropertyListType_spec = {
@@ -450,7 +450,7 @@ static PyType_Slot QtQml_VolatileBoolType_slots[] = {
     {Py_tp_str, (void *)reinterpret_cast<reprfunc>(QtQml_VolatileBoolObject_str)},
     {Py_tp_methods, (void *)QtQml_VolatileBoolObject_methods},
     {Py_tp_new, (void *)QtQml_VolatileBoolObject_new},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec QtQml_VolatileBoolType_spec = {
index fe5ca87658cd2cdd10f8646e000ced402a28b5da..c4bace77e443a9bf4cdcfd20518bf587033d761c 100644 (file)
@@ -60,7 +60,7 @@ static PyType_Slot PySideClassInfoType_slots[] = {
     {Py_tp_init, (void *)classInfoTpInit},
     {Py_tp_new, (void *)classInfoTpNew},
     {Py_tp_free, (void *)classInfoFree},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideClassInfoType_spec = {
index e0e0c439b3ecc37169cc1fdac64305213702d823..637aa0598848ddd4fa0f35cf354d99a87cd38ff5 100644 (file)
@@ -62,7 +62,7 @@ static PyType_Slot PySideMetaFunctionType_slots[] = {
     {Py_tp_call, (void *)functionCall},
     {Py_tp_new, (void *)PyType_GenericNew},
     {Py_tp_free, (void *)functionFree},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideMetaFunctionType_spec = {
index e1e2c29bf486c00c0112c0a2053e73a57f9ebe64..4d3f450f0ba328cdb2ccc0654d284a79a14b196f 100644 (file)
@@ -210,6 +210,11 @@ int qpropertyTpInit(PyObject *self, PyObject *args, PyObject *kwds)
 void qpropertyDeAlloc(PyObject *self)
 {
     qpropertyClear(self);
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // This was not needed before Python 3.8 (Python issue 35810)
+        Py_DECREF(Py_TYPE(self));
+    }
     Py_TYPE(self)->tp_free(self);
 }
 
index fd0ed005fc95ae4457fd53b9a668f3b759fa4dc1..33351440a85522b3d8046d9b3be8171c1d0f41dd 100644 (file)
@@ -152,7 +152,7 @@ namespace QFlags
 #endif
         {Py_tp_new, (void *)PySideQFlagsNew},
         {Py_tp_richcompare, (void *)PySideQFlagsRichCompare},
-        {Py_tp_dealloc, (void *)object_dealloc},
+        {Py_tp_dealloc, (void *)Sbk_object_dealloc},
         {0, 0}
     };
     static PyType_Spec SbkNewQFlagsType_spec = {
index a09c17a24b8e201a894109a095ffa4c30a547d65..22c27d3df5edddc08f2eeef01dabd18f2a4d17f1 100644 (file)
@@ -109,7 +109,7 @@ static PyType_Slot PySideMetaSignalType_slots[] = {
     {Py_tp_methods, (void *)MetaSignal_methods},
     {Py_tp_base, (void *)&PyType_Type},
     {Py_tp_free, (void *)PyObject_GC_Del},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideMetaSignalType_spec = {
@@ -141,7 +141,7 @@ static PyType_Slot PySideSignalType_slots[] = {
     {Py_tp_init, (void *)signalTpInit},
     {Py_tp_new, (void *)PyType_GenericNew},
     {Py_tp_free, (void *)signalFree},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideSignalType_spec = {
@@ -180,7 +180,7 @@ static PyType_Slot PySideSignalInstanceType_slots[] = {
     {Py_tp_methods, (void *)SignalInstance_methods},
     {Py_tp_new, (void *)PyType_GenericNew},
     {Py_tp_free, (void *)signalInstanceFree},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideSignalInstanceType_spec = {
@@ -615,7 +615,7 @@ void init(PyObject *module)
 {
     if (SbkSpecial_Type_Ready(module, PySideMetaSignalTypeF(), MetaSignal_SignatureStrings) < 0)
         return;
-    Py_INCREF(PySideSignalTypeF());
+    Py_INCREF(PySideMetaSignalTypeF());
     PyModule_AddObject(module, "MetaSignal", reinterpret_cast<PyObject *>(PySideMetaSignalTypeF()));
 
     if (SbkSpecial_Type_Ready(module, PySideSignalTypeF(), Signal_SignatureStrings) < 0)
index 204253aa2a6613b7083d7a0fc643adabd621a9cf..04212a64eaa4504f89ef0dd9d3e4aebfbc27c0c0 100644 (file)
@@ -71,7 +71,7 @@ static PyType_Slot PySideSlotType_slots[] = {
     {Py_tp_call, (void *)slotCall},
     {Py_tp_init, (void *)slotTpInit},
     {Py_tp_new, (void *)PyType_GenericNew},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideSlotType_spec = {
index 2b27f9545bd6db646a708b75551ff55227b5fc5b..faa3abe82afcd5b67b7174ace3860fff74c3eada 100644 (file)
@@ -53,7 +53,7 @@ static PyObject *CallableObject_call(PyObject *callable_object, PyObject *args,
 
 static PyType_Slot PySideCallableObjectType_slots[] = {
     {Py_tp_call, (void *)CallableObject_call},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, 0}
 };
 static PyType_Spec PySideCallableObjectType_spec = {
@@ -94,9 +94,15 @@ PyObject *create(PyObject *obj, PySideWeakRefFunction func, void *userData)
         PyType_Ready(PySideCallableObjectTypeF());
     }
 
-    PySideCallableObject *callable = PyObject_New(PySideCallableObject, PySideCallableObjectTypeF());
+    PyTypeObject *type = PySideCallableObjectTypeF();
+    PySideCallableObject *callable = PyObject_New(PySideCallableObject, type);
     if (!callable || PyErr_Occurred())
         return 0;
+    if (!PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // Workaround for Python issue 35810; no longer necessary in Python 3.8
+        Py_INCREF(type);
+    }
 
     PyObject *weak = PyWeakref_NewRef(obj, reinterpret_cast<PyObject *>(callable));
     if (!weak || PyErr_Occurred())
index 9eb783d77b0ff29d5d58db0ecf874f4b22b05bf1..4a595912c30cd53787b11ed8540f24cad4cef3fe 100644 (file)
@@ -56,13 +56,15 @@ class ConnectTest(unittest.TestCase):
         # if this is no debug build, then we check at least that
         # we do not crash any longer.
         if not skiptest:
-            total = sys.gettotalrefcount()
+            total = gettotalrefcount()
         for idx in range(1000):
             o.selectionModel().destroyed.connect(self.callback)
             o.selectionModel().destroyed.disconnect(self.callback)
         gc.collect()
         if not skiptest:
-            self.assertTrue(abs(gettotalrefcount() - total) < 10)
+            delta = gettotalrefcount() - total
+            print("delta total refcount =", delta)
+            self.assertTrue(abs(delta) < 10)
 
 
 if __name__ == '__main__':
index 61429b383ac3e414ab2b9d0c8d1ace319461d9c8..78f0bc12ea57aa0f6b56d5f0a0becddda090a693 100644 (file)
@@ -3863,7 +3863,7 @@ void CppGenerator::writeClassDefinition(QTextStream &s,
     if (metaClass->isNamespace() || metaClass->hasPrivateDestructor()) {
         tp_dealloc = metaClass->hasPrivateDestructor() ?
                      QLatin1String("SbkDeallocWrapperWithPrivateDtor") :
-                     QLatin1String("object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */");
+                     QLatin1String("Sbk_object_dealloc /* PYSIDE-832: Prevent replacement of \"0\" with subtype_dealloc. */");
         tp_init.clear();
     } else {
         QString deallocClassName;
index 9d233b847f2df581d346af03b58875bca31be56c..e9bef07f90e2395a1d5a39e9be67ef341e4e5b07 100644 (file)
 #include "qapp_macro.h"
 #include "voidptr.h"
 
+#if defined(__APPLE__)
+#include <dlfcn.h>
+#endif
+
 namespace {
     void _destroyParentInfo(SbkObject *obj, bool keepReference);
 }
@@ -73,6 +77,17 @@ static void callDestructor(const Shiboken::DtorAccumulatorVisitor::DestructorEnt
 extern "C"
 {
 
+// PYSIDE-939: A general replacement for object_dealloc.
+void Sbk_object_dealloc(PyObject *self)
+{
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // This was not needed before Python 3.8 (Python issue 35810)
+        Py_DECREF(Py_TYPE(self));
+    }
+    Py_TYPE(self)->tp_free(self);
+}
+
 static void SbkObjectTypeDealloc(PyObject *pyObj);
 static PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds);
 
@@ -309,8 +324,32 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
     // Need to decref the type if this is the dealloc func; if type
     // is subclassed, that dealloc func will decref (see subtype_dealloc
     // in typeobject.c in the python sources)
-    bool needTypeDecref = (PyType_GetSlot(pyType, Py_tp_dealloc) == SbkDeallocWrapper
+    bool needTypeDecref = (false
+                           || PyType_GetSlot(pyType, Py_tp_dealloc) == SbkDeallocWrapper
                            || PyType_GetSlot(pyType, Py_tp_dealloc) == SbkDeallocWrapperWithPrivateDtor);
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Additional rule: Also when a subtype is heap allocated,
+        // then the subtype_dealloc deref will be suppressed, and we need again
+        // to supply a decref.
+        needTypeDecref |= (pyType->tp_base->tp_flags & Py_TPFLAGS_HEAPTYPE) != 0;
+    }
+
+#if defined(__APPLE__)
+    // Just checking once that our assumptions are right.
+    if (false) {
+        void *p = PyType_GetSlot(pyType, Py_tp_dealloc);
+        Dl_info dl_info;
+        dladdr(p, &dl_info);
+        fprintf(stderr, "tp_dealloc is %s\n", dl_info.dli_sname);
+    }
+    // Gives one of our functions
+    //  "Sbk_object_dealloc"
+    //  "SbkDeallocWrapperWithPrivateDtor"
+    //  "SbkDeallocQAppWrapper"
+    //  "SbkDeallocWrapper"
+    // but for typedealloc_test.py we get
+    //  "subtype_dealloc"
+#endif
 
     // Ensure that the GC is no longer tracking this object to avoid a
     // possible reentrancy problem.  Since there are multiple steps involved
@@ -369,6 +408,11 @@ static void SbkDeallocWrapperCommon(PyObject *pyObj, bool canDelete)
 
     if (needTypeDecref)
         Py_DECREF(pyType);
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // This was not needed before Python 3.8 (Python issue 35810)
+        Py_DECREF(pyType);
+    }
 }
 
 void SbkDeallocWrapper(PyObject *pyObj)
@@ -412,6 +456,11 @@ void SbkObjectTypeDealloc(PyObject *pyObj)
 #ifndef Py_LIMITED_API
     Py_TRASHCAN_SAFE_END(pyObj);
 #endif
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // This was not needed before Python 3.8 (Python issue 35810)
+        Py_DECREF(Py_TYPE(pyObj));
+    }
 }
 
 PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
@@ -453,7 +502,16 @@ PyObject *SbkObjectTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *k
 
     // The meta type creates a new type when the Python programmer extends a wrapped C++ class.
     auto type_new = reinterpret_cast<newfunc>(PyType_Type.tp_new);
+
+    // PYSIDE-939: This is a temporary patch that circumvents the problem
+    // with Py_TPFLAGS_METHOD_DESCRIPTOR until this is finally solved.
+    PyObject *ob_PyType_Type = reinterpret_cast<PyObject *>(&PyType_Type);
+    PyObject *mro = PyObject_GetAttr(ob_PyType_Type, Shiboken::PyName::mro());
+    auto hold = Py_TYPE(mro)->tp_flags;
+    Py_TYPE(mro)->tp_flags &= ~Py_TPFLAGS_METHOD_DESCRIPTOR;
     auto *newType = reinterpret_cast<SbkObjectType *>(type_new(metatype, args, kwds));
+    Py_TYPE(mro)->tp_flags = hold;
+
     if (!newType)
         return nullptr;
 #if PY_VERSION_HEX < 0x03000000
@@ -554,12 +612,6 @@ PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *, PyObject *)
     return self == nullptr ? nullptr : _setupNew(self, subtype);
 }
 
-void
-object_dealloc(PyObject *self)
-{
-    Py_TYPE(self)->tp_free(self);
-}
-
 PyObject *
 SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *)
 {
index 7faf223bd2f558e7d0037ecd13b124c46b49e8d0..813870dac464764e8771149131facee782c299a2 100644 (file)
@@ -64,6 +64,9 @@ struct LIBSHIBOKEN_API SbkObject
 };
 
 
+/// PYSIDE-939: A general replacement for object_dealloc.
+LIBSHIBOKEN_API void Sbk_object_dealloc(PyObject *self);
+
 /// Dealloc the python object \p pyObj and the C++ object represented by it.
 LIBSHIBOKEN_API void SbkDeallocWrapper(PyObject *pyObj);
 LIBSHIBOKEN_API void SbkDeallocQAppWrapper(PyObject *pyObj);
@@ -116,7 +119,7 @@ LIBSHIBOKEN_API PyObject *SbkQAppTpNew(PyTypeObject *subtype, PyObject *args, Py
  *  nullptr. But the default before conversion to heaptypes was to assign
  *  object_dealloc. This seems to be a bug in the Limited API.
  */
-LIBSHIBOKEN_API void object_dealloc(PyObject *);
+/// PYSIDE-939: Replaced by Sbk_object_dealloc.
 LIBSHIBOKEN_API PyObject *SbkDummyNew(PyTypeObject *type, PyObject *, PyObject *);
 
 } // extern "C"
index fe7157d2417ed5c5abb0826e134263bcf41da61e..b2584fd7735c095133c3e3f7b3ffd0cfaf299b0f 100644 (file)
@@ -39,6 +39,8 @@
 
 #include "pep384impl.h"
 #include "autodecref.h"
+#include <stdlib.h>
+
 
 extern "C"
 {
@@ -156,7 +158,8 @@ check_PyTypeObject_valid()
         || probe_tp_free            != check->tp_free
         || probe_tp_is_gc           != check->tp_is_gc
         || probe_tp_bases           != typetype->tp_bases
-        || probe_tp_mro             != typetype->tp_mro)
+        || probe_tp_mro             != typetype->tp_mro
+        || Py_TPFLAGS_DEFAULT       != (check->tp_flags & Py_TPFLAGS_DEFAULT))
         Py_FatalError("The structure of type objects has changed!");
     Py_DECREF(check);
     Py_DECREF(probe_tp_base);
@@ -661,6 +664,25 @@ _Pep_PrivateMangle(PyObject *self, PyObject *name)
 #endif  // Py_LIMITED_API
 }
 
+/*****************************************************************************
+ *
+ * Runtime support for Python 3.8 incompatibilities
+ *
+ */
+
+int PepRuntime_38_flag = 0;
+
+static void
+init_PepRuntime()
+{
+    // We expect a string of the form "\d\.\d+\."
+    const char *version = Py_GetVersion();
+    if (version[0] < '3')
+        return;
+    if (std::atoi(version + 2) >= 8)
+        PepRuntime_38_flag = 1;
+}
+
 /*****************************************************************************
  *
  * Module Initialization
@@ -671,6 +693,7 @@ void
 Pep384_Init()
 {
     check_PyTypeObject_valid();
+    init_PepRuntime();
 #ifdef Py_LIMITED_API
     Pep_GetVerboseFlag();
     PepMethod_TypePtr = getMethodType();
index 93f7189885d0fb1d4efd9d0be5af9db63d49a13b..dfad8ccded05d7bd0cf1bde9c463693ad12d1bcc 100644 (file)
@@ -89,7 +89,7 @@ typedef struct _typeobject {
     Py_ssize_t tp_basicsize;
     void *X03; // Py_ssize_t tp_itemsize;
     void *X04; // destructor tp_dealloc;
-    void *X05; // printfunc tp_print;
+    void *X05; // Py_ssize_t tp_vectorcall_offset;
     void *X06; // getattrfunc tp_getattr;
     void *X07; // setattrfunc tp_setattr;
     void *X08; // PyAsyncMethods *tp_as_async;
@@ -103,7 +103,7 @@ typedef struct _typeobject {
     void *X16; // getattrofunc tp_getattro;
     void *X17; // setattrofunc tp_setattro;
     void *X18; // PyBufferProcs *tp_as_buffer;
-    void *X19; // unsigned long tp_flags;
+    unsigned long tp_flags;
     void *X20; // const char *tp_doc;
     traverseproc tp_traverse;
     inquiry tp_clear;
@@ -129,6 +129,13 @@ typedef struct _typeobject {
 
 } PyTypeObject;
 
+#ifndef PyObject_IS_GC
+/* Test if an object has a GC head */
+#define PyObject_IS_GC(o) \
+    (PyType_IS_GC(Py_TYPE(o)) \
+     && (Py_TYPE(o)->tp_is_gc == NULL || Py_TYPE(o)->tp_is_gc(o)))
+#endif
+
 // This was a macro error in the limited API from the beginning.
 // It was fixed in Python master, but did make it only in Python 3.8 .
 #define PY_ISSUE33738_SOLVED 0x03080000
@@ -292,7 +299,7 @@ LIBSHIBOKEN_API PyObject *PyRun_String(const char *, int, PyObject *, PyObject *
 // But this is no problem as we check it's validity for every version.
 
 #define PYTHON_BUFFER_VERSION_COMPATIBLE    (PY_VERSION_HEX >= 0x03030000 && \
-                                             PY_VERSION_HEX <  0x0307FFFF)
+                                             PY_VERSION_HEX <  0x0308FFFF)
 #if !PYTHON_BUFFER_VERSION_COMPATIBLE
 # error Please check the buffer compatibility for this python version!
 #endif
@@ -486,6 +493,19 @@ extern LIBSHIBOKEN_API PyTypeObject *PepMethodDescr_TypePtr;
 #define PepMethodDescr_TypePtr &PyMethodDescr_Type
 #endif
 
+/*****************************************************************************
+ *
+ * Runtime support for Python 3.8 incompatibilities
+ *
+ */
+
+#ifndef Py_TPFLAGS_METHOD_DESCRIPTOR
+/* Objects behave like an unbound method */
+#define Py_TPFLAGS_METHOD_DESCRIPTOR (1UL << 17)
+#endif
+
+extern LIBSHIBOKEN_API int PepRuntime_38_flag;
+
 /*****************************************************************************
  *
  * Module Initialization
index 2dc785884ff4cfd1d31a73d9b0b39a274b4b68e4..ec40802379e05b3959e1456568666d036fc91017 100644 (file)
@@ -321,6 +321,11 @@ void SbkEnumTypeDealloc(PyObject *pyObj)
 #ifndef Py_LIMITED_API
     Py_TRASHCAN_SAFE_END(pyObj);
 #endif
+    if (PepRuntime_38_flag) {
+        // PYSIDE-939: Handling references correctly.
+        // This was not needed before Python 3.8 (Python issue 35810)
+        Py_DECREF(Py_TYPE(pyObj));
+    }
 }
 
 PyObject *SbkEnumTypeTpNew(PyTypeObject *metatype, PyObject *args, PyObject *kwds)
@@ -519,7 +524,7 @@ static PyType_Slot SbkNewType_slots[] = {
     {Py_nb_index, (void *)enum_int},
     {Py_tp_richcompare, (void *)enum_richcompare},
     {Py_tp_hash, (void *)enum_hash},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {0, nullptr}
 };
 static PyType_Spec SbkNewType_spec = {
index 6dc5b00bcd7047b838987d7d8c048cd2a36935cf..a1d4d6ca8fd05133a4401e0c04371cc67320f38b 100644 (file)
@@ -713,7 +713,7 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
     if (PyType_Ready(type) < 0)
         goto fail;
 
-    // no ht_hached_keys in Python 2
+    // no ht_cached_keys in Python 2
     // if (type->tp_dictoffset) {
     //     res->ht_cached_keys = _PyDict_NewKeysForClass();
     // }
index d4ce58c872b5c847366c2c36493172df1f07b903..46f49b67eb35d359b51134b28ae3e3fe6795fcda 100644 (file)
@@ -335,7 +335,7 @@ static PyType_Slot SbkVoidPtrType_slots[] = {
     {Py_tp_richcompare, (void *)SbkVoidPtrObject_richcmp},
     {Py_tp_init, (void *)SbkVoidPtrObject_init},
     {Py_tp_new, (void *)SbkVoidPtrObject_new},
-    {Py_tp_dealloc, (void *)object_dealloc},
+    {Py_tp_dealloc, (void *)Sbk_object_dealloc},
     {Py_tp_methods, (void *)SbkVoidPtrObject_methods},
     {0, nullptr}
 };