Skip to content

[Bug]: PGF backend crashes at program exit after creating a plot #27437

Closed
@startrekdude

Description

@startrekdude

Bug summary

After successfully creating a plot using the PGF backend, Python will crash on exit while running cleanup code.

Code for reproduction

import matplotlib
matplotlib.use("pgf")

import matplotlib.pyplot as plt

fig, ax = plt.subplots(1, 1)
ax.plot(list(range(100)), [x * 2 for x in range(100)])
fig.savefig("test.pgf", format="pgf")

Actual outcome

Two exceptions are produced at exit. The first is:

Traceback (most recent call last):
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\weakref.py", line 666, in _exitfunc
    f()
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\weakref.py", line 590, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Anon\Desktop\Projects\mplbug\venv\Lib\site-packages\matplotlib\backends\backend_pgf.py", line 277, in finalize_latex
    latex.communicate()
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\subprocess.py", line 1209, in communicate
    stdout, stderr = self._communicate(input, endtime, timeout)
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\subprocess.py", line 1610, in _communicate
    self.stdout_thread.start()
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\threading.py", line 971, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't create new thread at interpreter shutdown

The second, which will not be produced if time elapses between plot creation and program exit (read: a sleep(0.5) call), is:

Traceback (most recent call last):
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 634, in _rmtree_unsafe
    os.unlink(fullname)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\Anon\\AppData\\Local\\Temp\\tmp4qorphqa\\texput.aux'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\tempfile.py", line 891, in onexc
    _os.unlink(path)
PermissionError: [WinError 32] The process cannot access the file because it is being used by another process: 'C:\\Users\\Anon\\AppData\\Local\\Temp\\tmp4qorphqa\\texput.aux'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\weakref.py", line 666, in _exitfunc
    f()
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\weakref.py", line 590, in __call__
    return info.func(*info.args, **(info.kwargs or {}))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\tempfile.py", line 923, in cleanup
    self._rmtree(self.name, ignore_errors=self._ignore_cleanup_errors)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\tempfile.py", line 903, in _rmtree
    _shutil.rmtree(name, onexc=onexc)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 796, in rmtree
    return _rmtree_unsafe(path, onexc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 636, in _rmtree_unsafe
    onexc(os.unlink, fullname, err)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\tempfile.py", line 894, in onexc
    cls._rmtree(path, ignore_errors=ignore_errors)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\tempfile.py", line 903, in _rmtree
    _shutil.rmtree(name, onexc=onexc)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 796, in rmtree
    return _rmtree_unsafe(path, onexc)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 612, in _rmtree_unsafe
    onexc(os.scandir, path, err)
  File "C:\Users\Anon\AppData\Local\Programs\Python\Python312\Lib\shutil.py", line 609, in _rmtree_unsafe
    with os.scandir(path) as scandir_it:
         ^^^^^^^^^^^^^^^^
NotADirectoryError: [WinError 267] The directory name is invalid: 'C:\\Users\\Anon\\AppData\\Local\\Temp\\tmp4qorphqa\\texput.aux'

Expected outcome

No crashes.

Additional information

Workaround that prevents both exceptions is running weakref.finalize._exitfunc() before program exit.
Workaround that prevents the second exception only is letting time elapse before program exit (like with a time.sleep(0.5) call).

Operating system

Windows 11 Enterprise 22H2

Matplotlib Version

3.8.2

Matplotlib Backend

pgf

Python version

3.12.0

Jupyter version

No response

Installation

pip

Metadata

Metadata

Assignees

No one assigned

    Labels

    OS: MicrosoftRelease criticalFor bugs that make the library unusable (segfaults, incorrect plots, etc) and major regressions.backend: pgf

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions