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);
The 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 API; 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 argument.
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