Skip to content

[Repo Assist] [Python] Fix TCO context adding unnecessary default params to nested lambdas#4426

Merged
dbrattli merged 4 commits into
mainfrom
repo-assist/fix-python-tco-unnecessary-closure-capture-e64e452bdb8069e0
Mar 21, 2026
Merged

[Repo Assist] [Python] Fix TCO context adding unnecessary default params to nested lambdas#4426
dbrattli merged 4 commits into
mainfrom
repo-assist/fix-python-tco-unnecessary-closure-capture-e64e452bdb8069e0

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Summary

  • Fixes python: passing function reference introduces unnecessary closure #3877: function references passed as arguments in TCO contexts were gaining spurious default parameters for outer TCO variables they don't reference
  • Root cause: transformFunction in Fable2Python.Transforms.fs unconditionally appended all TCO args as default parameters to every nested lambda, regardless of whether the lambda body references those variables
  • Fix: filter TCO args with isIdentUsed name body before adding them as defaults

Test plan

  • New test test Passing a function reference in a TCO context does not capture unneeded outer args added to tests/Python/TestTailCall.fs
  • Existing TCO closure-capture tests still pass (closures that DO reference the TCO variable still get correct defaults)
  • Run ./build.sh test python --skip-fable-library to verify

🤖 Generated with [Claude Code]((claude.com/redacted)

Generated by Repo Assist ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/repo-assist.md@346204513ecfa08b81566450d7d599556807389f

 #3877)

When a function is tail-call optimised, all nested functions/lambdas
created within its body previously inherited all TCO variables as default
parameters (e.g. `_arg: Any=_arg`), even when the nested function doesn't
reference those variables at all.

Root cause: `transformFunction` computes `tcArgs` from the outer
`TailCallOpportunity` in context and appends them unconditionally to every
nested function. The capture is needed for closures that *do* reference a
mutated TCO variable (Python captures by reference, so defaults bind the
current value). But it was applied indiscriminately.

Fix: before appending a TCO arg as a default, check whether the function
body actually references that variable using `isIdentUsed`. Variables not
referenced in the body are excluded from the captured defaults.

This eliminates spurious parameters like `_arg: Any=_arg` on lambdas like
`fun () -> g()` that don't use the outer TCO variable, and keeps the
capture for lambdas like `fun () -> i` that do.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions github-actions Bot added automation Automated changes repo-assist Created by Repo Assist labels Mar 20, 2026
@dbrattli dbrattli marked this pull request as ready for review March 21, 2026 09:28
@github-actions

Copy link
Copy Markdown
Contributor Author

Python Type Checking Results (Pyright)

Metric Value
Total errors 18
Files with errors 4
Excluded files 4
New errors ✅ No
Excluded files with errors (4 files)

These files have known type errors and are excluded from CI. Remove from pyrightconfig.ci.json as errors are fixed.

File Errors Status
temp/tests/Python/test_applicative.py 12 Excluded
temp/tests/Python/test_hash_set.py 3 Excluded
temp/tests/Python/test_nested_and_recursive_pattern.py 2 Excluded
temp/tests/Python/fable_modules/thoth_json_python/encode.py 1 Excluded

@dbrattli dbrattli merged commit c33cce0 into main Mar 21, 2026
24 checks passed
@dbrattli dbrattli deleted the repo-assist/fix-python-tco-unnecessary-closure-capture-e64e452bdb8069e0 branch March 21, 2026 11:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

automation Automated changes repo-assist Created by Repo Assist

Projects

None yet

Development

Successfully merging this pull request may close these issues.

python: passing function reference introduces unnecessary closure

1 participant