Fixed ResourceWarning from unclosed SQLite connection on Python 3.13+.

- backends.sqlite.tests.ThreadSharing.test_database_sharing_in_threads
- backends.tests.ThreadTests.test_default_connection_thread_local:
    on SQLite, close() doesn't explicitly close in-memory connections.
- servers.tests.LiveServerInMemoryDatabaseLockTest
- test_runner.tests.SQLiteInMemoryTestDbs.test_transaction_support

Check out https://github.com/python/cpython/pull/108015.
This commit is contained in:
Mariusz Felisiak 2023-08-23 09:09:23 +02:00 committed by GitHub
parent a9e0f3d301
commit dd45d5223b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 40 additions and 17 deletions

View File

@ -6,7 +6,13 @@ import unittest
from pathlib import Path from pathlib import Path
from unittest import mock from unittest import mock
from django.db import NotSupportedError, connection, transaction from django.db import (
DEFAULT_DB_ALIAS,
NotSupportedError,
connection,
connections,
transaction,
)
from django.db.models import Aggregate, Avg, StdDev, Sum, Variance from django.db.models import Aggregate, Avg, StdDev, Sum, Variance
from django.db.utils import ConnectionHandler from django.db.utils import ConnectionHandler
from django.test import TestCase, TransactionTestCase, override_settings from django.test import TestCase, TransactionTestCase, override_settings
@ -222,11 +228,20 @@ class ThreadSharing(TransactionTestCase):
available_apps = ["backends"] available_apps = ["backends"]
def test_database_sharing_in_threads(self): def test_database_sharing_in_threads(self):
thread_connections = []
def create_object(): def create_object():
Object.objects.create() Object.objects.create()
thread_connections.append(connections[DEFAULT_DB_ALIAS].connection)
create_object() main_connection = connections[DEFAULT_DB_ALIAS].connection
thread = threading.Thread(target=create_object) try:
thread.start() create_object()
thread.join() thread = threading.Thread(target=create_object)
self.assertEqual(Object.objects.count(), 2) thread.start()
thread.join()
self.assertEqual(Object.objects.count(), 2)
finally:
for conn in thread_connections:
if conn is not main_connection:
conn.close()

View File

@ -792,7 +792,8 @@ class ThreadTests(TransactionTestCase):
# closed on teardown). # closed on teardown).
for conn in connections_dict.values(): for conn in connections_dict.values():
if conn is not connection and conn.allow_thread_sharing: if conn is not connection and conn.allow_thread_sharing:
conn.close() conn.validate_thread_sharing()
conn._close()
conn.dec_thread_sharing() conn.dec_thread_sharing()
def test_connections_thread_local(self): def test_connections_thread_local(self):

View File

@ -115,6 +115,7 @@ class LiveServerInMemoryDatabaseLockTest(LiveServerBase):
connection. connection.
""" """
conn = self.server_thread.connections_override[DEFAULT_DB_ALIAS] conn = self.server_thread.connections_override[DEFAULT_DB_ALIAS]
source_connection = conn.connection
# Open a connection to the database. # Open a connection to the database.
conn.connect() conn.connect()
# Create a transaction to lock the database. # Create a transaction to lock the database.
@ -128,6 +129,7 @@ class LiveServerInMemoryDatabaseLockTest(LiveServerBase):
finally: finally:
# Release the transaction. # Release the transaction.
cursor.execute("ROLLBACK") cursor.execute("ROLLBACK")
source_connection.close()
class FailingLiveServerThread(LiveServerThread): class FailingLiveServerThread(LiveServerThread):

View File

@ -779,16 +779,21 @@ class SQLiteInMemoryTestDbs(TransactionTestCase):
) )
with mock.patch("django.test.utils.connections", new=tested_connections): with mock.patch("django.test.utils.connections", new=tested_connections):
other = tested_connections["other"] other = tested_connections["other"]
DiscoverRunner(verbosity=0).setup_databases() try:
msg = ( new_test_connections = DiscoverRunner(verbosity=0).setup_databases()
"DATABASES setting '%s' option set to sqlite3's ':memory:' value " msg = (
"shouldn't interfere with transaction support detection." f"DATABASES setting '{option_key}' option set to sqlite3's "
% option_key "':memory:' value shouldn't interfere with transaction support "
) "detection."
# Transaction support is properly initialized for the 'other' DB. )
self.assertTrue(other.features.supports_transactions, msg) # Transaction support is properly initialized for the
# And all the DBs report that they support transactions. # 'other' DB.
self.assertTrue(connections_support_transactions(), msg) self.assertTrue(other.features.supports_transactions, msg)
# And all the DBs report that they support transactions.
self.assertTrue(connections_support_transactions(), msg)
finally:
for test_connection, _, _ in new_test_connections:
test_connection._close()
class DummyBackendTest(unittest.TestCase): class DummyBackendTest(unittest.TestCase):