aws / aws/chalice

Static analysis cannot detect nested functions

Open
#1,841 3 comments 1 reaction 0 assignees View on GitHub
bug
Dominant language
Python
Stars
11.1k
Forks
1k
Avg merge
1d 22h
Merged PRs (30d)
2

Description

Chalice version 1.26.2
Python 3.9

I believe this is a regression, because I'm fairly certain this worked in previous versions of Chalice.

To reproduce, try something like this:

```python
@app.route('/')
def home():
def response_wrapper(text):
return {"text": text}
return response_wrapper("hello")
```

This is not our exact code, of course, but is roughly equivalent. This will create the following stack trace:

```
Traceback (most recent call last):
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/cli/__init__.py", line 636, in main
return cli(obj={})
File "/home/circleci/.local/lib/python3.9/site-packages/click/core.py", line 1128, in __call__
return self.main(*args, **kwargs)
File "/home/circleci/.local/lib/python3.9/site-packages/click/core.py", line 1053, in main
rv = self.invoke(ctx)
File "/home/circleci/.local/lib/python3.9/site-packages/click/core.py", line 1659, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/home/circleci/.local/lib/python3.9/site-packages/click/core.py", line 1395, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/home/circleci/.local/lib/python3.9/site-packages/click/core.py", line 754, in invoke
return __callback(*args, **kwargs)
File "/home/circleci/.local/lib/python3.9/site-packages/click/decorators.py", line 26, in new_func
return f(get_current_context(), *args, **kwargs)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/cli/__init__.py", line 189, in deploy
deployed_values = d.deploy(config, chalice_stage_name=stage)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/deploy/deployer.py", line 376, in deploy
return self._deploy(config, chalice_stage_name)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/deploy/deployer.py", line 386, in _deploy
self._build_stage.execute(config, resources)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/deploy/deployer.py", line 652, in execute
step.handle(config, resource)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/deploy/deployer.py", line 419, in handle
handler(config, resource)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/deploy/deployer.py", line 637, in handle_autogeniampolicy
policy = self._policy_gen.generate_policy(config)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/policy.py", line 93, in generate_policy
app_policy = policy_from_source_code(app_source)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/policy.py", line 28, in policy_from_source_code
client_calls = get_client_calls_for_app(source_code)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 74, in get_client_calls_for_app
binder = t.bind_types()
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 684, in bind_types
self.visit(self._parsed_code.parsed_ast)
File "/usr/local/lib/python3.9/ast.py", line 407, in visit
return visitor(node)
File "/usr/local/lib/python3.9/ast.py", line 415, in generic_visit
self.visit(item)
File "/usr/local/lib/python3.9/ast.py", line 407, in visit
return visitor(node)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 694, in visit_FunctionDef
child_infer.bind_types()
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 352, in bind_types
self.visit(self._current_ast_namespace)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 662, in visit
return ast.NodeVisitor.visit(self, node)
File "/usr/local/lib/python3.9/ast.py", line 407, in visit
return visitor(node)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 540, in visit_FunctionDef
self.visit(child)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 662, in visit
return ast.NodeVisitor.visit(self, node)
File "/usr/local/lib/python3.9/ast.py", line 407, in visit
return visitor(node)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 563, in visit_Return
self.generic_visit(node)
File "/usr/local/lib/python3.9/ast.py", line 417, in generic_visit
self.visit(value)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 662, in visit
return ast.NodeVisitor.visit(self, node)
File "/usr/local/lib/python3.9/ast.py", line 407, in visit
return visitor(node)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 477, in visit_Call
self._infer_function_call(node)
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 498, in _infer_function_call
sub_table = self._symbol_table.lookup_sub_namespace(
File "/home/circleci/.local/lib/python3.9/site-packages/chalice/analyzer.py", line 280, in lookup_sub_namespace
raise ValueError("Unknown symbol name: %s" % name)
ValueError: Unknown symbol name: response_wrapper
```

However, when I declare the function like so:

```python
def response_wrapper(text):
return {"text": text}

@app.route('/')
def home():
return response_wrapper("hello")
```

The project will build and deploy successfully.

**Expected behavior:** I would expect to be able to declare nested functions and Chalice be able to build/deploy successfully.

Contributor guide

Open the contributing guide

Research direction

Start in chalice/analyzer.py at bind_types(), visit_FunctionDef(), and lookup_sub_namespace(), which appear in the traceback. Reproduce the nested-function example and inspect the analyzer's handling of nested namespaces. Done means nested functions no longer raise the unknown-symbol error and the application builds and deploys successfully, with a regression test covering the example.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
backend, cloud
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.