Mark Dickinson wrote:
On Sep 30, 9:21 am, Terry Reedy <[EMAIL PROTECTED]> wrote:
If no one beats me to it, I will probably file a bug report or two, but
I am still thinking about what to say and to suggest.

I can't see many good options here.  Some possibilities:

Thanks for responding. Agreeing on a fix would make it more likely to happen sooner ;-)

(0) Do nothing besides documenting the problem
somewhere (perhaps in a manual section entitled
'Infrequently Asked Questions', or
'Uncommon Python Pitfalls').  I guess the rule is
simply that Decimals don't mix well with other
numeric types besides integers:  if you put both
floats and Decimals into a set, or compare a
Decimal with a Fraction, you're asking for
trouble.  I suppose the obvious place for such
a note would be in the decimal documentation,
since non-users of decimal are unlikely to encounter
these problems.

Documenting the problem properly would mean changing the set documentation to change at least the definitions of union (|), issubset (<=), issuperset (>=), and symmetric_difference (^) from their current math set based definitions to implementation based definitions that describe what they actually do instead of what they intend to do. I do not like this option.

(1) 'Fix' the Decimal type to do numerical comparisons
with other numeric types correctly, and fix up the
Decimal hash appropriately.

(1A) All that is needed for fix equality transitivity corruption and the consequent set/dictview problems is to correctly compare integral values. For this, Decimal hash seems fine already. For the int i I tried, hash(i) == hash(float(i)) == hash(Decimal(i)) == hash(Fraction(i)) == i.

It is fine for transitivity that all fractional decimals are unequal to all fractional floats (and all fractions) since there is no integer (or fraction) that either is equal to, let alone both.

This is what I would choose unless there is some 'hidden' problem. But it seem to me this should work: when a float and decimal are both integral (easy to determine) convert either to an int and use the current int-whichever comparison.

(2) I wonder whether there's a way to make Decimals
and floats incomparable, so that an (in)equality check
between them always raises an exception, and any
attempt to have both Decimals and floats in the same
set (or as keys in the same dict) also gives an error.
(Decimals and integers should still be allowed to
mix happily, of course.) But I can't see how this could
be done without adversely affecting set performance.

I pretty strongly believe that equality checks should always work (at least in Python as delivered) just as boolean checks should (and do).

Option (1) is certainly technically feasible, but I
don't like it much: it means adding a whole load
of code to the Decimal module that benefits few users
but slows down hash computations for everyone.
And then any new numeric type that wants to fit in
with Python's rules had better worry about hashing
equal to ints, floats, Fractions, complexes, *and*
Decimals...

I believe (1A) would be much easier both to implement and for new numeric types.

Option (2) appeals to me, but I can't see how to
implement it.

So I guess that just leaves updating the docs.
Other thoughts?

(3) Further isolate decimals by making decimals also unequal to all ints. Like (1A), this would easily fix transitivity breakage, but I would consider the result less desirable.

My ranking: 1A > 3 > 0 > 2. I might put 1 between 1A and 3, but I am not sure.

Mark

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list

Reply via email to