py-harness-cli 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- finetune/__init__.py +1 -0
- finetune/agent_system.py +41 -0
- finetune/agent_traces.py +157 -0
- finetune/everyday.py +30 -0
- finetune/hf_ollama.py +158 -0
- finetune/huggingface_store.py +144 -0
- finetune/models.py +74 -0
- finetune/paths.py +11 -0
- finetune/python_vibe.py +788 -0
- finetune/splits.py +54 -0
- finetune/systems.py +9 -0
- harness/__init__.py +42 -0
- harness/__main__.py +8 -0
- harness/act/__init__.py +6 -0
- harness/act/autofix/__init__.py +110 -0
- harness/act/autofix/additions.py +217 -0
- harness/act/autofix/conflicts.py +124 -0
- harness/act/autofix/cover.py +419 -0
- harness/act/autofix/mechanical.py +151 -0
- harness/act/autofix/missing_imports.py +50 -0
- harness/act/autofix/moves.py +439 -0
- harness/act/autofix/names.py +339 -0
- harness/act/autofix/scaffold.py +224 -0
- harness/act/code.py +157 -0
- harness/act/gate.py +229 -0
- harness/act/parse.py +247 -0
- harness/act/patch_fix.py +138 -0
- harness/act/tools.py +244 -0
- harness/agent/__init__.py +11 -0
- harness/agent/dispatch.py +235 -0
- harness/agent/loop.py +699 -0
- harness/agent/options.py +144 -0
- harness/agent/policy.py +856 -0
- harness/agent/prompt.py +170 -0
- harness/cli.py +393 -0
- harness/editor_kit.py +265 -0
- harness/guard/__init__.py +6 -0
- harness/guard/fallbacks.py +6 -0
- harness/guard/loop_guard.py +57 -0
- harness/guard/python_vibe.py +68 -0
- harness/guard/run.py +41 -0
- harness/guard/types.py +19 -0
- harness/locate.py +767 -0
- harness/mcp_stdio.py +306 -0
- harness/memory/__init__.py +5 -0
- harness/memory/conversation.py +104 -0
- harness/model/__init__.py +6 -0
- harness/model/chat_backend.py +100 -0
- harness/model/engine.py +165 -0
- harness/model/ollama_generate.py +60 -0
- harness/model/openai_generate.py +156 -0
- harness/model/outbound.py +83 -0
- harness/model/route.py +90 -0
- harness/observe/__init__.py +6 -0
- harness/observe/eval_gate.py +80 -0
- harness/observe/eval_loop.py +185 -0
- harness/observe/eval_tasks.py +399 -0
- harness/observe/report_md.py +102 -0
- harness/observe/trace_record.py +79 -0
- harness/openai_api.py +81 -0
- harness/paths.py +88 -0
- harness/py.typed +0 -0
- harness/scan/__init__.py +6 -0
- harness/scan/app_spec.py +338 -0
- harness/scan/design.py +112 -0
- harness/scan/existing.py +131 -0
- harness/scan/layout.py +254 -0
- harness/scan/names.py +308 -0
- harness/scan/project_brief.py +287 -0
- harness/scan/project_docs.py +42 -0
- harness/scan/project_scan.py +49 -0
- harness/scan/repo_map.py +101 -0
- harness/secrets.py +39 -0
- harness/server.py +199 -0
- harness/ship/__init__.py +1 -0
- harness/ship/bot_pr.py +221 -0
- harness/ship/git_ship.py +262 -0
- harness/ship/identity.py +62 -0
- harness/ship/ticket.py +251 -0
- harness/skillkit/__init__.py +6 -0
- harness/skillkit/catalog.py +241 -0
- harness/skillkit/refuse_change.py +640 -0
- harness/skillkit/refuse_finish.py +295 -0
- harness/skillkit/target.py +238 -0
- harness/task.py +717 -0
- py_harness_cli-0.3.0.dist-info/METADATA +177 -0
- py_harness_cli-0.3.0.dist-info/RECORD +92 -0
- py_harness_cli-0.3.0.dist-info/WHEEL +5 -0
- py_harness_cli-0.3.0.dist-info/entry_points.txt +3 -0
- py_harness_cli-0.3.0.dist-info/licenses/LICENSE +202 -0
- py_harness_cli-0.3.0.dist-info/licenses/NOTICE +6 -0
- py_harness_cli-0.3.0.dist-info/top_level.txt +2 -0
finetune/python_vibe.py
ADDED
|
@@ -0,0 +1,788 @@
|
|
|
1
|
+
"""Python vibe-coding pairs — working code first, short note after."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def all_pairs() -> list[tuple[str, str]]:
|
|
7
|
+
return list(_PAIRS)
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
_PAIRS: list[tuple[str, str]] = [
|
|
11
|
+
(
|
|
12
|
+
"Write a script that lists the largest files under a directory.",
|
|
13
|
+
"""Walks with `pathlib`, sorts by size, prints a table.
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
#!/usr/bin/env python3
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
import argparse
|
|
19
|
+
|
|
20
|
+
def main() -> None:
|
|
21
|
+
p = argparse.ArgumentParser()
|
|
22
|
+
p.add_argument("root", type=Path, default=Path("."), nargs="?")
|
|
23
|
+
p.add_argument("-n", type=int, default=20)
|
|
24
|
+
args = p.parse_args()
|
|
25
|
+
files = [f for f in args.root.rglob("*") if f.is_file()]
|
|
26
|
+
files.sort(key=lambda f: f.stat().st_size, reverse=True)
|
|
27
|
+
for f in files[: args.n]:
|
|
28
|
+
print(f"{f.stat().st_size:>12} {f}")
|
|
29
|
+
|
|
30
|
+
if __name__ == "__main__":
|
|
31
|
+
main()
|
|
32
|
+
```
|
|
33
|
+
""",
|
|
34
|
+
),
|
|
35
|
+
(
|
|
36
|
+
"JSONL reader that yields dicts and skips bad lines.",
|
|
37
|
+
"""Don't crash the whole file on one bad row.
|
|
38
|
+
|
|
39
|
+
```python
|
|
40
|
+
import json
|
|
41
|
+
from collections.abc import Iterator
|
|
42
|
+
from pathlib import Path
|
|
43
|
+
|
|
44
|
+
def read_jsonl(path: Path) -> Iterator[dict]:
|
|
45
|
+
with path.open(encoding="utf-8") as fh:
|
|
46
|
+
for line_no, line in enumerate(fh, 1):
|
|
47
|
+
line = line.strip()
|
|
48
|
+
if not line:
|
|
49
|
+
continue
|
|
50
|
+
try:
|
|
51
|
+
row = json.loads(line)
|
|
52
|
+
except json.JSONDecodeError as exc:
|
|
53
|
+
print(f"skip {path}:{line_no}: {exc}")
|
|
54
|
+
continue
|
|
55
|
+
if isinstance(row, dict):
|
|
56
|
+
yield row
|
|
57
|
+
```
|
|
58
|
+
""",
|
|
59
|
+
),
|
|
60
|
+
(
|
|
61
|
+
"Tiny FastAPI ping + echo.",
|
|
62
|
+
"""One file. Run with `uvicorn app:app --reload`.
|
|
63
|
+
|
|
64
|
+
```python
|
|
65
|
+
from fastapi import FastAPI
|
|
66
|
+
from pydantic import BaseModel
|
|
67
|
+
|
|
68
|
+
app = FastAPI()
|
|
69
|
+
|
|
70
|
+
class Echo(BaseModel):
|
|
71
|
+
text: str
|
|
72
|
+
|
|
73
|
+
@app.get("/health")
|
|
74
|
+
def health() -> dict[str, str]:
|
|
75
|
+
return {"status": "ok"}
|
|
76
|
+
|
|
77
|
+
@app.post("/echo")
|
|
78
|
+
def echo(body: Echo) -> Echo:
|
|
79
|
+
return body
|
|
80
|
+
```
|
|
81
|
+
""",
|
|
82
|
+
),
|
|
83
|
+
(
|
|
84
|
+
"Retry a function three times with backoff.",
|
|
85
|
+
"""Stdlib only.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
import time
|
|
89
|
+
from collections.abc import Callable
|
|
90
|
+
from typing import TypeVar
|
|
91
|
+
|
|
92
|
+
T = TypeVar("T")
|
|
93
|
+
|
|
94
|
+
def retry(fn: Callable[[], T], *, attempts: int = 3, base: float = 0.2) -> T:
|
|
95
|
+
last: Exception | None = None
|
|
96
|
+
for i in range(attempts):
|
|
97
|
+
try:
|
|
98
|
+
return fn()
|
|
99
|
+
except Exception as exc:
|
|
100
|
+
last = exc
|
|
101
|
+
time.sleep(base * (2 ** i))
|
|
102
|
+
assert last is not None
|
|
103
|
+
raise last
|
|
104
|
+
```
|
|
105
|
+
""",
|
|
106
|
+
),
|
|
107
|
+
(
|
|
108
|
+
"Async gather with a timeout per task.",
|
|
109
|
+
"""`asyncio.wait_for` per call, then `gather`.
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
import asyncio
|
|
113
|
+
from collections.abc import Awaitable, Sequence
|
|
114
|
+
from typing import TypeVar
|
|
115
|
+
|
|
116
|
+
T = TypeVar("T")
|
|
117
|
+
|
|
118
|
+
async def gather_timeout(
|
|
119
|
+
aws: Sequence[Awaitable[T]], timeout: float
|
|
120
|
+
) -> list[T | BaseException]:
|
|
121
|
+
wrapped = [asyncio.wait_for(aw, timeout) for aw in aws]
|
|
122
|
+
return list(await asyncio.gather(*wrapped, return_exceptions=True))
|
|
123
|
+
```
|
|
124
|
+
""",
|
|
125
|
+
),
|
|
126
|
+
(
|
|
127
|
+
"pytest: temp file in, expected string out.",
|
|
128
|
+
"""Fixture writes the input; assert the function.
|
|
129
|
+
|
|
130
|
+
```python
|
|
131
|
+
from pathlib import Path
|
|
132
|
+
import pytest
|
|
133
|
+
from mypkg.io import slugify_file
|
|
134
|
+
|
|
135
|
+
def test_slugify_file(tmp_path: Path) -> None:
|
|
136
|
+
src = tmp_path / "Hello World.TXT"
|
|
137
|
+
src.write_text("x", encoding="utf-8")
|
|
138
|
+
out = slugify_file(src)
|
|
139
|
+
assert out.name == "hello-world.txt"
|
|
140
|
+
```
|
|
141
|
+
""",
|
|
142
|
+
),
|
|
143
|
+
(
|
|
144
|
+
"Parse a .env file into a dict. No extra libs.",
|
|
145
|
+
"""Ignore comments and blank lines. Last key wins.
|
|
146
|
+
|
|
147
|
+
```python
|
|
148
|
+
from pathlib import Path
|
|
149
|
+
|
|
150
|
+
def load_dotenv(path: Path) -> dict[str, str]:
|
|
151
|
+
out: dict[str, str] = {}
|
|
152
|
+
for raw in path.read_text(encoding="utf-8").splitlines():
|
|
153
|
+
line = raw.strip()
|
|
154
|
+
if not line or line.startswith("#") or "=" not in line:
|
|
155
|
+
continue
|
|
156
|
+
key, _, value = line.partition("=")
|
|
157
|
+
out[key.strip()] = value.strip().strip("\"'")
|
|
158
|
+
return out
|
|
159
|
+
```
|
|
160
|
+
""",
|
|
161
|
+
),
|
|
162
|
+
(
|
|
163
|
+
"Dedup a list of dicts by (name, version) without json.dumps.",
|
|
164
|
+
"""Tuple keys, not stringified JSON.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
def unique_packages(rows: list[dict]) -> list[dict]:
|
|
168
|
+
seen: set[tuple[str, str]] = set()
|
|
169
|
+
out: list[dict] = []
|
|
170
|
+
for row in rows:
|
|
171
|
+
key = (row["name"], row["version"])
|
|
172
|
+
if key in seen:
|
|
173
|
+
continue
|
|
174
|
+
seen.add(key)
|
|
175
|
+
out.append(row)
|
|
176
|
+
return out
|
|
177
|
+
```
|
|
178
|
+
""",
|
|
179
|
+
),
|
|
180
|
+
(
|
|
181
|
+
"Context manager that cd's and comes back.",
|
|
182
|
+
"""
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from contextlib import contextmanager
|
|
186
|
+
from pathlib import Path
|
|
187
|
+
import os
|
|
188
|
+
from collections.abc import Iterator
|
|
189
|
+
|
|
190
|
+
@contextmanager
|
|
191
|
+
def pushd(path: Path) -> Iterator[None]:
|
|
192
|
+
prev = Path.cwd()
|
|
193
|
+
os.chdir(path)
|
|
194
|
+
try:
|
|
195
|
+
yield
|
|
196
|
+
finally:
|
|
197
|
+
os.chdir(prev)
|
|
198
|
+
```
|
|
199
|
+
""",
|
|
200
|
+
),
|
|
201
|
+
(
|
|
202
|
+
"SQLite insert-or-ignore for a url cache.",
|
|
203
|
+
"""
|
|
204
|
+
|
|
205
|
+
```python
|
|
206
|
+
import sqlite3
|
|
207
|
+
from pathlib import Path
|
|
208
|
+
|
|
209
|
+
def open_cache(path: Path) -> sqlite3.Connection:
|
|
210
|
+
conn = sqlite3.connect(path)
|
|
211
|
+
conn.execute(
|
|
212
|
+
"CREATE TABLE IF NOT EXISTS pages (url TEXT PRIMARY KEY, body TEXT)"
|
|
213
|
+
)
|
|
214
|
+
return conn
|
|
215
|
+
|
|
216
|
+
def put(conn: sqlite3.Connection, url: str, body: str) -> None:
|
|
217
|
+
conn.execute("INSERT OR IGNORE INTO pages(url, body) VALUES (?, ?)", (url, body))
|
|
218
|
+
conn.commit()
|
|
219
|
+
```
|
|
220
|
+
""",
|
|
221
|
+
),
|
|
222
|
+
(
|
|
223
|
+
"httpx GET with a hard timeout and raise for status.",
|
|
224
|
+
"""
|
|
225
|
+
|
|
226
|
+
```python
|
|
227
|
+
import httpx
|
|
228
|
+
|
|
229
|
+
def fetch_text(url: str, timeout: float = 10.0) -> str:
|
|
230
|
+
with httpx.Client(timeout=timeout) as client:
|
|
231
|
+
response = client.get(url)
|
|
232
|
+
response.raise_for_status()
|
|
233
|
+
return response.text
|
|
234
|
+
```
|
|
235
|
+
""",
|
|
236
|
+
),
|
|
237
|
+
(
|
|
238
|
+
"dataclass for a train example, frozen.",
|
|
239
|
+
"""
|
|
240
|
+
|
|
241
|
+
```python
|
|
242
|
+
from dataclasses import dataclass
|
|
243
|
+
|
|
244
|
+
@dataclass(frozen=True)
|
|
245
|
+
class Example:
|
|
246
|
+
user: str
|
|
247
|
+
assistant: str
|
|
248
|
+
|
|
249
|
+
def as_pair(self) -> tuple[str, str]:
|
|
250
|
+
return self.user, self.assistant
|
|
251
|
+
```
|
|
252
|
+
""",
|
|
253
|
+
),
|
|
254
|
+
(
|
|
255
|
+
"argparse: required input file, optional --out, default stdout.",
|
|
256
|
+
"""
|
|
257
|
+
|
|
258
|
+
```python
|
|
259
|
+
import argparse
|
|
260
|
+
import sys
|
|
261
|
+
from pathlib import Path
|
|
262
|
+
|
|
263
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
264
|
+
p = argparse.ArgumentParser(description="Transform a file")
|
|
265
|
+
p.add_argument("src", type=Path)
|
|
266
|
+
p.add_argument("--out", type=Path)
|
|
267
|
+
return p
|
|
268
|
+
|
|
269
|
+
def main() -> None:
|
|
270
|
+
args = build_parser().parse_args()
|
|
271
|
+
text = args.src.read_text(encoding="utf-8")
|
|
272
|
+
if args.out:
|
|
273
|
+
args.out.write_text(text.upper(), encoding="utf-8")
|
|
274
|
+
else:
|
|
275
|
+
sys.stdout.write(text.upper())
|
|
276
|
+
```
|
|
277
|
+
""",
|
|
278
|
+
),
|
|
279
|
+
(
|
|
280
|
+
"Split a list into chunks of n.",
|
|
281
|
+
"""
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
from collections.abc import Iterator, Sequence
|
|
285
|
+
from typing import TypeVar
|
|
286
|
+
|
|
287
|
+
T = TypeVar("T")
|
|
288
|
+
|
|
289
|
+
def chunks(items: Sequence[T], n: int) -> Iterator[Sequence[T]]:
|
|
290
|
+
if n <= 0:
|
|
291
|
+
raise ValueError("n must be > 0")
|
|
292
|
+
for i in range(0, len(items), n):
|
|
293
|
+
yield items[i : i + n]
|
|
294
|
+
```
|
|
295
|
+
""",
|
|
296
|
+
),
|
|
297
|
+
(
|
|
298
|
+
"logging setup that isn't ugly.",
|
|
299
|
+
"""One call at the entrypoint.
|
|
300
|
+
|
|
301
|
+
```python
|
|
302
|
+
import logging
|
|
303
|
+
|
|
304
|
+
def setup_logging(level: str = "INFO") -> None:
|
|
305
|
+
logging.basicConfig(
|
|
306
|
+
level=getattr(logging, level.upper(), logging.INFO),
|
|
307
|
+
format="%(asctime)s %(levelname)s %(name)s: %(message)s",
|
|
308
|
+
)
|
|
309
|
+
```
|
|
310
|
+
""",
|
|
311
|
+
),
|
|
312
|
+
(
|
|
313
|
+
"Filter None from a list and keep types honest.",
|
|
314
|
+
"""
|
|
315
|
+
|
|
316
|
+
```python
|
|
317
|
+
from typing import TypeVar
|
|
318
|
+
|
|
319
|
+
T = TypeVar("T")
|
|
320
|
+
|
|
321
|
+
def present(items: list[T | None]) -> list[T]:
|
|
322
|
+
return [item for item in items if item is not None]
|
|
323
|
+
```
|
|
324
|
+
""",
|
|
325
|
+
),
|
|
326
|
+
(
|
|
327
|
+
"Read stdin, count words, print top 10.",
|
|
328
|
+
"""
|
|
329
|
+
|
|
330
|
+
```python
|
|
331
|
+
import sys
|
|
332
|
+
from collections import Counter
|
|
333
|
+
import re
|
|
334
|
+
|
|
335
|
+
words = re.findall(r"[A-Za-z']+", sys.stdin.read().lower())
|
|
336
|
+
for word, n in Counter(words).most_common(10):
|
|
337
|
+
print(f"{n:>6} {word}")
|
|
338
|
+
```
|
|
339
|
+
""",
|
|
340
|
+
),
|
|
341
|
+
(
|
|
342
|
+
"Make a pathlib helper that refuses to write outside a root.",
|
|
343
|
+
"""Stops `../` surprises.
|
|
344
|
+
|
|
345
|
+
```python
|
|
346
|
+
from pathlib import Path
|
|
347
|
+
|
|
348
|
+
def safe_join(root: Path, relative: str) -> Path:
|
|
349
|
+
dest = (root / relative).resolve()
|
|
350
|
+
if not dest.is_relative_to(root.resolve()):
|
|
351
|
+
raise ValueError(f"escape: {relative}")
|
|
352
|
+
return dest
|
|
353
|
+
```
|
|
354
|
+
""",
|
|
355
|
+
),
|
|
356
|
+
(
|
|
357
|
+
"Pydantic v2 model for a chat message.",
|
|
358
|
+
"""
|
|
359
|
+
|
|
360
|
+
```python
|
|
361
|
+
from typing import Literal
|
|
362
|
+
from pydantic import BaseModel, Field
|
|
363
|
+
|
|
364
|
+
class Message(BaseModel):
|
|
365
|
+
role: Literal["system", "user", "assistant"]
|
|
366
|
+
content: str = Field(min_length=1)
|
|
367
|
+
```
|
|
368
|
+
""",
|
|
369
|
+
),
|
|
370
|
+
(
|
|
371
|
+
"Replace a nested key in a dict without deepcopy.",
|
|
372
|
+
"""Mutate a shallow copy of the path.
|
|
373
|
+
|
|
374
|
+
```python
|
|
375
|
+
def set_path(row: dict, path: tuple[str, ...], value: object) -> dict:
|
|
376
|
+
if not path:
|
|
377
|
+
raise ValueError("empty path")
|
|
378
|
+
out = dict(row)
|
|
379
|
+
cur = out
|
|
380
|
+
for key in path[:-1]:
|
|
381
|
+
nxt = dict(cur.get(key) or {})
|
|
382
|
+
cur[key] = nxt
|
|
383
|
+
cur = nxt
|
|
384
|
+
cur[path[-1]] = value
|
|
385
|
+
return out
|
|
386
|
+
```
|
|
387
|
+
""",
|
|
388
|
+
),
|
|
389
|
+
(
|
|
390
|
+
"Watch a directory and print new files. No watchdog lib.",
|
|
391
|
+
"""Poll mtime. Good enough for a local tool.
|
|
392
|
+
|
|
393
|
+
```python
|
|
394
|
+
import time
|
|
395
|
+
from pathlib import Path
|
|
396
|
+
|
|
397
|
+
def watch(root: Path, seconds: float = 1.0) -> None:
|
|
398
|
+
seen = {p: p.stat().st_mtime for p in root.glob("*") if p.is_file()}
|
|
399
|
+
while True:
|
|
400
|
+
time.sleep(seconds)
|
|
401
|
+
for path in root.glob("*"):
|
|
402
|
+
if not path.is_file():
|
|
403
|
+
continue
|
|
404
|
+
mtime = path.stat().st_mtime
|
|
405
|
+
if path not in seen or seen[path] < mtime:
|
|
406
|
+
print(path)
|
|
407
|
+
seen[path] = mtime
|
|
408
|
+
```
|
|
409
|
+
""",
|
|
410
|
+
),
|
|
411
|
+
(
|
|
412
|
+
"Turn a traceback into a one-liner for logs. Don't leak to users.",
|
|
413
|
+
"""Log server-side; return a boring string to the client.
|
|
414
|
+
|
|
415
|
+
```python
|
|
416
|
+
import logging
|
|
417
|
+
import traceback
|
|
418
|
+
|
|
419
|
+
log = logging.getLogger("app")
|
|
420
|
+
|
|
421
|
+
def handle(exc: Exception) -> str:
|
|
422
|
+
log.exception("request failed")
|
|
423
|
+
return "internal error"
|
|
424
|
+
```
|
|
425
|
+
""",
|
|
426
|
+
),
|
|
427
|
+
(
|
|
428
|
+
"Minimal Makefile-less test runner: python -m pytest tests -q",
|
|
429
|
+
"""Put this in a justfile or alias. That's the vibe.
|
|
430
|
+
|
|
431
|
+
```text
|
|
432
|
+
python -m pytest tests -q --tb=short
|
|
433
|
+
```
|
|
434
|
+
""",
|
|
435
|
+
),
|
|
436
|
+
(
|
|
437
|
+
"Generator that yields matching lines from a huge log.",
|
|
438
|
+
"""Don't read the whole file.
|
|
439
|
+
|
|
440
|
+
```python
|
|
441
|
+
from collections.abc import Iterator
|
|
442
|
+
from pathlib import Path
|
|
443
|
+
|
|
444
|
+
def grep(path: Path, needle: str) -> Iterator[str]:
|
|
445
|
+
with path.open(encoding="utf-8", errors="replace") as fh:
|
|
446
|
+
for line in fh:
|
|
447
|
+
if needle in line:
|
|
448
|
+
yield line.rstrip("\\n")
|
|
449
|
+
```
|
|
450
|
+
""",
|
|
451
|
+
),
|
|
452
|
+
(
|
|
453
|
+
"dataclass + Path for CLI config loaded from JSON.",
|
|
454
|
+
"""
|
|
455
|
+
|
|
456
|
+
```python
|
|
457
|
+
import json
|
|
458
|
+
from dataclasses import dataclass
|
|
459
|
+
from pathlib import Path
|
|
460
|
+
|
|
461
|
+
@dataclass(frozen=True)
|
|
462
|
+
class Config:
|
|
463
|
+
root: Path
|
|
464
|
+
workers: int = 4
|
|
465
|
+
|
|
466
|
+
@classmethod
|
|
467
|
+
def load(cls, path: Path) -> "Config":
|
|
468
|
+
raw = json.loads(path.read_text(encoding="utf-8"))
|
|
469
|
+
return cls(root=Path(raw["root"]), workers=int(raw.get("workers", 4)))
|
|
470
|
+
```
|
|
471
|
+
""",
|
|
472
|
+
),
|
|
473
|
+
(
|
|
474
|
+
"Fix this: except: pass",
|
|
475
|
+
"""Catch what you mean. Log it.
|
|
476
|
+
|
|
477
|
+
```python
|
|
478
|
+
import logging
|
|
479
|
+
|
|
480
|
+
log = logging.getLogger(__name__)
|
|
481
|
+
|
|
482
|
+
try:
|
|
483
|
+
payload = load()
|
|
484
|
+
except (OSError, ValueError) as exc:
|
|
485
|
+
log.warning("load failed: %s", exc)
|
|
486
|
+
payload = {}
|
|
487
|
+
```
|
|
488
|
+
""",
|
|
489
|
+
),
|
|
490
|
+
(
|
|
491
|
+
"Thread pool for a list of CPU-light tasks.",
|
|
492
|
+
"""I/O bound → threads. CPU bound → processes.
|
|
493
|
+
|
|
494
|
+
```python
|
|
495
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
496
|
+
from collections.abc import Callable, Iterable
|
|
497
|
+
from typing import TypeVar
|
|
498
|
+
|
|
499
|
+
T = TypeVar("T")
|
|
500
|
+
R = TypeVar("R")
|
|
501
|
+
|
|
502
|
+
def map_threads(fn: Callable[[T], R], items: Iterable[T], workers: int = 8) -> list[R]:
|
|
503
|
+
with ThreadPoolExecutor(max_workers=workers) as pool:
|
|
504
|
+
futs = [pool.submit(fn, item) for item in items]
|
|
505
|
+
return [fut.result() for fut in as_completed(futs)]
|
|
506
|
+
```
|
|
507
|
+
""",
|
|
508
|
+
),
|
|
509
|
+
(
|
|
510
|
+
"Pretty-print a table without pandas.",
|
|
511
|
+
"""
|
|
512
|
+
|
|
513
|
+
```python
|
|
514
|
+
def print_table(rows: list[tuple[str, ...]]) -> None:
|
|
515
|
+
if not rows:
|
|
516
|
+
return
|
|
517
|
+
widths = [max(len(r[i]) for r in rows) for i in range(len(rows[0]))]
|
|
518
|
+
for row in rows:
|
|
519
|
+
print(" ".join(cell.ljust(widths[i]) for i, cell in enumerate(row)))
|
|
520
|
+
```
|
|
521
|
+
""",
|
|
522
|
+
),
|
|
523
|
+
(
|
|
524
|
+
"Enum for job status, plus a terminal check.",
|
|
525
|
+
"""
|
|
526
|
+
|
|
527
|
+
```python
|
|
528
|
+
from enum import StrEnum
|
|
529
|
+
|
|
530
|
+
class Status(StrEnum):
|
|
531
|
+
queued = "queued"
|
|
532
|
+
running = "running"
|
|
533
|
+
done = "done"
|
|
534
|
+
failed = "failed"
|
|
535
|
+
|
|
536
|
+
def terminal(self) -> bool:
|
|
537
|
+
return self in {Status.done, Status.failed}
|
|
538
|
+
```
|
|
539
|
+
""",
|
|
540
|
+
),
|
|
541
|
+
(
|
|
542
|
+
"sha256 of a file in 1MB chunks.",
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
```python
|
|
546
|
+
import hashlib
|
|
547
|
+
from pathlib import Path
|
|
548
|
+
|
|
549
|
+
def sha256_file(path: Path) -> str:
|
|
550
|
+
digest = hashlib.sha256()
|
|
551
|
+
with path.open("rb") as fh:
|
|
552
|
+
while chunk := fh.read(1024 * 1024):
|
|
553
|
+
digest.update(chunk)
|
|
554
|
+
return digest.hexdigest()
|
|
555
|
+
```
|
|
556
|
+
""",
|
|
557
|
+
),
|
|
558
|
+
(
|
|
559
|
+
"Typed CLI using only argparse subcommands: add and ls.",
|
|
560
|
+
"""
|
|
561
|
+
|
|
562
|
+
```python
|
|
563
|
+
import argparse
|
|
564
|
+
|
|
565
|
+
def add(args: argparse.Namespace) -> None:
|
|
566
|
+
print(args.a + args.b)
|
|
567
|
+
|
|
568
|
+
def ls(_: argparse.Namespace) -> None:
|
|
569
|
+
print("ok")
|
|
570
|
+
|
|
571
|
+
def main() -> None:
|
|
572
|
+
p = argparse.ArgumentParser()
|
|
573
|
+
sub = p.add_subparsers(required=True)
|
|
574
|
+
add_p = sub.add_parser("add")
|
|
575
|
+
add_p.add_argument("a", type=int)
|
|
576
|
+
add_p.add_argument("b", type=int)
|
|
577
|
+
add_p.set_defaults(fn=add)
|
|
578
|
+
ls_p = sub.add_parser("ls")
|
|
579
|
+
ls_p.set_defaults(fn=ls)
|
|
580
|
+
args = p.parse_args()
|
|
581
|
+
args.fn(args)
|
|
582
|
+
```
|
|
583
|
+
""",
|
|
584
|
+
),
|
|
585
|
+
(
|
|
586
|
+
"Freeze requirements from the current venv the boring way.",
|
|
587
|
+
"""
|
|
588
|
+
|
|
589
|
+
```bash
|
|
590
|
+
python -m pip freeze > requirements.lock
|
|
591
|
+
```
|
|
592
|
+
""",
|
|
593
|
+
),
|
|
594
|
+
(
|
|
595
|
+
"Match glob **/*.py and skip .venv.",
|
|
596
|
+
"""
|
|
597
|
+
|
|
598
|
+
```python
|
|
599
|
+
from pathlib import Path
|
|
600
|
+
|
|
601
|
+
def py_files(root: Path) -> list[Path]:
|
|
602
|
+
return [
|
|
603
|
+
p
|
|
604
|
+
for p in root.rglob("*.py")
|
|
605
|
+
if ".venv" not in p.parts and "__pycache__" not in p.parts
|
|
606
|
+
]
|
|
607
|
+
```
|
|
608
|
+
""",
|
|
609
|
+
),
|
|
610
|
+
(
|
|
611
|
+
"httpx + tenacity? nah, just a loop.",
|
|
612
|
+
"""Keep it boring.
|
|
613
|
+
|
|
614
|
+
```python
|
|
615
|
+
import time
|
|
616
|
+
import httpx
|
|
617
|
+
|
|
618
|
+
def get_ok(url: str) -> httpx.Response:
|
|
619
|
+
last: Exception | None = None
|
|
620
|
+
for i in range(4):
|
|
621
|
+
try:
|
|
622
|
+
r = httpx.get(url, timeout=10)
|
|
623
|
+
r.raise_for_status()
|
|
624
|
+
return r
|
|
625
|
+
except httpx.HTTPError as exc:
|
|
626
|
+
last = exc
|
|
627
|
+
time.sleep(0.25 * (i + 1))
|
|
628
|
+
raise last # type: ignore[misc]
|
|
629
|
+
```
|
|
630
|
+
""",
|
|
631
|
+
),
|
|
632
|
+
(
|
|
633
|
+
"Split train/valid ids with a seed. No sklearn.",
|
|
634
|
+
"""
|
|
635
|
+
|
|
636
|
+
```python
|
|
637
|
+
import random
|
|
638
|
+
|
|
639
|
+
def split_ids(ids: list[str], valid_frac: float = 0.1, seed: int = 0) -> tuple[list[str], list[str]]:
|
|
640
|
+
rng = random.Random(seed)
|
|
641
|
+
shuffled = list(ids)
|
|
642
|
+
rng.shuffle(shuffled)
|
|
643
|
+
n_valid = max(1, int(len(shuffled) * valid_frac))
|
|
644
|
+
return shuffled[n_valid:], shuffled[:n_valid]
|
|
645
|
+
```
|
|
646
|
+
""",
|
|
647
|
+
),
|
|
648
|
+
(
|
|
649
|
+
"Write JSON atomically (temp file + replace).",
|
|
650
|
+
"""
|
|
651
|
+
|
|
652
|
+
```python
|
|
653
|
+
import json
|
|
654
|
+
import os
|
|
655
|
+
from pathlib import Path
|
|
656
|
+
|
|
657
|
+
def write_json(path: Path, data: object) -> None:
|
|
658
|
+
tmp = path.with_suffix(path.suffix + ".tmp")
|
|
659
|
+
tmp.write_text(json.dumps(data, indent=2) + "\\n", encoding="utf-8")
|
|
660
|
+
os.replace(tmp, path)
|
|
661
|
+
```
|
|
662
|
+
""",
|
|
663
|
+
),
|
|
664
|
+
(
|
|
665
|
+
"dataclass slots for a hot row.",
|
|
666
|
+
"""
|
|
667
|
+
|
|
668
|
+
```python
|
|
669
|
+
from dataclasses import dataclass
|
|
670
|
+
|
|
671
|
+
@dataclass(slots=True)
|
|
672
|
+
class Row:
|
|
673
|
+
name: str
|
|
674
|
+
n: int
|
|
675
|
+
```
|
|
676
|
+
""",
|
|
677
|
+
),
|
|
678
|
+
(
|
|
679
|
+
"How do I run a module as a script in a src layout?",
|
|
680
|
+
"""From the repo root, with `src` on the path:
|
|
681
|
+
|
|
682
|
+
```bash
|
|
683
|
+
PYTHONPATH=src python -m finetune.whatever
|
|
684
|
+
```
|
|
685
|
+
|
|
686
|
+
Or install the package editable and drop PYTHONPATH.
|
|
687
|
+
""",
|
|
688
|
+
),
|
|
689
|
+
(
|
|
690
|
+
"Type a JSONL stream as list[dict[str, object]].",
|
|
691
|
+
"""Don't pretend you know the schema if you don't.
|
|
692
|
+
|
|
693
|
+
```python
|
|
694
|
+
import json
|
|
695
|
+
from pathlib import Path
|
|
696
|
+
|
|
697
|
+
def load_rows(path: Path) -> list[dict[str, object]]:
|
|
698
|
+
rows: list[dict[str, object]] = []
|
|
699
|
+
for line in path.read_text(encoding="utf-8").splitlines():
|
|
700
|
+
if line.strip():
|
|
701
|
+
rows.append(json.loads(line))
|
|
702
|
+
return rows
|
|
703
|
+
```
|
|
704
|
+
""",
|
|
705
|
+
),
|
|
706
|
+
(
|
|
707
|
+
"Kill a hung subprocess after N seconds.",
|
|
708
|
+
"""
|
|
709
|
+
|
|
710
|
+
```python
|
|
711
|
+
import subprocess
|
|
712
|
+
|
|
713
|
+
def run_capped(cmd: list[str], seconds: int) -> subprocess.CompletedProcess[str]:
|
|
714
|
+
return subprocess.run(
|
|
715
|
+
cmd,
|
|
716
|
+
check=False,
|
|
717
|
+
text=True,
|
|
718
|
+
capture_output=True,
|
|
719
|
+
timeout=seconds,
|
|
720
|
+
)
|
|
721
|
+
```
|
|
722
|
+
""",
|
|
723
|
+
),
|
|
724
|
+
(
|
|
725
|
+
"Sort paths so 2 comes before 10.",
|
|
726
|
+
"""Natural sort on the name.
|
|
727
|
+
|
|
728
|
+
```python
|
|
729
|
+
import re
|
|
730
|
+
from pathlib import Path
|
|
731
|
+
|
|
732
|
+
_NUM = re.compile(r"(\\d+)")
|
|
733
|
+
|
|
734
|
+
def key(path: Path) -> tuple:
|
|
735
|
+
parts = _NUM.split(path.name)
|
|
736
|
+
return tuple(int(p) if p.isdigit() else p.lower() for p in parts)
|
|
737
|
+
```
|
|
738
|
+
""",
|
|
739
|
+
),
|
|
740
|
+
(
|
|
741
|
+
"One-liner to start a venv and install mlx on 3.13.",
|
|
742
|
+
"""
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
/opt/homebrew/bin/python3.13 -m venv .venv
|
|
746
|
+
source .venv/bin/activate
|
|
747
|
+
pip install -U pip
|
|
748
|
+
pip install 'mlx-lm[train]'
|
|
749
|
+
```
|
|
750
|
+
""",
|
|
751
|
+
),
|
|
752
|
+
(
|
|
753
|
+
"Don't use mutable default args.",
|
|
754
|
+
"""
|
|
755
|
+
|
|
756
|
+
```python
|
|
757
|
+
def add_tag(row: dict, tag: str, tags: list[str] | None = None) -> list[str]:
|
|
758
|
+
out = list(tags or [])
|
|
759
|
+
out.append(tag)
|
|
760
|
+
row["tags"] = out
|
|
761
|
+
return out
|
|
762
|
+
```
|
|
763
|
+
""",
|
|
764
|
+
),
|
|
765
|
+
(
|
|
766
|
+
"Zip two lists and drop extras — or keep them?",
|
|
767
|
+
"""`zip` drops. `itertools.zip_longest` keeps.
|
|
768
|
+
|
|
769
|
+
```python
|
|
770
|
+
from itertools import zip_longest
|
|
771
|
+
|
|
772
|
+
def pairs(left: list[str], right: list[str]) -> list[tuple[str | None, str | None]]:
|
|
773
|
+
return list(zip_longest(left, right))
|
|
774
|
+
```
|
|
775
|
+
""",
|
|
776
|
+
),
|
|
777
|
+
(
|
|
778
|
+
"Path.read_text vs open. Which?",
|
|
779
|
+
"""`Path.read_text(encoding='utf-8')` for whole files. `open` when you stream.
|
|
780
|
+
|
|
781
|
+
```python
|
|
782
|
+
from pathlib import Path
|
|
783
|
+
|
|
784
|
+
text = Path("notes.md").read_text(encoding="utf-8")
|
|
785
|
+
```
|
|
786
|
+
""",
|
|
787
|
+
),
|
|
788
|
+
]
|