New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[BUG] Possible regression in handling of default function arguments #6192
Comments
The bad commit is 2c8e7b2. Although my feeling is that commit likely isn't the real problem here. |
I originally suspected that the issue might have been related to the new |
No - there's about 3 different ways of handling defaults depending on how "literal" those defaults are and what type of function it is. It all goes wrong if an optimization accidentally shuffles something between the different mechanisms late in the process. In this case |
Fixes cython#6192. The basic issue is that the argument is deduced to be dynamic default argument, and then at a late stage is optimized into an empty string literal. This means that correct handling code for the literal is skipped because is has "is_dynamic" set, and the correct assignment code into the dynamic struct is skipped because it's a literal. I think the solution is to make the code that writes into the dynamic struct more tolerant of literals.
Describe the bug
A function with a default parameter value of
str()
or evenint()
appears to to get mapped tonull
. If this value is then later used in a location that performs a null check, such as assigning the value to a dictionary, then the resulting code segfaults. This behavior is new in 3+; in <3, cython appears to correctly map a value such asstr()
into an empty string, and a value such asint()
to a zero.Looking at the cythonized code, I can see that a value such as
''
is treated as an immediate value, whereasstr()
is treated as a dynamic default argument.Looking at the cython 0.29 code, I think this is relevant section:
You can see the
__pyx_arg_this_crashes
getting assigned to the default value ofstr()
(PyString_Type).In contrast, under 3, it becomes:
With:
This is just copying values out of the defaults object into a tuple though. I can't find anywhere where
__pyx_arg_this_crashes
is actually set.Any help you can offer would be appreciated.
Repro:
Using the attached code snippet, invoked as pure-python:
python3 -c "from snippet import run_it; run_it()"
If I cythonize the attached code using:
cythonize -i -f snippet.py
Then result segfaults.
Code to reproduce the behaviour:
Expected behaviour
The code outputs:
{'this_works': '', 'this_crashes': ''}
OS
Linux
Python version
3.9.16
Cython version
3.0.10
Additional context
No response
The text was updated successfully, but these errors were encountered: