[Python-Dev] PEP 399: Pure Python/C Accelerator Module Compatibiilty Requirements

Stefan Krah stefan at bytereef.org
Wed Apr 6 21:08:24 CEST 2011


Brett Cannon <brett at python.org> wrote:
>     * We also suffer from inconsistency in choice of
>      exceptions (i.e. overly large sequence indices
>      raising either an IndexError, OverflowError, or
>      ValueError).
> 
> 
> Once again, a general issue in our C code and not special to this PEP.

Not only in the C code. I get the impression that exceptions are
sometimes handled somewhat arbitrarily. Example:


decimal.py encodes the rounding mode as strings. For a simple invalid
argument we have the following three cases:


# I would prefer a ValueError:
>>> Decimal("1").quantize(Decimal('2'), "this is not a rounding mode")
Decimal('1')

# I would prefer a ValueError:
>>> Decimal("1.11111111111").quantize(Decimal('1e100000'), "this is not a rounding mode")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/stefan/pydev/cpython/Lib/decimal.py", line 2494, in quantize
    ans = self._rescale(exp._exp, rounding)
  File "/home/stefan/pydev/cpython/Lib/decimal.py", line 2557, in _rescale
    this_function = getattr(self, self._pick_rounding_function[rounding])
KeyError: 'this is not a rounding mode'

# I would prefer a TypeError:
>>> Decimal("1.23456789").quantize(Decimal('1e-100000'), ROUND_UP, "this is not a context")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/stefan/pydev/cpython/Lib/decimal.py", line 2478, in quantize
    if not (context.Etiny() <= exp._exp <= context.Emax):
AttributeError: 'str' object has no attribute 'Etiny'


cdecimal naturally encodes the rounding mode as integers and raises a
TypeError in all three cases. The context in cdecimal is a custom
type that translates the flag dictionaries to simple C integers.

This is extremely fast since the slow dictionaries are only updated
on actual accesses. In normal usage, there is no visible difference
to the decimal.py semantics, but there is no way that one could
use a custom context (why would one anyway?).


I think Raymond is right that these issues need to be addressed. Other
C modules will have similar discrepancies to their Python counterparts.


A start would be:

  1) Module constants (like ROUND_UP), should be treated as opaque. If
     a user relies on a specific type, he is on his own.

  2) If it is not expected that custom types will used for a certain
     data structure, then a fixed type can be used.


For cdecimal, the context actually falls under the recently added subset
clause of the PEP, but 2) might be interesting for other modules.



Stefan Krah




More information about the Python-Dev mailing list