[Python-Dev] Subclasses vs. special methods
Serhiy Storchaka
storchaka at gmail.com
Sat Jan 4 13:58:57 CET 2014
Should implicit converting an instance of int, float, complex, str,
bytes, etc subclasses to call appropriate special method __int__ (or
__index__), __float__, __complex__, __str__, __bytes__, etc? Currently
explicit converting calls these methods, but implicit converting doesn't.
>>> class I(int):
... def __int__(self): return 42
... def __index__(self): return 43
...
>>> class F(float):
... def __float__(self): return 42.0
...
>>> class S(str):
... def __str__(self): return '*'
...
>>> int(I(65))
42
>>> float(F(65))
42.0
>>> str(S('A'))
'*'
>>> chr(I(65))
'A'
>>> import cmath; cmath.rect(F(65), 0)
(65+0j)
>>> ord(S('A'))
65
Issue17576 [1] proposes to call special methods for implicit converting.
I have doubts about this.
1. I afraid that this will adds places where arbitrary Python code is
unexpectedly called. For example see changeset9a61be172c23 discussed in
neighbor thread. If the "k" format code will call __int__(), Python code
can modify unpacked list argument during parsing arguments in
PyArg_ParseTuple().
2. PyLong_As*() functions already is not very consistent. Some of them
calls __int__() for argument which is not an instance of int subclass,
other accepts only instances of int subclasses. PyLong_AsVoidPtr() calls
or not calls __int__() depending on the sign of the argument.
3. We can't consistency call special methods for all types. E.g. for
strings we can't call __str__() when processing the "s" code in
PyArg_ParseTuple() because this will cause a leak.
I think that overriding special converting method in a subclass of
corresponding type should be restricted. I see two consistent and safe
possibilities:
1. Forbidden. I.e. above declarations of I, F and S classes should raise
exceptions.
2. Has no effect. I.e. both int(I(65)) and operator.index(I(65)) should
return 65.
[1] http://bugs.python.org/issue17576
More information about the Python-Dev
mailing list