| Weyfour WWWWolf ( @ 2008-07-01 11:43:00 |
| Entry tags: | gimp, programming, python |
Slowly learning to tolerate Python
Sorry if this sounds like an irrational flame - perhaps it is. I'm still in the process of cooling down...
For me, Python has been a language that I really have divided opinions about. It's probably an important language, and in many ways, it's quite elegant; yet, at the times, I feel that the designers had no idea what they were doing. Perl can get ugly and P5 is pretty outdated and certainly out of fashion, but at least it's designed. Ruby is inefficient, but at least it's got a very clean syntax. Python? Sometimes it's cool, sometimes it's hell, and as with all languages, the makers of libraries may or may not know where they're heading. Well, at least it's far better than PHP. =)
A few days ago I wrote a script to replace my old shell script that fires up WLAN connection with specified settings. Whee - I learned of Python shell help() feature. Damn, that's cool. (The reason I didn't use it before was that I thought help()s are useless. if it was called interactive_documentation() I might have paid attention. =) If it can one day do something similar to Ruby's (Class or object).public_methods.grep(/whatever/).s
Anyway, I ported my earlier GIMP bloom script to Python-Fu. While I like some of the OO stuff, some of the stuff is pretty weird, and certainly doesn't match with the documentation I had at hand. I'd offer some random comments from the source code - censored, because the script was, after all, posted on deviantART - and I thought that now that I've slept over night, I might actually talk about the problems in a calm and collected fashion.
For some background: GIMP's promary programming interface is the Procedural Database (PDB), which is basically a standard set of calls that GIMP understands and you can call them no matter what language you are programming in - the same calls work in Scheme (Script-Fu), Perl (Perl-Fu), and Python (Python-F... excuse me, GIMP-Python.) However, Perl and Python APIs also include an object-oriented API for some internal GIMP objects, like images and layers. Obviously, you want to use the OO API as much as possible - especially in Python, the Superiour OO Programming Language®.
Why the [censored] are the [censored] parameters in different order compared to gimp_layer_new PDB call? Just for [censored] fun? Not very funny to me, [censored]! I like to stare at PDB browser, and if the parameters are not in that order, well, [censored]!For some obscure reason, the standard gimp_layer_new PDB call and Python gimp.Layer OO constructor take parameters different order. Same for other stuff, like channels and images and whatever. Not a biggie... I just need to keep two sets of documentation open; one for the GIMP OO API, and the PDB browser. You see, if the arguments were in same order, I could easily take whatever it says in gimp_layer_new call documentation and just stick gimp.Layer(...) there instead.
Why the [censored] do I get a [censored] type mismatch when doing the non-PDB version of the command? Exactly as said in spec! And more [censored] importantly, which [censored] argument triggers that [censored] error??? [censored] Python only says "type mismatch", yeah, as if that's going to get me [censored] anywhere.selchn = gimp.Channel(img,"For selection",width,height,100,(0,0,0)) doesn't work. selchn = pdb.gimp_channel_new(img,width,height,"F
I have no idea what causes the "type mismatch" error here. The Python API doc also says the last argument should be "...colour (one of the *_CHANNEL constants)". Er... Script-Fu and Perl-Fu want, uh, er... you know, a colour as the last argument. One that specifies the channel colour, you know. And obviously, the *_CHANNEL constants aren't listed anywhere in the spec... so a quick grep says legit values are PF_CHANNEL and PDB_CHANNEL, neither of which work. What the shit? I don't know about you, but I get a nagging feeling that maybe the spec is wrong. Very wrong.
Then a pop quiz. How do you paste stuff in Perl?
my $fs = gimp_edit_paste($selchn,1);Yeah, pretty simple. The script was done in Perl::Fu style, but can mix OO style in if it makes sense. Now, how do you paste shit in Python?
$fs->anchor();
fs = pdb.gimp_edit_paste(selchn,1)"OO is failure, OO is failure, tralla la lalla la lalla la!" Excuse me, you can't anchor a floating selection via an OO call in this allegedly Superiour OO Programming Language®, you have to use one of those evil no-good PDB calls.
pdb.gimp_floating_sel_anchor(fs)
[censored] Python-Fu needs the [censored] list length, which Perl-Fu can figure out on its own. I can't [censored] believe this [censored]!In Perl, the call is in form gimp_curves_spline($selchn,0,[127,0,254,2
So what does Python want? pdb.gimp_curves_spline(selchn,0,4,[127,0,254,254]) ... um, did I just see list length argument? Did I just see a bloody list length argument? This isn't some shitty language like C where you have to be super-careful about list lengths, you know! This is the Superiour OO Programming Language®! Goddamn it.
Another [censored] type mismatch, even when the reference says you can specifically feed it None to say no channel is active... Oh well, don't blame me if this blows up!I thought it was nice to tell GIMP that active channel is not active... in a proper OO fashion. img.active_channel = None should do the trick, right? That's what the spec says, right? Blam! Type mismatch! Cannot assign that here! The spec is looking rather weird right now!
All in all, converting the script to Python-Fu wasn't that difficult... but I still can't quite shake away the feeling that something is not really all that well designed here.