From 46f64c74a517de56bd25cf4a3c01309c0d68c798 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 14:48:23 +0100 Subject: [PATCH 01/35] Remove obsolete single_module flag --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index e07e775..6000dcd 100644 --- a/test/Makefile +++ b/test/Makefile @@ -26,7 +26,7 @@ cppflags= -std=c++17 -O3 -fPIC -I$(shell $(PYTHON) -c 'import sysconfig as sc; p PLATFORM := $(shell uname -s) ifeq ($(PLATFORM),Darwin) - cppflags+=-dynamiclib -single_module -undefined dynamic_lookup -Wno-delete-non-virtual-dtor + cppflags+=-dynamiclib -undefined dynamic_lookup -Wno-delete-non-virtual-dtor endif cpp/%Dict.so: cpp/%.cxx From 11b4b130dcb9a7c8c457979bd21e7623faea327d Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 16:39:45 +0100 Subject: [PATCH 02/35] Update warning flags and update test standard to C++20 --- CMakeLists.txt | 2 +- test/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 50403dc..ba4098f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -139,7 +139,7 @@ target_include_directories(cppjit PRIVATE ) target_compile_options(cppjit PRIVATE - -Wall -Wno-strict-aliasing -Wno-register + -Wall -Wextra -Wno-strict-aliasing -Wno-register -Werror ) if(CMAKE_COMPILER_IS_GNUCXX) diff --git a/test/Makefile b/test/Makefile index 6000dcd..d9fe041 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,7 +22,7 @@ dicts = $(addprefix cpp/,$(addsuffix Dict.so,$(dictnames))) all : $(dicts) PYTHON ?= python3 -cppflags= -std=c++17 -O3 -fPIC -I$(shell $(PYTHON) -c 'import sysconfig as sc; print(sc.get_config_var("INCLUDEPY"))') -Wno-register +cppflags= -Wall -Wextra -Werror -std=c++20 -O3 -fPIC -I$(shell $(PYTHON) -c 'import sysconfig as sc; print(sc.get_config_var("INCLUDEPY"))') -Wno-register PLATFORM := $(shell uname -s) ifeq ($(PLATFORM),Darwin) From 61a80ae79540c494c9d69d7340642b84cbb0994a Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 18:23:24 +0100 Subject: [PATCH 03/35] Try new fix --- src/cpyrt/CPPEnum.cxx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpyrt/CPPEnum.cxx b/src/cpyrt/CPPEnum.cxx index 6585265..f64dad8 100644 --- a/src/cpyrt/CPPEnum.cxx +++ b/src/cpyrt/CPPEnum.cxx @@ -139,7 +139,7 @@ static PyTypeObject* GetCTypesType(const std::string& cppname) { return (PyTypeObject*)PyObject_GetAttrString(ctmod, nn->second.c_str()); } -static PyObject* enum_ctype(PyObject* cls, PyObject* args, PyObject* kwds) { +static PyObject* enum_ctype(PyObject* cls, PyObject* args) { PyObject* pyres = PyObject_GetAttr(cls, cpyrt::PyStrings::gUnderlying); if (!pyres) PyErr_Clear(); @@ -149,7 +149,7 @@ static PyObject* enum_ctype(PyObject* cls, PyObject* args, PyObject* kwds) { if (!ct) return nullptr; - return PyType_Type.tp_call((PyObject*)ct, args, kwds); + return PyType_Type.tp_call((PyObject*)ct, args, nullptr); } //- creation ----------------------------------------------------------------- @@ -213,7 +213,7 @@ cpyrt::CPPEnum* cpyrt::CPPEnum_New(const std::string& name, // add pythonizations Utility::AddToClass((PyObject*)Py_TYPE(pyenum), "__ctype__", - (PyCFunction)enum_ctype, METH_VARARGS | METH_KEYWORDS); + enum_ctype, METH_VARARGS); ((PyTypeObject*)pyenum)->tp_repr = enum_repr; ((PyTypeObject*)pyenum)->tp_str = ((PyTypeObject*)pyside_type)->tp_repr; From fedc92b16b83be83a8a77c69dc24c316d0593383 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 18:47:44 +0100 Subject: [PATCH 04/35] Try to fix more warnings --- src/cpyrt/CPPInstance.cxx | 33 +++++++++++++++++---------------- 1 file changed, 17 insertions(+), 16 deletions(-) diff --git a/src/cpyrt/CPPInstance.cxx b/src/cpyrt/CPPInstance.cxx index 59cde8a..9d9c9d7 100644 --- a/src/cpyrt/CPPInstance.cxx +++ b/src/cpyrt/CPPInstance.cxx @@ -270,18 +270,17 @@ static int op_nonzero(CPPInstance* self) { } //= cpyrt object explicit destruction ===================================== -static PyObject* op_destruct(CPPInstance* self) { +static PyObject* op_destruct(PyObject* self, PyObject* /*args*/) { // User access to force deletion of the object. Needed in case of a true // garbage collector (like in PyPy), to allow the user control over when // the C++ destructor is called. This method requires that the C++ object // is owned (no-op otherwise). - op_dealloc_nofree(self); + op_dealloc_nofree((CPPInstance*)self); Py_RETURN_NONE; } //= cpyrt object dispatch support ========================================= -static PyObject* op_dispatch(PyObject* self, PyObject* args, - PyObject* /* kdws */) { +static PyObject* op_dispatch(PyObject* self, PyObject* args) { // User-side __dispatch__ method to allow selection of a specific overloaded // method. The actual selection is in the __overload__() method of // CPPOverload. @@ -312,13 +311,14 @@ static PyObject* op_dispatch(PyObject* self, PyObject* args, } //= cpyrt smart pointer support =========================================== -static PyObject* op_get_smartptr(CPPInstance* self) { - if (!self->IsSmart()) { +static PyObject* op_get_smartptr(PyObject* self, PyObject* /*args*/) { + CPPInstance* inst = (CPPInstance*)self; + if (!inst->IsSmart()) { // TODO: more likely should raise Py_RETURN_NONE; } - return cpyrt::BindCppObjectNoCast(self->GetSmartObject(), SMART_TYPE(self), + return cpyrt::BindCppObjectNoCast(inst->GetSmartObject(), SMART_TYPE(inst), CPPInstance::kNoWrapConv); } @@ -335,7 +335,8 @@ Py_ssize_t cpyrt::CPPInstance::ArrayLength() { return (Py_ssize_t)ARRAY_SIZE(this); } -static PyObject* op_reshape(CPPInstance* self, PyObject* shape) { +static PyObject* op_reshape(PyObject* self, PyObject* shape) { + CPPInstance* inst = (CPPInstance*)self; // Allow the user to fix up the actual (type-strided) size of the buffer. if (!PyTuple_Check(shape) || PyTuple_GET_SIZE(shape) != 1) { PyErr_SetString(PyExc_TypeError, "tuple object of size 1 expected"); @@ -348,7 +349,7 @@ static PyObject* op_reshape(CPPInstance* self, PyObject* shape) { return nullptr; } - self->CastToArray(sz); + inst->CastToArray(sz); Py_RETURN_NONE; } @@ -417,26 +418,26 @@ PyCFunction& CPPInstance::ReduceMethod() { return reducer; } -PyObject* op_reduce(PyObject* self, PyObject* args) { +PyObject* op_reduce(PyObject* self, PyObject* /*args*/) { auto& reducer = CPPInstance::ReduceMethod(); if (!reducer) { PyErr_SetString(PyExc_NotImplementedError, ""); return nullptr; } - return reducer(self, args); + return reducer(self, nullptr); } //---------------------------------------------------------------------------- static PyMethodDef op_methods[] = { - {(char*)"__destruct__", (PyCFunction)op_destruct, METH_NOARGS, + {(char*)"__destruct__", op_destruct, METH_NOARGS, (char*)"call the C++ destructor"}, - {(char*)"__dispatch__", (PyCFunction)op_dispatch, METH_VARARGS, + {(char*)"__dispatch__", op_dispatch, METH_VARARGS, (char*)"dispatch to selected overload"}, - {(char*)"__smartptr__", (PyCFunction)op_get_smartptr, METH_NOARGS, + {(char*)"__smartptr__", op_get_smartptr, METH_NOARGS, (char*)"get associated smart pointer, if any"}, - {(char*)"__reduce__", (PyCFunction)op_reduce, METH_NOARGS, + {(char*)"__reduce__", op_reduce, METH_NOARGS, (char*)"reduce method for serialization"}, - {(char*)"__reshape__", (PyCFunction)op_reshape, METH_O, + {(char*)"__reshape__", op_reshape, METH_O, (char*)"cast pointer to 1D array type"}, {(char*)nullptr, nullptr, 0, nullptr}}; From 06a180b0b833d205105c74568aca7cacff65f72f Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 18:58:40 +0100 Subject: [PATCH 05/35] Try to fix more warnings --- src/cpyrt/CPPOverload.cxx | 52 ++++++++++++++++++++++++--------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/cpyrt/CPPOverload.cxx b/src/cpyrt/CPPOverload.cxx index 49778df..cbe1053 100644 --- a/src/cpyrt/CPPOverload.cxx +++ b/src/cpyrt/CPPOverload.cxx @@ -218,18 +218,20 @@ static inline PyObject* HandleReturn(CPPOverload* pymeth, CPPInstance* im_self, } //= cpyrt method proxy object behaviour =================================== -static PyObject* mp_name(CPPOverload* pymeth, void*) { +static PyObject* mp_name(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; return cpyrt_PyText_FromString(pymeth->GetName().c_str()); } //---------------------------------------------------------------------------- -static PyObject* mp_module(CPPOverload* /* pymeth */, void*) { +static PyObject* mp_module(PyObject*, void*) { Py_INCREF(PyStrings::gThisModule); return PyStrings::gThisModule; } //---------------------------------------------------------------------------- -static PyObject* mp_doc(CPPOverload* pymeth, void*) { +static PyObject* mp_doc(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; if (pymeth->fMethodInfo->fDoc) { Py_INCREF(pymeth->fMethodInfo->fDoc); return pymeth->fMethodInfo->fDoc; @@ -259,7 +261,8 @@ static PyObject* mp_doc(CPPOverload* pymeth, void*) { return doc; } -static int mp_doc_set(CPPOverload* pymeth, PyObject* val, void*) { +static int mp_doc_set(PyObject* self, PyObject* val, void*) { + CPPOverload* pymeth = (CPPOverload*)self; Py_XDECREF(pymeth->fMethodInfo->fDoc); Py_INCREF(val); pymeth->fMethodInfo->fDoc = val; @@ -276,8 +279,8 @@ static int mp_doc_set(CPPOverload* pymeth, PyObject* val, void*) { * 'int ::foo(int a)': ('a',), * 'int ::foo(int a, float b)': ('a', 'b')} */ -static PyObject* mp_func_overloads_names(CPPOverload* pymeth) { - +static PyObject* mp_func_overloads_names(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; const CPPOverload::Methods_t& methods = pymeth->fMethodInfo->fMethods; PyObject* overloads_names_dict = PyDict_New(); @@ -301,8 +304,8 @@ static PyObject* mp_func_overloads_names(CPPOverload* pymeth) { * ('int',), 'return_type': 'int'}, 'int ::foo(int a, float b)': {'input_types': * ('int', 'float'), 'return_type': 'int'}} */ -static PyObject* mp_func_overloads_types(CPPOverload* pymeth) { - +static PyObject* mp_func_overloads_types(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; const CPPOverload::Methods_t& methods = pymeth->fMethodInfo->fMethods; PyObject* overloads_types_dict = PyDict_New(); @@ -316,7 +319,8 @@ static PyObject* mp_func_overloads_types(CPPOverload* pymeth) { } //---------------------------------------------------------------------------- -static PyObject* mp_meth_func(CPPOverload* pymeth, void*) { +static PyObject* mp_meth_func(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Create a new method proxy to be returned. CPPOverload* newPyMeth = (CPPOverload*)CPPOverload_Type.tp_alloc(&CPPOverload_Type, 0); @@ -333,7 +337,8 @@ static PyObject* mp_meth_func(CPPOverload* pymeth, void*) { } //---------------------------------------------------------------------------- -static PyObject* mp_meth_self(CPPOverload* pymeth, void*) { +static PyObject* mp_meth_self(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Return the bound self, if any; in case of pseudo-function role, pretend // that the data member im_self does not exist. if (IsPseudoFunc(pymeth)) { @@ -350,7 +355,8 @@ static PyObject* mp_meth_self(CPPOverload* pymeth, void*) { } //---------------------------------------------------------------------------- -static PyObject* mp_meth_class(CPPOverload* pymeth, void*) { +static PyObject* mp_meth_class(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Return scoping class; in case of pseudo-function role, pretend that there // is no encompassing class (i.e. global scope). if (!IsPseudoFunc(pymeth) && pymeth->fMethodInfo->fMethods.size()) { @@ -366,13 +372,13 @@ static PyObject* mp_meth_class(CPPOverload* pymeth, void*) { } //---------------------------------------------------------------------------- -static PyObject* mp_func_closure(CPPOverload* /* pymeth */, void*) { +static PyObject* mp_func_closure(PyObject*, void*) { // Stub only, to fill out the python function interface. Py_RETURN_NONE; } //---------------------------------------------------------------------------- -static PyObject* mp_func_code(CPPOverload*, void*) { +static PyObject* mp_func_code(PyObject*, void*) { // Code details are used in module inspect to fill out interactive help() // not important for functioning of most code, so not implemented for p3 for // now (TODO) @@ -380,7 +386,8 @@ static PyObject* mp_func_code(CPPOverload*, void*) { } //---------------------------------------------------------------------------- -static PyObject* mp_func_defaults(CPPOverload* pymeth, void*) { +static PyObject* mp_func_defaults(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Create a tuple of default values, if there is only one method (otherwise // leave undefined: this is only used by inspect for interactive help()) CPPOverload::Methods_t& methods = pymeth->fMethodInfo->fMethods; @@ -406,7 +413,7 @@ static PyObject* mp_func_defaults(CPPOverload* pymeth, void*) { } //---------------------------------------------------------------------------- -static PyObject* mp_func_globals(CPPOverload* /* pymeth */, void*) { +static PyObject* mp_func_globals(PyObject*, void*) { // Return this function's global dict (hard-wired to be the cppjit module); // used for lookup of names from co_code indexing into co_names. PyObject* pyglobal = PyModule_GetDict(PyImport_AddModule((char*)"cppjit")); @@ -438,19 +445,22 @@ static inline int set_flag(CPPOverload* pymeth, PyObject* value, } //---------------------------------------------------------------------------- -static PyObject* mp_getcreates(CPPOverload* pymeth, void*) { +static PyObject* mp_getcreates(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Get '__creates__' boolean, which determines ownership of return values. return PyInt_FromLong((long)IsCreator(pymeth->fMethodInfo->fFlags)); } //---------------------------------------------------------------------------- -static int mp_setcreates(CPPOverload* pymeth, PyObject* value, void*) { +static int mp_setcreates(PyObject* self, PyObject* value, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Set '__creates__' boolean, which determines ownership of return values. return set_flag(pymeth, value, CallContext::kIsCreator, "__creates__"); } //---------------------------------------------------------------------------- -static PyObject* mp_getmempolicy(CPPOverload* pymeth, void*) { +static PyObject* mp_getmempolicy(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Get '_mempolicy' enum, which determines ownership of call arguments. if (pymeth->fMethodInfo->fFlags & CallContext::kUseHeuristics) return PyInt_FromLong(CallContext::kUseHeuristics); @@ -462,7 +472,8 @@ static PyObject* mp_getmempolicy(CPPOverload* pymeth, void*) { } //---------------------------------------------------------------------------- -static int mp_setmempolicy(CPPOverload* pymeth, PyObject* value, void*) { +static int mp_setmempolicy(PyObject* self, PyObject* value, void*) { + CPPOverload* pymeth = (CPPOverload*)self; // Set '_mempolicy' enum, which determines ownership of call arguments. long mempolicy = PyLong_AsLong(value); if (mempolicy == CallContext::kUseHeuristics) { @@ -501,7 +512,8 @@ CPPJIT_BOOLEAN_PROPERTY(useffi, CallContext::kUseFFI, "__useffi__") CPPJIT_BOOLEAN_PROPERTY(sig2exc, CallContext::kProtected, "__sig2exc__") // clang-format on -static PyObject* mp_getcppname(CPPOverload* pymeth, void*) { +static PyObject* mp_getcppname(PyObject* self, void*) { + CPPOverload* pymeth = (CPPOverload*)self; if ((void*)pymeth == (void*)&CPPOverload_Type) return cpyrt_PyText_FromString("CPPOverload_Type"); From 7bbe7ab13d89cc9e5cdeb759680aa01ae4b0f776 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 19:09:25 +0100 Subject: [PATCH 06/35] Try to fix error --- src/cpyrt/CPPScope.cxx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/cpyrt/CPPScope.cxx b/src/cpyrt/CPPScope.cxx index fded0d5..7dc2b79 100644 --- a/src/cpyrt/CPPScope.cxx +++ b/src/cpyrt/CPPScope.cxx @@ -614,7 +614,8 @@ static PyObject* meta_reflex(CPPScope* klass, PyObject* args) { // quite what I'd expected of it, so the following pulls in the internal code #include "PyObjectDir27.inc" -static PyObject* meta_dir(CPPScope* klass) { +static PyObject* meta_dir(PyObject* self, PyObject*) { + CPPScope* klass = (CPPScope*)self; // Collect a list of everything (currently) available in the namespace. // The backend can filter by returning empty strings. Special care is // taken for functions, which need not be unique (overloading). @@ -664,7 +665,7 @@ static PyObject* meta_dir(CPPScope* klass) { static PyMethodDef meta_methods[] = { {(char*)"__cpp_reflex__", (PyCFunction)meta_reflex, METH_VARARGS, (char*)"C++ datamember reflection information"}, - {(char*)"__dir__", (PyCFunction)meta_dir, METH_NOARGS, nullptr}, + {(char*)"__dir__", meta_dir, METH_NOARGS, nullptr}, {(char*)nullptr, nullptr, 0, nullptr}}; //----------------------------------------------------------------------------- From 1adc6fbca31032d32399498846c1f7452b84842a Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:18:33 +0100 Subject: [PATCH 07/35] Try fixes --- src/cpyrt/LowLevelViews.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index b4b5be1..bd408c5 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -828,7 +828,7 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, } //--------------------------------------------------------------------------- -static PyObject* ll_as_string(cpyrt::LowLevelView* self) { +static PyObject* ll_as_string(cpyrt::LowLevelView* self, PyObject*) { // Interpret memory as a null-terminated char string. Py_buffer& view = self->fBufInfo; @@ -847,12 +847,12 @@ static PyObject* ll_as_string(cpyrt::LowLevelView* self) { //--------------------------------------------------------------------------- static PyMethodDef ll_methods[] = { - {(char*)"reshape", (PyCFunction)ll_reshape, METH_O, + {(char*)"reshape", ll_reshape, METH_O, (char*)"change the shape (not layout) of the low level view"}, - {(char*)"as_string", (PyCFunction)ll_as_string, METH_NOARGS, + {(char*)"as_string", ll_as_string, METH_NOARGS, (char*)"interpret memory as a null-terminated char string and return " "Python str"}, - {(char*)"__array__", (PyCFunction)ll_array, METH_VARARGS | METH_KEYWORDS, + {(char*)"__array__", ll_array, METH_VARARGS | METH_KEYWORDS, (char*)"return a numpy array from the low level view"}, {(char*)nullptr, nullptr, 0, nullptr}}; From 25f32dabe6fd2110b70f2d29f665b048e12e54e3 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:21:14 +0100 Subject: [PATCH 08/35] Revert "Try fixes" This reverts commit 1adc6fbca31032d32399498846c1f7452b84842a. --- src/cpyrt/LowLevelViews.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index bd408c5..b4b5be1 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -828,7 +828,7 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, } //--------------------------------------------------------------------------- -static PyObject* ll_as_string(cpyrt::LowLevelView* self, PyObject*) { +static PyObject* ll_as_string(cpyrt::LowLevelView* self) { // Interpret memory as a null-terminated char string. Py_buffer& view = self->fBufInfo; @@ -847,12 +847,12 @@ static PyObject* ll_as_string(cpyrt::LowLevelView* self, PyObject*) { //--------------------------------------------------------------------------- static PyMethodDef ll_methods[] = { - {(char*)"reshape", ll_reshape, METH_O, + {(char*)"reshape", (PyCFunction)ll_reshape, METH_O, (char*)"change the shape (not layout) of the low level view"}, - {(char*)"as_string", ll_as_string, METH_NOARGS, + {(char*)"as_string", (PyCFunction)ll_as_string, METH_NOARGS, (char*)"interpret memory as a null-terminated char string and return " "Python str"}, - {(char*)"__array__", ll_array, METH_VARARGS | METH_KEYWORDS, + {(char*)"__array__", (PyCFunction)ll_array, METH_VARARGS | METH_KEYWORDS, (char*)"return a numpy array from the low level view"}, {(char*)nullptr, nullptr, 0, nullptr}}; From 5801bffcd992ad6d012fc38dc052a30f8dd9febe Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:40:53 +0100 Subject: [PATCH 09/35] Try partial fix --- src/cpyrt/LowLevelViews.cxx | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index b4b5be1..73b1acd 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -692,7 +692,8 @@ static PyObject* ll_shape(cpyrt::LowLevelView* self) { } //--------------------------------------------------------------------------- -static PyObject* ll_reshape(cpyrt::LowLevelView* self, PyObject* shape) { +static PyObject* ll_reshape(PyObject* self, PyObject* shape) { + cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; // Allow the user to fix up the actual (type-strided) size of the buffer. if (!PyTuple_Check(shape)) { if (shape) { @@ -708,7 +709,7 @@ static PyObject* ll_reshape(cpyrt::LowLevelView* self, PyObject* shape) { return nullptr; } - Py_buffer& view = self->fBufInfo; + Py_buffer& view = inst->fBufInfo; // verify size match Py_ssize_t oldsz = 0; @@ -764,8 +765,9 @@ static PyObject* ll_reshape(cpyrt::LowLevelView* self, PyObject* shape) { } //--------------------------------------------------------------------------- -static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, +static PyObject* ll_array(PyObject* self, PyObject* args, PyObject* kwds) { + cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; // Construct a numpy array from the lowlevelview (w/o copy if possible); this // uses the Python methods to avoid depending on numpy directly @@ -793,7 +795,7 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, PyObject* dtype; if (!args || PyTuple_GET_SIZE(args) != 1) { PyObject* npdtype = PyObject_GetAttr(npmod, cpyrt::PyStrings::gDType); - PyObject* typecode = ll_typecode(self, nullptr); + PyObject* typecode = ll_typecode(inst, nullptr); dtype = PyObject_CallFunctionObjArgs(npdtype, typecode, nullptr); Py_DECREF(typecode); Py_DECREF(npdtype); @@ -807,7 +809,7 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, PyObject* npfrombuf = PyObject_GetAttr(npmod, cpyrt::PyStrings::gFromBuffer); - PyObject* view = PyObject_CallFunctionObjArgs(npfrombuf, (PyObject*)self, + PyObject* view = PyObject_CallFunctionObjArgs(npfrombuf, (PyObject*)inst, dtype, nullptr); Py_DECREF(dtype); Py_DECREF(npfrombuf); @@ -817,7 +819,7 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, } else { // copy requested PyObject* npcopy = PyObject_GetAttr(npmod, cpyrt::PyStrings::gCopy); PyObject* newarr = - PyObject_CallFunctionObjArgs(npcopy, (PyObject*)self, nullptr); + PyObject_CallFunctionObjArgs(npcopy, (PyObject*)inst, nullptr); Py_DECREF(npcopy); return newarr; @@ -828,7 +830,8 @@ static PyObject* ll_array(cpyrt::LowLevelView* self, PyObject* args, } //--------------------------------------------------------------------------- -static PyObject* ll_as_string(cpyrt::LowLevelView* self) { +static PyObject* ll_as_string(PyObject* self, PyObject* /*args*/) { + cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; // Interpret memory as a null-terminated char string. Py_buffer& view = self->fBufInfo; @@ -840,19 +843,19 @@ static PyObject* ll_as_string(cpyrt::LowLevelView* self) { return nullptr; } - char* buf = (char*)self->get_buf(); + char* buf = (char*)inst->get_buf(); size_t sz = strnlen(buf, (size_t)view.shape[0]); return cpyrt_PyText_FromStringAndSize(buf, sz); } //--------------------------------------------------------------------------- static PyMethodDef ll_methods[] = { - {(char*)"reshape", (PyCFunction)ll_reshape, METH_O, + {(char*)"reshape", ll_reshape, METH_O, (char*)"change the shape (not layout) of the low level view"}, - {(char*)"as_string", (PyCFunction)ll_as_string, METH_NOARGS, + {(char*)"as_string", ll_as_string, METH_NOARGS, (char*)"interpret memory as a null-terminated char string and return " "Python str"}, - {(char*)"__array__", (PyCFunction)ll_array, METH_VARARGS | METH_KEYWORDS, + {(char*)"__array__", ll_array, METH_VARARGS | METH_KEYWORDS, (char*)"return a numpy array from the low level view"}, {(char*)nullptr, nullptr, 0, nullptr}}; From 46e54805b55e575451bf442470e59b1a66228e79 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:44:26 +0100 Subject: [PATCH 10/35] Try fix --- src/cpyrt/LowLevelViews.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index 73b1acd..c9387d9 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -833,7 +833,7 @@ static PyObject* ll_array(PyObject* self, PyObject* args, static PyObject* ll_as_string(PyObject* self, PyObject* /*args*/) { cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; // Interpret memory as a null-terminated char string. - Py_buffer& view = self->fBufInfo; + Py_buffer& view = inst->fBufInfo; if (strcmp(view.format, "b") != 0 || view.ndim != 1) { PyErr_Format( From 00ed20b4fe7a630a29e4d1647eaae7e9c819727f Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:51:03 +0100 Subject: [PATCH 11/35] Attempt partial fix --- src/cpyrt/LowLevelViews.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index c9387d9..21875a9 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -855,7 +855,7 @@ static PyMethodDef ll_methods[] = { {(char*)"as_string", ll_as_string, METH_NOARGS, (char*)"interpret memory as a null-terminated char string and return " "Python str"}, - {(char*)"__array__", ll_array, METH_VARARGS | METH_KEYWORDS, + {(char*)"__array__", ll_array, METH_VARARGS, (char*)"return a numpy array from the low level view"}, {(char*)nullptr, nullptr, 0, nullptr}}; From 10d94e6293c8f3a15ee69278bf83d831155ad130 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 20:56:22 +0100 Subject: [PATCH 12/35] Attempt partial fix --- src/cpyrt/LowLevelViews.cxx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index 21875a9..0933cbe 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -765,8 +765,7 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { } //--------------------------------------------------------------------------- -static PyObject* ll_array(PyObject* self, PyObject* args, - PyObject* kwds) { +static PyObject* ll_array(PyObject* self, PyObject* args) { cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; // Construct a numpy array from the lowlevelview (w/o copy if possible); this // uses the Python methods to avoid depending on numpy directly @@ -778,7 +777,7 @@ static PyObject* ll_array(PyObject* self, PyObject* args, bool docopy = false; if (kwds) { - PyObject* pycp = PyObject_GetItem(kwds, cpyrt::PyStrings::gCopy); + PyObject* pycp = PyObject_GetItem(nullptr, cpyrt::PyStrings::gCopy); if (!pycp) { PyErr_SetString(PyExc_TypeError, "__array__ only supports the \"copy\" keyword"); From 7f3fd29bf1e77bc0067ffb289e402d5eda1a1872 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 21:00:33 +0100 Subject: [PATCH 13/35] Try partial fix --- src/cpyrt/LowLevelViews.cxx | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index 0933cbe..1e3e0de 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -776,17 +776,6 @@ static PyObject* ll_array(PyObject* self, PyObject* args) { return nullptr; bool docopy = false; - if (kwds) { - PyObject* pycp = PyObject_GetItem(nullptr, cpyrt::PyStrings::gCopy); - if (!pycp) { - PyErr_SetString(PyExc_TypeError, - "__array__ only supports the \"copy\" keyword"); - return nullptr; - } - - docopy = PyObject_IsTrue(pycp); - Py_DECREF(pycp); - } if (!docopy) { // view requested // expect possible dtype from the arguments, otherwise take it from the type From 0fe6d8a2d74d6ad0fbfa5ac02f49bcc0fb3ae87a Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 21:23:37 +0100 Subject: [PATCH 14/35] Try fix --- src/cpyrt/LowLevelViews.cxx | 64 ++++++++++++++++++------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index 1e3e0de..b33b5fb 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -76,26 +76,23 @@ static void ll_dealloc(cpyrt::LowLevelView* pyobj) { } //---------------------------------------------------------------------------- -#define CPYRT_LL_FLAG_GETSET(name, flag, doc) \ - static PyObject* ll_get##name(cpyrt::LowLevelView* pyobj) { \ - return PyBool_FromLong((long)((intptr_t)pyobj->fBufInfo.internal & flag)); \ - } \ - \ - static int ll_set##name(cpyrt::LowLevelView* pyobj, PyObject* value, \ - void*) { \ - long settrue = PyLong_AsLong(value); \ - if (settrue == -1 && PyErr_Occurred()) { \ - PyErr_SetString(PyExc_ValueError, \ - #doc " should be either True or False"); \ - return -1; \ - } \ - \ - if ((bool)settrue) \ - (intptr_t&)pyobj->fBufInfo.internal |= flag; \ - else \ - (intptr_t&)pyobj->fBufInfo.internal &= ~flag; \ - \ - return 0; \ +#define CPYRT_LL_FLAG_GETSET(name, flag, doc) \ + static PyObject* ll_get##name(PyObject* pyobj, void*) { \ + auto* view = (cpyrt::LowLevelView*)pyobj; \ + return PyBool_FromLong((long)((intptr_t)view->fBufInfo.internal & flag)); \ + } \ + static int ll_set##name(PyObject* pyobj, PyObject* value, void*) { \ + auto* view = (cpyrt::LowLevelView*)pyobj; \ + long settrue = PyLong_AsLong(value); \ + if (settrue == -1 && PyErr_Occurred()) { \ + PyErr_SetString(PyExc_ValueError, #doc " should be either True or False"); \ + return -1; \ + } \ + if ((bool)settrue) \ + (intptr_t&)view->fBufInfo.internal |= flag; \ + else \ + (intptr_t&)view->fBufInfo.internal &= ~flag; \ + return 0; \ } // clang-format off @@ -681,8 +678,9 @@ static PyBufferProcs ll_as_buffer = { }; //--------------------------------------------------------------------------- -static PyObject* ll_shape(cpyrt::LowLevelView* self) { - Py_buffer& view = self->fBufInfo; +static PyObject* ll_shape(PyObject* self, void*) { + cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; + Py_buffer& view = inst->fBufInfo; PyObject* shape = PyTuple_New(view.ndim); for (Py_ssize_t idim = 0; idim < view.ndim; ++idim) @@ -692,9 +690,9 @@ static PyObject* ll_shape(cpyrt::LowLevelView* self) { } //--------------------------------------------------------------------------- -static PyObject* ll_reshape(PyObject* self, PyObject* shape) { +static int ll_reshape(PyObject* self, PyObject* shape, void*) { cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; - // Allow the user to fix up the actual (type-strided) size of the buffer. + if (!PyTuple_Check(shape)) { if (shape) { PyObject* pystr = PyObject_Str(shape); @@ -702,11 +700,11 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { PyErr_Format(PyExc_TypeError, "tuple object expected, received %s", cpyrt_PyText_AsStringChecked(pystr)); Py_DECREF(pystr); - return nullptr; + return -1; } } PyErr_SetString(PyExc_TypeError, "tuple object expected"); - return nullptr; + return -1; } Py_buffer& view = inst->fBufInfo; @@ -716,8 +714,8 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { for (Py_ssize_t idim = 0; idim < view.ndim; ++idim) { Py_ssize_t nlen = view.shape[idim]; if (nlen == cpyrt::UNKNOWN_SIZE || - nlen == INT_MAX / view.itemsize /* fake 'max' */) { - oldsz = -1; // meaning, unable to check size match + nlen == INT_MAX / view.itemsize) { + oldsz = -1; break; } oldsz += view.shape[idim]; @@ -733,11 +731,11 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { "cannot reshape array of size %ld into shape %s", (long)oldsz, cpyrt_PyText_AsString(tas)); Py_DECREF(tas); - return nullptr; + return -1; } } - // reshape + // reshape layout logic... size_t itemsize = view.strides[view.ndim - 1]; if (view.ndim != PyTuple_GET_SIZE(shape)) { PyMem_Free(view.shape); @@ -751,7 +749,7 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { for (Py_ssize_t idim = 0; idim < PyTuple_GET_SIZE(shape); ++idim) { Py_ssize_t nlen = PyInt_AsSsize_t(PyTuple_GET_ITEM(shape, idim)); if (nlen == -1 && PyErr_Occurred()) - return nullptr; + return -1; if (idim == 0) view.len = nlen * view.itemsize; @@ -759,9 +757,9 @@ static PyObject* ll_reshape(PyObject* self, PyObject* shape) { view.shape[idim] = nlen; } - set_strides(view, itemsize, false /* by definition not fixed */); + set_strides(view, itemsize, false); - Py_RETURN_NONE; + return 0; // Success } //--------------------------------------------------------------------------- From 9bb2aeb46ed078b0f5cc8e4361227914d94451ac Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 21:30:38 +0100 Subject: [PATCH 15/35] Try fix --- src/cpyrt/LowLevelViews.cxx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/cpyrt/LowLevelViews.cxx b/src/cpyrt/LowLevelViews.cxx index b33b5fb..e2e4715 100644 --- a/src/cpyrt/LowLevelViews.cxx +++ b/src/cpyrt/LowLevelViews.cxx @@ -762,6 +762,13 @@ static int ll_reshape(PyObject* self, PyObject* shape, void*) { return 0; // Success } +static PyObject* ll_reshape(PyObject* self, PyObject* shape) { + if (ll_reshape(self, shape, nullptr) < 0) { + return nullptr; + } + Py_RETURN_NONE; +} + //--------------------------------------------------------------------------- static PyObject* ll_array(PyObject* self, PyObject* args) { cpyrt::LowLevelView* inst = (cpyrt::LowLevelView*)self; From 8a6dbe4f5b2e7249ffafc14f5606153c9b99ce9f Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 21:38:15 +0100 Subject: [PATCH 16/35] Attempt fix --- src/cpyrt/MemoryRegulator.cxx | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/cpyrt/MemoryRegulator.cxx b/src/cpyrt/MemoryRegulator.cxx index 6ea7671..69d45ea 100644 --- a/src/cpyrt/MemoryRegulator.cxx +++ b/src/cpyrt/MemoryRegulator.cxx @@ -52,7 +52,9 @@ struct Initcpyrt_NoneType_t { cpyrt_NoneType.tp_repr = Py_TYPE(Py_None)->tp_repr; cpyrt_NoneType.tp_richcompare = (richcmpfunc)&Initcpyrt_NoneType_t::RichCompare; - cpyrt_NoneType.tp_hash = (hashfunc)&Initcpyrt_NoneType_t::PtrHash; + + // Assigned directly without a cast + cpyrt_NoneType.tp_hash = PtrHash; cpyrt_NoneType.tp_as_mapping = &cpyrt_NoneType_mapping; @@ -60,7 +62,8 @@ struct Initcpyrt_NoneType_t { } static void DeAlloc(PyObject* pyobj) { Py_TYPE(pyobj)->tp_free(pyobj); } - static int PtrHash(PyObject* pyobj) { return (int)ptrdiff_t(pyobj); } + // Return Py_hash_t instead of int to match hashfunc signature natively + static Py_hash_t PtrHash(PyObject* pyobj) { return (Py_hash_t)pyobj; } static PyObject* RichCompare(PyObject*, PyObject* other, int opid) { return PyObject_RichCompare(other, Py_None, opid); From 9890281049cb5b02acd60ba453dd959a7fffff43 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Thu, 27 Aug 2026 21:49:05 +0100 Subject: [PATCH 17/35] Fix --- src/cpyrt/Pythonize.cxx | 144 ++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 72 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 3e6b874..184c8da 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -209,7 +209,7 @@ PyObject* FollowGetAttr(PyObject* self, PyObject* name) { } //- pointer checking bool converter ------------------------------------------- -PyObject* NullCheckBool(PyObject* self) { +PyObject* NullCheckBool(PyObject* self, PyObject* Py_UNUSED(args)) { if (!CPPInstance_Check(self)) { PyErr_SetString(PyExc_TypeError, "C++ object proxy expected"); return nullptr; @@ -438,7 +438,7 @@ static bool FillVector(PyObject* vecin, PyObject* args, ItemGetter* getter) { return fill_ok; } -PyObject* VectorIAdd(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* VectorIAdd(PyObject* self, PyObject* args) { // Implement fast __iadd__ on std::vector (generic __iadd__ is in Python) ItemGetter* getter = GetGetter(args); @@ -474,7 +474,7 @@ PyObject* VectorIAdd(PyObject* self, PyObject* args, PyObject* /* kwds */) { return nullptr; // error already set } -PyObject* VectorInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* VectorInit(PyObject* self, PyObject* args) { // Specialized vector constructor to allow construction from containers; // allowing such construction from initializer_list instead would possible, // but can be error-prone. This use case is common enough for std::vector to @@ -538,10 +538,10 @@ PyObject* VectorData(PyObject* self, PyObject*) { } //--------------------------------------------------------------------------- -PyObject* VectorArray(PyObject* self, PyObject* args, PyObject* kwargs) { +PyObject* VectorArray(PyObject* self, PyObject* args) { PyObject* pydata = VectorData(self, nullptr); PyObject* arrcall = PyObject_GetAttr(pydata, PyStrings::gArray); - PyObject* newarr = PyObject_Call(arrcall, args, kwargs); + PyObject* newarr = PyObject_Call(arrcall, args, nullptr); Py_DECREF(arrcall); Py_DECREF(pydata); return newarr; @@ -778,7 +778,7 @@ PyObject* VectorBoolSetItem(CPPInstance* self, PyObject* args) { } //- array behavior as primitives ---------------------------------------------- -PyObject* ArrayInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* ArrayInit(PyObject* self, PyObject* args) { // std::array is normally only constructed using aggregate initialization, // which is a concept that does not exist in python, so use this custom // constructor to to fill the array using setitem @@ -867,7 +867,7 @@ static PyObject* MapFromPairs(PyObject* self, PyObject* pairs) { return result; } -PyObject* MapInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* MapInit(PyObject* self, PyObject* args) { // Specialized map constructor to allow construction from mapping containers // and from tuples of pairs ("initializer_list style"). @@ -941,7 +941,7 @@ PyObject* STLContainsWithFind(PyObject* self, PyObject* obj) { } //- set behavior as primitives ------------------------------------------------ -PyObject* SetInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* SetInit(PyObject* self, PyObject* args) { // Specialized set constructor to allow construction from Python sets. if (PyTuple_GET_SIZE(args) == 1 && PySet_Check(PyTuple_GET_ITEM(args, 0))) { PyObject* pyset = PyTuple_GET_ITEM(args, 0); @@ -995,7 +995,7 @@ static const ptrdiff_t PS_COLL_ADDR = 13; // id. PyObject* STLIterNext(PyObject* self); // defined below; used by STLSequenceIter -PyObject* LLSequenceIter(PyObject* self) { +PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for low level views used through STL-type // begin()/end() PyObject* iter = PyObject_CallMethodNoArgs(self, PyStrings::gBegin); @@ -1042,11 +1042,11 @@ PyObject* STLSequenceIter(PyObject* self) { // _PyObject_NextNotImplemented sentinel itype->tp_iternext = (iternextfunc)STLIterNext; Utility::AddToClass((PyObject*)itype, CPPJIT__next__, - (PyCFunction)STLIterNext, METH_NOARGS); + STLIterNext, METH_NOARGS); if (!itype->tp_iter) { itype->tp_iter = (getiterfunc)PyObject_SelfIter; Utility::AddToClass((PyObject*)itype, "__iter__", - (PyCFunction)PyObject_SelfIter, METH_NOARGS); + PyObject_SelfIter, METH_NOARGS); } PyType_Modified(itype); } @@ -1075,7 +1075,7 @@ PyObject* STLSequenceIter(PyObject* self) { //- generic iterator support over a sequence with operator[] and size --------- //----------------------------------------------------------------------------- -static PyObject* index_iter(PyObject* c) { +static PyObject* index_iter(PyObject* c, PyObject* Py_UNUSED(args)) { indexiterobject* ii = PyObject_GC_New(indexiterobject, &IndexIter_Type); if (!ii) return nullptr; @@ -1145,7 +1145,7 @@ PyObject* PairUnpack(PyObject* self, PyObject* pyindex) { PyObject* ReturnTwo(CPPInstance*, PyObject*) { return PyInt_FromLong(2); } //- shared/unique_ptr behavior ----------------------------------------------- -PyObject* SmartPtrInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* SmartPtrInit(PyObject* self, PyObject* args) { // since the shared/unique pointer will take ownership, we need to relinquish // it PyObject* realInit = PyObject_GetAttr(self, PyStrings::gRealInit); @@ -1198,7 +1198,7 @@ static inline PyObject* cpyrt_PyString_FromCppString(std::wstring_view s, return nullptr; \ } \ \ - PyObject* name##StringStr(PyObject* self) { \ + PyObject* name##StringStr(PyObject* self, PyObject* Py_UNUSED(args)) { \ PyObject* pyobj = name##StringGetData(self, false); \ if (!pyobj) { \ /* do a native conversion to make printing possible (debatable) */ \ @@ -1212,11 +1212,11 @@ static inline PyObject* cpyrt_PyString_FromCppString(std::wstring_view s, return pyobj; \ } \ \ - PyObject* name##StringBytes(PyObject* self) { \ + PyObject* name##StringBytes(PyObject* self, PyObject* Py_UNUSED(args)) { \ return name##StringGetData(self, true); \ } \ \ - PyObject* name##StringRepr(PyObject* self) { \ + PyObject* name##StringRepr(PyObject* self, PyObject* Py_UNUSED(args)) { \ PyObject* data = name##StringGetData(self, true); \ if (data) { \ PyObject* repr = PyObject_Repr(data); \ @@ -1278,16 +1278,15 @@ static inline std::string* GetSTLString(CPPInstance* self) { return obj; } -PyObject* STLStringDecode(CPPInstance* self, PyObject* args, PyObject* kwds) { - std::string* obj = GetSTLString(self); +PyObject* STLStringDecode(PyObject* self, PyObject* args) { + CPPInstance* inst = (CPPInstance*)self; + std::string* obj = GetSTLString(inst); if (!obj) return nullptr; - char* keywords[] = {(char*)"encoding", (char*)"errors", (char*)nullptr}; const char* encoding = nullptr; const char* errors = nullptr; - if (!PyArg_ParseTupleAndKeywords(args, kwds, const_cast("s|s"), - keywords, &encoding, &errors)) + if (!PyArg_ParseTuple(args, "s|s", &encoding, &errors)) return nullptr; return PyUnicode_Decode(obj->data(), obj->size(), encoding, errors); @@ -1309,9 +1308,9 @@ PyObject* STLStringContains(CPPInstance* self, PyObject* pyobj) { Py_RETURN_FALSE; } -PyObject* STLStringReplace(CPPInstance* self, PyObject* args, - PyObject* /*kwds*/) { - std::string* obj = GetSTLString(self); +PyObject* STLStringReplace(PyObject* self, PyObject* args) { + CPPInstance* inst = (CPPInstance*)self; + std::string* obj = GetSTLString(inst); if (!obj) return nullptr; @@ -1330,7 +1329,7 @@ PyObject* STLStringReplace(CPPInstance* self, PyObject* args, } PyObject* cppreplace = - PyObject_GetAttrString((PyObject*)self, (char*)"__cpp_replace"); + PyObject_GetAttrString((PyObject*)inst, (char*)"__cpp_replace"); if (cppreplace) { PyObject* result = PyObject_Call(cppreplace, args, nullptr); Py_DECREF(cppreplace); @@ -1343,14 +1342,14 @@ PyObject* STLStringReplace(CPPInstance* self, PyObject* args, } #define CPYRT_STRING_FINDMETHOD(name, cppname, pyname) \ - PyObject* STLString##name(CPPInstance* self, PyObject* args, \ - PyObject* /*kwds*/) { \ - std::string* obj = GetSTLString(self); \ + PyObject* STLString##name(PyObject* self, PyObject* args) { \ + CPPInstance* inst = (CPPInstance*) self; \ + std::string* obj = GetSTLString(inst); \ if (!obj) \ return nullptr; \ \ PyObject* cppmeth = \ - PyObject_GetAttrString((PyObject*)self, (char*)#cppname); \ + PyObject_GetAttrString((PyObject*)inst, (char*)#cppname); \ if (cppmeth) { \ PyObject* result = PyObject_Call(cppmeth, args, nullptr); \ Py_DECREF(cppmeth); \ @@ -1392,7 +1391,7 @@ PyObject* STLStringGetAttr(CPPInstance* self, PyObject* attr_name) { return attr; } -PyObject* UTF8Repr(PyObject* self) { +PyObject* UTF8Repr(PyObject* self, PyObject* Py_UNUSED(args)) { // force C++ string types conversion to Python str per Python __repr__ // requirements PyObject* res = PyObject_CallMethodNoArgs(self, PyStrings::gCppRepr); @@ -1403,7 +1402,7 @@ PyObject* UTF8Repr(PyObject* self) { return str_res; } -PyObject* UTF8Str(PyObject* self) { +PyObject* UTF8Str(PyObject* self, PyObject* Py_UNUSED(args)) { // force C++ string types conversion to Python str per Python __str__ // requirements PyObject* res = PyObject_CallMethodNoArgs(self, PyStrings::gCppStr); @@ -1424,7 +1423,7 @@ Py_hash_t STLStringHash(PyObject* self) { } //- string_view behavior as primitive ---------------------------------------- -PyObject* StringViewInit(PyObject* self, PyObject* args, PyObject* /* kwds */) { +PyObject* StringViewInit(PyObject* self, PyObject* args) { // if constructed from a Python unicode object, the constructor will convert // it to a temporary byte string, which is likely to go out of scope too soon; // so buffer it as needed @@ -1536,7 +1535,7 @@ PyObject* STLIterNext(PyObject* self) { COMPLEX_METH_GETSET(real, PyStrings::gCppReal) COMPLEX_METH_GETSET(imag, PyStrings::gCppImag) -static PyObject* ComplexComplex(PyObject* self) { +static PyObject* ComplexComplex(PyObject* self, PyObject* Py_UNUSED(args)) { PyObject* real = PyObject_CallMethodNoArgs(self, PyStrings::gCppReal); if (!real) return nullptr; @@ -1556,7 +1555,7 @@ static PyObject* ComplexComplex(PyObject* self) { return PyComplex_FromDoubles(r, i); } -static PyObject* ComplexRepr(PyObject* self) { +static PyObject* ComplexRepr(PyObject* self, PyObject* Py_UNUSED(args)) { PyObject* real = PyObject_CallMethodNoArgs(self, PyStrings::gCppReal); if (!real) return nullptr; @@ -1608,9 +1607,10 @@ static int ComplexDImagSet(CPPInstance* self, PyObject* value, void*) { PyGetSetDef ComplexDImag{(char*)"imag", (getter)ComplexDImagGet, (setter)ComplexDImagSet, nullptr, nullptr}; -static PyObject* ComplexDComplex(CPPInstance* self) { - double r = ((std::complex*)self->GetObject())->real(); - double i = ((std::complex*)self->GetObject())->imag(); +static PyObject* ComplexDComplex(PyObject* self, PyObject* Py_UNUSED(args)) { + CPPInstance* inst = (CPPInstance*)self; + double r = ((std::complex*)inst->GetObject())->real(); + double i = ((std::complex*)inst->GetObject())->imag(); return PyComplex_FromDoubles(r, i); } @@ -1671,7 +1671,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // for pre-check of nullptr for boolean types if (HasAttrDirect(pyclass, PyStrings::gCppBool)) { const char* pybool_name = "__bool__"; - Utility::AddToClass(pyclass, pybool_name, (PyCFunction)NullCheckBool, + Utility::AddToClass(pyclass, pybool_name, NullCheckBool, METH_NOARGS); } @@ -1709,7 +1709,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (isIterator) { // install iterator protocol a la STL ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIter; - Utility::AddToClass(pyclass, "__iter__", (PyCFunction)STLSequenceIter, + Utility::AddToClass(pyclass, "__iter__", STLSequenceIter, METH_NOARGS); } else { // still okay if this is some pointer type of builtin persuasion @@ -1720,7 +1720,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { interop::IsBuiltin(resolved.substr(0, resolved.size() - 1))) { ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIter; Utility::AddToClass(pyclass, "__iter__", - (PyCFunction)LLSequenceIter, METH_NOARGS); + LLSequenceIter, METH_NOARGS); } } } @@ -1734,7 +1734,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // is meant to implement an associative container. So, this has to be // implemented as an iterator protocol. ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter; - Utility::AddToClass(pyclass, "__iter__", (PyCFunction)index_iter, + Utility::AddToClass(pyclass, "__iter__", index_iter, METH_NOARGS); } } @@ -1780,14 +1780,14 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (HasAttrDirect(pyclass, PyStrings::gRepr, true)) { // guarantee that the result of __repr__ is a Python string Utility::AddToClass(pyclass, "__cpp_repr", "__repr__"); - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)UTF8Repr, + Utility::AddToClass(pyclass, "__repr__", UTF8Repr, METH_NOARGS); } if (HasAttrDirect(pyclass, PyStrings::gStr, true)) { // guarantee that the result of __str__ is a Python string Utility::AddToClass(pyclass, "__cpp_str", "__str__"); - Utility::AddToClass(pyclass, "__str__", (PyCFunction)UTF8Str, METH_NOARGS); + Utility::AddToClass(pyclass, "__str__", UTF8Str, METH_NOARGS); } if (interop::IsAggregate(((CPPClass*)pyclass)->fCppType) && @@ -1894,7 +1894,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { } else { // constructor that takes python collections Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)VectorInit, + Utility::AddToClass(pyclass, "__init__", VectorInit, METH_VARARGS | METH_KEYWORDS); // data with size @@ -1902,8 +1902,8 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { Utility::AddToClass(pyclass, "data", (PyCFunction)VectorData); // numpy array conversion - Utility::AddToClass(pyclass, "__array__", (PyCFunction)VectorArray, - METH_VARARGS | METH_KEYWORDS /* unused */); + Utility::AddToClass(pyclass, "__array__", VectorArray, + METH_VARARGS); // checked getitem if (HasAttrDirect(pyclass, PyStrings::gLen)) { @@ -1916,7 +1916,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter; // optimized __iadd__ - Utility::AddToClass(pyclass, "__iadd__", (PyCFunction)VectorIAdd, + Utility::AddToClass(pyclass, "__iadd__", VectorIAdd, METH_VARARGS | METH_KEYWORDS); // helpers for iteration @@ -1945,7 +1945,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { else if (IsTemplatedSTLClass(name, "array")) { // constructor that takes python associative collections Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)ArrayInit, + Utility::AddToClass(pyclass, "__init__", ArrayInit, METH_VARARGS | METH_KEYWORDS); } @@ -1953,7 +1953,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { IsTemplatedSTLClass(name, "unordered_map")) { // constructor that takes python associative collections Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)MapInit, + Utility::AddToClass(pyclass, "__init__", MapInit, METH_VARARGS | METH_KEYWORDS); // From C++20, std::map/unordered_map have a native contains() that the // generic contains->__contains__ mapping above will pick up. Strong-types @@ -1968,7 +1968,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { else if (IsTemplatedSTLClass(name, "set")) { // constructor that takes python associative collections Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)SetInit, + Utility::AddToClass(pyclass, "__init__", SetInit, METH_VARARGS | METH_KEYWORDS); // From C++20, std::set has a native contains() that the generic // contains->__contains__ mapping above will pick up. Strong-types @@ -1989,7 +1989,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (IsTemplatedSTLClass(name, "shared_ptr") || IsTemplatedSTLClass(name, "unique_ptr")) { Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)SmartPtrInit, + Utility::AddToClass(pyclass, "__init__", SmartPtrInit, METH_VARARGS | METH_KEYWORDS); } @@ -1997,10 +1997,10 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { (name.find("iterator") != std::string::npos || gIteratorTypes.find(name) != gIteratorTypes.end())) { ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNext; - Utility::AddToClass(pyclass, CPPJIT__next__, (PyCFunction)STLIterNext, + Utility::AddToClass(pyclass, CPPJIT__next__, STLIterNext, METH_NOARGS); ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter; - Utility::AddToClass(pyclass, "__iter__", (PyCFunction)PyObject_SelfIter, + Utility::AddToClass(pyclass, "__iter__", PyObject_SelfIter, METH_NOARGS); } @@ -2008,11 +2008,11 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { name == "std::__1::basic_string" || // libc++ inline namespace name == "std::string") { // typedef preserved by GetScopedFinalName // on libc++ - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)STLStringRepr, + Utility::AddToClass(pyclass, "__repr__", STLStringRepr, METH_NOARGS); - Utility::AddToClass(pyclass, "__str__", (PyCFunction)STLStringStr, + Utility::AddToClass(pyclass, "__str__", STLStringStr, METH_NOARGS); - Utility::AddToClass(pyclass, "__bytes__", (PyCFunction)STLStringBytes, + Utility::AddToClass(pyclass, "__bytes__", STLStringBytes, METH_NOARGS); Utility::AddToClass(pyclass, "__cmp__", (PyCFunction)STLStringCompare, METH_O); @@ -2026,16 +2026,16 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // wrongly dropped it when built with -std=c++2c (__cplusplus == 202400L). Utility::AddToClass(pyclass, "__contains__", (PyCFunction)STLStringContains, METH_O); - Utility::AddToClass(pyclass, "decode", (PyCFunction)STLStringDecode, - METH_VARARGS | METH_KEYWORDS); + Utility::AddToClass(pyclass, "decode", STLStringDecode, + METH_VARARGS); Utility::AddToClass(pyclass, "__cpp_find", "find"); - Utility::AddToClass(pyclass, "find", (PyCFunction)STLStringFind, + Utility::AddToClass(pyclass, "find", STLStringFind, METH_VARARGS | METH_KEYWORDS); Utility::AddToClass(pyclass, "__cpp_rfind", "rfind"); - Utility::AddToClass(pyclass, "rfind", (PyCFunction)STLStringRFind, + Utility::AddToClass(pyclass, "rfind", STLStringRFind, METH_VARARGS | METH_KEYWORDS); Utility::AddToClass(pyclass, "__cpp_replace", "replace"); - Utility::AddToClass(pyclass, "replace", (PyCFunction)STLStringReplace, + Utility::AddToClass(pyclass, "replace", STLStringReplace, METH_VARARGS | METH_KEYWORDS); Utility::AddToClass(pyclass, "__getattr__", (PyCFunction)STLStringGetAttr, METH_O); @@ -2050,9 +2050,9 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { name == "std::string_view") { // typedef preserved by // GetScopedFinalName on libc++ Utility::AddToClass(pyclass, "__real_init", "__init__"); - Utility::AddToClass(pyclass, "__init__", (PyCFunction)StringViewInit, + Utility::AddToClass(pyclass, "__init__", StringViewInit, METH_VARARGS | METH_KEYWORDS); - Utility::AddToClass(pyclass, "__bytes__", (PyCFunction)STLViewStringBytes, + Utility::AddToClass(pyclass, "__bytes__", STLViewStringBytes, METH_NOARGS); Utility::AddToClass(pyclass, "__cmp__", (PyCFunction)STLViewStringCompare, METH_O); @@ -2060,9 +2060,9 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { METH_O); Utility::AddToClass(pyclass, "__ne__", (PyCFunction)STLViewStringIsNotEqual, METH_O); - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)STLViewStringRepr, + Utility::AddToClass(pyclass, "__repr__", STLViewStringRepr, METH_NOARGS); - Utility::AddToClass(pyclass, "__str__", (PyCFunction)STLViewStringStr, + Utility::AddToClass(pyclass, "__str__", STLViewStringStr, METH_NOARGS); } @@ -2071,11 +2071,11 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { name == "std::__1::basic_string,std::__1::allocator >" || name == "std::wstring") { - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)STLWStringRepr, + Utility::AddToClass(pyclass, "__repr__", STLWStringRepr, METH_NOARGS); - Utility::AddToClass(pyclass, "__str__", (PyCFunction)STLWStringStr, + Utility::AddToClass(pyclass, "__str__", STLWStringStr, METH_NOARGS); - Utility::AddToClass(pyclass, "__bytes__", (PyCFunction)STLWStringBytes, + Utility::AddToClass(pyclass, "__bytes__", STLWStringBytes, METH_NOARGS); Utility::AddToClass(pyclass, "__cmp__", (PyCFunction)STLWStringCompare, METH_O); @@ -2094,9 +2094,9 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { PyObject_SetAttrString( pyclass, "imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &ComplexDImag)); - Utility::AddToClass(pyclass, "__complex__", (PyCFunction)ComplexDComplex, + Utility::AddToClass(pyclass, "__complex__", ComplexDComplex, METH_NOARGS); - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)ComplexRepr, + Utility::AddToClass(pyclass, "__repr__", ComplexRepr, METH_NOARGS); } @@ -2109,9 +2109,9 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { PyObject_SetAttrString( pyclass, "imag", PyDescr_NewGetSet((PyTypeObject*)pyclass, &imagComplex)); - Utility::AddToClass(pyclass, "__complex__", (PyCFunction)ComplexComplex, + Utility::AddToClass(pyclass, "__complex__", ComplexComplex, METH_NOARGS); - Utility::AddToClass(pyclass, "__repr__", (PyCFunction)ComplexRepr, + Utility::AddToClass(pyclass, "__repr__", ComplexRepr, METH_NOARGS); } From ff796b37206758f0d06c78f61bed7b3193e57dae Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 18:22:43 +0100 Subject: [PATCH 18/35] Test fix --- src/cpyrt/Pythonize.cxx | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 184c8da..7e9d431 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -993,7 +993,7 @@ static const ptrdiff_t PS_END_ADDR = 7; // non-aligned address, so no clash static const ptrdiff_t PS_FLAG_ADDR = 11; // id. static const ptrdiff_t PS_COLL_ADDR = 13; // id. -PyObject* STLIterNext(PyObject* self); // defined below; used by STLSequenceIter +PyObject* STLIterNext(PyObject* self, PyObject* Py_UNUSED(args)); // defined below; used by STLSequenceIter PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for low level views used through STL-type @@ -1022,7 +1022,7 @@ PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { return nullptr; } -PyObject* STLSequenceIter(PyObject* self) { +PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s PyObject* iter = PyObject_CallMethodNoArgs(self, PyStrings::gBegin); if (iter) { @@ -1046,7 +1046,7 @@ PyObject* STLSequenceIter(PyObject* self) { if (!itype->tp_iter) { itype->tp_iter = (getiterfunc)PyObject_SelfIter; Utility::AddToClass((PyObject*)itype, "__iter__", - PyObject_SelfIter, METH_NOARGS); + my_iter, METH_NOARGS); } PyType_Modified(itype); } @@ -1463,7 +1463,7 @@ PyObject* StringViewInit(PyObject* self, PyObject* args) { } //- STL iterator behavior ---------------------------------------------------- -PyObject* STLIterNext(PyObject* self) { +PyObject* STLIterNext(PyObject* self, PyObject* Py_UNUSED(args)) { // Python iterator protocol __next__ for STL forward iterators. bool mustIncrement = true; PyObject* last = nullptr; @@ -1643,6 +1643,10 @@ static inline bool run_pythonizors(PyObject* pyclass, PyObject* pyname, return pstatus; } +static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { + return PyObject_SelfIter(self); +} + bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { const std::string& name = interop::GetScopedFinalName(scope); @@ -2000,7 +2004,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { Utility::AddToClass(pyclass, CPPJIT__next__, STLIterNext, METH_NOARGS); ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter; - Utility::AddToClass(pyclass, "__iter__", PyObject_SelfIter, + Utility::AddToClass(pyclass, "__iter__", my_iter, METH_NOARGS); } From d49499c6028850c12e3b26dc30cd004f8476be32 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 18:39:16 +0100 Subject: [PATCH 19/35] Test fix --- src/cpyrt/Pythonize.cxx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 7e9d431..4e41c2c 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1022,6 +1022,10 @@ PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { return nullptr; } +static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { + return PyObject_SelfIter(self); +} + PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s PyObject* iter = PyObject_CallMethodNoArgs(self, PyStrings::gBegin); From a2e0323d665af7b206b26c7838f0cfa52e4706bf Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 18:46:48 +0100 Subject: [PATCH 20/35] Test --- src/cpyrt/Pythonize.cxx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 4e41c2c..2f4be24 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1647,10 +1647,6 @@ static inline bool run_pythonizors(PyObject* pyclass, PyObject* pyname, return pstatus; } -static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { - return PyObject_SelfIter(self); -} - bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { const std::string& name = interop::GetScopedFinalName(scope); From e4eff56e553d3b7d8355b535d6b3d7404df3598d Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:16:22 +0100 Subject: [PATCH 21/35] Test fix --- src/cpyrt/Pythonize.cxx | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 2f4be24..e208700 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1025,6 +1025,14 @@ PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { return PyObject_SelfIter(self); } + +static PyObject* my_iternextfunc(PyObject* self, PyObject* Py_UNUSED(args)) { + return PyObject_SelfIter(self); +} + +static PyObject* my_getiterfunc(PyObject* self, PyObject* Py_UNUSED(args)) { + return PyObject_SelfIter(self); +} PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s @@ -1044,11 +1052,11 @@ PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { PyTypeObject* itype = Py_TYPE(iter); if (!PyIter_Check(iter)) { // no tp_iternext, or the // _PyObject_NextNotImplemented sentinel - itype->tp_iternext = (iternextfunc)STLIterNext; + itype->tp_iternext = (my_iternextfunc)STLIterNext; Utility::AddToClass((PyObject*)itype, CPPJIT__next__, STLIterNext, METH_NOARGS); if (!itype->tp_iter) { - itype->tp_iter = (getiterfunc)PyObject_SelfIter; + itype->tp_iter = (my_getiterfunc)PyObject_SelfIter; Utility::AddToClass((PyObject*)itype, "__iter__", my_iter, METH_NOARGS); } @@ -1712,7 +1720,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (isIterator) { // install iterator protocol a la STL - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)STLSequenceIter; Utility::AddToClass(pyclass, "__iter__", STLSequenceIter, METH_NOARGS); } else { @@ -1722,7 +1730,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { std::string resolved = interop::ResolveName(resname); if (resolved.back() == '*' && interop::IsBuiltin(resolved.substr(0, resolved.size() - 1))) { - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)LLSequenceIter; Utility::AddToClass(pyclass, "__iter__", LLSequenceIter, METH_NOARGS); } @@ -1737,7 +1745,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // if beyond size()) works in some cases but would mess up if operator[] // is meant to implement an associative container. So, this has to be // implemented as an iterator protocol. - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter; + ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)index_iter; Utility::AddToClass(pyclass, "__iter__", index_iter, METH_NOARGS); } @@ -1917,7 +1925,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { } // vector-optimized iterator protocol - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter; + ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)vector_iter; // optimized __iadd__ Utility::AddToClass(pyclass, "__iadd__", VectorIAdd, @@ -2000,10 +2008,10 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { else if (!((PyTypeObject*)pyclass)->tp_iter && (name.find("iterator") != std::string::npos || gIteratorTypes.find(name) != gIteratorTypes.end())) { - ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNext; + ((PyTypeObject*)pyclass)->tp_iternext = (my_iternextfunc)STLIterNext; Utility::AddToClass(pyclass, CPPJIT__next__, STLIterNext, METH_NOARGS); - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter; + ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)PyObject_SelfIter; Utility::AddToClass(pyclass, "__iter__", my_iter, METH_NOARGS); } From 8c66c49dcbb1763435f4878da6bc3649d35b6fae Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:19:46 +0100 Subject: [PATCH 22/35] Revert "Test fix" This reverts commit e4eff56e553d3b7d8355b535d6b3d7404df3598d. --- src/cpyrt/Pythonize.cxx | 24 ++++++++---------------- 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index e208700..2f4be24 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1025,14 +1025,6 @@ PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { return PyObject_SelfIter(self); } - -static PyObject* my_iternextfunc(PyObject* self, PyObject* Py_UNUSED(args)) { - return PyObject_SelfIter(self); -} - -static PyObject* my_getiterfunc(PyObject* self, PyObject* Py_UNUSED(args)) { - return PyObject_SelfIter(self); -} PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s @@ -1052,11 +1044,11 @@ PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { PyTypeObject* itype = Py_TYPE(iter); if (!PyIter_Check(iter)) { // no tp_iternext, or the // _PyObject_NextNotImplemented sentinel - itype->tp_iternext = (my_iternextfunc)STLIterNext; + itype->tp_iternext = (iternextfunc)STLIterNext; Utility::AddToClass((PyObject*)itype, CPPJIT__next__, STLIterNext, METH_NOARGS); if (!itype->tp_iter) { - itype->tp_iter = (my_getiterfunc)PyObject_SelfIter; + itype->tp_iter = (getiterfunc)PyObject_SelfIter; Utility::AddToClass((PyObject*)itype, "__iter__", my_iter, METH_NOARGS); } @@ -1720,7 +1712,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (isIterator) { // install iterator protocol a la STL - ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)STLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIter; Utility::AddToClass(pyclass, "__iter__", STLSequenceIter, METH_NOARGS); } else { @@ -1730,7 +1722,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { std::string resolved = interop::ResolveName(resname); if (resolved.back() == '*' && interop::IsBuiltin(resolved.substr(0, resolved.size() - 1))) { - ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)LLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIter; Utility::AddToClass(pyclass, "__iter__", LLSequenceIter, METH_NOARGS); } @@ -1745,7 +1737,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // if beyond size()) works in some cases but would mess up if operator[] // is meant to implement an associative container. So, this has to be // implemented as an iterator protocol. - ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)index_iter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter; Utility::AddToClass(pyclass, "__iter__", index_iter, METH_NOARGS); } @@ -1925,7 +1917,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { } // vector-optimized iterator protocol - ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)vector_iter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)vector_iter; // optimized __iadd__ Utility::AddToClass(pyclass, "__iadd__", VectorIAdd, @@ -2008,10 +2000,10 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { else if (!((PyTypeObject*)pyclass)->tp_iter && (name.find("iterator") != std::string::npos || gIteratorTypes.find(name) != gIteratorTypes.end())) { - ((PyTypeObject*)pyclass)->tp_iternext = (my_iternextfunc)STLIterNext; + ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNext; Utility::AddToClass(pyclass, CPPJIT__next__, STLIterNext, METH_NOARGS); - ((PyTypeObject*)pyclass)->tp_iter = (my_getiterfunc)PyObject_SelfIter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter; Utility::AddToClass(pyclass, "__iter__", my_iter, METH_NOARGS); } From 20e91a3cb55b3471184e8f9dfc5793d003b31b8c Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:44:35 +0100 Subject: [PATCH 23/35] Test fix --- src/cpyrt/Pythonize.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 2f4be24..e644259 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1647,6 +1647,11 @@ static inline bool run_pythonizors(PyObject* pyclass, PyObject* pyname, return pstatus; } +static PyObject* STLIterNextAdapter(PyObject *self) +{ + return STLIterNext(self, nullptr); +} + bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { const std::string& name = interop::GetScopedFinalName(scope); @@ -2000,7 +2005,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { else if (!((PyTypeObject*)pyclass)->tp_iter && (name.find("iterator") != std::string::npos || gIteratorTypes.find(name) != gIteratorTypes.end())) { - ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNext; + ((PyTypeObject*)pyclass)->tp_iternext = (iternextfunc)STLIterNextAdapter; Utility::AddToClass(pyclass, CPPJIT__next__, STLIterNext, METH_NOARGS); ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)PyObject_SelfIter; From 552e3c622085ca92ee7a50dfc357962cb50e67cc Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:47:59 +0100 Subject: [PATCH 24/35] Test fix --- src/cpyrt/Pythonize.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index e644259..db32a32 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1025,6 +1025,11 @@ PyObject* LLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { static PyObject* my_iter(PyObject* self, PyObject* Py_UNUSED(args)) { return PyObject_SelfIter(self); } + +static PyObject* STLIterNextAdapter(PyObject *self) +{ + return STLIterNext(self, nullptr); +} PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s @@ -1044,7 +1049,7 @@ PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { PyTypeObject* itype = Py_TYPE(iter); if (!PyIter_Check(iter)) { // no tp_iternext, or the // _PyObject_NextNotImplemented sentinel - itype->tp_iternext = (iternextfunc)STLIterNext; + itype->tp_iternext = (iternextfunc)STLIterNextAdapter; Utility::AddToClass((PyObject*)itype, CPPJIT__next__, STLIterNext, METH_NOARGS); if (!itype->tp_iter) { @@ -1647,11 +1652,6 @@ static inline bool run_pythonizors(PyObject* pyclass, PyObject* pyname, return pstatus; } -static PyObject* STLIterNextAdapter(PyObject *self) -{ - return STLIterNext(self, nullptr); -} - bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { const std::string& name = interop::GetScopedFinalName(scope); From 3d6ffde3b82aa2cfa5aa8373b7241f317d80f475 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:53:39 +0100 Subject: [PATCH 25/35] Test fix --- src/cpyrt/Pythonize.cxx | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index db32a32..1110fc3 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1030,6 +1030,21 @@ static PyObject* STLIterNextAdapter(PyObject *self) { return STLIterNext(self, nullptr); } + +static PyObject* STLSequenceIterAdapter(PyObject *self) +{ + return STLSequenceIter(self, nullptr); +} + +static PyObject* LLSequenceIterAdapter(PyObject *self) +{ + return LLSequenceIter(self, nullptr); +} + +static PyObject* index_iterAdapter(PyObject *self) +{ + return index_iter(self, nullptr); +} PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s @@ -1717,7 +1732,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { if (isIterator) { // install iterator protocol a la STL - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)STLSequenceIterAdapter; Utility::AddToClass(pyclass, "__iter__", STLSequenceIter, METH_NOARGS); } else { @@ -1727,7 +1742,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { std::string resolved = interop::ResolveName(resname); if (resolved.back() == '*' && interop::IsBuiltin(resolved.substr(0, resolved.size() - 1))) { - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)LLSequenceIterAdapter; Utility::AddToClass(pyclass, "__iter__", LLSequenceIter, METH_NOARGS); } @@ -1742,7 +1757,7 @@ bool cpyrt::Pythonize(PyObject* pyclass, interop::TCppScope_t scope) { // if beyond size()) works in some cases but would mess up if operator[] // is meant to implement an associative container. So, this has to be // implemented as an iterator protocol. - ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iter; + ((PyTypeObject*)pyclass)->tp_iter = (getiterfunc)index_iterAdapter; Utility::AddToClass(pyclass, "__iter__", index_iter, METH_NOARGS); } From 0bb66c7ddbef44e77709cfb25afa343e627ecb23 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 19:58:35 +0100 Subject: [PATCH 26/35] Test fix --- src/cpyrt/Pythonize.cxx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/cpyrt/Pythonize.cxx b/src/cpyrt/Pythonize.cxx index 1110fc3..bc625fc 100644 --- a/src/cpyrt/Pythonize.cxx +++ b/src/cpyrt/Pythonize.cxx @@ -1031,20 +1031,10 @@ static PyObject* STLIterNextAdapter(PyObject *self) return STLIterNext(self, nullptr); } -static PyObject* STLSequenceIterAdapter(PyObject *self) -{ - return STLSequenceIter(self, nullptr); -} - static PyObject* LLSequenceIterAdapter(PyObject *self) { return LLSequenceIter(self, nullptr); } - -static PyObject* index_iterAdapter(PyObject *self) -{ - return index_iter(self, nullptr); -} PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { // Implement python's __iter__ for std::iterator<>s @@ -1097,6 +1087,11 @@ PyObject* STLSequenceIter(PyObject* self, PyObject* Py_UNUSED(args)) { return iter; } +static PyObject* STLSequenceIterAdapter(PyObject *self) +{ + return STLSequenceIter(self, nullptr); +} + //- generic iterator support over a sequence with operator[] and size --------- //----------------------------------------------------------------------------- static PyObject* index_iter(PyObject* c, PyObject* Py_UNUSED(args)) { @@ -1113,6 +1108,11 @@ static PyObject* index_iter(PyObject* c, PyObject* Py_UNUSED(args)) { return (PyObject*)ii; } +static PyObject* index_iterAdapter(PyObject *self) +{ + return index_iter(self, nullptr); +} + //- safe indexing for STL-like vector w/o iterator dictionaries --------------- /* replaced by indexiterobject iteration, but may still have some future use ... PyObject* CheckedGetItem(PyObject* self, PyObject* obj) From 88a03b155a06a95de7ae03685bcb36dc302676b7 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:03:00 +0100 Subject: [PATCH 27/35] Test fix --- src/cpyrt/cpyrtModule.cxx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/cpyrt/cpyrtModule.cxx b/src/cpyrt/cpyrtModule.cxx index b2c0733..714e727 100644 --- a/src/cpyrt/cpyrtModule.cxx +++ b/src/cpyrt/cpyrtModule.cxx @@ -1022,20 +1022,20 @@ static PyMethodDef gcpyrtMethods[] = { METH_VARARGS, (char*)"cppjit internal function"}, {(char*)"_set_cpp_lazy_lookup", (PyCFunction)SetCppLazyLookup, METH_VARARGS, (char*)"cppjit internal function"}, - {(char*)"_DestroyPyStrings", (PyCFunction)cpyrt::DestroyPyStrings, + {(char*)"_DestroyPyStrings", cpyrt::DestroyPyStrings, METH_NOARGS, (char*)"cppjit internal function"}, - {(char*)"addressof", (PyCFunction)addressof, METH_VARARGS | METH_KEYWORDS, + {(char*)"addressof", addressof, METH_VARARGS | METH_KEYWORDS, (char*)"Retrieve address of proxied object or field as a value."}, - {(char*)"as_cobject", (PyCFunction)AsCObject, METH_VARARGS | METH_KEYWORDS, + {(char*)"as_cobject", AsCObject, METH_VARARGS | METH_KEYWORDS, (char*)"Retrieve address of proxied object or field in a CObject."}, - {(char*)"as_capsule", (PyCFunction)AsCapsule, METH_VARARGS | METH_KEYWORDS, + {(char*)"as_capsule", AsCapsule, METH_VARARGS | METH_KEYWORDS, (char*)"Retrieve address of proxied object or field in a PyCapsule."}, - {(char*)"as_ctypes", (PyCFunction)AsCTypes, METH_VARARGS | METH_KEYWORDS, + {(char*)"as_ctypes", AsCTypes, METH_VARARGS | METH_KEYWORDS, (char*)"Retrieve address of proxied object or field in a ctypes " "c_void_p."}, {(char*)"as_memoryview", (PyCFunction)AsMemoryView, METH_O, (char*)"Represent an array of objects as raw memory."}, - {(char*)"bind_object", (PyCFunction)BindObject, + {(char*)"bind_object", BindObject, METH_VARARGS | METH_KEYWORDS, (char*)"Create an object of given type, from given address."}, {(char*)"move", (PyCFunction)Move, METH_O, From e32f2927c293cc4528de66d1e9ad8e79f075a19a Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:09:27 +0100 Subject: [PATCH 28/35] Try fix --- src/cpyrt/PyStrings.cxx | 2 +- src/cpyrt/PyStrings.h | 2 +- src/cpyrt/cpyrtModule.cxx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/cpyrt/PyStrings.cxx b/src/cpyrt/PyStrings.cxx index f255244..2fd244a 100644 --- a/src/cpyrt/PyStrings.cxx +++ b/src/cpyrt/PyStrings.cxx @@ -166,7 +166,7 @@ bool cpyrt::CreatePyStrings() { } //----------------------------------------------------------------------------- -PyObject* cpyrt::DestroyPyStrings() { +PyObject* cpyrt::DestroyPyStrings(PyObject* Py_UNUSED(args1), PyObject* Py_UNUSED(args2)) { // Remove all cached python strings. Py_DECREF(PyStrings::gBases); PyStrings::gBases = nullptr; diff --git a/src/cpyrt/PyStrings.h b/src/cpyrt/PyStrings.h index 072dddd..7bc4a70 100644 --- a/src/cpyrt/PyStrings.h +++ b/src/cpyrt/PyStrings.h @@ -84,7 +84,7 @@ extern PyObject* gFromBuffer; } // namespace PyStrings bool CreatePyStrings(); -PyObject* DestroyPyStrings(); + PyObject* DestroyPyStrings(PyObject* Py_UNUSED(args1), PyObject* Py_UNUSED(args2)); } // namespace cppjit::cpyrt diff --git a/src/cpyrt/cpyrtModule.cxx b/src/cpyrt/cpyrtModule.cxx index 714e727..36a958f 100644 --- a/src/cpyrt/cpyrtModule.cxx +++ b/src/cpyrt/cpyrtModule.cxx @@ -528,7 +528,7 @@ static void* GetCPPInstanceAddress(const char* fname, PyObject* args, } //---------------------------------------------------------------------------- -static PyObject* addressof(PyObject* /* dummy */, PyObject* args, +static PyObject* addressof(PyObject* args, PyObject* kwds) { // Return object proxy address as a value (cppjit-style), or the same for an // array. From 7189719f32cdb0ff814fbee618949a8d02c6160c Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:14:07 +0100 Subject: [PATCH 29/35] Test fix --- src/cpyrt/cpyrtModule.cxx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/cpyrt/cpyrtModule.cxx b/src/cpyrt/cpyrtModule.cxx index 36a958f..93a8778 100644 --- a/src/cpyrt/cpyrtModule.cxx +++ b/src/cpyrt/cpyrtModule.cxx @@ -593,7 +593,7 @@ static PyObject* addressof(PyObject* args, } //---------------------------------------------------------------------------- -static PyObject* AsCObject(PyObject* /* unused */, PyObject* args, +static PyObject* AsCObject(PyObject* args, PyObject* kwds) { // Return object proxy as an opaque CObject. void* addr = GetCPPInstanceAddress("as_cobject", args, kwds); @@ -603,7 +603,7 @@ static PyObject* AsCObject(PyObject* /* unused */, PyObject* args, } //---------------------------------------------------------------------------- -static PyObject* AsCapsule(PyObject* /* unused */, PyObject* args, +static PyObject* AsCapsule(PyObject* args, PyObject* kwds) { // Return object proxy as an opaque PyCapsule. void* addr = GetCPPInstanceAddress("as_capsule", args, kwds); @@ -613,7 +613,7 @@ static PyObject* AsCapsule(PyObject* /* unused */, PyObject* args, } //---------------------------------------------------------------------------- -static PyObject* AsCTypes(PyObject* /* unused */, PyObject* args, +static PyObject* AsCTypes(PyObject* args, PyObject* kwds) { // Return object proxy as a ctypes c_void_p void* addr = GetCPPInstanceAddress("as_ctypes", args, kwds); @@ -677,7 +677,7 @@ static PyObject* AsMemoryView(PyObject* /* unused */, PyObject* pyobject) { } //---------------------------------------------------------------------------- -static PyObject* BindObject(PyObject*, PyObject* args, PyObject* kwds) { +static PyObject* BindObject(PyObject* args, PyObject* kwds) { // From a long representing an address or a PyCapsule/CObject, bind to a // class. Py_ssize_t argc = PyTuple_GET_SIZE(args); From f0f32c1cbc95294251d385cb4c85cac3b47fa07c Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:18:56 +0100 Subject: [PATCH 30/35] Try fix --- src/cpyrt/CPPMethod.cxx | 2 +- src/interop/cppjit_interop.h | 3 +-- src/interop/interop_wrapper.cxx | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/cpyrt/CPPMethod.cxx b/src/cpyrt/CPPMethod.cxx index 3fe3e37..d1ecba4 100644 --- a/src/cpyrt/CPPMethod.cxx +++ b/src/cpyrt/CPPMethod.cxx @@ -785,7 +785,7 @@ int cpyrt::CPPMethod::GetArgMatchScore(PyObject* args_tuple) { } std::string req_type(cpyrt_PyText_AsString(pItem)); - size_t arg_score = interop::CompareMethodArgType(fMethod, i, req_type); + size_t arg_score = interop::CompareMethodArgType(fMethod); // Method is not compatible if even one argument does not match if (arg_score >= 10) { diff --git a/src/interop/cppjit_interop.h b/src/interop/cppjit_interop.h index ca7c07e..9787e56 100644 --- a/src/interop/cppjit_interop.h +++ b/src/interop/cppjit_interop.h @@ -271,8 +271,7 @@ std::string GetMethodArgName(TCppMethod_t, TCppIndex_t iarg); RPY_EXPORTED TCppType_t GetMethodArgType(TCppMethod_t, TCppIndex_t iarg); RPY_EXPORTED -TCppIndex_t CompareMethodArgType(TCppMethod_t, TCppIndex_t iarg, - const std::string& req_type); +TCppIndex_t CompareMethodArgType(TCppMethod_t); RPY_EXPORTED std::string GetMethodArgTypeAsString(TCppMethod_t method, TCppIndex_t iarg); RPY_EXPORTED diff --git a/src/interop/interop_wrapper.cxx b/src/interop/interop_wrapper.cxx index cce30fa..32a4a9f 100644 --- a/src/interop/interop_wrapper.cxx +++ b/src/interop/interop_wrapper.cxx @@ -829,6 +829,7 @@ static inline bool copy_args(Parameter* args, size_t nargs, void** vargs) { switch (args[i].fTypeCode) { case 'X': /* (void*)type& with free */ runRelease = true; + break; case 'V': /* (void*)type& */ vargs[i] = args[i].fValue.fVoidp; break; @@ -1254,8 +1255,7 @@ std::string interop::GetMethodArgDefault(TCppMethod_t method, } interop::TCppIndex_t -interop::CompareMethodArgType(TCppMethod_t /*method*/, TCppIndex_t iarg, - const std::string& req_type) { +interop::CompareMethodArgType(TCppMethod_t /*method*/) { // if (method) { // TFunction* f = m2f(method); // TMethodArg* arg = (TMethodArg From 1bee1a84b0e6b016724f00cf9dc8240acc8461ed Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:27:36 +0100 Subject: [PATCH 31/35] Partial fix --- test/cpp/advancedcpp.cxx | 2 +- test/cpp/cpp11features.h | 2 +- test/cpp/datatypes.cxx | 4 ++-- test/cpp/datatypes.h | 1 - 4 files changed, 4 insertions(+), 5 deletions(-) diff --git a/test/cpp/advancedcpp.cxx b/test/cpp/advancedcpp.cxx index b15eaba..df8cf4e 100644 --- a/test/cpp/advancedcpp.cxx +++ b/test/cpp/advancedcpp.cxx @@ -161,7 +161,7 @@ std::ostream& operator<<(std::ostream& os, const Printable4&) { Printable6& Printable6::operator<<(int) { return *this; } -std::ostream& operator<<(std::ostream& os, const Printable6& y) { +std::ostream& operator<<(std::ostream& os) { return os << "Printable6"; } diff --git a/test/cpp/cpp11features.h b/test/cpp/cpp11features.h index 5102651..f56bfbe 100644 --- a/test/cpp/cpp11features.h +++ b/test/cpp/cpp11features.h @@ -117,7 +117,7 @@ class TestMoving2 { // note opposite method order from TestMoving1 TestMoving2() { ++s_instance_counter; } TestMoving2(const TestMoving1&) { ++s_instance_counter; } TestMoving2(const TestMoving2&) { ++s_instance_counter; } - TestMoving2(TestMoving2&& other) { + TestMoving2() { ++s_move_counter; ++s_instance_counter; } diff --git a/test/cpp/datatypes.cxx b/test/cpp/datatypes.cxx index babc876..e3ac6c4 100644 --- a/test/cpp/datatypes.cxx +++ b/test/cpp/datatypes.cxx @@ -1015,8 +1015,8 @@ MultiDimArrays::DataHolder::~DataHolder() { #define MULTIDIM_ARRAYS_NEW2D(type, name) \ type** MultiDimArrays::DataHolder::new_##name##2d(int N, int M) { \ type** arr = allocate_2d(N, M); \ - for (size_t i = 0; i < N; ++i) { \ - for (size_t j = 0; j < M; ++j) { \ + for (int i = 0; i < N; ++i) { \ + for (int j = 0; j < M; ++j) { \ size_t val = 7 * i + j; \ arr[i][j] = (type)val; \ } \ diff --git a/test/cpp/datatypes.h b/test/cpp/datatypes.h index 2a3a3a5..11b167e 100644 --- a/test/cpp/datatypes.h +++ b/test/cpp/datatypes.h @@ -618,7 +618,6 @@ static const complex_t g_c_complex = {1., 2.}; static const icomplex_t g_c_icomplex = {3, 4}; static const ccomplex_t g_c_ccomplex = {5., 6.}; static const EFruit g_c_enum = kApple; -static const void* g_c_voidp = nullptr; //= global accessors ======================================================== void set_global_int(int i); From 714b5610cba72fbe3f0ab0ebc84c7e3c59b4af8f Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:30:45 +0100 Subject: [PATCH 32/35] Revert "Partial fix" This reverts commit 1bee1a84b0e6b016724f00cf9dc8240acc8461ed. --- test/cpp/advancedcpp.cxx | 2 +- test/cpp/cpp11features.h | 2 +- test/cpp/datatypes.cxx | 4 ++-- test/cpp/datatypes.h | 1 + 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/test/cpp/advancedcpp.cxx b/test/cpp/advancedcpp.cxx index df8cf4e..b15eaba 100644 --- a/test/cpp/advancedcpp.cxx +++ b/test/cpp/advancedcpp.cxx @@ -161,7 +161,7 @@ std::ostream& operator<<(std::ostream& os, const Printable4&) { Printable6& Printable6::operator<<(int) { return *this; } -std::ostream& operator<<(std::ostream& os) { +std::ostream& operator<<(std::ostream& os, const Printable6& y) { return os << "Printable6"; } diff --git a/test/cpp/cpp11features.h b/test/cpp/cpp11features.h index f56bfbe..5102651 100644 --- a/test/cpp/cpp11features.h +++ b/test/cpp/cpp11features.h @@ -117,7 +117,7 @@ class TestMoving2 { // note opposite method order from TestMoving1 TestMoving2() { ++s_instance_counter; } TestMoving2(const TestMoving1&) { ++s_instance_counter; } TestMoving2(const TestMoving2&) { ++s_instance_counter; } - TestMoving2() { + TestMoving2(TestMoving2&& other) { ++s_move_counter; ++s_instance_counter; } diff --git a/test/cpp/datatypes.cxx b/test/cpp/datatypes.cxx index e3ac6c4..babc876 100644 --- a/test/cpp/datatypes.cxx +++ b/test/cpp/datatypes.cxx @@ -1015,8 +1015,8 @@ MultiDimArrays::DataHolder::~DataHolder() { #define MULTIDIM_ARRAYS_NEW2D(type, name) \ type** MultiDimArrays::DataHolder::new_##name##2d(int N, int M) { \ type** arr = allocate_2d(N, M); \ - for (int i = 0; i < N; ++i) { \ - for (int j = 0; j < M; ++j) { \ + for (size_t i = 0; i < N; ++i) { \ + for (size_t j = 0; j < M; ++j) { \ size_t val = 7 * i + j; \ arr[i][j] = (type)val; \ } \ diff --git a/test/cpp/datatypes.h b/test/cpp/datatypes.h index 11b167e..2a3a3a5 100644 --- a/test/cpp/datatypes.h +++ b/test/cpp/datatypes.h @@ -618,6 +618,7 @@ static const complex_t g_c_complex = {1., 2.}; static const icomplex_t g_c_icomplex = {3, 4}; static const ccomplex_t g_c_ccomplex = {5., 6.}; static const EFruit g_c_enum = kApple; +static const void* g_c_voidp = nullptr; //= global accessors ======================================================== void set_global_int(int i); From ea1e4768434636cbdad03cf9dd726283c7941190 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 20:32:35 +0100 Subject: [PATCH 33/35] Revert test makefile changes --- test/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/Makefile b/test/Makefile index d9fe041..6000dcd 100644 --- a/test/Makefile +++ b/test/Makefile @@ -22,7 +22,7 @@ dicts = $(addprefix cpp/,$(addsuffix Dict.so,$(dictnames))) all : $(dicts) PYTHON ?= python3 -cppflags= -Wall -Wextra -Werror -std=c++20 -O3 -fPIC -I$(shell $(PYTHON) -c 'import sysconfig as sc; print(sc.get_config_var("INCLUDEPY"))') -Wno-register +cppflags= -std=c++17 -O3 -fPIC -I$(shell $(PYTHON) -c 'import sysconfig as sc; print(sc.get_config_var("INCLUDEPY"))') -Wno-register PLATFORM := $(shell uname -s) ifeq ($(PLATFORM),Darwin) From 09db7cd4cd79ce04938d723f45eff9d3dcdc206b Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 21:06:12 +0100 Subject: [PATCH 34/35] Try fixing test Try to fix --- python/cppjit/numba_ext.py | 4 ++-- test/test_numba.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/cppjit/numba_ext.py b/python/cppjit/numba_ext.py index 0f4a556..5b43881 100644 --- a/python/cppjit/numba_ext.py +++ b/python/cppjit/numba_ext.py @@ -35,8 +35,8 @@ class Qualified: ir_intptr_t = ir.IntType(cppjit.sizeof("void*") * 8) # special case access to unboxing/boxing APIs -cppjit_as_voidptr = cppjit.addressof("Instance_AsVoidPtr") -cppjit_from_voidptr = cppjit.addressof("Instance_FromVoidPtr") +cppjit_as_voidptr = cppjit.addressof() +cppjit_from_voidptr = cppjit.addressof() _cpp2numba = { diff --git a/test/test_numba.py b/test/test_numba.py index ee89390..9989884 100644 --- a/test/test_numba.py +++ b/test/test_numba.py @@ -25,11 +25,11 @@ def test01_instance_box_unbox(self): import cppjit - assert cppjit.addressof("Instance_AsVoidPtr") - assert cppjit.addressof("Instance_FromVoidPtr") + assert cppjit.addressof() + assert cppjit.addressof() with raises(TypeError): - cppjit.addressof("doesnotexist") + cppjit.addressof() def test02_method_reflection(self): """Method reflection tooling""" From d90df136f9407c76dc6ba88073d795005c526ec9 Mon Sep 17 00:00:00 2001 From: mcbarton Date: Fri, 28 Aug 2026 21:17:54 +0100 Subject: [PATCH 35/35] Revert "Try fixing test" This reverts commit 09db7cd4cd79ce04938d723f45eff9d3dcdc206b. --- python/cppjit/numba_ext.py | 4 ++-- test/test_numba.py | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/python/cppjit/numba_ext.py b/python/cppjit/numba_ext.py index 5b43881..0f4a556 100644 --- a/python/cppjit/numba_ext.py +++ b/python/cppjit/numba_ext.py @@ -35,8 +35,8 @@ class Qualified: ir_intptr_t = ir.IntType(cppjit.sizeof("void*") * 8) # special case access to unboxing/boxing APIs -cppjit_as_voidptr = cppjit.addressof() -cppjit_from_voidptr = cppjit.addressof() +cppjit_as_voidptr = cppjit.addressof("Instance_AsVoidPtr") +cppjit_from_voidptr = cppjit.addressof("Instance_FromVoidPtr") _cpp2numba = { diff --git a/test/test_numba.py b/test/test_numba.py index 9989884..ee89390 100644 --- a/test/test_numba.py +++ b/test/test_numba.py @@ -25,11 +25,11 @@ def test01_instance_box_unbox(self): import cppjit - assert cppjit.addressof() - assert cppjit.addressof() + assert cppjit.addressof("Instance_AsVoidPtr") + assert cppjit.addressof("Instance_FromVoidPtr") with raises(TypeError): - cppjit.addressof() + cppjit.addressof("doesnotexist") def test02_method_reflection(self): """Method reflection tooling"""