-
Notifications
You must be signed in to change notification settings - Fork 1.1k
PYTHON-3193 - Add ResourceWarning for unclosed MongoClients in __del__ #1833
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
pymongo/asynchronous/mongo_client.py
Outdated
@@ -1173,6 +1175,22 @@ def __getitem__(self, name: str) -> database.AsyncDatabase[_DocumentType]: | |||
""" | |||
return database.AsyncDatabase(self, name) | |||
|
|||
def __del__(self) -> None: | |||
"""Check that this AsyncMongoClient has been closed and issue a warning if not.""" | |||
# TODO: Remove in https://jira.mongodb.org/browse/PYTHON-4731 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't realize we removed MongoClient.__del__
. I think we should preserve the 4.8 behavior and change connect=False
and remove the __del__
behavior together in 5.0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't we want to keep the __del__
warning forever?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh wait, we never had a __del__
. Yes, I agree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this comment now.
pymongo/asynchronous/mongo_client.py
Outdated
source=self, | ||
) | ||
if _IS_SYNC and self._opened: | ||
self.close() # type: ignore[unused-coroutine] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can't call close() even in the sync api because it might deadlock.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ooh good point.
pymongo/asynchronous/mongo_client.py
Outdated
try: | ||
if not self._closed: | ||
warnings.warn( | ||
f"Unclosed {self}", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should add more information here so users know why/when this started.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What kind of information should be here? Something like:
Unclosed MongoClient. Call MongoClient.close() to safely shut down your client and free up resources.
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should point users to the docs for https://jira.mongodb.org/browse/PYTHON-3606 (still TODO)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to pull that ticket up to 4.9, then? We should do them both in the same release if we want them to be linked.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. We need good docs or else we're going to be inundated with questions.
@NoahStapp could you also do some history digging into |
My understanding is that if you try to do any actual cleanup inside |
Yes that's one issue but there's another unrelated issue. Adding |
pymongo/asynchronous/mongo_client.py
Outdated
# TODO: Remove in https://jira.mongodb.org/browse/PYTHON-4731 | ||
try: | ||
if not self._closed: | ||
if _IS_SYNC: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer to remove the await
from the error message to reduce the duplication here.
pymongo/asynchronous/mongo_client.py
Outdated
if _IS_SYNC: | ||
msg = ( | ||
f"Unclosed {type(self)}. " | ||
f"Call {type(self)}.close() to safely shut down your client and free up resources." |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message can/should also include the traceback of where the client was opened via topology_settings._stack.
pymongo/asynchronous/mongo_client.py
Outdated
@@ -1173,6 +1175,22 @@ def __getitem__(self, name: str) -> database.AsyncDatabase[_DocumentType]: | |||
""" | |||
return database.AsyncDatabase(self, name) | |||
|
|||
def __del__(self) -> None: | |||
"""Check that this AsyncMongoClient has been closed and issue a warning if not.""" | |||
# TODO: Remove in https://jira.mongodb.org/browse/PYTHON-4731 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can remove this comment now.
I can't find an example of |
Thanks for looking into it. Could you?:
|
Here's the current warning:
|
What about the "Call {type(self).name}.close() to safely shut down your client and free up resources." part? |
Also I wonder if we can remove the last two frames from the trace to make it cleaner. |
Fixed. |
Return just the first frame? That should always be the line where the client was constructed, right? |
I mean
|
doc/changelog.rst
Outdated
@@ -42,6 +42,8 @@ PyMongo 4.9 brings a number of improvements including: | |||
- Fixed a bug where PyMongo would raise ``InvalidBSON: date value out of range`` | |||
when using :attr:`~bson.codec_options.DatetimeConversion.DATETIME_CLAMP` or | |||
:attr:`~bson.codec_options.DatetimeConversion.DATETIME_AUTO` with a non-UTC timezone. | |||
- Added a warning to unclosed MongoClient instances | |||
telling users to explicitly close clients when finished with them to avoid leaking resources . |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
resources .
-> resources.
Let's include an example of the warning here too.
doc/changelog.rst
Outdated
@@ -42,6 +42,16 @@ PyMongo 4.9 brings a number of improvements including: | |||
- Fixed a bug where PyMongo would raise ``InvalidBSON: date value out of range`` | |||
when using :attr:`~bson.codec_options.DatetimeConversion.DATETIME_CLAMP` or | |||
:attr:`~bson.codec_options.DatetimeConversion.DATETIME_AUTO` with a non-UTC timezone. | |||
- Added a warning to unclosed MongoClient instances | |||
telling users to explicitly close clients when finished with them to avoid leaking resources. | |||
Here's an example of what the warning looks like: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Here's an example of what the warning looks like:
-> For example:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
No description provided.