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?

Thanks!

_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev

Reply via email to