Some types have alternative constructors -- class methods used to create an instance of the class. For example: int.from_bytes(), float.fromhex(), dict.fromkeys(), Decimal.from_float().

But what should return these methods for subclasses? Should they return an instance of base class or an instance of subclass? Almost all alternative constructors return an instance of subclass (exceptions are new in 3.6 bytes.fromhex() and bytearray.fromhex() that return bare bytes and bytearray). But there is a problem, because this allows to break invariants provided by the main constructor.

For example, there are only two instances of the bool class: False and True. But with the from_bytes() method inherited from int you can create new boolean values!

   >>> Confusion = bool.from_bytes(b'\2', 'big')
   >>> isinstance(Confusion, bool)
   True
   >>> Confusion == True
   False
   >>> bool(Confusion)
   True
   >>> Confusion
   False
   >>> not Confusion
   False

bool is just the most impressive example, the same problem exists with IntEnum and other enums derived from float, Decimal, datetime. [1]

The simplest solution is to return an instance of base class. But this can breaks a code, and for this case we should be use static method (like str.maketrans), not class method.

Should alternative constructor call __new__ and __init__ methods? Thay can change signature in derived class. Should it complain if __new__ or __init__ were overridden?

[1] http://bugs.python.org/issue23640

_______________________________________________
Python-Dev mailing list
Python-Dev@python.org
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to