]> git.ipfire.org Git - thirdparty/psycopg.git/commitdiff
Don't look up other modules objects in __del__ methods
authorDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 6 Jan 2022 16:09:22 +0000 (17:09 +0100)
committerDaniele Varrazzo <daniele.varrazzo@gmail.com>
Thu, 6 Jan 2022 21:49:20 +0000 (22:49 +0100)
The modules might have been already cleaned up during interpreted
shutdown. See <https://bugs.python.org/issue46256#msg409847> 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.

docs/news.rst
psycopg/psycopg/connection.py
psycopg/psycopg/pq/pq_ctypes.py
psycopg/psycopg/server_cursor.py

index 2b8b2fbbd9cf347d33efb0b91480eeb270661ef6..3e597a15cfc0822bb3597aa519c23f6390c77f21 100644 (file)
@@ -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
index d2bedf8e33bf9feccc0c88ad381258b70bc8c3db..6af5a327b6d03813a5be948959e56e0b6e9fc41e 100644 (file)
@@ -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,
index a4d2775b563d5accf16d4d0c30719d055869c54e..83b2882123f93d9c2c14a90d1b3c9247a355702f 100644 (file)
@@ -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.
index 8ef1e9af9f6706b1df1af7955d837e4dcd507efa..a245d9573340e093f40f8852194006ee74d3f2db 100644 (file)
@@ -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,