1 Jun 2010 06:48
[Cython] Exceptions?
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):...and in the caller (CPython code, inheriting from unittest):
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 ''
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?
Thanks!
<div>
<br>
I'm attempting to get a Cython module to raise exceptions that'll be
visible to the calling CPython.<br><br>
The Cython code in question looks like:<br><blockquote> def add_from_fileno(self, fileno, length_to_add):<br>
exception_string = self.add_from_fileno_c(fileno, length_to_add)<br>
if exception_string.startswith("Buffer error"):<br>
raise exceptions.BufferError, exception_string<br>
elif exception_string == '':<br>
pass<br>
else:<br>
raise exceptions.AssertionError, exception_string<br><br>
cdef add_from_fileno_c(self, fileno, length_to_add):<br>
if self.would_overflow(length_to_add):<br>
return "Buffer error: Would overflow"<br>
# FIXME: We need to do something about EINTR on these 3 read's!<br>
if self.would_add_wrap(length_to_add):<br>
# do the read in two pieces<br>
first_length, second_length =
self.split_to_two_add(length_to_add)<br>
length_added = read(fileno, &self.buffer[self.end],
first_length)<br>
if length_added != first_length:<br>
return "length_added != first_length"<br>
length_added = read(fileno, self.buffer, second_length)<br>
if length_added != second_length:<br>
return "length_added != second_length"<br>
self.end = second_length<br>
else:<br>
# do the read in one piece<br>
length_added = read(fileno, &self.buffer[self.end],
length_to_add)<br>
if length_added != length_to_add:<br>
return "length_added != length_to_add"<br>
self.end += length_to_add<br>
return ''<br>
</blockquote>
...and in the caller (CPython code, inheriting from unittest):<br><blockquote> def test_fileno_from_file_overflow(self):<br>
file_ = open('input-file', 'w')<br>
file_.write('abc' * 15)<br>
file_.close()<br><br>
rb = ring_buffer_mod.Ring_buffer(buffer_size = 10)<br>
input_fileno = os.open('input-file', os.O_RDONLY)<br>
for i in xrange(10):<br>
rb.add_from_fileno(input_fileno, 1)<br>
#self.assertRaises(exceptions.BufferError, rb.add_from_fileno,
input_fileno, 1)<br>
try:<br>
rb.add_from_fileno(input_fileno, 1)<br>
except exceptions.BufferError:<br>
pass<br>
</blockquote>
<br>
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.<br><br>
I've googled quite a bit, but haven't found much on the topic that
didn't seem kind of hand wavey.<br><br>
What do I need to do, to raise an exception in Cython, that CPython
code will be able to see?<br><br>
Thanks!<br><br>
</div>
RSS Feed