fix(lint): warn on private state capture#9411
fix(lint): warn on private state capture#9411onthebed wants to merge 3 commits intomarimo-team:mainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
for more information, see https://pre-commit.ci
There was a problem hiding this comment.
2 issues found across 4 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="marimo/_lint/rules/runtime/private_state_capture.py">
<violation number="1" location="marimo/_lint/rules/runtime/private_state_capture.py:61">
P2: Exclude self-references from `private_refs`; recursive private definitions are currently misreported as capturing private state.</violation>
<violation number="2" location="marimo/_lint/rules/runtime/private_state_capture.py:67">
P2: Use unmangled definition names for diagnostics; current output can leak internal mangled names and degrade line/column accuracy for private defs.</violation>
</file>
Architecture diagram
sequenceDiagram
participant Linter as Lint Runner
participant Graph as DirectedGraph
participant Rule as NEW: PrivateStateCaptureRule
participant Ctx as RuleContext
participant DB as Diagnostic Store
Note over Linter,DB: Runtime Linting Process
Linter->>Graph: get_graph()
Graph-->>Linter: notebook dependency graph
Linter->>Rule: validate_graph(graph, context)
loop For each Cell in graph
Rule->>Rule: Inspect variable_data
loop For each Variable (Function/Class)
Rule->>Rule: Extract required_refs
alt NEW: Check for private capture
Rule->>Rule: is_mangled_local(ref, cell_id)
opt Ref is private cell-local
Rule->>Rule: unmangle_local(ref)
Rule->>Ctx: _get_variable_line_info(cell_id, var_name)
Ctx-->>Rule: line, column
Rule->>Ctx: NEW: add_diagnostic(Diagnostic)
Ctx->>DB: Store MR004 warning
end
end
end
end
Linter->>DB: get_diagnostics()
DB-->>Linter: List[Diagnostic]
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review, or fix all with cubic.
| if not private_refs: | ||
| continue | ||
|
|
||
| line, column = self._get_variable_line_info( |
There was a problem hiding this comment.
P2: Use unmangled definition names for diagnostics; current output can leak internal mangled names and degrade line/column accuracy for private defs.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At marimo/_lint/rules/runtime/private_state_capture.py, line 67:
<comment>Use unmangled definition names for diagnostics; current output can leak internal mangled names and degrade line/column accuracy for private defs.</comment>
<file context>
@@ -0,0 +1,90 @@
+ if not private_refs:
+ continue
+
+ line, column = self._get_variable_line_info(
+ cell_id, variable_name, ctx
+ )
</file context>
| { | ||
| unmangle_local(ref, cell_id).name | ||
| for ref in variable_data.required_refs | ||
| if is_mangled_local(ref, cell_id) |
There was a problem hiding this comment.
P2: Exclude self-references from private_refs; recursive private definitions are currently misreported as capturing private state.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At marimo/_lint/rules/runtime/private_state_capture.py, line 61:
<comment>Exclude self-references from `private_refs`; recursive private definitions are currently misreported as capturing private state.</comment>
<file context>
@@ -0,0 +1,90 @@
+ {
+ unmangle_local(ref, cell_id).name
+ for ref in variable_data.required_refs
+ if is_mangled_local(ref, cell_id)
+ }
+ )
</file context>
dmadisetti
left a comment
There was a problem hiding this comment.
I'm going to move this back to draft. I captures the specific case but not general.
| return _cache[x] + 1 | ||
| res = x * x | ||
| _cache[x] = res | ||
| return res |
There was a problem hiding this comment.
This isn't an issue if it's called within the cell
|
|
||
| - value: The value of the `UIElement`. | ||
| - value: The current value of the `UIElement`. Read-only; it reflects | ||
| frontend state and can't be assigned directly. If you need to |
There was a problem hiding this comment.
Can you revert these doc changes?
| if x in _cache: | ||
| return _cache[x] + 1 | ||
| _cache[x] = x * x | ||
| return _cache[x] |
There was a problem hiding this comment.
Hmm, this is fixated on the specific report but not really addressing the general issue. I think that this in a single cell is actually fine.
Title should probably be: MR004: Cross cell variable mutation.
Here are things that the rule should catch:
a = []
b = set()a.append(value) # I think we can hardcode for known types
b.add(1234)
a[0] = 123 # __setindex__Or mutation cross cell from closures
cache = {} # doesn't have to be private ! def square(x):
if x in cache:
return cache[x] + 1
cache[x] = x * x
return cache[x]square(1) # the error would be here
📝 Summary
Closes #9407.
Add a runtime lint warning for top-level functions and classes that capture private cell-local variables from the same cell. This surfaces execution-order-dependent patterns like cached closures without changing runtime behavior.
📋 Pre-Review Checklist
✅ Merge Checklist
Verification
uv run --group test pytest tests/_lint/test_private_state_capture.py -quv run --group test pytest tests/_lint/test_run_check.py tests/_lint/test_validate_graph.py tests/_lint/test_json_formatter.py::TestJSONFormatterIntegration::test_run_check_json_format_with_issues -quv run --group test ruff check marimo/_lint/rules/runtime/private_state_capture.py marimo/_lint/rules/runtime/__init__.py tests/_lint/test_private_state_capture.py