Skip to content

Commit a024f65

Browse files
Amine-LGclaude
andcommitted
Windows: type-check the POSIX file lock by platform; read files as UTF-8
GitHub CI (first run): mypy on Windows rejected fcntl.flock in the spending ledger, because fcntl is POSIX-only. The lock is now taken under a sys.platform check that mypy understands; runtime behaviour is unchanged (file lock on POSIX, thread lock on Windows, as documented). Also read JSON files as UTF-8 explicitly, so Windows does not fall back to its locale code page (Spider loader, scripts, tests). No change to evaluation behaviour. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01E1YjKkuhoLd53dFQNTgHfH
1 parent 554da8f commit a024f65

7 files changed

Lines changed: 9 additions & 10 deletions

File tree

‎intentsql/benchmark/spider_ir.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class Unconvertible(ValueError):
2626
@lru_cache(maxsize=4)
2727
def _tables(split: str) -> dict[str, dict]:
2828
path = spider_root() / SPLIT_FILES[split][2]
29-
return {db["db_id"]: db for db in json.loads(Path(path).read_text())}
29+
return {db["db_id"]: db for db in json.loads(Path(path).read_text(encoding="utf-8"))}
3030

3131

3232
class _Converter:

‎intentsql/spending.py‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
import json
2323
import os
24+
import sys
2425
import threading
2526
import time
2627
from collections.abc import Iterator
@@ -77,11 +78,9 @@ def _locked(self) -> Iterator[dict[str, Any]]:
7778
return
7879
self.ledger.parent.mkdir(parents=True, exist_ok=True)
7980
with open(self.ledger.with_suffix(".lock"), "a+") as lock_file:
80-
try:
81+
if sys.platform != "win32": # Windows: the thread lock only
8182
import fcntl
8283
fcntl.flock(lock_file, fcntl.LOCK_EX)
83-
except ImportError: # Windows: thread lock only
84-
pass
8584
try:
8685
state = json.loads(self.ledger.read_text(encoding="utf-8"))
8786
if not isinstance(state, dict):

‎scripts/check_ir_coverage.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
def main(split: str, limit: int | None = None, show: int = 8) -> None:
2323
root = spider_root()
24-
data = json.loads((root / SPLIT_FILES[split][0]).read_text())[:limit]
24+
data = json.loads((root / SPLIT_FILES[split][0]).read_text(encoding="utf-8"))[:limit]
2525
outcome: Counter[str] = Counter()
2626
shown = 0
2727
for index, item in enumerate(data):

‎scripts/failures.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
import json
55
import sys
66

7-
report = json.load(open(sys.argv[1]))
7+
report = json.load(open(sys.argv[1], encoding="utf-8"))
88
if report["meta"].get("split") == "test":
99
sys.exit("refusing to print held-out test cases")
1010
filt = sys.argv[2] if len(sys.argv) > 2 else None

‎scripts/fit_calibration.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
def main(provider: str, paths: list[str]) -> None:
2121
points = []
2222
for path in paths:
23-
report = json.load(open(path))
23+
report = json.load(open(path, encoding="utf-8"))
2424
meta = report.get("meta", {})
2525
if meta.get("split") != "train":
2626
sys.exit(f"{path}: calibration is fitted on train reports only")

‎tests/test_custom_models.py‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def test_add_test_edit_and_remove(self):
115115
moved = self.add(id="lab-model", api_key=None, url="https://elsewhere.example/decide").json()
116116
self.assertFalse(self.card(moved)["has_key"])
117117

118-
stored = json.loads((Path(self.tmp.name) / "connection.json").read_text())
118+
stored = json.loads((Path(self.tmp.name) / "connection.json").read_text(encoding="utf-8"))
119119
if os.name == "posix": # Windows has no owner-only mode bits
120120
self.assertEqual((Path(self.tmp.name) / "connection.json").stat().st_mode & 0o777, 0o600)
121121
self.assertNotIn("custom:lab-model", stored["keys"])
@@ -297,7 +297,7 @@ def test_hand_edited_settings_cannot_crash_or_bypass_the_rules(self):
297297
json.dumps({"custom": {"evil": {"label": "E", "url": "http://evil.example/x", "model": "m",
298298
"max_chars": -5}},
299299
"keys": {"custom:evil": "k-0123456789", "typesafe": 12345}})):
300-
path.write_text(content)
300+
path.write_text(content, encoding="utf-8")
301301
config.settings.cache_clear()
302302
response = self.client.get("/api/connection")
303303
self.assertEqual(response.status_code, 200, content)

‎tests/test_spending.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def test_ledger_persists_and_its_limit_cannot_be_raised(self):
4242
second.reserve(0.7)
4343
lower = Budget(0.5, self.ledger)
4444
self.assertEqual(Budget(None, self.ledger).limit, 0.5)
45-
self.assertEqual(json.loads(self.ledger.read_text())["requests"], 1)
45+
self.assertEqual(json.loads(self.ledger.read_text(encoding="utf-8"))["requests"], 1)
4646
self.assertIsNotNone(lower)
4747

4848
def test_concurrent_reservations_never_pass_the_limit(self):

0 commit comments

Comments
 (0)