1

Tools: Python 3.10, cmd2 2.4.0, Windows 11, tk 0.1.0, matplotlib 3.5.1, pytest 7.0.1, cmd2-ext-test 2.0.0

I am building a set of pytest tests that cover code which normally outputs plots using matplotlib (backend="TkAgg"). This code is using cmd2 so the tests are calling cmd2 commands using cmd2-ext-test. In testing mode, I call plt.close('all') instead of plt.show() so that I don't have to manually close any windows while testing - that's the only difference in testing mode.

When running these tests, 1 or 2 out of 20 will randomly fail with an error that claims a file in tcl8.6 or tk8.6 doesn't exist even though it does (often a different file each time). Different tests fail, and sometimes none of them fail.

My Python packages are all installed for all users (so at c:/program files/python310/Lib using an administrator cmd prompt). Based on other answers online, I've tried copying the tcl/tcl8.6 and tcl/tk8.6 directories to Lib and no change. I tried commenting out the plt.close('all') and also no change.

The error is always triggered on a plt.figure() call. One example of the error I get when using pytest -vv (verbose mode) is shown below:

E             +     new_fig = plt.figure()
E             +   File "C:\Program Files\Python310\lib\site-packages\matplotlib\pyplot.py", line 787, in figure
E             +     manager = new_figure_manager(
E             +   File "C:\Program Files\Python310\lib\site-packages\matplotlib\pyplot.py", line 306, in new_figure_manager
E             +     return _backend_mod.new_figure_manager(*args, **kwargs)
E             +   File "C:\Program Files\Python310\lib\site-packages\matplotlib\backend_bases.py", line 3494, in new_figure_manager
E             +     return cls.new_figure_manager_given_figure(num, fig)
E             +   File "C:\Program Files\Python310\lib\site-packages\matplotlib\backends\_backend_tk.py", line 925, in new_figure_manager_given_figure
E             +     window = tk.Tk(className="matplotlib")
E             +   File "C:\Program Files\Python310\lib\tkinter\__init__.py", line 2299, in __init__
E             +     self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
E             + _tkinter.TclError: Can't find a usable init.tcl in the following directories:
E             +     {C:\Program Files\Python310\tcl\tcl8.6}
E             +
E             + C:/Program Files/Python310/tcl/tcl8.6/init.tcl: couldn't read file "C:/Program Files/Python310/tcl/tcl8.6/init.tcl": No error
E             + couldn't read file "C:/Program Files/Python310/tcl/tcl8.6/init.tcl": No error
E             +     while executing
E             + "source {C:/Program Files/Python310/tcl/tcl8.6/init.tcl}"
E             +     ("uplevel" body line 1)
E             +     invoked from within
E             + "uplevel #0 [list source $tclfile]"
E             +
E             +
E             + This probably means that Tcl wasn't installed properly.
E             +
E             + EXCEPTION of type 'TclError' occurred with message: Can't find a usable init.tcl in the following directories:
E             +     {C:\Program Files\Python310\tcl\tcl8.6}
E             +
E             + C:/Program Files/Python310/tcl/tcl8.6/init.tcl: couldn't read file "C:/Program Files/Python310/tcl/tcl8.6/init.tcl": No error
E             + couldn't read file "C:/Program Files/Python310/tcl/tcl8.6/init.tcl": No error
E             +     while executing
E             + "source {C:/Program Files/Python310/tcl/tcl8.6/init.tcl}"
E             +     ("uplevel" body line 1)
E             +     invoked from within
E             + "uplevel #0 [list source $tclfile]"
E             +
E             +
E             + This probably means that Tcl wasn't installed properly.

I'm totally stumped! Any help would be greatly appreciated!

jwcoder
  • 131
  • 9
  • The core error message there is `couldn't read file "C:/Program Files/Python310/tcl/tcl8.6/init.tcl": No error`; everything else is just wrapping. And `No error` is _very_ strange at that point! – Donal Fellows Mar 11 '22 at 21:50
  • I tried re-installing Python, using 3.9 instead of 3.10, and still get the same strange behavior – jwcoder Mar 12 '22 at 18:41
  • The issue is that there's a failure in some system call (*probably* `OpenFile()`) but when `GetLastError()` is called (Tcl calls it pretty much immediately on failure) it's returning a code indicating no error. Probably. **That's deeply weird, in the space of “that's not supposed to happen”.** I've previously only ever heard of this sort of thing happening with an anti-virus product (or malware) that was badly implemented, such that it was producing inconsistent system call behaviour. If that's the case, we have no fix available for you except to suggest getting rid of that AV product. – Donal Fellows Mar 14 '22 at 13:04
  • I don't have an AV product. I do see that my Windows 11 Security Manager isn't working properly - seems to be an issue that affects a lot of people (https://www.technipages.com/fix-windows-11-cannot-open-windows-security#:~:text=If%20you%20can't%20open,uninstall%20third%2Dparty%20security%20tools.) but using powershell to fix it which seems to work for most people, isn't working for me. I wonder if that's interacting here. – jwcoder Mar 14 '22 at 16:10
  • One thing I am doing that might be unusual is running from a VeraCrypt mounted folder (ie. the files are normally encrypted on disk). The Python installation and the Tcl files are NOT in that encrypted location. Not sure if that would matter in this case. – jwcoder Mar 14 '22 at 16:35
  • On the Windows 11 security manager, I fixed it by using a different solution (Get-AppXPackage -AllUsers | Foreach {Add-AppxPackage -DisableDevelopmentMode -Register “$($_.InstallLocation)\AppXManifest.xml”}). But still same issue with flaky Tcl when running tests. – jwcoder Mar 14 '22 at 16:55
  • Just to clarify my previous comment, I fixed the Windows 11 security manager issue I mentioned, but that had no impact on the flaky test behaviour in the main question. So there's still the weird behavior happening with pytest and tcl. – jwcoder Apr 12 '22 at 19:53
  • Has anybody of you already come closer to solving this issue? Half or our CI-run pytests fail randomly due to this error and its a huge hassle to restart them manually... – snek May 13 '22 at 07:41
  • 1
    @snek, I wasn't able to find a solution. My workaround was to use the flaky plugin for pytest so that these particular tests are rerun automatically 2 or 3 times if they fail. That has worked reliably for months now (for me). – jwcoder May 14 '22 at 11:38
  • I have a similar problem and work around it using flaky as well. It is curious that I cannot really find many examples of code combining tk and pytest, maybe there is something in the background of either that is conflicting? – agomcas Dec 19 '22 at 08:51

0 Answers0