7

I've found a strange behavior in the decimal module. The "signature" of the class Decimal is:

Decimal(value='0', context=None)

So, I supposed that I can do something like:Decimal('3', None). But this code raises a TypeError exception in python3.3 but not in python2.7.

In my investigations, I tried debugging with pdb:pdb.set_trace("Decimal('3', None)"), but nothing happened! As soon as I type s the same exception is raised.

Can someone explain the reasons of these behaviors?

SilentGhost
  • 307,395
  • 66
  • 306
  • 293
G Tux
  • 73
  • 1
  • 3
  • For what it's worth, I'm unable to reproduce this under Python 3.2.3: `import decimal; decimal.Decimal("3", None)` successfully returns `Decimal('3')`. – Frédéric Hamidi Nov 02 '12 at 11:34
  • 3
    [It's a bug](http://bugs.python.org/issue15783) – SilentGhost Nov 02 '12 at 15:37
  • @SilentGhost: I see in the link that it's a bug in the c accelerator version of the module (whatever this is). This can explain why I get nothing from pdb. But can I specify that I want the pure python version? – G Tux Nov 02 '12 at 17:25
  • 1
    @GTux: it would be a hack. Can't you just check what you're passing to constructor? – SilentGhost Nov 02 '12 at 17:48
  • 1
    @SilentGhost: that's what i'm doing. I wanted to learn a new trick :) – G Tux Nov 02 '12 at 18:38
  • @SilentGhost: My apology (+1's to the comments). I did not want to steal the idea. I just did not noticed :) – pepr Nov 02 '12 at 20:47

1 Answers1

5

I can confirm the behaviour for Python 3.3. It somehow detects that you passed the None as the context and it does not like it (even though it is documented as the default value).

Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:57:17) [MSC v.1600 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> decimal.Decimal('3', None)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: optional argument must be a context
>>> decimal.Decimal('3')
Decimal('3')

Update: But it works with 3.2.3

Python 3.2.3 (default, Apr 11 2012, 07:12:16) [MSC v.1500 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import decimal
>>> decimal.Decimal('3', None)
Decimal('3')
>>>

Update: The reason can be found in the doc...

What’s New In Python 3.3 says:

decimal

issue 7652 - integrate fast native decimal arithmetic. C-module and libmpdec written by Stefan Krah.

When comparing the decimal.py files, they may look the same at first, but the Python 3.3 version contains the following code almost at the end:

try:
    import _decimal
except ImportError:
    pass
else:
    s1 = set(dir())
    s2 = set(dir(_decimal))
    for name in s1 - s2:
        del globals()[name]
    del s1, s2, name
    from _decimal import *

... while the older Python 3.2 does not. It says that if the binary _decimal implementation could be imported, the older implementation from decimal.py is ignored. And the binary module cannot be debugged using the Python-code debugger.

The question is whether the observed behaviour should not be considered a bug.

pepr
  • 20,112
  • 15
  • 76
  • 139
  • like I said, I just want to understand this behavior, and why I can't see the code execution with pdb. In my code, I use an ugly workaround (I test `context` and call the appropriate form). – G Tux Nov 02 '12 at 16:28
  • thanks, now I understand. About your question, apparently the bug is already openned, see SilentGhost comment. – G Tux Nov 02 '12 at 20:41
  • @GTux: The hack mentioned by Silent Ghost could be to comment out the `try` block mentioned in the answer. But in the case, I recommend to rename it and put it to your script directory -- say `mydecimal.py`. – pepr Nov 02 '12 at 20:51
  • Now that I know why it's happening, I can sleep peacefully, continue to use my old hack (test `context` before instantiating), and wait for the bug to be fixed. – G Tux Nov 02 '12 at 21:07
  • @GTux: Yes. And do not forget to add a comment why you did it. (You know, Zaphod Beeblebrox forgot to do that... :) – pepr Nov 02 '12 at 21:19
  • Actually, I didn't think to do so. So thank you again, good advice. – G Tux Nov 02 '12 at 21:30