[Scribus] Scripter API

Craig Ringer craig
Tue Dec 25 16:25:03 CET 2007

Henning Schr?der wrote:

> Actually you cannot design an API without knowing about what is
> possible with the different approaches.
> For example with ScripterNG and Kross (as far as I know) you cannot
> have exceptions. So error handling means
> to rely on functions which return False or None/null.

It looks like the old Kross for Qt3 does support exceptions. It'd seem 
odd for them to have removed such support. The alternative for functions 
that must return a value is to either poke the error code into a global 
(think "errno" with all its problems) or require that the user pass a 
mutable object (list/dictionary usually) to fill with error info. The 
global approach and some sort of GetLastError() function is more likely 
to be portable across many scripting languages.

Boost::Python, at least, can transparently translate C++ exceptions to 
Python (and vice versa IIRC) so that when you throw in C++ it "just 
works". To me, using exceptions to report issues from C++ and letting 
the wrapper generator take care of them seems ideal - but if most 
wrapper generators can't handle C++ exceptions, I guess we just have to 
fall back on more primitive error handling.

I'd say that really sucks for Python users... but actually, for basic 
automation, exceptions may sometimes just confuse people. They're 
important when you're doing anything more complicated in Python, but for 
"do this then this" sort of stuff it's probably OK to do without.

It'd be nice to see people who didn't know C++ able to do more with 
Scribus using Python and PyQt, though. For that, solid exception support 
is likely to make many things easier.

I think it's important to see what the options are for exception 
handling in various frameworks, since it'll have such a major influence 
on the API.

If the core C++ API does land up not supporting exceptions, it'll be 
possible to use Python to translate the error codes to exceptions. 
Assuming that there's a GetLastError() that returns `None' on no error, 
and otherwise an ( error_no, error_string, error_file, error_line ) 
tuple, any method can be wrapped like this:

def wrapped_method1(*args,**kwargs):
    ret = scribus.method1(*args,**kwargs)
    err = scribus.getLastError()
    if err:
       raise Exception("Scribus error %s: "%s" at %s:%s" % err)
    return ret

With a bit more work it's possible to write a function that generates a 
wrapper around any method. From there, since Python is all dynamic, you 
can just insert your wrapped methods into the original classes. 
Alternately, "mirror" classes can be produced. It's nowhere near as nice 
as just having the core API throw exceptions directly to Python, but it 
can work.

Craig Ringer

More information about the scribus mailing list