Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/openai/_base_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -879,7 +879,7 @@ def __del__(self) -> None:
try:
self.close()
except Exception:
pass
log.debug("Failed to auto-close client during finalization", exc_info=True)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

__del__ can run during interpreter shutdown after module globals have been cleared or set to None. This new diagnostic call is not guarded, so a close failure can now escape the destructor as an unraisable AttributeError when log is unavailable.

Using the same broken sync/async wrappers with base_client.log = None, base e67afa88 records [], while this head records two "'NoneType' object has no attribute 'debug'" events through sys.unraisablehook; the result is unchanged on the clean merge with current main d9029e3a.

Please keep the diagnostic, but guard the logging call itself and add regression coverage for both wrappers. A nested try around log.debug(...) restored [] locally and passed Ruff lint/format. Python documents the shutdown/global-state constraint for __del__.



class SyncAPIClient(BaseClient[httpx.Client, Stream[Any]]):
Expand Down Expand Up @@ -1505,7 +1505,7 @@ def __del__(self) -> None:
# TODO(someday): support non asyncio runtimes here
asyncio.get_running_loop().create_task(self.aclose())
except Exception:
pass
log.debug("Failed to schedule auto-close for async client during finalization", exc_info=True)


class AsyncAPIClient(BaseClient[httpx.AsyncClient, AsyncStream[Any]]):
Expand Down