Dan Stromberg wrote:
> On 05/31/2010 10:21 PM, Robert Bradshaw wrote:
>
>> On May 31, 2010, at 9:48 PM, Dan Stromberg wrote:
>>
>>
>>
>>> I'm attempting to get a Cython module to raise exceptions that'll be
>>> visible to the calling CPython.
>>>
>>> The Cython code in question looks like:
>>> def add_from_fileno(self, fileno, length_to_add):
>>> exception_string = self.add_from_fileno_c(fileno, length_to_add)
>>> if exception_string.startswith("Buffer error"):
>>> raise exceptions.BufferError, exception_string
>>> elif exception_string == '':
>>> pass
>>> else:
>>> raise exceptions.AssertionError, exception_string
>>>
>>> cdef add_from_fileno_c(self, fileno, length_to_add):
>>> if self.would_overflow(length_to_add):
>>> return "Buffer error: Would overflow"
>>> # FIXME: We need to do something about EINTR on these 3 read's!
>>> if self.would_add_wrap(length_to_add):
>>> # do the read in two pieces
>>> first_length, second_length =
>>> self.split_to_two_add(length_to_add)
>>> length_added = read(fileno,&self.buffer[self.end],
>>> first_length)
>>> if length_added != first_length:
>>> return "length_added != first_length"
>>> length_added = read(fileno, self.buffer, second_length)
>>> if length_added != second_length:
>>> return "length_added != second_length"
>>> self.end = second_length
>>> else:
>>> # do the read in one piece
>>> length_added = read(fileno,&self.buffer[self.end],
>>> length_to_add)
>>> if length_added != length_to_add:
>>> return "length_added != length_to_add"
>>> self.end += length_to_add
>>> return ''
>>> ...and in the caller (CPython code, inheriting from unittest):
>>> def test_fileno_from_file_overflow(self):
>>> file_ = open('input-file', 'w')
>>> file_.write('abc' * 15)
>>> file_.close()
>>>
>>> rb = ring_buffer_mod.Ring_buffer(buffer_size = 10)
>>> input_fileno = os.open('input-file', os.O_RDONLY)
>>> for i in xrange(10):
>>> rb.add_from_fileno(input_fileno, 1)
>>> #self.assertRaises(exceptions.BufferError, rb.add_from_fileno,
>>> input_fileno, 1)
>>> try:
>>> rb.add_from_fileno(input_fileno, 1)
>>> except exceptions.BufferError:
>>> pass
>>>
>>> All seems fine, except for the exceptions. When I raise an
>>> exception in Cython, I see a message on my terminal (I believe there
>>> should be none), and the calling CPython code doesn't appear to
>>> realize that an exception has been raised. I added the
>>> add_from_fileno_c/add_from_file distinction, because I was hoping
>>> that a def would be able to raise an exception, after finding that
>>> cdef's and cpdef's seemed to have problems with it - but it appears
>>> that there's some sort of exception barrier between Cython and
>>> CPython.
>>>
>>> I've googled quite a bit, but haven't found much on the topic that
>>> didn't seem kind of hand wavey.
>>>
>>> What do I need to do, to raise an exception in Cython, that CPython
>>> code will be able to see?
>>>
>>>
>> This should work just fine for def functions, as well as c(p)def
>> functions not declaring a c return type (in which case you should see
>> [1]). Have you tried calling this directly from the command line
>> (eliminating the possibility that it's something with the unittest
>> framework?) What if you do
>>
>> cdef class A:
>> def spam(self):
>> raise TypeError
>> cpdef eggs(self):
>> raise ValueError
>>
>> Does that work for you? (It does for me.)
>>
>> - Robert
>>
>> [1]
>> http://docs.cython.org/src/userguide/language_basics.html#error-return-values
>>
>> _______________________________________________
>> Cython-dev mailing list
>> [email protected]
>> http://codespeak.net/mailman/listinfo/cython-dev
>>
>>
> You're right - it must be something about the unittest module - for some
> reason, it's printing the exception I'm trying to catch. It works as
> expected interactively.
>
> Apologies for not going to the cython-users list - I wasn't aware of it
> when I sent my message, and had subscribed to cython-dev (only) long ago.
>
> Thanks for the cool software and assistance!
>
> PS: I might suggest adding something to the FAQ about cdef functions not
> declaring a return type doing this well. It's kind of there, but kind
> of not - and in a FAQ, it's perhaps best to have it fully there.
>
Please go ahead!
Dag
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev