jsii icon indicating copy to clipboard operation
jsii copied to clipboard

Python code failing type checking

Open rix0rrr opened this issue 1 year ago • 3 comments

Reported in another issue

@dmartin-gh

I am also experiencing the interface issues described above. We're looking to adopt the CDK for our main platform and as a mostly Python/C++ shop the Python CDK seemed like a great choice for us. I didn't make it very far into my first sample app to test things out before mypy started throwing errors.

from aws_cdk.core import Construct, Stack
from aws_cdk import aws_ec2 as ec2

class MyEC2Stack(Stack):

    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)

        ec2.Instance(self, 'my-app',
            instance_type=ec2.InstanceType('m5.4xlarge'),
            machine_image=ec2.MachineImage.generic_linux({
                'us-east-1': 'ami-0affd4508a5d2481b', # CentOS 7 (x86_64) - with Updates HVM
            }),
            vpc=ec2.Vpc(self, "my-app-vpc"))

image I would love to see this fixed so we can start building out our application stack with confidence that we're passing the right level of constructs around!

Is this still a problem today? I have been trying to reproduce this (with CDK v2, though), and am not getting the MyPy error you report here... if you still happen to have the error, maybe this is because of your specific MyMy version or configuration (in which case, I would like to know what these are so I can reproduce).

Indeed it is still a problem. For example try loading up apigw-http-api-lambda-dynamodb-python-cdk in vscode, then pyright reports for

        # Create the Lambda function to receive the request
        api_hanlder = lambda_.Function(
            ...
        )

        ...

        # Create API Gateway
        apigw_.LambdaRestApi(
           ...
            handler=api_hanlder,  # Pyright error: Argument of type "Function" cannot be assigned to parameter "handler" of type "IFunction"
        )

typecheck error

Argument of type "Function" cannot be assigned to parameter "handler" of type "IFunction" in function "__init__"
  "Function" is incompatible with protocol "IFunction"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"
    "IFunction" is incompatible with "Function"Pylance[reportArgumentType](https://github.com/microsoft/pyright/blob/main/docs/configuration.md#reportArgumentType)
(variable) api_hanlder: Function

as shown in this screenshot

image

That project uses aws-cdk-lib==2.77.0 however the same issue exists after updating to recent aws-cdk-lib==2.143.1. On my machine it happens with the following configuration

pyright 1.1.364
pylance 2024.5.103
aws-cdk-lib 2.143.1
python 3.11.2
vscode 1.89.1

Originally posted by @mariogalic in https://github.com/aws/jsii/issues/1919#issuecomment-2142047331

rix0rrr avatar Jun 03 '24 14:06 rix0rrr

Also related to this issue:

  • https://github.com/aws/jsii/issues/3931 (another user experience report)
  • https://github.com/aws/jsii/pull/3350 (perhaps a fix?)

I'm also still seeing this issue (https://github.com/aws/jsii/issues/2877) in a JetBrains IDE (Intellij IDEA Ultimate with Python plugin). A comment in the issue near the end says it's fixed, but I see the same Expected type 'str | str | None', got '() -> str | str' instead error in my IDE today using CDK v2.144.0.

These two typing issues combined make Python experience really rough because your IDE thinks you have a lot of invalid types and sometimes its hard to see which typing issue is an actual problem unless you run cdk synth/deploy.

polothy avatar Jun 03 '24 17:06 polothy

I took a look at apigw-http-api-lambda-dynamodb-python-cdk and was able to root cause at least one issue causing these type checker errors.

When you implement an interface in TS, the method names have to match, but the method argument names do not, as long as the argument types are in the correct order. In Python however, when you implement a Protocol (which is how we do interfaces), the method argument names do have to match. So when our TS library has things like IPrincipal.addToPrincipalPolicy(statement: PolicyStatement) and an implementation of PrincipalBase.addToPrincipalPolicy(_statement: PolicyStatement) the former generates an IPrincipal Protocol in python, and the latter generates a class that's incompatible, and we get the PyRight error:

...
        "AnyPrincipal" is incompatible with protocol "IPrincipal"
          "IPrincipal" is incompatible with "AnyPrincipal"
          "IPrincipal" is incompatible with "AnyPrincipal"
          "IPrincipal" is incompatible with "AnyPrincipal"
          "add_to_principal_policy" is an incompatible type

The suggested fix here is to always use the method argument names in the base (Protocol) class, when generating subclasses. In the example above, PrincipalBase.addToPrincipalPolicy() would use the method argument statement instead of what's in the TS code, _statement. I didn't get as far as implementation but hopefully this context is useful.

mikewrighton avatar Jun 07 '24 20:06 mikewrighton

I have this issue too in Intellij IDEA Ultimate w/ Python. Super annoying. I don't get the error in VS Code.

adriandelgg avatar Jun 27 '24 03:06 adriandelgg

I used typing.cast(aws_iam.IPricipal, principal) as a muffler, but got fed up with it. So, upvote.

dytyniuk avatar Jul 12 '24 14:07 dytyniuk

I used typing.cast(aws_iam.IPricipal, principal) as a muffler, but got fed up with it. So, upvote.

Yeah, there shouldn't be a need to do that at all though. It seems to not throw the same type errors in VS Code, but it's definitely a bug with jsii due to how it transforms TypeScript code to other languages. Python is weird in general IMHO.

adriandelgg avatar Jul 12 '24 19:07 adriandelgg

Possible duplicate of https://github.com/aws/jsii/issues/2927 / https://github.com/aws/jsii/issues/4541

gshpychka avatar Jul 26 '24 08:07 gshpychka

This issue has become hard to follow because it surfaces many different issues. I am closing it out as all issues have dedicated issues for them. See:

  • https://github.com/aws/jsii/issues/3633
  • https://github.com/aws/jsii/issues/4541
  • https://github.com/aws/jsii/issues/3931

iliapolo avatar Sep 09 '24 07:09 iliapolo

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] avatar Sep 09 '24 07:09 github-actions[bot]

This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.

github-actions[bot] avatar Sep 09 '24 07:09 github-actions[bot]