aws / aws/chalice

Policy analyzer does not handle paginators

Open
#818 1 comment 1 reaction 0 assignees View on GitHub
enhancement
Dominant language
Python
Stars
11.1k
Forks
1k
Avg merge
1d 22h
Merged PRs (30d)
2

Description

The policy analyzer currently does not handle `get_paginator`.

```diff
diff --git a/tests/unit/test_analyzer.py b/tests/unit/test_analyzer.py
index 0cff024..35f94cd 100644
--- a/tests/unit/test_analyzer.py
+++ b/tests/unit/test_analyzer.py
@@ -636,6 +636,17 @@ def test_can_handle_async_await():
""") == {'dynamodb': set(['list_tables'])}

+def test_can_handle_paginator():
+ assert aws_calls("""\
+ import boto3
+ client = boto3.client('ec2')
+ paginator = client.get_paginator('describe_instances')
+
+ for page in paginator.paginate():
+ print(page)
+ """) == {'ec2': set(['describe_instances'])}
+
+
# def test_tuple_assignment():
# assert aws_calls("""\
# import boto3
```

```
E AssertionError: assert {'ec2': {'get_paginator'}} == {'ec2': {'describe_instances'}}
E Differing items:
E {'ec2': {'get_paginator'}} != {'ec2': {'describe_instances'}}
E Full diff:
E - {'ec2': {'get_paginator'}}
E + {'ec2': {'describe_instances'}}
```

I'm not across AST parsing, so the solution I cobbled together picks up the creation of the paginator, regardless of whether the paginator is actually called (as in, makes any http calls).

```diff
diff --git a/chalice/analyzer.py b/chalice/analyzer.py
index 49a75ae..00aaab5 100644
--- a/chalice/analyzer.py
+++ b/chalice/analyzer.py
@@ -324,6 +324,7 @@ class TypeBinder(object):
class SymbolTableTypeInfer(ast.NodeVisitor):
_SDK_PACKAGE = 'boto3'
_CREATE_CLIENT = 'client'
+ _GET_PAGINATOR = 'get_paginator'

def __init__(self, parsed_code, binder=None, visited=None):
# type: (ParsedCode, Optional[TypeBinder], OptASTSet) -> None
@@ -450,11 +451,16 @@ class SymbolTableTypeInfer(ast.NodeVisitor):
inferred_type = Boto3ClientType(sub_type.value)
self._set_inferred_type_for_node(node, inferred_type)
elif isinstance(inferred_func_type, Boto3ClientMethodType):
+ if inferred_func_type.method_name == self._GET_PAGINATOR:
+ # This detects creation, not "use" of paginator.
+ method_name = node.args[0].s
+ else:
+ method_name = inferred_func_type.method_name
self._set_inferred_type_for_node(
node,
Boto3ClientMethodCallType(
inferred_func_type.service_name,
- inferred_func_type.method_name
+ method_name
)
)
elif isinstance(inferred_func_type, FunctionType):
```

Contributor guide

Open the contributing guide

Research direction

Start with tests/unit/test_analyzer.py and the existing analyzer logic in chalice/analyzer.py. Run test_can_handle_paginator to reproduce the current result, then trace how get_paginator is represented by the AST analyzer. Done means the test reports describe_instances for the ec2 service rather than get_paginator.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.