From 03b16e6d939ee0832ec77547a6e89137005ae82a Mon Sep 17 00:00:00 2001 From: Aaron Jomy Date: Fri, 28 Aug 2026 17:53:47 +0200 Subject: [PATCH] [cpyrt] Raise TypeError when a template argument names no C++ type Every Python object has a __name__, so an object naming no C++ type reached AddTypeName's fallback, where GetType() returned null; that null was then pushed as a template argument and dereferenced by IsEnumType. Skip such an argument, and report the string-based path's failure as TypeError like the type-based one already does. --- src/cpyrt/Utility.cxx | 8 +++++++- test/test_regression.py | 12 ++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/src/cpyrt/Utility.cxx b/src/cpyrt/Utility.cxx index 9e947e9..0761fc5 100644 --- a/src/cpyrt/Utility.cxx +++ b/src/cpyrt/Utility.cxx @@ -659,7 +659,7 @@ std::string cpyrt::Utility::ConstructTemplateArgs(PyObject* pyname, (args ? PyTuple_GET_ITEM(args, i) : nullptr), pref, pcnt)) { PyErr_SetString( - PyExc_SyntaxError, + PyExc_TypeError, "could not construct C++ name from provided template argument."); return ""; } @@ -827,6 +827,12 @@ static bool AddTypeName(std::vector& types, PyObject* tn, if (tpName) { interop::TCppType_t type = interop::GetType( cpyrt_PyText_AsString(tpName), /* enable_slow_lookup */ true); + if (!type) { + // any Python object has a __name__; one that does not name a C++ + // type contributes no argument + Py_DECREF(tpName); + continue; + } if (interop::IsEnumType(type)) { PyObject* value_int = PyNumber_Index(tn); if (!value_int) { diff --git a/test/test_regression.py b/test/test_regression.py index af96a3b..945e4d3 100644 --- a/test/test_regression.py +++ b/test/test_regression.py @@ -1631,3 +1631,15 @@ def test51_nontype_enum_template_arg(self): # ...nor leave the interpreter unable to compile a later call wrapper assert ns.probe(41) == 42 + + def test52_no_cpp_name_for_template_arg(self): + """Template arguments with no C++ equivalent raise TypeError""" + + import cppjit + + # a lambda has a __name__ ("") that resolves to no C++ type + with raises(TypeError): + cppjit.gbl.std.vector[lambda: None] + + with raises(TypeError): + cppjit.gbl.std.vector[object()]