[Python-Dev] PEP 253: Subtyping Built-in Types

M.-A. Lemburg mal@lemburg.com
Sun, 22 Jul 2001 19:41:56 +0200


Guido van Rossum wrote:
> 
> > Hmm, I don't like these class methods, but it would probably
> > help with the problem...
> >
> > from mx.DateTime import DateTime
> >
> > dt1 = DateTime(2001,1,16)
> > dt2 = DateTime.From("16. Januar 2001")
> >
> > Still looks silly to me... (I don't like these class methods).
> 
> Maybe it's time you started to like them. :-)

I'll have a hard time finding my way through all these extra
dots in the names ;-)
 
> > Good, so overriding the tp_alloc/free slots is generally not
> > a wise thing to do, I guess.
> 
> If the base type has a custom free list (like the int type does), you
> *have* to override it if the instances of the subtype are larger than
> the base type.  Currently int doesn't allow subtyping yet because I
> haven't refactored its code in this area yet.

What I did was to enhance the base class' tp_alloc and tp_dealloc 
APIs to only use the free list in case the type being passed to the
APIs is a base type; in all other cases, standard processing takes
place.

Perhaps ints could do the same ?

> > > > - Could the generic APIs perhaps fall back to tp_getattr to make
> > > >   the transition from classic types to base types a little easier ?
> > >
> > > I'd rather not: that would prevent discovery of attributes supported
> > > by the classic tp_getattr.  The beauty of the new scheme is that *all*
> > > attributes (methods and data) are listed in the type's __dict__.
> >
> > Uhm, I think you misunderstood me: tp_getattr is not used anymore
> > once the Python interpreter finds a tp_getattro slot
> > implementation, so there's nothing to prevent ;-):
> >
> > PyObject_GetAttr() does not use tp_getattr if tp_getattro is
> > defined, while PyObject_GetAttrString() prefers tp_getattr over
> > tp_getattro -- something is not symmertic here !
> >
> > As a result, dir() finds the __members__ attribute which lists
> > the attributes (it uses PyObject_GetAttrString(), but
> > instance.attribute does not work because it uses PyObject_GetAttr().
> 
> The simplified rule is that a type should only provide *either*
> tp_getattr *or* tp_getattro, and likewise for set.  The complete rule
> is that if you insist on having both tp_getattr and tp_getattro, they
> should implement the same semantics -- tp_getattr should be faster
> when PyObject_GetAttrString() is called, and tp_getattro should be
> faster when PyObject_GetAttr() is called.

Ah, ok, didn't know that rule.
 
> Apparently you left your tp_getattr implementation in place but added
> PyObject_GenericGetAttr to the tp_getattro slot -- this simply doesn't
> follow the rules.

Yep. That's what I did.

I'll move to the new scheme for 2.2 then and leave the old tp_getattr
around for backward compatibility.

-- 
Marc-Andre Lemburg
CEO eGenix.com Software GmbH
______________________________________________________________________
Consulting & Company:                           http://www.egenix.com/
Python Software:                        http://www.lemburg.com/python/