[Python-Dev] PEP 3144 review.

Mark Dickinson dickinsm at gmail.com
Wed Sep 30 10:31:25 CEST 2009


On Wed, Sep 30, 2009 at 1:44 AM, Nick Coghlan <ncoghlan at gmail.com> wrote:
> Martin v. Löwis wrote:
>>> I would say that there certainly are precedents in other areas for
>>> keeping the information about the input form around. For example,
>>> occasionally it would be handy if parsing a hex integer returned an
>>> object that was compatible with other integers but somehow kept a hint
>>> that would cause printing it to use hex by default.
>>
>> At the risk of bringing in false analogies: it seems that Python
>> typically represents values of some type in their canonical form,
>> rather than remembering the form in which they arrived in the program:
>> - integer values "forget" how many preceding zeroes they have
>> - string literals forget which of the characters had been escaped, and
>>   whether the string was single- or double-quoted
>> - floating point values forget a lot more about their literal
>>   representation (including even the literal decimal value)
>>
>> I guess a close case would be rational numbers: clearly, 3÷2 == 6÷4;
>> would a Python library still remember (and repr) the original numerator
>> and denominator?
>
> For a concrete example of an object which remembers details about its
> creation that it ignores when determining equality, we have decimal.Decimal:
>
> .>> from decimal import Decimal as d
> .>> x = d("3.0")
> .>> y = d("3.00")
> .>> x
> d("3.0")
> .>> y
> d("3.00")
> .>> repr(x) == repr(y)
> False
> .>> x.as_tuple() == y.as_tuple()
> False
> .>> x == y
> True
[snipped]

[More on the Decimal analogy below.]

Please could someone who understands the uses of IPNetwork better than
I do explain why the following wouldn't be a significant problem, if __eq__
and __hash__ were modified to disregard the .ip attribute as suggested:

>>> linus = IPv4Network('172.16.200.1/24')
>>> snoopy = IPv4Network('172.16.200.3/24')
>>> fqdn = {linus: 'linus.peanuts.net', snoopy: 'snoopy.peanuts.net'}
>>> fqdn[linus]  # expecting 'linus.peanuts.net'
'snoopy.peanuts.net'

Is this just a problem of education, teaching the users not to abuse
IPv4Network this way?  Or is this just an unlikely use of IPv4Network?
Or have I misunderstood the proposal altogether?

As for Decimal, I see that as another whole kettle of tuna:  equality for
Decimal couldn't reasonably have been done any other way---if it weren't
mandated by the standard, there would still be a very strong expectation
that == would mean numeric equality.  That is, I see the == operator
as having two distinct but mostly compatible uses in Python:  it's
used for numeric equality, *and* it's used as the equivalence relation for
determining container membership.  Mostly these two different meanings
get along fine, though they lead to some fun when trying to ensure
that x == y implies hash(x) == hash(y) for x and y two different numeric
types.

But since Decimals and floats aren't used as set elements or dict keys
that often, the fact that you can't store Decimal('1.0') and Decimal('1.00')
together in a set doesn't often get in the way.  I'd expect putting
IPv4Network objects in a set or dict to be more common.

Mark


More information about the Python-Dev mailing list