Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there any implementation of Python2 where ordering is transitive?

Is there any existing implementation of Python2 where ordering is transitive? That is, where it's impossible to see this behaviour without creating user-defined types:

>>> x < y < z < x
True

CPython is not transitive because of this counterexample

x = 'b'
y = ()
z = u'ab'

However, this ordering in CPython is documented as only an implementation detail.

like image 237
wim Avatar asked Oct 21 '16 16:10

wim


1 Answers

Every mainstream Python implementation fails in one way or another except for Skulpt, but it's arguably an incomplete implementation.

CPython (and variants), PyPy, and Jython:

>>> 'b' < () < u'ab' < 'b'
True

IronPython:

IronPython internally compares the .NET Object.GetHashCode() hashes of unlike objects, so you can break it by abusing the special handling of int and float comparisons and the fact that the internal hash representation of float('+inf') is less than the hash of [] (I'm not sure how stable this is, so it might not work on every installation of IronPython):

>>> 2**200 < float('+inf') < [] < 2**200
True

CLPython

>>> {1: 3} < {1: 4} < {1: 3}
1
>>> {1: 3} < {1: 3}
0

Skulpt

If you count Skulpt as a complete implementation of Python 2 (it can't compare dictionaries and a few other inconvenient types, and has no unicode type), it actually does work by copying CPython's rules for comparison and conveniently leaving out the unicode type:

# 1. None is less than anything
# 2. Sequence types are greater than numeric types
# 3. [d]ict < [l]ist < [s]tring < [t]uple

>>> None < 0 < {} < [] < '' < ()
True

For CPython 2, you would actually have [t]uple < [u]nicode, but because unicode and str comparisons are handled as a special case, you lose transitivity. Although it's unlikely that Python 2 will get a patch to fix this "bug", I think you can ensure transitivity by just explicitly changing the order from:

[d]ict < [l]ist < [s]tring < [t]uple < [u]nicode

To:

[u]nicode < [d]ict < [l]ist < [s]tring < [t]uple

That way, the special case of str to unicode comparisons doesn't break anything.

like image 161
Blender Avatar answered Nov 14 '22 05:11

Blender