The __unicode__ method in the C API, and other __-methods

Marcin 'Qrczak' Kowalczyk qrczak at knm.org.pl
Wed Jun 9 14:44:38 CEST 2004


I made a bridge between my language Kogut
<http://qrnik.knm.org.pl/~qrczak/kogut/kogut.html> and Python,
which gives my language instant access to Python libraries.

There is a minor annoyance in the C API: the __unicode__ method does not
have its own slot in type objects, it's not treated specially like __str__.

                /* XXX As soon as we have a tp_unicode slot, we should
                       check this before trying the __unicode__
                       method. */
                if (unicodestr == NULL) {
                        unicodestr= PyString_InternFromString(
                                                       "__unicode__");
                        if (unicodestr == NULL)
                                return NULL;
                }
                func = PyObject_GetAttr(v, unicodestr);

Strings in Kogut are Unicode only. Thus on one hand I must use the
equivalent of the above code when I want to convert an arbitrary Python
object to a Python Unicode object, and on the other hand the implementation
of tp_getattro of Kogut objects wrapped in Python has a special case,
only one special case, which checks for "__unicode__" and returns the
appropriate convert-to-Unicode bound method instead of forwarding the
attribute access to the original object.

Could __unicode__ have its slot in the C API in future Python versions?
This is the only missing method of this kind I suppose.

* * *

Unless I count iteritems.

The problem is that in Kogut iteration over a dictionary gives key-value
pairs, where in Python it defaults to iterating over keys. The standard
dict type provides iteritems, which does not have a C API equivalent.

Currently iterating over a Python dictionary from Kogut produces key-value
pairs, because this is what Kogut expects - I call iteritems through
PyObject_GetAttr.

Iterating over a Kogut dictionary from Python is somewhat wrong, because
it blindly returns what the Kogut iterator produces, that is: pairs
(and they even can't be automatically converted to Python pairs, unless
I treat this case specially). I think I will fix it and return keys only
when the Kogut object is a dictionary.

* * *

Maybe the wrapped objects should support all these __-methods. I mean, for
example len(obj) works (it calls the C slot which calls the Size function
in Kogut), but obj.__len__ doesn't work (it tries to blindly access the
attribute named __len__ in Kogut, which doesn't exist).

Is that wrong? Does Python code assume that len(obj) is equivalent to
obj.__len__()?

Improving this would be tedious, because I would have to make bound
methods myself. I can't use PyObject_GenericGetAttr because I must
forward regular attribute lookup to Kogut, so I would probably have
to code everything by hand.

Also I don't known which methods are available without trying to call them,
so all objects would have the __len__ slot, with for non-collection
objects throws an exception when applied.

-- 
   __("<         Marcin Kowalczyk
   \__/       qrczak at knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/




More information about the Python-list mailing list