[Cython] can we deprecate for-from loops?

Stefan Behnel stefan_ml at behnel.de
Fri Oct 16 02:26:26 EDT 2015

Jakub Wilk schrieb am 15.10.2015 um 23:26:
> * Stefan Behnel, 2015-10-11, 16:30:
>> The syntax construct "for i from 0 <= i < 10" has been silently outdated
>> for years. Can we start issuing a warning that normal range() loops are
>> preferred?
> Hmm. AFAICS, Cython doesn't aways optimize range() loops that well... For
> the attached example code, Cython 0.23.4 generated nice for loops for the
> for_from() function:
>  for (__pyx_t_1 = 0; __pyx_t_1 < 10; __pyx_t_1++) {
>    ...
>    for (__pyx_t_3 = 0; __pyx_t_3 < 10; __pyx_t_3++) {
>    ...
> but not for the for_range() function:
>  __pyx_t_1 = __Pyx_PyObject_Call(__pyx_builtin_range, __pyx_tuple_, NULL); ...
>  ...

Your example was:

def for_from():
    for i from 0 <= i < 10:
        for j from 0 <= j < 10:
            print(i + j)

def for_range():
    for i in range(10):
        for j in range(10):
            print(i + j)

The reason why i and j are not automatically being inferred as C long
variables (although the range obviously fits into a long) is not the range
loop but the fact that afterwards you are doing "i + j". Cython doesn't see
their original value range at that point any more and thus cannot determine
that this operation will not overflow in C long space, so it takes the safe
route and makes both Python objects. If instead you did

  for i in range(10):
     for j in range(10):

then Cython would consider C long a safe choice for i and j. You can get
the same effect by setting the directive "infer_types=True", which enables
full (unsafe) type inference.

BTW, my guess is that in the first example, only the C for-loop is executed
in C space. The values would be converted to a Python object right
afterwards, which, as Robert said, pretty much ruins the advantage.


More information about the cython-devel mailing list