Skip to content

Issue #1293: fix: give the GraphQL filter input cache the lifetime of one schema build - #1314

Merged
bjagg merged 2 commits into
mainfrom
issue-1293-per-build-input-type-cache
Sep 26, 2026
Merged

bjagg merged 2 commits into
mainfrom
issue-1293-per-build-input-type-cache

Conversation

@dereck-symmetry

Copy link
Copy Markdown
Contributor
Description of Change

Problem. components/lif/openapi_to_graphql/type_factory.py declared input_type_cache at module level, keyed by type name alone, and nothing ever cleared it. So the second schema built in a process reused the first schema's filter input types. Two schemas whose Person had entirely different queryable fields silently shared one PersonInput. mutable_input_type_cache, its sibling, was already per build.

As #1293 says, this isn't reachable in production today: bases/lif/api_graphql/core.py builds the schema once, in lifespan. It did already bite tests, though. Two test helpers carried a monkeypatch.setattr(type_factory, "input_type_cache", {}) workaround, and without it a test passed alone but failed in the suite. It would also turn any future schema hot-reload after an MDR change into a silent bug.

Solution. This is the issue's suggested change. generate_graphql_root_types (core.py) now creates input_type_cache = {} next to mutable_input_type_cache and passes it to create_input_type. That gains an input_type_cache parameter, matching create_mutable_input_type. The module-level variable is gone. create_input_type isn't exported from the package (__init__.py exports generate_graphql_root_types / generate_graphql_schema), and core.py is its only caller.

Both test workarounds are removed: the one the issue names in test_core.py::TestQueryPlannerFailureReachesCaller, and a second copy in test_lif_client_header.py that #1301 added. Their _schema helpers no longer take monkeypatch.

Side effects. None in production. The service builds one schema per process, and it's built the same way.

How reviewers should test it.

uv run pytest test/components/lif/openapi_to_graphql/ -q
Related Issues

Closes #1293
Refs #1131

Type of Change
  • Bug fix (non-breaking change which fixes an issue)
Project Area(s) Affected
  • components/
  • test/ or e2e/

Checklist
  • commit message follows commit guidelines (see commitlint.config.mjs)
  • tests are included (unit and/or integration tests)
  • code passes linting checks (uv run ruff check)
  • code passes formatting checks (uv run ruff format)
  • code passes type checking (uv run ty check)
  • pre-commit hooks have been run successfully
Testing
  • Automated tests added/updated

TestInputTypesArePerSchemaBuild builds two schemas in one process: one where Person has a single queryable field alpha, and one where it's beta. It reads each schema's PersonInput fields by introspection.

  • On main it fails exactly as the issue describes: assert {'alpha'} == {'beta'}. The second schema reused the first's input type.
  • With the fix it passes.

The removed workarounds are the third acceptance criterion. With them gone, all 30 tests in test/components/lif/openapi_to_graphql/ pass in the same run, including the ones that used to need them. pre-commit run --files on all four changed files is green, including the full pytest suite.

No README or CHANGELOG change: the component README doesn't mention the cache, and nothing changes for a caller.

Additional Notes

Merge order with #1311 (#1309), measured by a trial merge. #1311's new TestMutationFailureDoesNotLeakBody carries a third copy of the same workaround line.

  1. Textual conflict in test_core.py: both PRs append a test class at the end of the file. Keep both classes.
  2. Then, a runtime failure git can't see: once resolved, Issue #1309: fix: keep the Query Planner's error body out of GraphQL mutation errors #1311's test fails with AttributeError: <module 'lif.openapi_to_graphql.type_factory'> has no attribute 'input_type_cache', because monkeypatch.setattr refuses a missing attribute. Delete that one line (monkeypatch.setattr(type_factory, "input_type_cache", {})) and the brick passes (31 passed in the trial).

Whichever PR merges second needs both steps. main requires branches to be up to date, so that PR's CI will surface step 2 if it's missed.

Shared brick (#1171). components/lif/openapi_to_graphql is packaged by lif_graphql_api only, and its deploy workflow already covers the brick.

🤖 Generated with Claude Code

… one schema build

input_type_cache was module-level and keyed by type name alone, so the
second schema built in a process silently reused the first one's input
types. It is now created per build in generate_graphql_root_types, next to
mutable_input_type_cache, and threaded through create_input_type. The two
test workarounds that reset the module-level cache are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

@bjagg bjagg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving. 30 pass; reverting the brick's code to main fails 8 (the new test plus the ones the removed workarounds were masking). Hoisting the cache back to module level is caught. I checked there's no second module-level cache in the brick, core.py is the only caller, and the new parameter is required rather than a mutable default, which would have reintroduced this. The #1311 merge-order note is accurate: whichever lands second needs the one monkeypatch.setattr(... "input_type_cache" ...) line removed.

@bjagg
bjagg merged commit d7c4b33 into main Sep 26, 2026
4 checks passed
@bjagg
bjagg deleted the issue-1293-per-build-input-type-cache branch September 26, 2026 01:31
bjagg added a commit that referenced this pull request Sep 26, 2026
Resolve CHANGELOG.md with #1310 and #1313 by keeping every entry. In
test_core.py, keep main's file plus this branch's
TestMutationFailureDoesNotLeakBody, minus its
monkeypatch.setattr(type_factory, "input_type_cache", {}) line: #1314
removed that module attribute, so the line raised AttributeError (the
step #1314's PR body describes).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

openapi_to_graphql: module-level input_type_cache is shared across schema builds

2 participants