Skip to content

Commit

Permalink
Transform boto3.ServiceRequest to look like dynamic class
Browse files Browse the repository at this point in the history
`boto3.resource` creates resources dynamically via a resource factory.
Unfortunately that completely breaks static analysis leading to spurious
false positives since pylint cannot determine sanely that attributes
exist or not.

Here's an example of accessing the Topic class out of the `sns` resource.
As you can see, the class is created dynamically rather than existing
in the codebase itself:

```
In [2]: boto3.resource
Out[2]: <function boto3.resource(*args, **kwargs)>

In [3]: boto3.resource('sns')
Out[3]: sns.ServiceResource()

In [4]: boto3.resource('sns').Topic
Out[4]: <bound method ResourceFactory._create_class_partial.<locals>.create_resource of sns.ServiceResource()>
```

This patch adds a fake `__getattr__` method to `ServiceRequest`.
This will prevent `pylint` from emitting `no-member` at all for `ServiceRequest`
instances, but that is a good solution for now until we can load typeshed-like
annotation packages.

Close pylint-dev/pylint#3134
  • Loading branch information
PCManticore committed Mar 4, 2020
1 parent 8999464 commit 01b5b57
Showing 1 changed file with 28 additions and 0 deletions.
28 changes: 28 additions & 0 deletions astroid/brain/brain_boto3.py
@@ -0,0 +1,28 @@
# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
# For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER

"""Astroid hooks for understanding boto3.ServiceRequest()"""
import astroid
from astroid import MANAGER, extract_node

BOTO_SERVICE_FACTORY_QUALIFIED_NAME = "boto3.resources.base.ServiceResource"


def service_request_transform(node):
"""Transform ServiceResource to look like dynamic classes"""
code = """
def __getattr__(self, attr):
return 0
"""
func_getattr = extract_node(code)
node.locals["__getattr__"] = [func_getattr]
return node


def _looks_like_boto3_service_request(node):
return node.qname() == BOTO_SERVICE_FACTORY_QUALIFIED_NAME


MANAGER.register_transform(
astroid.ClassDef, service_request_transform, _looks_like_boto3_service_request
)

0 comments on commit 01b5b57

Please sign in to comment.