-
Notifications
You must be signed in to change notification settings - Fork 699
Description
Triggered during a Pytest run for me
Describe the bug
PyRIT’s SQLite memory cleanup can emit a shutdown-time logging error when dispose_engine() logs after a logging handler’s underlying stream has already been closed. This results in:
ValueError: I/O operation on closed file
The cleanup is registered via atexit.register(self.dispose_engine) and weakref.finalize(self, self.dispose_engine) in MemoryInterface.cleanup(). During interpreter shutdown these callbacks can run after other code has already closed logging streams/handlers.
Steps/Code to Reproduce
Steps:
mkdir pyrit-shutdown-log-repro
cd pyrit-shutdown-log-repro
uv venv --python 3.12
source .venv/bin/activate
uv pip install pyrit
uv run python repro_closed_logging_stream.py
Code (repro_closed_logging_stream.py):
import io
import logging
from pyrit.memory.sqlite_memory import SQLiteMemory
# Simulate an application/test-runner that creates a handler writing to a stream,
# then closes that stream before interpreter shutdown.
stream = io.StringIO()
handler = logging.StreamHandler(stream)
root = logging.getLogger()
root.addHandler(handler)
root.setLevel(logging.INFO)
# Instantiating SQLiteMemory registers shutdown cleanup via atexit + weakref.finalize.
SQLiteMemory()
# Close the stream before interpreter shutdown; PyRIT's finalizer logs during shutdown.
stream.close()
print("created; stream closed; exiting now")Expected Results
No shutdown-time logging error. Cleanup should be silent or robust even if log handler streams are already closed.
Actual Results
On process exit (after the script prints created; stream closed; exiting now), Python emits a logging error similar to:
ValueError: I/O operation on closed file
Call stack:
File ".../site-packages/pyrit/memory/sqlite_memory.py", line 343, in dispose_engine
logger.info("Engine disposed and all connections closed.")
Message: 'Engine disposed and all connections closed.'
Arguments: ()
Screenshots
N/A
Versions
- OS: Linux (WSL2)
- Python version: 3.12.x
- PyRIT version: 0.11.0
pyrit.show_versions()
import pyrit
pyrit.show_versions()Output:
pyrit.show_versions()
System:
python: 3.12.3 (main, Mar 3 2026, 12:15:18) [GCC 13.3.0]
executable: /reponame/.venv/bin/python
machine: Linux-6.6.87.2-microsoft-standard-WSL2-x86_64-with-glibc2.39
Python dependencies:
pyrit: 0.11.0
Cython: None
numpy: 2.2.6
openai: 2.21.0
packaging: 26.0
pip: None
scipy: 1.17.0
setuptools: 79.0.1
sqlite3: None
torch: 2.8.0
transformers: 5.2.0