[Cython] automatically raise MemoryError on exceptional C return values

Robert Bradshaw robertwb at gmail.com
Thu Aug 9 09:15:18 CEST 2012


On Wed, Aug 8, 2012 at 10:12 PM, Stefan Behnel <stefan_ml at behnel.de> wrote:
> Robert Bradshaw, 09.08.2012 01:45:
>> On Tue, Aug 7, 2012 at 2:53 AM, Stefan Behnel wrote:
>>> given how ubiquitous manual memory management is in C, I think it would be
>>> nice to let Cython generate the exception raising also for C, not only for
>>> C++. The difference is this:
>>>
>>>   cdef extern from "...":
>>>       char* make_new_buffer() except NULL as MemoryError
>>>       int append_to_buffer(char* buffer, char* value) \
>>>                                      except -1 as MemoryError
>>>
>>>   c_buffer = make_new_buffer()           # raises MemoryError on NULL
>>>   append_to_buffer(c_buffer, "testdata") # raises MemoryError on -1
>>>   append_to_buffer(c_buffer, "moredata") # raises MemoryError on -1
>>>
>>> versus this:
>>>
>>>    cdef extern from "...":
>>>        char* make_new_buffer()
>>>        int append_to_buffer(char* buffer, char* value)
>>>
>>>    c_buffer = make_new_buffer()
>>>    if c_buffer is NULL:
>>>        raise MemoryError()
>>>    if append_to_buffer(c_buffer, "testdata") == -1:
>>>        raise MemoryError()
>>>    if append_to_buffer(c_buffer, "moredata") == -1:
>>>        raise MemoryError()
>>>
>>> I don't think it's necessary to support this for anything but MemoryError,
>>> since you'd normally want a formatted error message for everything else.
>>>
>>> Alternative colours for the bike shed:
>>>
>>>     char* make_new_buffer() except NULL raise MemoryError
>>>
>>>     char* make_new_buffer() raise MemoryError for NULL
>>>
>>>     char* make_new_buffer() raise MemoryError from NULL
>>>
>>> What do you think?
>>
>> I'm +0.5 (with a preference to the "except NULL as MemoryError"
>> flavor). Basically, it is new syntax to make up for the lack of proper
>> meta programming.
>
> In a way, yes.
>
>
>> Alternatively (just throwing it out there, not sure
>> if it's a good idea), could this be done as a decorator of some sort?
>> That's how one would write such a concept in Python. The need to fix
>> types does constrain things.
>
> A decorator on the external function declaration, you mean? Something like
> this?
>
>     @autoraise(MemoryError)
>     char* make_new_buffer() except NULL
>
> Or like this?
>
>     @autoraise(MemoryError, error_value="NULL")
>     char* make_new_buffer()
>
> I wouldn't mind. Although there isn't currently a pure Python syntax for
> external declarations that would benefit from this ...

I think that's too heavyweight for what is essentially magic.

> Or did you mean that it should be a user implemented decorator? That would
> be nice, but even fused types would make a simple case like this rather
> code heavy, I guess.

Yeah, that was the vague hope. Even being able to write

    check(make_new_buffer()[, NULL, MemoryError])

could be another option, if fused types could permit this. Just
exploring options, though I'm starting to leaning towards just adding
a bit of syntax if this feature is desired.

- Robert


More information about the cython-devel mailing list