Skip to content

Commit 67381dc

Browse files
fix: false positive for returns in async defs for hook use
1 parent 2e0dc29 commit 67381dc

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

solara/validate_hooks.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ class InvalidReactivityCause(Enum):
3131

3232

3333
if sys.version_info < (3, 11):
34-
ScopeNodeType = t.Union[ast.For, ast.While, ast.If, ast.Try, ast.FunctionDef]
34+
ScopeNodeType = t.Union[ast.For, ast.While, ast.If, ast.Try, ast.FunctionDef, ast.AsyncFunctionDef]
3535
TryNodes = (ast.Try,)
3636
else:
3737
# except* nodes are only standardized in 3.11+
38-
ScopeNodeType = t.Union[ast.For, ast.While, ast.If, ast.Try, ast.TryStar, ast.FunctionDef]
38+
ScopeNodeType = t.Union[ast.For, ast.While, ast.If, ast.Try, ast.TryStar, ast.FunctionDef, ast.AsyncFunctionDef]
3939
TryNodes = (ast.Try, ast.TryStar)
4040

4141

@@ -100,7 +100,7 @@ def __init__(self, component: t.Callable, use_functions=DEFAULT_USE_FUNCTIONS):
100100
parsed = ast.parse(parsed_source)
101101
# Get nodes from inside the function body
102102
func_definition = t.cast(ast.FunctionDef, parsed.body[0])
103-
self.function_scope: ast.FunctionDef = func_definition
103+
self.function_scope: t.Union[ast.FunctionDef, ast.AsyncFunctionDef] = func_definition
104104
self._root_function_scope = self.function_scope
105105
# None means, *DO* qa
106106
self.no_qa: t.Optional[t.Set[InvalidReactivityCause]] = None
@@ -129,7 +129,7 @@ def node_to_scope_cause(self, node: ScopeNodeType) -> InvalidReactivityCause:
129129
return InvalidReactivityCause.CONDITIONAL_USE
130130
elif isinstance(node, (ast.For, ast.While)):
131131
return InvalidReactivityCause.LOOP_USE
132-
elif isinstance(node, ast.FunctionDef):
132+
elif isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)):
133133
return InvalidReactivityCause.NESTED_FUNCTION_USE
134134
elif isinstance(node, TryNodes):
135135
return InvalidReactivityCause.EXCEPTION_USE
@@ -175,6 +175,12 @@ def visit_FunctionDef(self, node: ast.FunctionDef):
175175
self._visit_children_using_scope(node)
176176
self.function_scope = old_function_scope
177177

178+
def visit_AsyncFunctionDef(self, node: ast.AsyncFunctionDef):
179+
old_function_scope = self.function_scope
180+
self.function_scope = node
181+
self._visit_children_using_scope(node)
182+
self.function_scope = old_function_scope
183+
178184
def _visit_children_using_scope(self, node: ScopeNodeType):
179185
outer_scope = self.outer_scope
180186
self.outer_scope = node

tests/unit/hook_use_invalid_test.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,13 @@ def Page3( # noqa: SH101
120120
return
121121
solara.use_state(1)
122122

123+
@solara.component
124+
def Page4():
125+
async def inner_function():
126+
return
127+
128+
solara.use_state(1)
129+
123130

124131
def test_hook_use_nested_function():
125132
# sometimes we know that the use of a hook is stable, even when in a loop

0 commit comments

Comments
 (0)