Fix apply_op for tuple containers and keyword container inputs - #53
Open
Max Freedom Pollard (MaxFreedomPollard) wants to merge 1 commit into
Open
Conversation
Author
|
@microsoft-github-policy-service agree |
apply_op broadcasts an operator over containers of Nodes, but two cases in opto/trace/broadcast.py never worked: - A tuple container raised "TypeError: 'tuple' object does not support item assignment", because the loop assigned into the tuple in place. The trailing `if isinstance(output, tuple): output = tuple(output)` was therefore unreachable. Accumulate into a list and convert back. - Keyword inputs against a Node-valued attribute of a NodeContainer tested `isinstance(v, Node)` (the output's attribute) instead of `isinstance(vv, Node)` (the keyword input), so a container passed by keyword was forwarded whole instead of being indexed by attribute, tripping the admissible-type assertion. The positional path already did the right thing. Adds regression tests covering a tuple container standalone and nested in a NodeContainer, a list and a dict; a bare Node broadcast against a tuple; the existing in-place list behaviour; and keyword inputs whose values are containers, including one mixed with a bare Node.
Max Freedom Pollard (MaxFreedomPollard)
force-pushed
the
fix/apply-op-tuple-and-kwargs
branch
from
September 5, 2026 00:28
42ec623 to
4231612
Compare
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.
Summary
apply_op(exported fromopto.trace) broadcasts an operator over a container ofNodes. The Broadcasting section ofdocs/tutorials/basic_tutorial.ipynbdocuments the supported containers aslist,tuple,dict, or a container class — but atuplehas never worked, and neither have container inputs passed by keyword. The tutorial only demonstrates thelist,dictand class cases, so the gap isn't visible from the notebook output.The source change is +6/-2 in
opto/trace/broadcast.py; the rest is regression tests.1. Tuple containers raise
TypeErrorThe list/tuple branch assigns into
outputelement by element, which a tuple cannot do:The intent was already in the code — the branch ends with
which is a no-op as written, and for a non-empty tuple the loop raises before ever reaching it. (An empty tuple does reach it, and round-trips unchanged.) The fix records whether the output was a tuple, works on a list, and converts back at the end. Lists keep their current in-place behaviour, which
test_apply_op.pyrelies on.2. Keyword container inputs hit an assertion
The
NodeContainerbranch builds_kwargswithvis the output's attribute;vvis the keyword input. When an attribute of the output is aNode, every keyword input is forwarded whole instead of being indexed by attribute name, and the recursive call trips the admissible-type assertion:The positional path one line above already uses the input (
x), and the list and dict branches already testisinstance(vv, Node). This makes the keyword path consistent with them; the same call passed positionally works today and returns"foobar".Tests
tests/unit_tests/test_apply_op.pygains coverage for:NodeContainer, a list, and a dict — checking the result type, the values, and that the inputs are wired in as parentsNodebroadcast against every element of a tupleNodeBoth new blocks were re-run against the unpatched
broadcast.py: the tuple cases fail with theTypeErrorabove, the keyword cases with theAssertionErrorabove. Both pass with the fix.Verification
The
Python unit testsworkflow in this repo is awaiting maintainer approval here, as it does for any first-time contributor. I ran that same workflow, unmodified, on this exact commit in my fork:https://github.com/MaxFreedomPollard/Trace/actions/runs/33940060529 — green, 22/22 (
test_apply_op.pyincluded), Python 3.9.25 onubuntu-24.04.Also checked locally:
python tests/unit_tests/run.pyon Python 3.9python tests/unit_tests/run.pyon Python 3.12black==23.3.0(pinned in.pre-commit-config.yaml)ruff==0.0.261(pinned)codespell==2.2.6(pinned)No API, signature, or dependency changes. The one pre-existing
E501inbroadcast.py(line 57, a commented-out line) is untouched.