Older blog entries for TazForEver (starting at number 15)

Python : the socket.error trap

I spent my lunch hacking a dirty remote shell in python.

signal.signal(signal.SIGCHLD, reaper)
# ...
while True:
    client, who = server.accept()

Blam ! When the server process receives SIGCHLD, accept() is interrupted. So I added a try/except around the accept() :

  while True:
        try:
            client, who = server.accept()
        except OSError, e:
            if e.errno != errno.EINTR:
                sys.exit(e)
            else:
                continue

Re-blam. I didn't paid attention to the previous exception's type. It was socket.error. I though it was a subclass of OSError ... it's not. issubclass(socket.error, OSError) == False. pydoc socket :/

The correct except statement is :

   while True:
        try:
            client, who = server.accept()
        except socket.error, e:
            if e.args[0] != errno.EINTR:
                sys.exit(e)
            else:
                continue

The socket.* error classes are just Exception. It would be nice to turn them into OSError :)

12 Jun 2005 (updated 12 Jun 2005 at 21:18 UTC) »
Drivel 2.0

Wow, Drivel 2.0 is amazing :)

GObject *_get_type() + G_GNUC_CONST

When you define your own GObject class, you have to define 2 casts macro (instance cast and class cast). So you write :

#define MY_TYPE (My_Type_get_type())
#define MY_TYPE(inst) (G_TYPE_CHECK_INSTANCE_CAST((inst), MY_TYPE, My_Type))

e.g :
#define GTK_TYPE_LABEL (gtk_label_get_type ())
#define GTK_LABEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_LABEL, GtkLabel))

Now have a look at My_Type_get_type() declaration and definition. My_Type_get_type() always return the same GType. So if you write multiple cast, only one call to My_Type_get_type() is really necessary. But gcc is a good servant and does what you ask him : calls My_Type_get_type() whenever you call it. Think about this kind of loop :

for( ... ) {
    GtkWidget* widget= ...;
    gtk_box_pack_start(GTK_BOX(hbox), widget, ...);
}

To avoid such a waste, you have to tell gcc that all calls to My_Type_get_type() return the same GType.

GType My_Type_get_type (void) G_GNUC_CONST;

e.g:
GType gtk_label_get_type (void) G_GNUC_CONST;

Yes, it's that simple. Just add a G_GNUC_CONST attribute, and gcc will optimize all your to My_Type_get_type(), therefore all your MY_TYPE(inst).

Be smart, don't forget G_GNUC_CONST when you create your GObject class :)
Of course, glib and gtk+ already do this kind of optimization.

The gboolean trap

gboolean is just int !

#include <stdbool.h>
#include <stdio.h>

#include <glib.h>

int main() { float f; gboolean gb; bool b;

f = 0.5f; gb = f; b = f;

printf("gboolean %d\n" "bool %d\n", (int)gb, (int)b);

return 0; }

Ouput :

gboolean 0
bool     1

0.5f is converted to int 0. But 0.5f is obsviously not zero and therefore should be evaluated as TRUE. So be carefull with gboolean.

NB: <stdbool.h>, bool, true and false are C99.

sizeof troubles

I always took for granted that my name -- Benoît -- was 6 chars long. I was wrong.
It's 7, UTF-8 speaking.
It took me some time this afternoon to understand why sizeof "Benoît" == 8 where i would expect 7. So i hexdump'ed my C file and realized that î is encoded as 0xC3AE. I'm glad that ASCII chars are still encoded on a single byte in UTF-8 so hacks like this one:
char buf[magic]; /* enough to hold "plop" */
are still 0k. I'll try to be less lazy and always code :
char buf[sizeof "plop"];

WTF is î ?
U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX
UTF-8 : 0xC3 0xAE
In French, circumflexes '^' on vowels often replace old French 's' :
- hôpital for hospital
- hôtel for hostel (= hotel)
- Benoît for Benoist
- côte for coste (= coast)
- etc
Benoît is the french for Benedict.
Linux.Conf.Au 2004
May be some of you have missed the LCA2004 DVD event record. I have.
Here's the BitTorrent and MD5

Linux.Conf.Au 2004 Videos
24 Sep 2004 (updated 24 Sep 2004 at 07:51 UTC) »
PyPMU
I've hacked a small python wrapper for PowerMac Power Management Unit.

PyPMU 0.1.1

I'll soon make a control-based desklets on it.
I'd like to get the C backend used by GNOME battstat applet (supports only ACPI/APM, but i steel haven't been able to contact its maintainer. I think I'll have to provide a full patch to get a chance to get PMU support in ...

LibGTop
I'm working hard on libgtop. Fixed a nasty bug on Linux/Sparc64.
I've been granted access to 5 Solaris (sparcs) machines in a German University, and started to fix Solaris support. I still haven't decided if this will go 2.8.1 or 2.9.0 ...

24 Aug 2004 (updated 24 Sep 2004 at 03:04 UTC) »
python debugging : repr vs. str

Today, i've wasted one hour debugging a network app : receive an UDP packet, unpack it and insert data into a PostgreSQL database. Quite simple. The program sending data is written in C.

I was getting a pg error about bad queries. So i added a try...except and a print statement on exception. Everything looked OK, i didn't understand what was wrong. So i opened a psql shell and a python shell, dumped there my query. Ran fine. I was crazy. I spent 15 minutes sending packet and watching my error log ...

Then repr came !(Python lib)
so i replace my print 'Query was %s' % (my_query,) by print 'Query was %s' % (repr(my_query),) ... there were some non-printable chars in my data (C '\0' grrrr /me stupid). repr displays them, str doesn't.

Next time, i'll be more carefull with string and i'll use repr each time i'll need to print data in an error messages.

A word about IronPython
I've downloaded IronPython 0.6. I've started an interactive shell. I type dir() brrrrrrrrrrrr ... finally got the result. Feels like a bit slow comparing to python. So i'm looking for application where IronPython is faster than every other python application. I'm thinking about JIT..

Benchmarks files and results DNABench.py doesn't provide the time module

  • Python 2.3.4
    time python ~/Python/tmp/DNABench.py
    found AAAGTAAGCC at 1000000 it took 0 miliseconds
    found AAATGAAAAAG at 1048960 it took 1071 miliseconds
    found GAAAAAGTAAG at 1085441 it took 1947 miliseconds
    found TCTAAAAATAG at 1179694 it took 4075 miliseconds
    found ACGTGATGTAG at 1204636 it took 4697 miliseconds
    found AATAGATTCGG at 1548576 it took 13325 miliseconds
    found TCGTACAAATG at 1576094 it took 14024 miliseconds
    found CGGACGTGATG at 1599255 it took 14524 miliseconds
    found ATTCGGACGTG at 1689064 it took 16926 miliseconds
    found AGATTCGGACG at 1859204 it took 20982 miliseconds
    found TGATGTAGTCG at 1984902 it took 23993 miliseconds
    found AAATAGATTCG at 2000000 it took 24339 miliseconds
    Python regex took 24339 milliseconds
    
    

    real 0m24.459s user 0m19.622s sys 0m0.067s

  • Pysco 1.2.2
    time python /home/benoit/Python/tmp/DNABenchPsyco.py
    found AAAGTAAGCC at 1000000 it took 1 miliseconds
    found AAATGAAAAAG at 1048960 it took 309 miliseconds
    found GAAAAAGTAAG at 1085441 it took 631 miliseconds
    found TCTAAAAATAG at 1179694 it took 1220 miliseconds
    found ACGTGATGTAG at 1204636 it took 1529 miliseconds
    found AATAGATTCGG at 1548576 it took 4442 miliseconds
    found TCGTACAAATG at 1576094 it took 4645 miliseconds
    found CGGACGTGATG at 1599255 it took 4800 miliseconds
    found ATTCGGACGTG at 1689064 it took 5372 miliseconds
    found AGATTCGGACG at 1859204 it took 6490 miliseconds
    found TGATGTAGTCG at 1984902 it took 7377 miliseconds
    found AAATAGATTCG at 2000000 it took 7480 miliseconds
    Python regex took 7480 milliseconds
    
    

    real 0m7.714s user 0m5.654s sys 0m0.029s

  • IronPython 0.6
    time bin/IronPythonConsole.exe /home/benoit/Python/tmp/DNABenchIron.py
    Python regex took - milliseconds
    
    

    real 0m44.932s user 0m0.060s sys 0m0.044s

    Ok. obviously Psyco wins. IronPython is damn slow, so my shell experience was more than a feeling.
    Btw, as you can see, i have a bug to report because IronPython doesn't find any DNA subsequence ...

  • 19 Jul 2004 (updated 20 Jul 2004 at 05:59 UTC) »
    About C# reflexion
    I'm really disapointed about C# reflection.

    If you want to retrieve the type, i.e System.Type, of a class, you have to use the typeof operator :
    System.Type st = typeof(Stack);
    sweet.

    But if you want to retrieve the type of an object, you have to use object::GetType().
    System.Type st = my_stack.GetType();

    This sucks so much ... why typeof can't be applied to an object ? and this ugly method call makes me crazy ... all the C# API is full of these shits, it seems that may be half of the µ$ hackers were not aware of properties. And guess what, object::GetType() is overloaded ... We're so far from python __class__ attribute :
    obj.__class__
    KISS

    This is a very bad design : it would have been too easy to extend the typeof operator and put everything else in System.Reflection ... i really can't understand why they did this. Even if i think C# is a bit better than Java, it just sucks. I hate these languages that are designed in 6 months... i can't understand ...

    6 older entries...

    New Advogato Features

    New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

    Keep up with the latest Advogato features by reading the Advogato status blog.

    If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!