Usually, when writing bindings for a C library in a high level language, there’s a sweet spot where you have to leave the relative safety of an API similar to the library you are wrapping and the idiomatic correctness dictated by the language itself.
For instance, in the PyClutter bindings a typical
clutter.Behaviour constructor is lifted directly from the equivalend function call:
behaviour = clutter.BehaviourDepth(alpha, -100, 100) behaviour = clutter_behaviour_depth_new (alpha, -100, 100);
ClutterAlpha parameter, though, can ben
NULL, so a “keep the API similar to the C equivalent” approach would be:
behaviour = clutter.BehaviourDepth(None, -100, 100) behaviour = clutter_behaviour_depth_new (NULL, -100, 100);
This is, though, different from the “pythonic” approach; as Python has the syntactic sugar to support arguments with default values, the place for those parameters would be at the end of the function call:
behaviour = clutter.BehaviourDepth(-100, 100)
Correctness issue aside, let’s add the fact that a pythonic approach allows the poor maintainer (yours truly) to drop a lot of hand-written code.
Unfortunately, though, the pythonic approach breaks the API1; more unfortunately, it breaks the API without giving a useful error message: the PyGObject bindings will raise a not very useful
"TypeError: could not convert parameter 'depth_start' of type 'gint'"
exception when encountering the wrong value type for the argument2.
The question then is: should the idiomatic correctness sway in favour of the language or the underlying library?
Here the blog post ends. I’d like to have an answer for the question, but I’m still undecided; if anyone has some insight, especially Python developers, I’d appreciate a comment
- This is not a huge issue as it might seem: the underlying C library has already done that for us [↩]
- The error message should be a more useful “could not convert value of type X, and parameter Y requires a value of type Z”, which would require a bit of tinkering in the bindings themselves and it wouldn’t be useful anyway because only the new versions would pick that change up [↩]