New submission from Serhiy Storchaka: Python implementation of Decimal.from_float() calls __new__ and __init__ methods of subclass.
>>> from _pydecimal import Decimal >>> class D(Decimal): ... def __new__(cls, *args, **kwargs): ... print('__new__') ... return Decimal.__new__(cls, *args, **kwargs) ... def __init__(self, *args, **kwargs): ... print('__init__') ... >>> print(type(D.from_float(42))) __new__ __init__ <class '__main__.D'> >>> print(type(D.from_float(42.0))) __new__ __init__ <class '__main__.D'> But C implementation doesn't. >>> from decimal import Decimal >>> class D(Decimal): ... def __new__(cls, *args, **kwargs): ... print('__new__') ... return Decimal.__new__(cls, *args, **kwargs) ... def __init__(self, *args, **kwargs): ... print('__init__') ... >>> print(type(D.from_float(42))) <class '__main__.D'> >>> print(type(D.from_float(42.0))) <class '__main__.D'> This means that resulting instance of Decimal subclass can be in not valid state. Example is Decimal enums (see also issue23640). >>> from decimal import Decimal >>> from enum import Enum >>> class D(Decimal, Enum): ... A = Decimal('3.25') ... >>> D(Decimal(3.25)) <D.A: Decimal('3.25')> >>> D(3.25) <D.A: Decimal('3.25')> >>> D.from_float(3.25) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/serhiy/py/cpython/Lib/enum.py", line 486, in __repr__ self.__class__.__name__, self._name_, self._value_) AttributeError: 'D' object has no attribute '_name_' A solution is to reproduce Python implementation in C code: result = ... # create exact Decimal if cls is not Decimal: result = cls(result) return result ---------- components: Extension Modules messages: 265368 nosy: facundobatista, mark.dickinson, rhettinger, serhiy.storchaka, skrah priority: normal severity: normal status: open title: C implementation of Decimal.from_float() bypasses __new__ and __init__ type: behavior versions: Python 3.5, Python 3.6 _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue27006> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com