From: Daniele Varrazzo Date: Thu, 6 Jan 2022 16:09:22 +0000 (+0100) Subject: Don't look up other modules objects in __del__ methods X-Git-Tag: pool-3.1~38 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4ea31ca597926746d3fb3ca11697d3b2fa5fc70;p=thirdparty%2Fpsycopg.git Don't look up other modules objects in __del__ methods The modules might have been already cleaned up during interpreted shutdown. See for an explanation. The stdlib guards against the same thing happening too. However they take a reference in the function closure, which is stronger than what we do. Doing so, on our strictly typed codebase, is a tedious chore, so, if this is enough (it should be, according to the OP), I'm happy this way. Close #198. --- diff --git a/docs/news.rst b/docs/news.rst index 2b8b2fbbd..3e597a15c 100644 --- a/docs/news.rst +++ b/docs/news.rst @@ -24,6 +24,8 @@ Psycopg 3.0.8 (unreleased) - Decode connection errors in the ``client_encoding`` specified in the connection string, if available (:ticket:`#194`). +- Fix possible warnings in objects deletion on interpreter shutdown + (:ticket:`#198`). Psycopg 3.0.7 diff --git a/psycopg/psycopg/connection.py b/psycopg/psycopg/connection.py index d2bedf8e3..6af5a327b 100644 --- a/psycopg/psycopg/connection.py +++ b/psycopg/psycopg/connection.py @@ -5,13 +5,13 @@ psycopg connection objects # Copyright (C) 2020-2021 The Psycopg Team import logging -import warnings import threading from types import TracebackType from typing import Any, Callable, cast, Dict, Generator, Generic, Iterator from typing import List, NamedTuple, Optional, Type, TypeVar, Tuple, Union from typing import overload, TYPE_CHECKING from weakref import ref, ReferenceType +from warnings import warn from functools import partial from contextlib import contextmanager @@ -146,7 +146,7 @@ class BaseConnection(Generic[Row]): if hasattr(self, "_pool"): return - warnings.warn( + warn( f"connection {self} was deleted while still open." f" Please use 'with' or '.close()' to close the connection", ResourceWarning, diff --git a/psycopg/psycopg/pq/pq_ctypes.py b/psycopg/psycopg/pq/pq_ctypes.py index a4d2775b5..83b288212 100644 --- a/psycopg/psycopg/pq/pq_ctypes.py +++ b/psycopg/psycopg/pq/pq_ctypes.py @@ -8,9 +8,9 @@ implementation. # Copyright (C) 2020-2021 The Psycopg Team -import os -import logging import sys +import logging +from os import getpid from weakref import ref from functools import partial @@ -25,6 +25,9 @@ from .misc import PGnotify, ConninfoOption, PGresAttDesc from .misc import error_message, connection_summary from ._enums import Format, ExecStatus, Trace +# Imported locally to call them from __del__ methods +from ._pq_ctypes import PQclear, PQfinish, PQfreeCancel, PQstatus + if TYPE_CHECKING: from . import abc @@ -84,12 +87,12 @@ class PGconn: ) impl.PQsetNoticeReceiver(pgconn_ptr, self._notice_receiver, None) - self._procpid = os.getpid() + self._procpid = getpid() def __del__(self) -> None: # Close the connection only if it was created in this process, # not if this object is being GC'd after fork. - if os.getpid() == self._procpid: + if getpid() == self._procpid: self.finish() def __repr__(self) -> str: @@ -123,7 +126,7 @@ class PGconn: def finish(self) -> None: self._pgconn_ptr, p = None, self._pgconn_ptr if p: - impl.PQfinish(p) + PQfinish(p) @property def pgconn_ptr(self) -> Optional[int]: @@ -203,7 +206,7 @@ class PGconn: @property def status(self) -> int: - return impl.PQstatus(self._pgconn_ptr) + return PQstatus(self._pgconn_ptr) @property def transaction_status(self) -> int: @@ -743,7 +746,7 @@ class PGresult: def clear(self) -> None: self._pgresult_ptr, p = None, self._pgresult_ptr if p: - impl.PQclear(p) + PQclear(p) @property def pgresult_ptr(self) -> Optional[int]: @@ -876,7 +879,7 @@ class PGcancel: """ self.pgcancel_ptr, p = None, self.pgcancel_ptr if p: - impl.PQfreeCancel(p) + PQfreeCancel(p) def cancel(self) -> None: """Requests that the server abandon processing of the current command. diff --git a/psycopg/psycopg/server_cursor.py b/psycopg/psycopg/server_cursor.py index 8ef1e9af9..a245d9573 100644 --- a/psycopg/psycopg/server_cursor.py +++ b/psycopg/psycopg/server_cursor.py @@ -4,9 +4,9 @@ psycopg server-side cursor objects. # Copyright (C) 2020-2021 The Psycopg Team -import warnings from typing import Any, AsyncIterator, Generic, List, Iterable, Iterator from typing import Optional, TypeVar, TYPE_CHECKING +from warnings import warn from . import pq from . import sql @@ -200,7 +200,7 @@ class ServerCursor(Cursor[Row]): def __del__(self) -> None: if not self.closed: - warnings.warn( + warn( f"the server-side cursor {self} was deleted while still open." f" Please use 'with' or '.close()' to close the cursor properly", ResourceWarning, @@ -343,7 +343,7 @@ class AsyncServerCursor(AsyncCursor[Row]): def __del__(self) -> None: if not self.closed: - warnings.warn( + warn( f"the server-side cursor {self} was deleted while still open." f" Please use 'with' or '.close()' to close the cursor properly", ResourceWarning,