feat!: adopt Python 3.15 and support BattlesnakeArena
- Require Python 3.15 in project metadata, runtime pin, and Docker stages. - Use lazy imports for database backends and type-only dependencies. - Defer benchmark dependencies until their code paths are used. - Rely on deferred annotations and use Path.info for file discovery. - Accept BattlesnakeArena alongside BattlesnakeEngine on game endpoints. - Advance quart_common for Python 3.15 and multi-agent validation. - Add pytest development dependencies and refresh the uv lockfile. - Test lazy backend loading, import order, and fresh file discovery. - Document the runtime requirements and locked uv workflow. BREAKING CHANGE: Python 3.15 or newer is required; earlier runtimes cannot parse the lazy import syntax.
This commit is contained in:
@@ -4,6 +4,30 @@ import unittest
|
||||
from pathlib import Path
|
||||
|
||||
class TestDatabasePackageImports(unittest.TestCase):
|
||||
def test_builder_works_after_direct_backend_module_import(self):
|
||||
from server.database.backend.SqliteGameplayBackend import SqliteGameplayBackend
|
||||
from server.database.backend import GameplayBackendBuilder
|
||||
|
||||
backend = GameplayBackendBuilder.build(db_path=":memory:")
|
||||
self.assertIsInstance(backend, SqliteGameplayBackend)
|
||||
|
||||
def test_builder_import_defers_backend_modules(self):
|
||||
project_root = Path(__file__).resolve().parents[1]
|
||||
script = """
|
||||
import sys
|
||||
from server.database.backend import GameplayBackendBuilder
|
||||
assert 'server.database.backend.SqliteGameplayBackend' not in sys.modules
|
||||
assert 'server.database.backend.PostgresqlGameplayBackend' not in sys.modules
|
||||
backend = GameplayBackendBuilder.build(db_path=':memory:')
|
||||
assert backend.__class__.__name__ == 'SqliteGameplayBackend'
|
||||
assert 'server.database.backend.PostgresqlGameplayBackend' not in sys.modules
|
||||
"""
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-c", script], cwd=project_root,
|
||||
text=True, capture_output=True,
|
||||
)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
|
||||
def test_sqlite_backend_import_does_not_require_aiofiles(self):
|
||||
project_root = Path(__file__).resolve().parents[1]
|
||||
script = """
|
||||
|
||||
@@ -18,6 +18,17 @@ class TestDatasetIO(unittest.TestCase):
|
||||
self.assertIn("a.jsonl", names)
|
||||
self.assertIn("b.jsonl.gz", names)
|
||||
|
||||
def test_resolve_input_files_uses_fresh_metadata_on_each_scan(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
base = Path(tmp)
|
||||
path = base / "rows.jsonl"
|
||||
path.write_text('{}\n', encoding="utf-8")
|
||||
self.assertEqual(DatasetIO.resolve_input_files([str(base)]), [path])
|
||||
path.unlink()
|
||||
self.assertEqual(DatasetIO.resolve_input_files([str(base)]), [])
|
||||
path.write_text('{}\n', encoding="utf-8")
|
||||
self.assertEqual(DatasetIO.resolve_input_files([str(path)]), [path])
|
||||
|
||||
def test_iter_jsonl_rows_reads_gz_file(self):
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
path = Path(tmp) / "rows.jsonl.gz"
|
||||
|
||||
Reference in New Issue
Block a user