'Python3 and Tkinter - Unable to alloc 27 bytes

In a piece of my code, my script generates a string to copy it in a scrolled text widget. if the size of the string is not so heavy, this process works without any kind of issues, but when the string is heavy, the script can't paste it into the scrolled text widget. when it happens, the script crashes, and an error message appears in the terminal: unable to alloc 27 bytes (it's not an exception event).

before the crash, I got the bytes size of the string via sys.getsizeof function, and it was 230031360 bytes (230 MB).

In these cases, the user can solve the issue by choosing to write the output message in a text file, but what about if the user tries to write a heavy string in the scrolled text widget anyway? In this specific case, I would very like to show a message box to advice the user to write the output in a text file, but how can I understand if the script can write the string in the scrolled text widget or not? what is the bytes limit of a string in Python?

UPDATE:

I wrote an example to show you where the issue occurs. the main window will crash in oround two minutes with an error message in the terminal, unable to alloc 28 bytes:

from tkinter import *
from tkinter import ttk, scrolledtext
import ipaddress

def GiveMeHosts():
    ls = []
    for host in ipaddress.ip_network("10.0.0.0/8").hosts():
        ls.append(str(host))
    return ls

parent = Tk()
parent.geometry("400x350")
parent.title("The window will crash..")

MyWidget=scrolledtext.ScrolledText(parent, wrap=WORD, width=36, height=14, font=("Segoe UI", 9), state="normal")
MyWidget.pack()

parent.update()

# the string "hosts" is too long, and "MyWidget" can't manage it!
hosts = "\n".join(GiveMeHosts())
MyWidget.insert("1.0", hosts) # it makes the script to crash

parent.mainloop()


Solution 1:[1]

I ran your code, and while it took quite some time, it did finally put all IP addresses in the scrolled text box. No errors and no crashes. By the way: unable to alloc 28 bytes, that is exactly the size of the last two ip-adresses ?!? (10.255.255.253 10.255.255.254).

I went one step further. Actually two steps. Tried to run the same code, but multiplied the return value ls *= 5. Still valid results, no crashes. Meanwhile ls has a size of 1790312344 bytes (1.67 GB).

At ls *=10 however, ls now has a size of 2545286976 bytes (2.37 GB), it finally did crash with the following Traceback:

Traceback (most recent call last):
  File "F:\pybin\StackOverflow\so.py", line 28, in <module>
    MyWidget.insert("1.0", hosts) # it makes the script to crash
  File "C:\Program Files\Python36\lib\tkinter\__init__.py", line 3266, in insert
    self.tk.call((self._w, 'insert', index, chars) + args)
OverflowError: string is too long

Altogether it seems that there is indeed a limit, but the limit may very well be system dependent. At least, that is what I conclude from it.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Ronald