aws-powertools / powertools-lambda-python

A developer toolkit to implement Serverless best practices and increase developer velocity.
https://docs.powertools.aws.dev/lambda/python/latest/
MIT No Attribution
2.81k stars 390 forks source link

Static typing: Untyped event_source decorator with mypy --strict #3568

Open JakubSosnovec opened 8 months ago

JakubSosnovec commented 8 months ago

Static type checker used

mypy (project's standard)

AWS Lambda function runtime

3.12

Powertools for AWS Lambda (Python) version

2.30.2

Static type checker info

Just mypy --strict, with mypy version 1.8.0. Output: error: Untyped decorator makes function "handler" untyped [misc]

Code snippet

$ pip freeze
aws-lambda-powertools==2.30.2
mypy==1.8.0
mypy-extensions==1.0.0
typing_extensions==4.9.0

$ cat main.py  --plain
from typing import Any
from aws_lambda_powertools.utilities.data_classes import SQSEvent, event_source
from aws_lambda_powertools.utilities.typing import LambdaContext
@event_source(data_class=SQSEvent)
def handler(event: SQSEvent, _context: LambdaContext) -> dict[str, Any]:
    return {}

$ mypy --strict main.py
main.py:7: error: Untyped decorator makes function "handler" untyped  [misc]
Found 1 error in 1 file (checked 1 source file)

Possible Solution

Very similar to #1060 which is claimed to be solved, but this issue appears in the latest release, mypy in strict mode still doesnt understand the return type. Maybe it came back?

boring-cyborg[bot] commented 8 months ago

Thanks for opening your first issue here! We'll come back to you as soon as we can. In the meantime, check out the #python channel on our Powertools for AWS Lambda Discord: Invite link

leandrodamascena commented 8 months ago

Hi @JakubSosnovec! Thanks for bringing this question! Strict typing has been on our radar for a long time and we are correcting what is possible every time we release a new version, but this project is not 100% compatible with strict typing and we are investigating how to include it in our roadmap, but we do not have an ETA for that. I'll add this issue to our backlog and see if we can do something specifically for this case.

@heitorlessa would love to hear your thoughts here.

BTW, I'm trying here with mypy 1.4+ and Powertoos 1.25.7 and I get the same error. It seems like something is still unresolved.

❯ pip freeze
aws-lambda-powertools==1.25.7
aws-xray-sdk==2.12.1
boto3==1.34.10
botocore==1.34.10
fastjsonschema==2.19.1
jmespath==0.10.0
mypy==1.4.1
mypy-extensions==1.0.0
python-dateutil==2.8.2
s3transfer==0.10.0
six==1.16.0
tomli==2.0.1
typing-extensions==4.9.0
urllib3==1.26.18
wrapt==1.16.0
from typing import Any
from aws_lambda_powertools.utilities.data_classes import SQSEvent, event_source
from aws_lambda_powertools.utilities.typing import LambdaContext
@event_source(data_class=SQSEvent)
def handler(event: SQSEvent, _context: LambdaContext) -> dict[str, Any]:
    return {}
❯ mypy --strict main.py       
main.py:4: error: Untyped decorator makes function "handler" untyped  [misc]
Found 1 error in 1 file (checked 1 source file)
robmoss2k commented 5 months ago

The simple fix for this to remove the error for event_source would be to add -> Any to def event_source, is it not? You already have the fact that the callable returns that type in the definition: handler: Callable[[Any, LambdaContext], Any],, so it is, in fact, also the correct fix.

robmoss2k commented 5 months ago

@leandrodamascena - PR with fix submitted. Quite possibly the smallest one you'll ever see...

manmartgarc commented 3 months ago

Maybe unrelated, but I'm having trouble decorating an instance method, for example:


class MyClass:
    @event_source(MyDataClass)
    def handle(self, event: MyDataClass, context: LambdaContext) -> None:
         return self._handle_inner(event, context)

    def _handle_inner(self, event: Any, context: LambdaContext) -> None:
        return None

Getting this error:

MyClass._handle_inner() takes 2 positional arguments but 3 were given
heitorlessa commented 3 months ago

oh hey @manmartgarc that's because the decorator doesn't support class methods, only functions.

The error but 3 were given is because the self argument of the class is being injected.

manmartgarc commented 3 months ago

oh hey @manmartgarc that's because the decorator doesn't support class methods, only functions.

The error but 3 were given is because the self argument of the class is being injected.

Thanks. I figured it would support them. Is there a reason they're not supported and if not, is there a plan to support them? If we're just waiting on a PR, I'm happy to submit one.

manmartgarc commented 3 weeks ago

hey @heitorlessa, was there a conscious decision to not support class methods? I think we can make the typing work to support both; can I work on this feature?

leandrodamascena commented 3 weeks ago

Hey @manmartgarc! Please go ahead with this PR and let me know if you need any help!

If you're planning to start working on this right now, please fork a new branch from the v3 branch.