[Python-Dev] reflections on basestring -- and other abstract
aleaxit at yahoo.com
Sun Nov 2 17:19:42 EST 2003
1. Shouldn't class UserString.UserString inherit from basestring? After all,
basestring exists specifically in order to encourage typetests of the form
isinstance(x, basestring) -- wouldn't it be better if such tests could
also catch "user-tweaked strings" derived from UserString ... ?
2. If we do want to encourage such typetest idioms, it might be a good idea
to provide some other such abstract basetypes for the purpose.
For example, I see quite a few cases of isinstance(x, (int,long,gmpy.mpz))
in my code -- and that, despite the fact that I'm not enamoured of
typetesting as a general idea and that I'm quite aware that this kind of
check could miss some other kind of user-coded "integeroid number".
If there was an abstract basetype, say "baseinteger", from which int and
long derived, I'd be happy to tweak gmpy to make mpz subclass it (in 2.4
and later versions of Python only, of course) and allow such typetests to
happen more smoothly, faster and with more generality too.
3. And perhaps baseinteger (and float and complex) should all subclass yet
another basetype, say "basenumber"? Why not? I admit that right now
I have no use cases where I _do_ want to accept complex numbers as
well as int, long, float, and gmpy thingies (so, maybe there should be a
more specific "basereal" keeping complex out...?), but apart from this
detail such an abstract basetype would be similarly useful (in practice
I would use it since I do not expect complex in my apps anyway).
4. Furthermore, providing "basenumber" would let user-coded classes "flag"
in a simple and direct way "I'm emulating numbers". This might well be
useful _to Python itself_...
Right now, I'm stuck for an answer to the bug that a user-coded class
which exposes __mul__ but not __rmul__ happens to support its instances
being multiplied by an integer on the right -- quite surprising to users!
The problem is that this behavior is apparently expected, though not
documented, when the user-coded class is trying to simulate a _sequence_
rather than a number. So, I can't just take the peculiar "accidental
commutativity with integers only" away.
IF a user class could flag itself as "numeroid" by inheriting basenumber,
THEN the "accidental commutativity" COULD be easily removed at least
for such classes.
5. in fact, now that we fill in type descriptor slots bases on user-coded
classes' special methods, I suspect this isn't the only such issue. While
"flagging" (inheriting one of the abstract basetypes) would be entirely
optional for user-coded classes, it would at least provide a way to
_explicitly disambiguate_ what it is that the user-coded class IS trying
to emulate, if the user wants to.
6. of course, for that to be any use, the various basetypes should not be
"ambiguously" multiply inheritable from. Right now, is isnt so...:
>>> class x(basestring, int): pass
>>> isinstance(x(), int)
>>> isinstance(x(), basestring)
...does anybody see any problem if, in 2.4, we take away the ability to
multiply inherit from basestring AND also from another builtin type which
does not in turn inherit from basestring...? I have the impression that
right now this is working "sort of accidentally", rather than by design.
7. one might of course think of other perhaps-useful abstract basetypes,
such as e.g. basesequence or basemapping -- right now the new
forthcoming built-in 'reverse' is trying to avoid "accidentally working"
on mappings by featuretesting for (e.g.) has_key, but if the user
could optionally subclass either of these abstract basetypes (but not
both at once, see :-), that might ease reverse's task in some cases.
Why, such abstract basetypes might even make operator.isMappingType
useful again -- right now, of course:
and therefore there isn't much point in that function:-).
But I think that points 1-6 may be enough to discuss for the moment
(and I brace myself for the flames of the antitypetesters -- why, if I
hadn't matured this idea myself I might well be one of the flamers:-)
so I have no concrete proposals sub  -- yet.
...just a sec...
Ok, ready -- fire away!
More information about the Python-Dev