Repository navigation
Conversation
input_is_nested_too_deeply pushed one tuple per list item onto its stack before it popped any, so its memory grew with the width of the list. Keep one frame per nesting level (values, type, depth, next index) and stop the walk of a level when its item type cannot nest. Coercing a [Int] variable of 50,000 ints has a tracemalloc peak of 818,981 bytes, down from 4,091,392 bytes. The returned bool is unchanged. Co-Authored-By: Aiden <aiden@weco.ai>
The depth check keeps one frame per nesting level. No test used a list with several nested items or an empty list, so one line and one branch were not covered and the 100% coverage gate failed on Python 3.14. Co-Authored-By: Aiden <aiden@weco.ai>
Reuse the deep list type of the existing test instead of building it again in a second test. Co-Authored-By: Aiden <aiden@weco.ai>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
input_is_nested_too_deeply, the depth check for variable values.tracemallocpeak for a[Int]variable of 50,000 ints: 4,091,392 bytes -> 818,981 bytes, 80.0% less.PYTHONPATH=src python3 -m pytest tests/execution/test_variables.py -qpassed 106 tests.Refs #317
What & Why
Before, the check pushed one
(item, type, depth)tuple per list item onto its stack before it popped any.The memory for the check grew with the width of the list, about 70 bytes per item.
Now each stack frame holds one nesting level: the values, their type, the depth, and the next index.
The check also stops the walk of a level when the item type is not a list or an input object.
Such items cannot nest, so one depth check covers the full level.
The output stays identical because the check still visits each followed value at the same depth.
Empty lists still add no depth, and values under scalars are still not followed.
Validation
Peak traced memory (
tracemalloc) and best time of one call to the check:[Int], 50,000 ints[Int], 10,000 ints[[Int]], 500 lists of 100 ints[Point], 5,000 input objectsInt, one valueThe last row shows a case where the change does not help, and it shows no slowdown.
The number in the TL;DR is for the full
get_variable_valuescall, so it includes the coerced result.Measured on CPython 3.12.13, Linux x86-64, AMD EPYC 9R14, on one isolated core.
Script for the first row; run it on the base commit and on this change:
The complete suite also passed with
PYTHONPATH=src python3 -m pytest tests -q: 3,821 passed, 18 skipped.ruff check,ruff format --check(ruff 0.17.4) andmypy(2.4.1) passed forsrc/graphql/execution/values.py.Why this is safe and easy to maintain
The change is small and easy to read: 13 added lines in one private function, with no new imports.
The function keeps its loop, its explicit stack, and its signature.
Behaviour is unchanged, and the returned bool is the same for every value and type.
The tests in
tests/execution/test_variables.pycover the depth limit for lists, input objects, and custom scalars.Scope
This changes Python bookkeeping in a private helper only.
It adds no feature and does not change GraphQL behavior or the public API.
AI assistance
This PR was prepared with AI assistance from Aiden. Candidates were tracked with Weco Observe.
Weco share link: https://dashboard.weco.ai/share/yE6YtGpMB4NV3RCoYfCM3tHnAk6srhv_