From 773667a0e45546267bfbd8ba1f06c8202e2dfef9 Mon Sep 17 00:00:00 2001 From: da-woods Date: Tue, 5 Dec 2023 18:18:54 +0000 Subject: [PATCH] Fix an issue trying list.index indexing in FusedNode In some Python versions, generating the error message when .index fails to find an index leads to a compiler crash. Fix this by not relying on type being fully set up while generating __str__. Fixes #5894 and #5588 --- Cython/Compiler/PyrexTypes.py | 7 ++++++- tests/run/fused_cpdef.pxd | 4 ++++ tests/run/fused_cpdef.pyx | 13 +++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 tests/run/fused_cpdef.pxd diff --git a/Cython/Compiler/PyrexTypes.py b/Cython/Compiler/PyrexTypes.py index b6af4a5ab3f..1fd46754e06 100644 --- a/Cython/Compiler/PyrexTypes.py +++ b/Cython/Compiler/PyrexTypes.py @@ -3294,7 +3294,12 @@ def declaration_code(self, entity_code, if self.is_overridable: arg_decl_list.append("int %s" % Naming.skip_dispatch_cname) if self.optional_arg_count: - arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname)) + if self.op_arg_struct: + arg_decl_list.append(self.op_arg_struct.declaration_code(Naming.optional_args_cname)) + else: + # op_arg_struct may not be initialized at this point if this class is being used + # to prepare a Python error message or similar. In this case, just omit the args. + assert for_display if self.has_varargs: arg_decl_list.append("...") arg_decl_code = ", ".join(arg_decl_list) diff --git a/tests/run/fused_cpdef.pxd b/tests/run/fused_cpdef.pxd new file mode 100644 index 00000000000..e4f4a600dd6 --- /dev/null +++ b/tests/run/fused_cpdef.pxd @@ -0,0 +1,4 @@ +cimport cython + +cdef class C: + cpdef object has_default_struct(self, cython.floating x, a=?) diff --git a/tests/run/fused_cpdef.pyx b/tests/run/fused_cpdef.pyx index 3979570b75c..4f569c24c3e 100644 --- a/tests/run/fused_cpdef.pyx +++ b/tests/run/fused_cpdef.pyx @@ -205,3 +205,16 @@ def test_defaults(): >>> mutable_default(3,[]) [3] """ + +cdef class C: + cpdef object has_default_struct(self, cython.floating x, a=None): + return x, a + +# https://github.com/cython/cython/issues/5588 +# On some Python versions this was causing a compiler crash +def test_call_has_default_struct(C c, double x): + """ + >>> test_call_has_default_struct(C(), 5.) + (5.0, None) + """ + return c.has_default_struct(x)