Skip to content

Commit 24b1319

Browse files
committed
Fix more edge cases with multiple imports and nested list comprehensions
1 parent cfc8ee8 commit 24b1319

File tree

2 files changed

+44
-3
lines changed

2 files changed

+44
-3
lines changed

reflex/vars/dep_tracking.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,14 @@ def _populate_dependencies(self) -> None:
396396
elif self.scan_status == ScanStatus.GETTING_VAR:
397397
self.handle_getting_var(instruction)
398398
elif (
399-
instruction.opname in ("LOAD_FAST", "LOAD_DEREF", "LOAD_FAST_BORROW")
399+
instruction.opname
400+
in (
401+
"LOAD_FAST",
402+
"LOAD_DEREF",
403+
"LOAD_FAST_BORROW",
404+
"LOAD_FAST_CHECK",
405+
"LOAD_FAST_AND_CLEAR",
406+
)
400407
and instruction.argval in self.tracked_locals
401408
):
402409
# bytecode loaded the class instance to the top of stack, next load instruction
@@ -405,7 +412,11 @@ def _populate_dependencies(self) -> None:
405412
self.scan_status = ScanStatus.GETTING_ATTR
406413
elif (
407414
instruction.opname
408-
in ("LOAD_FAST_LOAD_FAST", "LOAD_FAST_BORROW_LOAD_FAST_BORROW")
415+
in (
416+
"LOAD_FAST_LOAD_FAST",
417+
"LOAD_FAST_BORROW_LOAD_FAST_BORROW",
418+
"STORE_FAST_LOAD_FAST",
419+
)
409420
and instruction.argval[-1] in self.tracked_locals
410421
):
411422
# Double LOAD_FAST family instructions load multiple values onto the stack,
@@ -457,7 +468,6 @@ def _populate_dependencies(self) -> None:
457468
)
458469
# If we see a STORE_FAST, we can assign the top of stack to an aliased name.
459470
self.top_of_stack = instruction.argval
460-
self._last_import_name = None
461471
elif instruction.opname == "STORE_FAST" and self.top_of_stack is not None:
462472
self.tracked_locals[instruction.argval] = self.tracked_locals.pop(
463473
self.top_of_stack

tests/units/vars/test_dep_tracking.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ class DependencyTestState(State):
2323
count: rx.Field[int] = rx.field(default=0)
2424
name: rx.Field[str] = rx.field(default="test")
2525
items: rx.Field[list[str]] = rx.field(default_factory=list)
26+
board: rx.Field[list[list[int]]] = rx.field(default_factory=list)
2627

2728

2829
class AnotherTestState(State):
@@ -102,6 +103,18 @@ def func_with_comprehension(self: DependencyTestState):
102103
assert tracker.dependencies == expected_deps
103104

104105

106+
def test_list_comprehension_dependencies_2():
107+
"""Test tracking dependencies in list comprehensions."""
108+
109+
def func_with_comprehension(self: DependencyTestState):
110+
return [[self.board[r][c] for r in range(3)] for c in range(5)]
111+
112+
tracker = DependencyTracker(func_with_comprehension, DependencyTestState)
113+
114+
expected_deps = {DependencyTestState.get_full_name(): {"board"}}
115+
assert tracker.dependencies == expected_deps
116+
117+
105118
def test_invalid_attribute_access():
106119
"""Test that accessing invalid attributes raises VarValueError."""
107120

@@ -167,6 +180,24 @@ async def get_state_import_from(self: DependencyTestState):
167180
assert tracker.dependencies == expected_deps
168181

169182

183+
def test_get_state_with_import_from_multiple():
184+
"""Test that get_state with function-local `from ... import ...` finds correct dependency."""
185+
186+
async def get_state_import_from(self: DependencyTestState):
187+
from tests.units.states.upload import ChildFileUploadState, SubUploadState
188+
189+
return (await self.get_state(SubUploadState)).img, (
190+
await self.get_state(ChildFileUploadState)
191+
).img_list
192+
193+
tracker = DependencyTracker(get_state_import_from, DependencyTestState)
194+
expected_deps = {
195+
tus_upload.SubUploadState.get_full_name(): {"img"},
196+
tus_upload.ChildFileUploadState.get_full_name(): {"img_list"},
197+
}
198+
assert tracker.dependencies == expected_deps
199+
200+
170201
def test_get_state_with_import_from_as():
171202
"""Test that get_state with function-local `from ... import ... as ...` finds correct dependency."""
172203

0 commit comments

Comments
 (0)