[Cython] pure mode quirk

Robert Bradshaw robertwb at gmail.com
Thu May 10 19:34:06 CEST 2012


On Thu, May 10, 2012 at 2:25 AM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> Hi,
>
> when declaring a C function in pure mode, you eventually end up with this:
>
>    @cython.cfunc
>    @cython.returns(cython.bint)
>    @cython.locals(a=cython.int, b=cython.int, c=cython.int)
>    def c_compare(a,b):
>        c = 5
>        return a == b + c
>
> That is very verbose, making it hard to find the name of the actual
> function. It's also not very intuitive that @cython.locals() is the way to
> declare arguments.
>
> I would find it more readable to support this:
>
>    @cython.cfunc(cython.bint, a=cython.int, b=cython.int)
>    @cython.locals(c=cython.int)
>    def c_compare(a,b):
>        c = 5
>        return a == b
>
> But the problem here is that it conflicts with
>
>    @cython.cfunc
>    def c_compare(a,b):
>        c = 5
>        return a == b
>
> when executed from Shadow.py. How should the fake decorator know that it is
> being called with a type as first argument and not with the function it
> decorates? Legacy, legacy ...
>
> An alternative would be this:
>
>    @cython.cfunc(a=cython.int, b=cython.int, _returns=cython.bint)
>    @cython.locals(c=cython.int)
>    def c_compare(a,b):
>        c = 5
>        return a == b
>
> But that's not clearer than an explicit decorator for the return value.
>
> I'm somewhat concerned about the redundancy this introduces with @locals(),
> which could still be used to declare argument types (even conflicting
> ones). However, getting rid of the need for a separate @returns() seems
> worthwhile by itself, so this might provide a compromise:
>
>    @cython.cfunc(returns=cython.bint)
>    @cython.locals(a=cython.int, b=cython.int, c=cython.int)
>    def c_compare(a,b):
>        c = 5
>        return a == b + c
>
> This would work in Shadow.py because it's easy to distinguish between a
> positional argument (the decorated function) and a keyword argument
> ("returns"). It might lead to bugs in user code, though, if they forget to
> pass the return type as a keyword argument. Maybe just a minor concern,
> because the decorator doesn't read well without the keyword.
>
> What do you think? Is this worth doing something about at all?

I didn't implement it this way originally because of the whole
called/not ambiguity, but I didn't think about taking a keyword and
using that to distinguish. (Testing the type of the input seemed to
hackish...) I'm +1 for this, as well as accepting argument types in
the cfunc decorator as well. There is a bit of overlap as "returns"
has a special meaning (vs. an argument named returns) but I think
that's OK, and cython.locals should still work.

- Robert


More information about the cython-devel mailing list