Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does six.py use custom class for finding MAXSIZE?

I was going through the code for six.py in the django utils, which, for non Jython implementations, tries, to find the MAXSIZE for the int. Now, the way this is done is interesting - instead of catching an exception on the statement itself, the statement is wrapped within a __len__ method in a custom class. What may be the reason(s) to do so?

class X(object):
    def __len__(self):
        return 1 << 31
try:
    len(X())
except OverflowError:
    # 32-bit
    MAXSIZE = int((1 << 31) - 1)
else:
    # 64-bit
    MAXSIZE = int((1 << 63) - 1)
del X

If I'm not wrong, the same could have been shortened to the below as well, right?

try:
    1 << 31
except OverflowError:
    # 32-bit
    MAXSIZE = int((1 << 31) - 1)
else:
    # 64-bit
    MAXSIZE = int((1 << 63) - 1)
like image 838
Anshul Goyal Avatar asked Sep 27 '22 23:09

Anshul Goyal


1 Answers

int in python3 is a poly-glot sort of class that can represent machine ints as well as big-ints; a feature that superseedes the distinction between int and long in python2. On python3, the construction int(1 << n) never throws an error.

So to solve that, six is using a neat trick that forces python to cram something into a machine sized int. The len builtin always trys to convert the return value of __len__ into a machine sized thing:

>>> class Lengthy(object):
...     def __init__(self, x):
...         self.x = x
...     def __len__(self):
...         return self.x
...     
>>> int(1<<100)
1267650600228229401496703205376L
>>> type(int(1<<100))
<type 'long'>
>>> len(Lengthy(1<<100))
Traceback (most recent call last):
  File "<ipython-input-6-6b1b77348950>", line 1, in <module>
    len(Lengthy(1<<100))
OverflowError: long int too large to convert to int

>>> 

or, in Python 3, the exception is slightly different:

>>> len(Lengthy(1<<100))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: cannot fit 'int' into an index-sized integer
>>> 
like image 58
SingleNegationElimination Avatar answered Oct 06 '22 20:10

SingleNegationElimination