On Mon, Feb 16, 2015 at 11:55 AM, Nick Wellnhofer <[email protected]> wrote:
> The Python tutorial also says:
>
>> Exceptions should typically be derived from the Exception class
>
> This sounds like it's possible to create exceptions that are not derived
> from the Exception class.

That used to be possible, but it was deprecated in Python 2.5-2.7 and removed
in Python 3.

    https://www.python.org/dev/peps/pep-0352/

>> Perhaps we can solve this problem by making Clownfish's exceptions under
>> Python wrap an host object which implements an interface, similar what to
>> Nick
>> proposed back in December:
>>
>>      http://s.apache.org/h0K
>
>
> I can't see how this would help. Most of what I proposed there wouldn't be
> needed for Python anyway.

I was hoping for something like this:

Define a Python exception class, instantiate it, and pass it into Clownfish:

    class MyErr(Exception):
        def __init__(self, mess):
            self.mess = mess
        def get_mess(self):
            return self.mess

    err = MyErr("oops")
    clownfish.Err.throw(err) # <--- wrap Python object

If Clownfish's Err type were to be defined as a Go-style interface with one
method required (`Get_Mess`), the I think your proposal applies and this code
would work.  The conversion code within the Python binding for
clownfish.Err.throw() would know that it needs to create a wrapper object.

However, this doesn't yet solve the problem of converting the other direction.
It allows Clownfish code to use a Python Exception as a Clownfish Err, but
doesn't make it possible for Python to use a Clownfish Err as a Python
Exception.

> Can't we simply convert a Clownfish exception to a Python exception in
> cfish_Err_do_throw (and convert it back in cfish_Err_trap)?

Yes, but the problem is that such a mechanism prevents catching specific
classes of exceptions.  In my provisional Python bindings, all Python method
wrappers run Clownfish code inside Err_trap, and if the Clownfish code throws
an exception, it's stringified and used as the message inside a Python
RuntimeError.  Catching all RuntimeErrors is too broad.

    try:
        indexer = lucy.Indexer.open(index='/path/to/index')
    except RuntimeError as e:
        ...

We could potentially introduce a class like ClownfishError to use instead of
RuntimeError, but that wouldn't make the host exception facilities available
for Clownfish exception types and it wouldn't allow fine-grained catching of
things like LockError.  You'd have to resort to string comparison:

    try:
        indexer = lucy.Indexer.open(index='/path/to/index')
    except ClownfishError as e:
        if len(e.args) > 0 and str(e.args[0]).find("LockErr") != -1:
            print("Caught LockErr!")
        ...

Marvin Humphrey

Reply via email to