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

Reply via email to