Skip to content

association 3.0.0

Choose a tag to compare

@jeffknupp jeffknupp released this 17 Sep 18:32
· 764 commits to master since this release
  • No function is more complex than radon grade C (cyclomatic complexity
    20), enforced by a xenon gate in pre-commit and CI, with no module worse
    than C and the average no worse than B. The worst were the router's
    route() at 127, parse_game_summary at 61 and a set of query templates
    between 21 and 89; each is split into named steps called in the original
    order. No behavior changes: every split was checked against the original
    code by calling it with thousands of inputs (405,588 for route(), 4,433
    slot sets for the templates, every fixture for the parser) and comparing
    the full results, besides the test suite.
  • Breaking: the package is reorganized, so the next release is 3.0.0.
    Nothing about what the commands or the query engine do changes; module paths
    do.
    • association.cli is a package: the commands are in
      association.cli.commands, and association.repo_paths is now
      association.cli.paths. association.cli:main (the console entry point)
      and association.cli:cli resolve as before.
    • The modules both fetch and query read moved from the package root
      into association.nba: association.season, association.coverage
      and association.franchises are now association.nba.season,
      association.nba.coverage and association.nba.franchises, and
      association.net_points_categories is association.nba.netpoints.
    • The load-time repairs and filtered tables moved under
      association.fetch.repairs: game_repair, team_box_repair,
      season_totals_repair, reconstructed_box and real_games.
    • association.query.templates is a package, one module per subject:
      common (the context and result types, the scoping and coverage checks,
      and the helpers more than one subject uses), players, games, teams,
      shots, netpoints and splits. The package re-exports TEMPLATES and
      the scoping API, so from association.query.templates import TEMPLATES, check_scope, ... still works; a private helper is imported from the
      module that defines it.
    • ROUTER_PROMPT, ROUTER_SCHEMA, ROUTER_NUM_CTX and
      ROUTER_PROMPT_TOKEN_BUDGET moved from association.query.router to
      association.query.router_prompt, byte-identical (hashed before and
      after), so what the model is told sits apart from what is done with its
      answer.
  • Importing the web API no longer loads ollama. association.web.runner
    imported the query Agent at module level for a type annotation, so
    import association.web.app brought in the model client that AGENTS.md says
    the API layer must never import. The import is now type-checking only. The
    rule and the package layering are enforced by import-linter in pre-commit and
    CI: cli > web > query | check > fetch > the leaf modules, fetch
    and query independent, and no fastapi, uvicorn or pydantic outside
    web.
  • Spelling is checked. codespell runs in pre-commit and CI with its
    British-to-American dictionary, and the 37 findings are fixed - mostly
    British forms in comments, docstrings and docs ("neighbouring", "cancelled",
    "behaviour", "judgement"), plus "unparseable" and "pre-empts". Comments and
    docs only: the router's compiled patterns and the prompt text hash
    identically before and after.
  • Every imported package is declared. botocore (imported by the
    NetPoints client) is now a core dependency and pydantic (imported by the
    web API) is in the web extra; both used to arrive only through boto3 and
    fastapi. The docs extra names packaging, which docs/conf.py imports.
    Nothing new is installed. deptry now checks this in pre-commit and CI.
  • Dead code is now a gate. vulture runs in pre-commit and CI at its lowest
    confidence, with the names only a framework calls listed, each with its
    caller, in vulture_whitelist.py. Its one real finding is removed:
    TeamMetric.needs_opponent, set on four team metrics and never read since
    the field was added.
  • Stricter lint, a dependency audit, and three pieces of dead code gone.
    Ruff now also enforces DTZ, BLE, RUF, PERF, C4, SIM, RET, PLW
    and PLE; the 66 findings were fixed, and the handful that are deliberate (a
    blind except at a boundary, the local calendar date in current_season)
    carry an inline reason. No behavior changed: eastern_day_utc_range now
    builds UTC-aware datetimes, which format to the same strings. pip-audit runs
    over uv.lock in a new Dependency audit workflow on every push and weekly
    (scripts/audit_dependencies.sh). Removed as unused: fetch.storage.write_row
    (no caller outside its own test - Pipeline._write_row is the real path),
    fetch.team_box_repair.REBUILT_COLUMNS (never read; the repair's SQL names
    its columns itself), and the private templates._as_int.
  • The 2001 playoff caveat names every short series, and counts
    Philadelphia right.
    A 2001 postseason answer said Philadelphia's run
    "reads 15 games" and named only the LAL-PHI Final and the MIL-PHI
    conference final. Finals Game 5, recovered by the scoreboard discovery pass,
    brought Philadelphia to 16, and MIL-CHA (two games) and LAL-SA (one) are
    short too. The note on games and team_box_stats now says ten games across
    all four series and 16 against ESPN's 23.
  • The README's first install command works. It was
    pip install 'association[web]', which the README's own note says does not
    work while PyPI is unreachable; it now installs from the release tag, as
    docs/usage.rst does too. The README also lists the 2001 playoffs' ten
    missing games among its known limitations, and its project layout names
    season.py, franchises.py and the load-time repairs.