473,770 Members | 5,880 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Decimal, __radd__, and custom numeric types...

I'm having some issues with decimal.Decimal objects playing nice with
custom data types. I have my own matrix and rational classes which
implement __add__ and __radd__. They know what to do with Decimal
objects and react appropriately.

The problem is that they only work with Decimals if the custom type is
on the left (and therefore __add__ gets called), but NOT if the Decimal
is on the left. The Decimal immediately throws the usual "TypeError:
You can interact Decimal only with int, long or Decimal data types."
without even trying my __radd__ method to see if my custom type can
handle Decimals.
From the Python docs (specifically sections 3.3.7 and 3.3.8), I thought

that the left object should try its own __add__, and if it doesn't know
what to do, THEN try the right object's __radd__ method. I guess
Decimal objects don't do this? Is there a way to change this behavior?
If Decimal objects prematurely throw a TypeError before trying the
__rop__, is Decimal broken, or was it designed this way? I think I'm
missing something...

Thanks,
Blake

Jul 18 '05 #1
7 2030
Blake T. Garretson <bl************ *@gmail.com> wrote:
I'm having some issues with decimal.Decimal objects playing nice with
custom data types. I have my own matrix and rational classes which
implement __add__ and __radd__. They know what to do with Decimal
objects and react appropriately.

The problem is that they only work with Decimals if the custom type is
on the left (and therefore __add__ gets called), but NOT if the Decimal
is on the left. The Decimal immediately throws the usual "TypeError:
You can interact Decimal only with int, long or Decimal data types."
without even trying my __radd__ method to see if my custom type can
handle Decimals.

From the Python docs (specifically sections 3.3.7 and 3.3.8), I thought
that the left object should try its own __add__, and if it doesn't know
what to do, THEN try the right object's __radd__ method. I guess
Decimal objects don't do this? Is there a way to change this behavior?
If Decimal objects prematurely throw a TypeError before trying the
__rop__, is Decimal broken, or was it designed this way? I think I'm
missing something...


It looks like from reading 3.3.8 if decimal raised a NotImplemented
exception instead of a TypeError then it would work.

For objects x and y, first x.__op__(y) is tried. If this is not
implemented or returns NotImplemented, y.__rop__(x) is tried. If
this is also not implemented or returns NotImplemented, a
TypeError exception is raised. But see the following exception:

Exception to the previous item: if the left operand is an instance
of a built-in type or a new-style class, and the right operand is
an instance of a proper subclass of that type or class, the right
operand's __rop__() method is tried before the left operand's
__op__() method. This is done so that a subclass can completely
override binary operators. Otherwise, the left operand's __op__
method would always accept the right operand: when an instance of
a given class is expected, an instance of a subclass of that class
is always acceptable.

You could try this with a local copy of decimal.py since it is
written in Python.

--
Nick Craig-Wood <ni**@craig-wood.com> -- http://www.craig-wood.com/nick
Jul 18 '05 #2
On 28 Feb 2005 12:11:33 -0800, "Blake T. Garretson"
<bl************ *@gmail.com> wrote:

[...]
From the Python docs (specifically sections 3.3.7 and 3.3.8), I thought
that the left object should try its own __add__, and if it doesn't know
what to do, THEN try the right object's __radd__ method.
To me it reads more like the interpreter is responsible for picking
which method to call. Specifically, section 3.3.8 of the reference
manual states that y.__rop__() will be called if x.__op__() is not
implemented or returns NotImplemented. The decision to call
y.__rop__() is made outside the x.__op__() method, implying that
x.__op__() doesn't handle a call to y.__rop__() in this case. The
other rules dealing with whether x.__op__() or y.__rop__() is called
don't apply to your situation (but they could, keep reading).
I guess
Decimal objects don't do this? Is there a way to change this behavior?
If Decimal objects prematurely throw a TypeError before trying the
__rop__, is Decimal broken, or was it designed this way? I think I'm
missing something...

You could change the behavior of Decimal.__add__ by patching it or you
could use subclassing. If your classes are subclasses of Decimal,
their __rop__ methods will be called before Decimal.__op__ is tried.
I'm guessing your matrix and rational classes don't use decimal
representation, which makes this an OOP style-breaking kludge.

Jul 18 '05 #3
Blake T. Garretson wrote:
If Decimal objects prematurely throw a TypeError before trying the
__rop__, is Decimal broken, or was it designed this way?


I suspect the former, since I can't recall this subject coming up at any point
during the PEP approval or implementation process. And I was one of the people
who worked on it before 2.4 was released :)

So I'd suggest:

a) Checking that replacing the relevant "raise TypeError" calls in
Lib/Decimal.py with "return NotImplemented" gives you friendlier behaviour.

b) Filing a bug report on SF

I'll be bringing the question up on py-dev as well.

Cheers,
Nick.

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #4
Nick Coghlan wrote:
a) Checking that replacing the relevant "raise TypeError" calls in
Lib/Decimal.py with "return NotImplemented" gives you friendlier behaviour.


It turns out this isn't really practical - there's too much code in the module
relying on those TypeErrors being raised.

So this may change for Python 2.5 (I think it's a genuine bug), but you're
probably stuck with it for 2.4 (since changing it is a big enough semantic
change to break code in the same module, so who knows what it would do to user
code).

Bugger :(

Cheers,
Nick.

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #5
Nick Coghlan wrote:
Nick Coghlan wrote:
a) Checking that replacing the relevant "raise TypeError" calls in
Lib/Decimal.py with "return NotImplemented" gives you friendlier
behaviour.

It turns out this isn't really practical - there's too much code in the
module relying on those TypeErrors being raised.


Then again, maybe it's not so bad:

Py> class C:
.... def __add__(self, other):
.... print "OK!"
.... __radd__ = __add__
....
Py> x = decimal.Decimal ()
Py> C() + x
OK!
Py> x + C()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "C:\Python24\li b\decimal.py", line 906, in __add__
other = _convert_other( other)
File "C:\Python24\li b\decimal.py", line 2863, in _convert_other
raise TypeError, "You can interact Decimal only with int, long or Decimal da
ta types."
TypeError: You can interact Decimal only with int, long or Decimal data types.

Py> x = friendly_decima l.Decimal()
Py> C() + x
OK!
Py> x + C()
OK!

Cheers,
Nick.
http://boredomandlaziness.skystorm.n...dly_decimal.py

--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #6
Thanks for the suggestions and modified module. I will probably just
use this "fixed" module to solve my immediate problem. I appreciate
your post to python-dev as well; it looks like this may be addressed in
a future release. :)

Thanks,
Blake

Jul 18 '05 #7
Blake T. Garretson wrote:
Thanks for the suggestions and modified module. I will probably just
use this "fixed" module to solve my immediate problem.


Expect its performance to be worse than the standard version - it does the right
thing, but it sure ain't pretty. . .

Cheers,
Nick.
--
Nick Coghlan | nc******@email. com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.skystorm.net
Jul 18 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
6150
by: John Bentley | last post by:
John Bentley: INTRO The phrase "decimal number" within a programming context is ambiguous. It could refer to the decimal datatype or the related but separate concept of a generic decimal number. "Decimal Number" sometimes serves to distinguish Base 10 numbers, eg "15", from Base 2 numbers, Eg "1111". At other times "Decimal Number" serves to differentiate a number from an integer. For the rest of this post I shall only use either...
3
14828
by: Mark | last post by:
I have a Decimal or a Double - your choice. I'd like to print the number as string with a specified number of decimal places. Let's say my number 110.5, and I'd like to capture it in a string with 3 decimal places: "110.500". How do you do this? My method below isn't working so hot. Decimal dcTotal = 110.5; string strMyString = (Decimal.Round(dcTotal, 3)).ToString(); //Do something with this string Thanks in advance!
3
12922
by: JenHu | last post by:
Hi all, I have to read from a text file and generate values and insert to database. But first of all, when the text file contains '0000000000', I received a sEfundAmt value = 0D instead of 0.0 on sEfundAmt = Decimal.Parse(Mid$(sRetLine, 30, 10)) / 100.0 For example, in the text file, value is '0000150776', I want to
11
2257
by: Pieter | last post by:
Hi, I'm having some troubles with my numeric-types in my VB.NET 2005 application, together with a SQL Server 2000. - I first used Single in my application, and Decimal in my database. But a Single with value 4.475 was converted to a Decimal with value 4.4749999999999996D. So after inserting and selecting it from the database I got another value than the original!
12
2171
by: Frank Millman | last post by:
Hi all I have a standard requirement for a 'decimal' type, to instantiate and manipulate numeric data that is stored in a database. I came up with a solution long before the introduction of the Decimal type, which has been working well for me. I know the 'scale' (number of decimal places) of the number in advance. When I read the number in from the database I scale it up to an integer. When I write it back I scale it down again. All...
2
19491
hyperpau
by: hyperpau | last post by:
Before anything else, I am not a very technical expert when it comes to VBA coding. I learned most of what I know by the excellent Access/VBA forum from bytes.com (formerly thescripts.com). Ergo, I will be writing this article intended for those who are in the same level, or maybe lower, of my technical knowledge. I would be using layman's words, or maybe, my own words as how I understand them, hoping, you will understand it the same way that...
7
13685
by: Andrus | last post by:
How to create format string for decimal data type which shows blank for zero and default format otherwize ? I tried format string "f;f;#" but this shows f for nonzero numbers. Andrus. using System.Windows.Forms;
17
6809
by: D'Arcy J.M. Cain | last post by:
I'm not sure I follow this logic. Can someone explain why float and integer can be compared with each other and decimal can be compared to integer but decimal can't be compared to float? True True False This seems to break the rule that if A is equal to B and B is equal to C then A is equal to C.
6
3711
by: Terry Reedy | last post by:
Gerhard Häring wrote: The new fractions module acts differently, which is to say, as most would want. True Traceback (most recent call last): File "<pyshell#20>", line 1, in <module> F(1.0) File "C:\Program Files\Python30\lib\fractions.py", line 97, in __new__
0
9432
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10232
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10059
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9873
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8891
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7420
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5313
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5454
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3974
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.