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()]