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
Infer float in "safe" mode #5234
Conversation
It currently infers to object, and double seems better than object. I've picked "double" on the basis that this will always give the same precision answer as Python so it seems to match the semantics of "safe" mode better.
tests/run/type_inference.pyx
Outdated
cdef float fl = 5.0 | ||
from_fl = fl | ||
assert typeof(from_fl) == "double", typeof(from_fl) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems … surprising. Why should we infer double
for a clear C float
? It's one thing to reduce Python float
to C double
, but C float
should not be affected by this.
There seems to be a conflict of this PR with #5058. CI fails with
The failing test code is: # because tuple is specifically special cased to go to ctuple where possible
def test_tuple_without_typing(a: tuple[cython.int, cython.float], b: tuple[cython.int, ...],
c: tuple[cython.int, object] # cannot be a ctuple
):
"""
>>> test_tuple_without_typing((1, 1.0), (1, 1.0), (1, 1.0))
int
int
Python object
Python object
(int, float)
tuple object
tuple object
tuple object
tuple object
"""
x: tuple[int, float] = (a[0], a[1]) # note: Python int/float, not cython.int/float
y: tuple[cython.int, ...] = (1,2.)
plain_tuple: tuple = ()
z = a[0] # should infer to C int
p = x[1] # should infer to Python float -> C double
print(cython.typeof(z))
print("int" if cython.compiled and cython.typeof(x[0]) == "Python object" else cython.typeof(x[0])) # FIXME: infer Python int
print(cython.typeof(p) if cython.compiled or cython.typeof(p) != 'float' else "Python object") # FIXME: infer C double
... I think we should be inferring Python float or C double instead of C float here. Might be a mismatch in the "looking for C type or Python type here" context. |
@scoder here's what I think is happening:
a is a c-tuple here or (C int, C float)
x is just typed as a regular tuple from the annotation, since it can't understand the Py-type subscripts
There's a bit of typing logic that says " (I actually made this change in |
Shouldn't |
So the current situation is:
is just interpreted as However, it knows the I could see the argument for inferring a C |
…lly be inferring either Python float or C double from the Python type annotation of 'x' instead, but as it stands, we infer the types from the ctuple assignment.
The missing type inference for Python container types is really a missing feature, more than a bug. I've changed the test to match the current behaviour. The test is a bit contrived anyway. Mixing Python float declarations arbitrarily with C float/double declarations should best be avoided. |
It currently infers to object, and double seems better than object.I've picked "double" on the basis that this will always give the same precision answer as Python so it seems to match the semantics of "safe" mode better.Now does the simpler thing and just keeps it as a C float
Closes #5202