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

Discussion in 'Python' started by Marcin 'Qrczak' Kowalczyk, Jun 9, 2004.

  1. 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
    \__/
    ^^ http://qrnik.knm.org.pl/~qrczak/
    Marcin 'Qrczak' Kowalczyk, Jun 9, 2004
    #1
    1. Advertising

  2. Marcin 'Qrczak' Kowalczyk wrote:
    > 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
    =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?=, Jun 11, 2004
    #2
    1. Advertising

  3. On Fri, 11 Jun 2004 07:04:55 +0200, Martin v. Löwis wrote:

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


    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.

    --
    __("< Marcin Kowalczyk
    \__/
    ^^ http://qrnik.knm.org.pl/~qrczak/
    Marcin 'Qrczak' Kowalczyk, Jun 11, 2004
    #3
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Manlio Perillo

    __unicode__ method for exception object

    Manlio Perillo, Jul 7, 2007, in forum: Python
    Replies:
    3
    Views:
    296
    Manlio Perillo
    Jul 8, 2007
  2. Timothy Grant
    Replies:
    5
    Views:
    406
    Timothy Grant
    Aug 6, 2008
  3. Jim Cain
    Replies:
    7
    Views:
    138
    Brian Candler
    Jul 18, 2003
  4. Kenneth McDonald
    Replies:
    5
    Views:
    301
    Kenneth McDonald
    Sep 26, 2008
  5. Roy Smith
    Replies:
    3
    Views:
    185
    Terry Reedy
    Nov 4, 2012
Loading...

Share This Page