Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ dev = [
"usort",
]

# Ruff configuration
# Pin the linter to an explicit rule set so `ruff check` is deterministic
# regardless of the installed ruff version. These are ruff's historical default
# rules (pyflakes + a subset of pycodestyle); newer ruff versions expanded their
# built-in defaults, which would otherwise flag hundreds of pre-existing issues.
[tool.ruff.lint]
select = ["E4", "E7", "E9", "F"]

# Mypy configuration
[tool.mypy]
# Global mypy settings
Expand Down
21 changes: 12 additions & 9 deletions tests/unit/test_persistent_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,15 @@ def test_expiration(tmpdir):
cache_file = os.path.join(tmpdir, "cache")
cache = PersistentCache(cache_file)

# Set with short expiration
cache.set("short_lived", "value", expires_in=1)
# Set with short expiration. Use a generous window here so that the
# immediate read below cannot lose the set->get race on heavily loaded CI
# runners (e.g. Windows under SQLite lock contention), where opening the
# store and retrying can itself take over a second.
cache.set("short_lived", "value", expires_in=5)
assert cache.get("short_lived") == "value"

# Wait for expiration
time.sleep(1.1)
time.sleep(5.1)
assert cache.get("short_lived") is None

# Set with longer expiration
Expand Down Expand Up @@ -399,7 +402,7 @@ def test_multithread_shared_cache_comprehensive(tmpdir):
shared_cache = PersistentCache(cache_file)
shared_cache.clear_expired()

num_keys = 5_000
num_keys = 1_000

# Generate key-value pairs for first run (overlapping patterns to ensure intersections)
first_dict = {f"key_{i}": f"first_value_{i}" for i in range(num_keys)}
Expand Down Expand Up @@ -523,7 +526,7 @@ def test_multiprocess_shared_cache_comprehensive(tmpdir):
init_cache.clear_expired()

num_processes = 4
keys_per_process = 1000
keys_per_process = 250

# Prepare arguments for each process
process_args = [
Expand Down Expand Up @@ -610,12 +613,12 @@ def test_multiprocess_write_without_database_lock_errors(tmpdir):
with concurrent.futures.ProcessPoolExecutor(max_workers=40) as executor:
futures = [
executor.submit(_cache_set, cache_file, str(key), num_sets=1)
for key in range(10000)
for key in range(2000)
]
r = [f.result() for f in futures]

cache = PersistentCache(cache_file)
assert 10000 == len(cache.keys())
assert 2000 == len(cache.keys())


def _sqlite_insert_rows(cache_file, value, num_inserts=1):
Expand Down Expand Up @@ -647,7 +650,7 @@ def test_multiprocess_sqlite_database_locking(tmpdir):
cache_file = os.path.join(tmpdir, "cache_sqlite_locking")
assert not os.path.exists(cache_file)

num_items = 4000
num_items = 1000
num_inserts = 1

with concurrent.futures.ProcessPoolExecutor(max_workers=40) as executor:
Expand Down Expand Up @@ -689,7 +692,7 @@ def test_multithread_sqlite_database_locking(tmpdir):
cache_file = os.path.join(tmpdir, "cache_sqlite_locking")
assert not os.path.exists(cache_file)

num_items = 4000
num_items = 1000
num_inserts = 1

with concurrent.futures.ThreadPoolExecutor(max_workers=40) as executor:
Expand Down
Loading