[Python-Dev] Subclasses vs. special methods (original) (raw)

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