diff --git a/Lib/test/test_dbm.py b/Lib/test/test_dbm.py index ae9faabd536a6c..ce3f7912d0aa53 100644 --- a/Lib/test/test_dbm.py +++ b/Lib/test/test_dbm.py @@ -4,7 +4,7 @@ import dbm import os from test.support import import_helper -from test.support import os_helper +from test.support import os_helper, gc_collect try: @@ -58,6 +58,7 @@ def init_db(self): for k in self._dict: f[k.encode("ascii")] = self._dict[k] f.close() + gc_collect() def keys_helper(self, f): keys = sorted(k.decode("ascii") for k in f.keys()) @@ -181,6 +182,7 @@ def _calculate_db_size(db_path): f[k.encode('ascii')] = self._dict[k] * 100000 db_keys = list(f.keys()) + gc_collect() # Make sure to calculate size of database only after file is closed to ensure file content are flushed to disk. size_before = _calculate_db_size(os.path.dirname(_fname)) @@ -191,6 +193,7 @@ def _calculate_db_size(db_path): del f[k] f.reorganize() + gc_collect() # Make sure to calculate size of database only after file is closed to ensure file content are flushed to disk. size_after = _calculate_db_size(os.path.dirname(_fname)) diff --git a/Lib/test/test_dbm_sqlite3.py b/Lib/test/test_dbm_sqlite3.py index f367a98865d4aa..cb3fd45755665f 100644 --- a/Lib/test/test_dbm_sqlite3.py +++ b/Lib/test/test_dbm_sqlite3.py @@ -5,7 +5,7 @@ from contextlib import closing from functools import partial from pathlib import Path -from test.support import import_helper, os_helper +from test.support import import_helper, os_helper, gc_collect dbm_sqlite3 = import_helper.import_module("dbm.sqlite3") # N.B. The test will fail on some platforms without sqlite3 @@ -32,7 +32,6 @@ def tearDown(self): for suffix in "", "-wal", "-shm": os_helper.unlink(self.filename + suffix) - class URI(unittest.TestCase): def test_uri_substitutions(self): @@ -72,6 +71,7 @@ def setUp(self): with dbm_sqlite3.open(self.filename, "w") as db: db[b"key1"] = "value1" db[b"key2"] = "value2" + gc_collect() self.db = dbm_sqlite3.open(self.filename, "r") def tearDown(self): @@ -112,6 +112,7 @@ def setUp(self): def test_readonly_file_read(self): os.chmod(self.db_path, stat.S_IREAD) + gc_collect() with dbm_sqlite3.open(self.db_path, "r") as db: self.assertEqual(db[b"key"], b"value") @@ -123,6 +124,7 @@ def test_readonly_file_write(self): def test_readonly_dir_read(self): os.chmod(self.test_dir, stat.S_IREAD | stat.S_IEXEC) + gc_collect() with dbm_sqlite3.open(self.db_path, "r") as db: self.assertEqual(db[b"key"], b"value") @@ -134,6 +136,7 @@ def test_readonly_dir_write(self): modified = True # on Windows and macOS except dbm_sqlite3.error: modified = False + gc_collect() with dbm_sqlite3.open(self.db_path, "r") as db: if modified: self.assertEqual(db[b"newkey"], b"newvalue") @@ -350,6 +353,7 @@ def test_corrupt_readwrite(self): check(fn=self.len_) def test_corrupt_force_new(self): + gc_collect() with closing(dbm_sqlite3.open(self.filename, "n")) as db: db["foo"] = "write" _ = db[b"foo"] diff --git a/Misc/NEWS.d/next/Library/2025-12-12-14-19-19.gh-issue-142631.SQ88Sh.rst b/Misc/NEWS.d/next/Library/2025-12-12-14-19-19.gh-issue-142631.SQ88Sh.rst new file mode 100644 index 00000000000000..4bf8458da5f09a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-12-14-19-19.gh-issue-142631.SQ88Sh.rst @@ -0,0 +1 @@ +Enable deferred reference counting on :class:`functools.lru_cache` objects for better scaling in free-threaded builds. Patch by Kumar Aditya. diff --git a/Modules/_functoolsmodule.c b/Modules/_functoolsmodule.c index 5773083ff68b46..7719f890eefcd0 100644 --- a/Modules/_functoolsmodule.c +++ b/Modules/_functoolsmodule.c @@ -1656,6 +1656,7 @@ lru_cache_new(PyTypeObject *type, PyObject *args, PyObject *kw) obj->cache_info_type = Py_NewRef(cache_info_type); obj->dict = NULL; obj->weakreflist = NULL; + _PyObject_SetDeferredRefcount((PyObject *)obj); return (PyObject *)obj; }