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

  • Thread starter Marcin 'Qrczak' Kowalczyk
  • Start date
M

Marcin 'Qrczak' Kowalczyk

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.
 
?

=?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=

Marcin said:
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.

Why didn't you use Py_FindMethod for that?

Regards,
Martin
 
M

Marcin 'Qrczak' Kowalczyk

Why didn't you use Py_FindMethod for that?

Because I forward all other method calls to the wrapped object.

While I could check if Py_FindMethod raised AttributeError, clear the
error, and forward it in this case only - it's an overkill if there is
only a single method to intercept, and the majority of cases is forwarded.

This would change if I intercepted more methods, i.e. of I made __len__
etc. available as methods. I don't know if providing __len__ is a
requirement if sq_length is provided, and if so, if it's somehow possible
to avoid wrapping all those methods by hand.

For example if a method takes two arguments, its tp/nb/sq/mp slot takes
two arguments, while a MethodDef must take and unpack a two-element tuple,
as I understand, with ints passed as Python ints rather than C ints etc.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top