tkinter broken for threaded Python on both pypy2 and pypy3

Issue #1929 new
Christopher Johnson
created an issue

I have a very large multi-threaded Python 3 and Tkinter project that I want to move to PyPy 3.

While moving my code over, I discovered that PyPy is broken in supporting threads.

So I made a small test program that demonstrates the bug. Here is the output displayed when running the program:

$ pypy3 tkintertest.py Exception in thread secondary: Traceback (most recent call last): File "/Users/christopher/bin/pypy3-2.4.0-osx64/lib-python/3/threading.py", line 740, in _bootstrap_inner self.run() File "/Users/christopher/bin/pypy3-2.4.0-osx64/lib-python/3/threading.py", line 693, in run self._target(self._args, self._kwargs) File "tkintertest.py", line 11, in secondary canvas.create_text(100, 50, text="Secondary thread") File "/Users/christopher/bin/pypy3-2.4.0-osx64/lib-python/3/tkinter/init.py", line 2256, in create_text return self._create('text', args, kw) File "/Users/christopher/bin/pypy3-2.4.0-osx64/lib-python/3/tkinter/init.py", line 2232, in _create (args + self._options(cnf, kw)))) File "/Users/christopher/bin/pypy3-2.4.0-osx64/lib_pypy/_tkinter/app.py", line 286, in call raise NotImplementedError("Call from another thread") NotImplementedError: Call from another thread

I cannot run my project on PyPy unless this gets fixed, and I cannot code around it, so I wish you all luck in working on this issue!

By the way, I tried running my test on PyPy 2 (with the Tkinter module name changed to capital T) and it failed with the same identical output. So PyPy 2 also need to be fixed.

I am running this on OS X 10.9.5 Mavericks. With the following displayed when I run PyPy interactively: Python 3.2.5 (b2091e973da6, Oct 19 2014, 18:30:58) [PyPy 2.4.0 with GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.51)] on darwin

--Christopher

Comments (8)

  1. Armin Rigo

    Indeed, it's an unimplemented behavior: CPython's tkinter module works around threads using logic that we don't have so far. But note that the tkinter module is pure Python in lib_pypy/_tkinter/. You can help! :-)

  2. timeyyy

    Running the ops code on windows with the pypy3.2 zip

    The first time i got this error

    Exception in thread secondary:                                                                                        
    Traceback (most recent call last):                                                                                    
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib-python\3\threading.py", line 740, in _bootstrap_inner    
        self.run()                                                                                                        
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib-python\3\threading.py", line 693, in run                 
        self._target(*self._args, **self._kwargs)                                                                         
      File "tkintertest.py", line 11, in secondary                                                                        
        canvas.create_text(100, 50, text="Secondary thread")                                                              
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib-python\3\tkinter\__init__.py", line 2256, in create_text 
        return self._create('text', args, kw)                                                                             
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib-python\3\tkinter\__init__.py", line 2232, in _create     
        *(args + self._options(cnf, kw))))                                                                                
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib_pypy\_tkinter\app.py", line 302, in call                 
        self.raiseTclError()                                                                                              
      File "C:\Users\timeyyy\Documents\git\pypy3-2.4.0-win32\lib_pypy\_tkinter\app.py", line 154, in raiseTclError        
        tklib.Tcl_GetStringResult(self.interp)).decode('utf-8'))                                                          
    _tkinter.TclError: invalid command name ".46120976" 
    

    Even after starting 10 threads and changing and adding buttons everything is still fine... The program froze when i tried to start 10 alert boxes though.

    Is there a reason the NotImplementedErro is no longer being raised??

  3. Armin Rigo

    Again, CPython's tkinter module works around threads using logic that we don't have so far. We ignore threads. This means using tk from more than a single thread can give total nonsense.

  4. timeyyy

    We CAN run python threads with tkinter, the behavior matches cpythons. The NotImplementedError is raised if tcl is compiled with threaded support. (pypy3.2 on windows is not available for download with tcl threaded support)

    The current state of tkinter pypy looks like this commit

    While the changes required to support a threaded tcl were introduced to cpython in this commit

    The changes required can be summarized as

    • the mainloop must be invoked in the thread that created the interpreter.
    • _tkinter will queue an event for the interpreter thread, which will then execute the command and pass back the result.
    • If the main thread is not in the mainloop, and invoking commands causes an exception
    • if the main loop is running but not processing events, the command invocation will block
  5. Log in to comment