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.
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev