Cython: (Why / When) Is it preferable to use Py_ssize_t for indexing?
Asked Answered
K

2

49

This is a follow-up to this question.

(Why / When) Is it preferable to use Py_ssize_t for indexing? In the docs I just found

# Purists could use "Py_ssize_t" which is the proper Python type for
# array indices.

-> Does that mean always when indexing NumPy/Cython - array(s)/-views one should use Py_ssize_t?

-> Is Py_ssize_t e. g. an unsigned int so that I can't used @cython.boundscheck(False)

Kalisz answered 8/1, 2014 at 5:2 Comment(1)
Also, from the Cython docs: "Py_ssize_t is the proper C type for Python array indices."Entice
A
47

Py_ssize_t is signed. See PEP 353, where it says "A new type Py_ssize_t is introduced, which has the same size as the compiler's size_t type, but is signed. It will be a typedef for ssize_t where available."

You should use Py_ssize_t for indexing. I didn't find a definitive statement of this in the Cython docs, but Stefan Behnel, a Cython developer, said as much in an email (https://groups.google.com/forum/#!topic/cython-users/brENF_M9zxM):

As a general remark, you are using ints as indices. You should use the Py_ssize_t type instead (or size_t, if you prefer an unsigned type) to properly accommodate for 64 bit architectures.

Aguish answered 8/1, 2014 at 5:12 Comment(2)
> ... or size_t, if you prefer an unsigned type ... It's worth pointing out that in general that's not such a good idea. I've seen code which blows up because it wasn't detecting error returns from some of the functions in the C Python library which return -1 to signal an error, which gets lost if you're using an unsigned type.Janiuszck
@BobKline The advice is to use size_t for indices specifically, not everywhere you might otherwise use an int. (If a negative value is being used for an index, it's going to blow up one way or the other, whether because it got implicitly converted to an unsigned, or because we index off the beginning of the array. So we might as well use the type that's guaranteed to be able to represent all valid indices.)Ciliary
B
29

Py_ssize_t is a typedef used internally in the implementation of CPython (the C implementation of Python - I'm not talking about Cython there, I'm talking about CPython). It's used everywhere Python C API functions accept or return a C-level integer that can be used for indexing Python sequences. That's why it's "the correct" type to use for an index.

Py_ssize_t in turn resolves to whatever the platform spelling is for the signed variant of the platform C's unsigned size_t type. So it's some signed integer type, but its width (number of bits) depends on the platform you're using.

Berkowitz answered 8/1, 2014 at 5:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.