chalice
chalice copied to clipboard
Static analysis cannot detect nested functions
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:
@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:
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.
Looks like this is a regression introduced in 1.18.1 when trying to fix https://github.com/aws/chalice/issues/1494. Thanks for reporting.
@jamesls Has there been any progress on this bug? I am affected by this, too.
I am a bit stuck here. I can no longer have an older version of chalice since apparently the newer version of chalice fixes this issue:
UpdateFunctionConfiguration operation: The operation cannot be performed at
this time. An update is in progress for resource:
But, I cannot upgrade to a newer version because of this regression without significant changes to my code.
Follow up to my last post. I have solved the issue. I moved my project to serverless and it's been working great so far.