Search code examples
pythondjangopython-2to3

Converting Django project from Python 2 to Python 3: How to fix Python int OverFlowError?


I am converting a Django website from Python 2 to Python 3. To do this, I ran 2to3 on the whole project. Now, upon running the server (which works fine in Python 2), an OverflowError occurs as shown in the first code block. The lower block shows the manage.py file.

I have read elsewhere this may be an issue relating to int/float, but I am not quite sure how to handle an iterator with regard to this.

(env) user:languages user$ python3 manage.py runserver
Fatal Python error: initsite: Failed to import the site module
Traceback (most recent call last):
  File ".../src/languages/env/bin/../lib/python3.7/site.py", line 66, in <module>
    import os
  File ".../src/languages/env/bin/../lib/python3.7/os.py", line 661, in <module>
    from _collections_abc import MutableMapping
  File "...src/languages/env/bin/../lib/python3.7/_collections_abc.py", line 45, in <module>
    longrange_iterator = type(iter(list(range(1 << 1000))))
OverflowError: Python int too large to convert to C ssize_tappleperson
#!/usr/bin/env python3

import os
import sys

if __name__ == "__main__":
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "site.settings")

    from django.core.management import execute_from_command_line

    execute_from_command_line(sys.argv)

I expected manage.py to run the server as normal and produce the website but instead it gets hungup on the overflow error described above.


Solution

  • The original code in _collections_abc.py, in the Python 3 version, is:

    longrange_iterator = type(iter(range(1 << 1000)))
    

    Your version is

    longrange_iterator = type(iter(list(range(1 << 1000))))
    

    It looks like you used 2to3 on the Python3 code as well. range created a list in Python 2, so the exact equivalent in Python 3 would be list(range(...)), which seems to be the replacement that took place here. It fails, as it forces the code to create a gigantic list, which the original does not.

    So, when using 2to3, only apply it to the Python 2 code.