[Cython] Fused Types

Robert Bradshaw robertwb at math.washington.edu
Tue Apr 26 20:05:48 CEST 2011

On Tue, Apr 26, 2011 at 8:18 AM, mark florisson
<markflorisson88 at gmail.com> wrote:
> On 26 April 2011 16:43, Stefan Behnel <stefan_ml at behnel.de> wrote:
>> mark florisson, 26.04.2011 16:23:
>>> I've been working a bit on fused types
>>> (http://wiki.cython.org/enhancements/fusedtypes), and I've got it to
>>> generate code for every permutation of specific types. Currently it
>>> only works for cdef functions. Now in SimpleCallNode I'm trying to use
>>> PyrexTypes.best_match() to find the function with the best signature,
>>> but it doesn't seem to take care of coercions, e.g. it calls
>>> 'assignable_from' on the dst_type (e.g. char *), but for
>>> BuiltinObjectType (a str) this returns false.
>> Which is correct. "char*" cannot coerce from/to "str". It can coerce to
>> "bytes", though.
>> http://wiki.cython.org/enhancements/stringliterals
> Right, I see, so the thing is that I was using string literals which
> should be inferred as the bytes type when they are assigned to a char
> *. The thing is that because the type is fused, the argument may be
> anything, so I was hoping best_match would figure it out for me.
> Apparently it doesn't, and indeed, this example doesn't work:
> cdef extern from "Foo.h":
>    cdef cppclass Foo:
>        Foo(char *)
>        Foo(int)
> cdef char *foo = "foo"
> cdef Foo* foo = new Foo("foo") # <- this doesn't work ("no suitable
> method found")
> cdef Foo* bar = new Foo(foo)   # <- this works
> So that's pretty lame, I think I should fix that.


>>> Why is this the case,
>>> don't calls to overloaded C++ methods need to dispatch properly here
>>> also?
>> If this doesn't work, I assume it just isn't implemented.
>>> Other issues are public and api declarations. So should we support
>>> that at all? We could define a macro that calls a function that does
>>> the dispatch. So e.g. for this
>>> ctypedef cython.fused_type(typeA, typeB) dtype
>>> cdef func(dtype x):
>>>     ...
>>> we would get two generated functions, say, __pyx_typeA_func and
>>> __pyx_typeB_func. So we could have a macro get_func(dtype) or
>>> something that then substitutes __pyx_get_func(#dtype), where
>>> __pyx_get_func returns the pointer to the right function based on the
>>> type names. I'm not sure we should support it, right now I just put
>>> the mangled names in the header. At least the cdef functions will be
>>> sharable between Cython implementation files.
>> I'm fine with explicitly forbidding this for now. It may eventually work for
>> Python object types where we can properly dispatch, but it won't easily work
>> for C types. It may work in C++, though.
> Ok, will do.

For the moment, putting mangled names in the header should be fine. A
macro might make sense in the long term.

Somewhat orthogonal, it could makes sense to do some dispatching on
type for cpdef functions.

>>> I also noticed that for cdef functions with optional argument it gets
>>> a struct as argument, but this struct doesn't seem to end up in the
>>> header file when the function is declared public. I believe that also
>>> the typedefs for ctypedef-ed things in the .pyx file don't make it
>>> there when used to type a cdef function's arguments. Should that be
>>> fixed?
>> No, I think this should also become a compiler error. These functions are
>> not meant to be called from C code. It's a Cython convenience feature. As
>> long as it's not correctly supported on both ends of the publicly exported
>> C-API, it's best to keep users from using it at all.
> Ok, I'll try to make Cython issue an error for these cases.


- Robert

More information about the cython-devel mailing list