[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: Proof of concept higher-level python bindings for SoC project

From: Giovanni Bajo <rasky_at_develer.com>
Date: 2007-04-07 03:08:18 CEST

On 07/04/2007 0.47, David James wrote:

>> > - Our SWIG bindings convert "svn_error_t" return codes into
>> exceptions
>> I personally consider this a feature. In Python, it's really Pythonic
>> that
>> errors are reported in form of exceptions. Having to look at the error
>> code of
>> each function I call is something I wouldn't expect from a Python
>> library.
> To be perfectly clear, I don't actually care whether our low-level C
> wrapper bindings are Pythonic -- I just want to be able to do the same
> things in Python that I can do in C, so that I can implement a
> higher-level Pythonic API, which is very friendly to users, and
> requires no knowledge of the Subversion C API or ctypes.

Ah sorry for the confusion, I had missed this fact of having two different
layers. That's pretty idiomatic with ctypes: ctypes makes it easier to provide
APIs which are very close to C, so you often need a higher level of wrapping
to provide a Pythonic version. I'm +1 on this design.

> Right now, our higher-level API checks the return code of every
> function it calls, and throws a SubversionException if necessary.
> Right now, we do this check every time we call a C-level function
> using a simple if-statement, but it'd be simpler to delegate this work
> to a function.

Yes, but either way, it is pretty error-prone.

> Should we write some code to edit lower-level API functions and
> upgrade them so that they throw exceptions instead of returning error
> codes? I think that this is a good idea, as long as this difference is
> carefully documented.

Of course. IMO, it is fine for the lower layer to provide an API which is
slightly modified from the C API, as long as the modifications are general and
automatic, and thus can be remembered by users without having to look at a
reference guide. Basically, you want your modifications *not* to require a
specific Python reference documentation: the C reference documentation ought
to be enough. Thus, the rules must be simple and general. For instance:

  - All functions returning an error through a svn_error_t automatically raise
a SubversionException() instead.
  - All functions returning multiple return values through the usual
C-language "pattern" of passing pointers to variables are modified to return
tuples of values instead.

These are good general rules which are easy to remember and can be
unconditionally applied to all functions. When somebody has read them in the
documentation, she can go ahead and use the API just by looking at the C

>> > - Our SWIG bindings convert APR arrays and APR hashes into Python
>> > arrays and Python hashes, if you write a whole bunch of boilerplate
>> > typemap code.
>> I guess that depends on how well you manage to wrap APR data
>> structures in
>> Python. My own personal preference is to provide a wrapper class built
>> over
>> the C-level APR functions, and making the class fully duckable with
>> regular
>> Python lists and maps (as much as possible). This lets the users write
>> natural
>> Python code to manage APR containers, and also allow maximum performance
>> because data structures must not be converted every time between
>> Python and APR.
> Our higher-level Python bindings will certainly allow users to use
> friendly Python lists and dictionaries, and will convert these Python
> datatypes automatically into the appropriate APR datastructures.
> It's tempting for me to consider providing some automatic type
> conversion in the low-level ctypes bindings, as well, but I'd like to
> stay away from this: I think that any type conversions in our
> low-level bindings should only happen when explicitly requested, so
> that we don't make our Python bindings too "magical" and confusing,
> like our SWIG bindings.

OK, I agree with that. But what about providing a higher-level APR data
structure Pythonic wrapper, which is duck-typeable to standard Python types,
and thus can be directly used without going through conversion functions each

> I'd like to stay away from automatic type conversions, and instead
> convert the types manually in the higher-level layer by calling the
> appropriate conversion functions.

If you create Pythonic APR data structures, you don't need to convert them at
all. Conversion functions are still useful for people passing in Python data
types (eg: literals), but getting an APR data structure, modifying it, and
passing it back the C level is much more efficient.

> I don't think that our low-level API should automatically, for
> example, convert indirect pointers into return values, because this
> isn't a safe conversion in general, and it's especially confusing for
> users when we do the conversion automatically but wrong. I'd rather do
> this conversion manually.

Do you have an example of when you think the conversion isn't safe?

Giovanni Bajo
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Sat Apr 7 03:09:08 2007

This is an archived mail posted to the Subversion Dev mailing list.

This site is subject to the Apache Privacy Policy and the Apache Public Forum Archive Policy.