Fix Windows PermissionError in pass_manager_drawer by correctly closi… #15495
+21
−3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
This PR fixes a PermissionError: [WinError 32] that occurs on Windows systems when using pass_manager_drawer as described in issue #15472
Details and comments
The current implementation generates a temporary image file, opens it with PIL.Image.open(), and immediately attempts to delete it via os.remove().
On Linux/Unix, deleting an open file is permitted (the inode remains until the file handle is closed).
On Windows, the file system enforces a lock on open files. Because PIL.Image.open() keeps the file handle active, os.remove() fails, crashing the visualization routine.
The Fix I have updated the file handling logic to use a context manager (with statement).
The image is opened within a with block to ensure the file handle is explicitly closed after reading.
The image data is copied to memory (.copy()) so the visualization object remains valid after the file is closed.
os.remove() is called only after the context manager exits (ensuring the file is closed).
Added a try/except block around the deletion as a defensive measure against other OS-level locks (e.g., antivirus scanners).
This approach provides a robust, OS-agnostic fix without requiring conditional logic (e.g., if sys.platform == 'win32').
Related Issue
Fixes WinError 32 during using qiskit.visualization.pass_manager_visualization in qiskit #15472
How to verify
Run the following code on a Windows environment:
Python
from qiskit.transpiler import generate_preset_pass_manager
from qiskit.visualization import pass_manager_drawer
pm = generate_preset_pass_manager(optimization_level=0)
This previously crashed with WinError 32
pass_manager_drawer(pm)
Verify the image renders correctly in the notebook.
Verify no PermissionError is raised.
AI Disclosure: AI tool used: Google Gemini