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

Reply via email to