Invalid index type ?

36 views
Skip to first unread message

Stu

unread,
Aug 12, 2017, 3:06:31 PM8/12/17
to cython...@googlegroups.com
I tried compiling a .pyx file from pygame and hit "Invalid index type".
It seems like it works in cython 0.20, but not in 0.21


Any idea what I need to fix ?



Here is the error -




Error compiling Cython file:
------------------------------------------------------------
...
        if num_events >= 1:
            for ev_no in range(num_events):
                events.append(
                    [
                        [
                            buffer[ev_no].message & 0xFF,
                                 ^
------------------------------------------------------------

pypm.pyx:697:34: Invalid index type 'PmError'

Error compiling Cython file:
------------------------------------------------------------
...
            for ev_no in range(num_events):
                events.append(
                    [
                        [
                            buffer[ev_no].message & 0xFF,
                            (buffer[ev_no].message >> 8) & 0xFF,
                                  ^
------------------------------------------------------------

pypm.pyx:698:35: Invalid index type 'PmError'

Error compiling Cython file:
------------------------------------------------------------
...
                events.append(
                    [
                        [
                            buffer[ev_no].message & 0xFF,
                            (buffer[ev_no].message >> 8) & 0xFF,
                            (buffer[ev_no].message >> 16) & 0xFF,
                                  ^
------------------------------------------------------------

pypm.pyx:699:35: Invalid index type 'PmError'

Error compiling Cython file:
------------------------------------------------------------
...
                    [
                        [
                            buffer[ev_no].message & 0xFF,
                            (buffer[ev_no].message >> 8) & 0xFF,
                            (buffer[ev_no].message >> 16) & 0xFF,
                            (buffer[ev_no].message >> 24) & 0xFF
                                  ^
------------------------------------------------------------

pypm.pyx:700:35: Invalid index type 'PmError'

Error compiling Cython file:
------------------------------------------------------------
...
                            buffer[ev_no].message & 0xFF,
                            (buffer[ev_no].message >> 8) & 0xFF,
                            (buffer[ev_no].message >> 16) & 0xFF,
                            (buffer[ev_no].message >> 24) & 0xFF
                        ],
                        buffer[ev_no].timestamp
                             ^
------------------------------------------------------------

pypm.pyx:702:30: Invalid index type 'PmError'

Stefan Behnel

unread,
Aug 17, 2017, 7:44:50 AM8/17/17
to cython...@googlegroups.com
Stu schrieb am 12.08.2017 um 21:06:
> I tried compiling a .pyx file from pygame and hit "Invalid index type".
>
> https://github.com/pygame/pygame/blob/master/src/pypm.pyx
>
> It seems like it works in cython 0.20, but not in 0.21
>
>
> Any idea what I need to fix ?
>
> Here is the error -
>
> Error compiling Cython file:
> ------------------------------------------------------------
> ...
> if num_events >= 1:
> for ev_no in range(num_events):
> events.append(
> [
> [
> buffer[ev_no].message & 0xFF,
> ^
> ------------------------------------------------------------
>
> pypm.pyx:697:34: Invalid index type 'PmError'

It's inferring the loop variable "ev_no" as enum type "PmError" because
that's what the type of "num_events" is. You can work around that with an
explicit cast like this:

for ev_no in range(<int>num_events):

although I'd rather type the "num_events" variable as "int" right away,
given your numeric comparison right above that line. Taking the range of an
enum value, especially an extern enum, has a bit of a code smell for me.

That being said, it could be argued that enum types as loop variables are
not something that Cython should ever infer itself. I'll see if I can do
something about it.

Stefan

Stefan Behnel

unread,
Aug 17, 2017, 8:17:24 AM8/17/17
to cython...@googlegroups.com
Turns out that that's not trivial to change in Cython because in most
cases, inferring an enum type *is* actually the correct thing to do. And in
the case of an untyped loop variable, it's also not *entirely* wrong. Plus,
people tend to use (extern) enum declarations for all sorts of things,
including arbitrary (numeric) constants.

Would anyone object to leaving it as it is?

While at it, I noticed that the loop didn't get converted to an actual C
integer loop, despite having the loop variable inferred as C enum (i.e. it
used slow iteration and converted back to C enum in the loop). I changed
that here:

https://github.com/cython/cython/commit/bd4658c4be70b45d4a20d6f73346dcb8ce2bc693

Stefan

Stefan Behnel

unread,
Aug 17, 2017, 11:32:56 AM8/17/17
to cython...@googlegroups.com
... and that broke the iteration under C++, which disallows arbitrary
integer assignments to enum variables. So I ended up implementing the
internally generated C for-loop as an integer loop and casting the current
loop value to the correct enum value.

https://github.com/cython/cython/commit/7e4f2ac0f9c369acefb916ba3b90196ee635de1e

Note that this does not help with the original problem, as the loop
variable is still inferred as enum. But at least the generated C(++) code
is correct now.

Stefan

Stu

unread,
Aug 23, 2017, 8:59:08 AM8/23/17
to cython...@googlegroups.com
Thanks for having a look at this and mentioning where to put the cast to make it work.

This is probably the most cython code I've tried to understand, and had a vague feeling of the code smell, using an Enum like that, but not enough cython experience to work out how to rewrite it differently.

--

---
You received this message because you are subscribed to the Google Groups "cython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cython-users+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Robert Bradshaw

unread,
Aug 24, 2017, 12:00:26 AM8/24/17
to cython...@googlegroups.com
I would have a slight preference for typing the loop variable as a
plain int, but don't feel too strongly. There would also be the
question of how to pick an integer that's large enough.
>
> While at it, I noticed that the loop didn't get converted to an actual C
> integer loop, despite having the loop variable inferred as C enum (i.e. it
> used slow iteration and converted back to C enum in the loop). I changed
> that here:
>
> https://github.com/cython/cython/commit/bd4658c4be70b45d4a20d6f73346dcb8ce2bc693

As above, we can't guarantee that long is large enough to hold the
enum values(s). It may be too large to fit into a signed value, but
also may allow negative values.
Reply all
Reply to author
Forward
0 new messages