skills/python/SKILL.md
Python standards and the Python environment on this Windows machine. Sourced from abixio/tests, abixio/build.py, endless/scripts, and claude-blueprints/scripts. Read when running Python or writing scripts.
npx skillsauth add abix-/claude-blueprints pythonInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
4 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Source repos: abix-/abixio (build + e2e), abix-/endless/scripts,
claude-blueprints/scripts. Style is stdlib-first, script-shaped,
no virtualenvs. Real CPython on the machine, used directly.
| Command | Path | Works |
|---------|------|-------|
| python | C:/Users/Abix/AppData/Local/Programs/Python/Python312/python | Yes |
| py | C:/Users/Abix/AppData/Local/Programs/Python/Launcher/py | Yes |
| python3 | Symlink to Python312 (was Store shim, fixed 2026-03-06) | Yes |
Version: Python 3.12.10. No virtualenv. Scripts import what's
installed system-wide. Pin requirements at the top of a script in a
try/except ImportError block with a pip install hint (see e2e.py).
abixio/build.py shells out to cargo).endless/scripts/brp.py).abixio/tests/e2e.py).re + pathlib is shorter than bash
(scripts/dehyphen.py).Reach for Go or Rust when: cold start matters, a single binary is needed, types/lifetimes matter, perf hot path.
#!/usr/bin/env python3
"""One-line purpose. Then a longer description if needed.
Usage:
python path/to/script.py [args]
Requires: requests (pip install requests) # only if non-stdlib
"""
Real example from abixio/build.py:
"""build abixio (server) and abixio-ui release binaries for windows."""
Lowercase, informal, terse. No "This module..." preamble.
isort formality
for short scripts; just keep it ordered.from pathlib import Path always. Never use os.path in new code.try:
import requests
except ImportError:
print("ERROR: pip install requests")
sys.exit(1)
urllib.request over requests when the call is simple
(see endless/scripts/brp.py). requests is fine when the script
is already complex (see abixio/tests/e2e.py).sys.argv parsing.
if len(sys.argv) < 2:
print("Usage: python scripts/brp.py <method> [params_json]")
sys.exit(1)
argparse.argparse with subparsers, not
click / typer. Stdlib is enough.ROOT = Path(__file__).resolve().parent
__file__, not CWD.Path for everything. Use / operator: ROOT / "target" / "release".Path.exists(), Path.read_text(), Path.write_text(encoding="utf-8").Path objects to subprocess; it handles separators.Pattern from abixio/build.py:
def run(args, cwd=None):
print(f" > {' '.join(str(a) for a in args)}")
result = subprocess.run(args, cwd=cwd)
if result.returncode != 0:
print(f"FAILED (exit {result.returncode})")
sys.exit(1)
subprocess.run, never os.system or os.popen.args as a list, not a shell string. No shell=True.returncode manually when you want a custom error message;
use check=True when default behavior is fine.capture_output=True, text=True then read
result.stdout. UTF-8 is the default in 3.7+.Pattern across all repos:
print(f"ERROR: {msg}", file=sys.stderr)
sys.exit(1)
% formatting, no .format().Stdlib for simple POST/GET (endless/scripts/brp.py):
req = urllib.request.Request(
f"http://localhost:{port}",
json.dumps(body).encode(),
{"Content-Type": "application/json"},
)
resp = json.loads(urllib.request.urlopen(req, timeout=5).read())
timeout. Default is unbounded.requests. Don't fight stdlib past its sweet spot.TestRunner in e2e.py: counter +
errors list).dict or tuple
is fine. Use dataclasses when the type appears across functions.Protocol if needed.from __future__ import annotations at the top if you want to use
postponed evaluation (list[int] style on 3.9-) or forward refs.mypy enforcement in current repos. Don't add it without buy-in.abixio/tests/e2e.py is the model: a TestRunner class with
check(name, condition, detail) and summary(). Plain script,
exit code reflects pass/fail.unittest is acceptable but
verbose for this code's shape.python tests/e2e.py.f" {p.name} {size_mb:.1f} MB".Scripts should be safe to re-run. Examples:
dehyphen.py rewrites prose; running twice on a clean file is a no-op.build.py overwrites the exe in place; no leftover state.The dominant rule: don't optimize Python. Profile to confirm Python is the bottleneck, then rewrite that path in Rust (via PyO3 or just a separate binary) or Go.
re.compile once at module scope. Pattern compilation
dwarfs the match cost.subprocess.run has fixed overhead (~50ms). Batch when
possible. For many small commands, spawn one shell with bash -c
and let it loop.json.loads on a bytes object is fine in 3.6+; no decode
step. orjson is 3-5x faster if you can take a dependency.sum, min, max, any, all,
sorted, map, filter) beat hand-rolled loops.for + append loops by 30-50%.
Generator expressions (x for x in ...) use less memory when
feeding sum / any / all.dict.get(key, default) beats if key in dict: ... else.
One hash lookup vs two.+ in a loop is O(n^2). Use
''.join(parts) with a list, or io.StringIO.set membership is O(1). Use it for "is X in this list"
checks repeated many times.functools.lru_cache for memoizing pure functions. Free
speedup on recursive or repeated-input work.__slots__ on small classes used in large numbers. Skips
the per-instance __dict__; ~40% memory reduction, faster
attribute access.multiprocessing.Pool for CPU-bound parallelism. Each worker
has its own GIL. Cost: pickle every arg + result.concurrent.futures.ThreadPoolExecutor / ProcessPoolExecutor
for cleaner API over the above.asyncio beats threads. Single thread,
cooperative scheduling, no GIL contention.cProfile for function-level CPU time:
python -m cProfile -o prof.out script.py, then
snakeviz prof.out for a visualization.pyinstrument is a sampling profiler with cleaner output
than cProfile. pyinstrument script.py.line_profiler for line-by-line CPU in a specific function:
decorate with @profile, run with kernprof -lv script.py.memory_profiler for line-by-line memory: @profile +
python -m memory_profiler script.py.timeit for micro-benchmarks:
python -m timeit -s 'x = list(range(1000))' 'sum(x)'.tracemalloc for tracking allocations by source line. Stdlib.Path and
subprocess both handle them.text = path.read_text(encoding="utf-8-sig").\\?\ only if you actually hit MAX_PATH.import *. Never.os.path. Use pathlib.print(x) for errors. Use print(x, file=sys.stderr).eval / exec. Almost always wrong.shell=True in subprocess. Quoting bugs and injection.def f(x=[])). Use None and assign inside.except:. Always catch a specific class.pandas / numpy for jobs that 10 lines of stdlib
would solve.try/except ImportError pattern instead.development
YAML standards for config files, Ansible playbooks, k8s manifests, GitHub Actions, docker-compose, and any project config. Built from the YAML 1.2 spec, yamllint defaults, and the practical pitfalls (Norway problem, type coercion, anchor gotchas).
development
--- name: ueforge description: ueforge framework: the base layer every UE4SS Rust mod in the Grounded2Mods workspace builds on. Authoritative on the composition model (Effect/Trigger/Skill), the Def/Registry/Instance/Controller pattern, hot reload, discovery, hardening doctrine, and the five framework modules (rpg, stacks, difficulty, inventory, damage). Use when writing or modifying code under `ueforge/` in [abix-/Grounded2Mods](https://github.com/abix-/Grounded2Mods), or when promoting a patte
tools
TypeScript and JavaScript standards. Sourced from [abix-/chromium-extensions](https://github.com/abix-/chromium-extensions) (Hush + filter-anything-everywhere). Use when writing TS/JS, including browser extension bootstrap shims, MV3 service workers, and small web frontends.
development
--- name: schedule1 description: Modding Schedule 1 (TVGS, IL2CPP Unity + MelonLoader + Harmony). Authoritative on Schedule 1 game specifics: engine type, MelonLoader/Il2CppInterop references, eMployee mod root-cause findings, vanilla CookRoutine + StartMixingStationBehaviour internals, certainty-tracking discipline. Mod code lives in [`abix-/Schedule1Mods`](https://github.com/abix-/Schedule1Mods) (the `EmployeeReset` sidecar is the current shipped mod). Not for playing the game. user-invocable: