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

Reply via email to