Skip to content

binary_loads passthrough for mk_cli and api_pkg_maker; the generated package compiles (#21) - #22

Merged
thorwhalen merged 3 commits into
masterfrom
fix/binary-loads-cli-and-pkg-maker
Oct 13, 2026
Merged

thorwhalen merged 3 commits into
masterfrom
fix/binary-loads-cli-and-pkg-maker

Conversation

@thorwhalen

@thorwhalen thorwhalen commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Closes #21.

Change

  • CLI. mk_cli, dispatch_cli and register_cli_method take a keyword-only binary_loads=, which they pass to the HttpClient each command builds.
    • mk_cli validates it up front with check_loads.
    • mk_cli also now passes on config_filename, which it used to accept and ignore.
  • api_pkg_maker.
    • The spec is written as openapi_spec.json, package data that the generated funcs.py loads at import. It is never pasted as source.
    • Route names (the methods HttpClient registered) must be Python identifiers and not keywords.
    • Before, routes were named path[1:], which breaks on any path with a / or a {param}.
    • pkg_name must be an identifier, and the setup.cfg fields are collapsed to one line.
    • Result: the generated module compiles, and a spec fetched from a server cannot inject code into the package built from it.
    • mk_api_pkg gains binary_loads= (a callable, or its dotted path; it must be importable and must import back to the same object) and output_dir= (default OUTPUT_DIR, still read at call time).
    • New api_pkg_files() returns the sources without building them.
    • Behaviour change: a package built from openapi_url now carries the spec it was built from instead of fetching it again at import. Its functions were already fixed at build time.
  • 401. A 401 now raises AuthorizationError. py2http now answers AuthorizationError with 401 (Instance endpoints need an obj_owner and are bounded in size (#30) py2http#31), and without this branch the client raised RuntimeError. That was found by the adversarial review of py2http#31.

Tests

  • tests/: 62 passed.
  • --doctest-modules http2py: passed.
  • http2py/tests/api_pkg_maker_test.py: passed. It now builds into tmp_path instead of ~/http2py.

Adversarial review

Two fresh Opus passes.

Pass 1: SHIP-WITH-FIXES. It found no code injection. Fixed:

  • Route names could shadow the generated module's globals (apply_sig, Sig, api, or a full-width api). The internals are now _-prefixed, and route names must be ASCII, must not start with _, and must not be api or funcs.
  • A % in a setup.cfg value broke the build. Values are now escaped.
  • The sdist name did not match what setuptools wrote (MyPkg, v1.0). The built file is now taken from dist/.
  • A spec with no routes produced a SyntaxError. It is now refused.
  • String refs were not checked. They now must name a callable.
  • --openapi-spec given as JSON text crashed. It is now parsed.
  • Filed as HttpClient: a route's x-method_name can overwrite the client's own attributes #23: route names can overwrite HttpClient attributes. This is in client.py and predates this PR.
  • Note: a 401 now raises AuthorizationError instead of RuntimeError.

Pass 2: SHIP. Fixed anyway:

  • A ref to a module that is not installed at build time is now kept, with a warning.
  • The error message now says "ASCII identifier".
  • funcs is now reserved.

🤖 Generated with Claude Code

thorwhalen and others added 2 commits October 13, 2026 05:05
… package compiles (#21)

- mk_cli / dispatch_cli / register_cli_method take binary_loads= (keyword-only),
  forwarded to the HttpClient each command builds; mk_cli now also forwards
  config_filename, which it accepted and ignored.
- api_pkg_maker writes the spec as a JSON data file the package loads at
  import, never as source; route names must be identifiers, setup.cfg fields
  stay on one line. The generated module compiles (it did not with a real
  spec) and a spec cannot inject code into it.
- mk_api_pkg(binary_loads=<callable or dotted path>, output_dir=...);
  api_pkg_files() returns the generated sources without building.
- 401 responses raise AuthorizationError (py2http now answers it with 401).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…eal sdist name, checked refs

- Generated module's internals are _-prefixed; route names must be ASCII
  identifiers, not start with _, not be 'api' (no shadowing, no NFKC tricks).
- setup.cfg values escape % (interpolation); the built sdist is found in
  dist/ rather than its name reconstructed (setuptools normalizes it).
- object_ref imports string refs too and requires a callable.
- A spec with no routes is refused; a spec given as JSON text is parsed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ng, 'funcs' reserved

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@thorwhalen
thorwhalen merged commit 16acbce into master Oct 13, 2026
12 checks passed
@thorwhalen
thorwhalen deleted the fix/binary-loads-cli-and-pkg-maker branch October 13, 2026 05:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

mk_cli / api_pkg_maker: no binary_loads passthrough; generated funcs file does not compile

1 participant