On 27/09/18 22:50, Robert Bradshaw wrote:

    On Thu, Sep 27, 2018 at 10:38 AM Matti Picus
    <matti.pi...@gmail.com <mailto:matti.pi...@gmail.com>> wrote:
    To solve issue #2498, I did some experiments
    https://github.com/cython/cython/issues/2498#issuecomment-414543549
    with
    hiding direct field access in an external extension type (documented
    here
    
https://cython.readthedocs.io/en/latest/src/userguide/extension_types.html#external-extension-types).

    The idea is to write `a.ndims` in cython (in plain python code),
    and in
    C magically get the attribute lookup converted into a
    `PyArray_NDIMS(a)`
    getter, which could be a macro or a c-function.

    The experiments proved fruitful, and garnered some positive
    feedback so
    I am pushing forward.

    I would like to get some feedback on syntax before I progress too
    far.
    Should the syntax be extended to support

    ctypedef class numpy.ndarray [object PyArrayObject]:cdef: # Convert
    python __getattr__ access to c functions. int ndims PyArray_NDIMS |


    or perhaps a decorator, like Python

    |ctypedef class numpy.ndarray [object PyArrayObject]: cdef: # Convert
    python __getattr__ access to c functions. @property  cdef int
    ndims(self): return PyArray_NDIMS(self) or something else? The second
    seems more wordy but more explicit. I don't know which would be
    easier
to implement or require more effort to test and maintain.

    Matti |

Thanks for looking into this!

My preference would be to use the @property syntax, as this will be immediately understandable to any Cython user and could contain arbitrary code, rather than just a macro call.

There are, however, a couple of downsides. The first is that it may not be clear when accessing an attribute that a full function call may be invoked. (Arguably this is the same issue one has with Python, but there attribute access is already expensive. The function could be inline as well if desired.) The second is that this means that this attribute is no longer an lvalue. The last is that it's a bit special to be defining methods on an extern class. Maybe it would have to be inline if it's in the pxd?

If we're going to be defining a special syntax, I might prefer something like

cdef extern class ...:
    int ndims "PyArray_NDIMS(*)"

which more resembles

    int ndims "nd"

Open to bikeshedding on what the "self" placeholder should be. As before, should the ndims lose its lvalue status in this case, or not (in case the accessor is really a macro intended to be used like this)?


Sorry about the formatting messup, the original proposal was supposed to be (this time using double spacing to make sure it works):

-----------------------------------------------------------------------------

cdef extern class ...:

    @property

    cdef int ndims(self):

        return PyArray_NDIMS(self)

----------------------------------------------------------

vs

--------------------------------------------------------

cdef extern class ...:

    cdef int ndims PyArray_NDIMS

--------------------------------------------------------

The proposal  is for a getter via a C function or a macro. NumPy's current public API uses a mix. Currently I am interested in getters that would not allow lvalue at all. Maybe in the future we will have fast rvalue setter functions in NumPy, but the current API does not support them. It remains to be seem how much slowdown we see in real-life benchmarks when calling a small C function from a different shared object to access attributes rather than directly accessing them via struct fields.

As I point out in the "experiment" comment referenced above, pandas has code that needs lvalue access to ndarray data, so they would be stuck with the old API which is deprecated but still works for now. Scipy has no such code and oculd move forward to the newer API.

As far as bikeshedding the "self" parameter, I would propose doing without, and indeed I successfully hacked Cython to use the second proposal with no self argument and no quotations.

Matti
_______________________________________________
cython-devel mailing list
cython-devel@python.org
https://mail.python.org/mailman/listinfo/cython-devel

Reply via email to