Skip to content

(@aws_cdk) Python constructs do not implement a compatible interface #4658

@pradoz

Description

@pradoz

Describe the bug

Similar (old) issue: aws/aws-cdk#15651

aws_ec2.SubnetSelection cannot be initialized from a list of aws_ec2.Subnet's because aws_ec2.ISubnet is not a compatible interface

Fix

We yanked construct==10.3.1 and released construct==10.3.2 with correct dependency constraints.
Make sure your project is not using construct==10.3.1 and not using typeguard==4.3.0

Workaround

In requirements.txt, pin the version of typeguard:

typeguard==2.13.3

Expected Behavior

Passing a list of aws_ec2.Subnet's to an aws_ec2.SubnetSelection can initialize properly

Current Behavior

Error Message:

Traceback (most recent call last):
  File "/home/myuser/testdir/app2/app.py", line 34, in <module>
    App2(app, 'App2', env=env)
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/jsii/_runtime.py", line 118, in __call__
    inst = super(JSIIMeta, cast(JSIIMeta, cls)).__call__(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/myuser/testdir/app2/app.py", line 27, in __init__
    ec2.SubnetSelection(subnets=subnet_construct_list)  # this goes boom
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/aws_cdk/aws_ec2/__init__.py", line 85174, in __init__
    check_type(argname="argument subnets", value=subnets, expected_type=type_hints["subnets"])
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/aws_cdk/aws_ec2/__init__.py", line 2602, in check_type
    typeguard.check_type(value=value, expected_type=expected_type, collection_check_strategy=typeguard.CollectionCheckStrategy.ALL_ITEMS) # type:ignore
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/typeguard/_functions.py", line 106, in check_type
    check_type_internal(value, expected_type, memo)
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/typeguard/_checkers.py", line 861, in check_type_internal
    checker(value, origin_type, args, memo)
  File "/home/myuser/testdir/.venv/lib/python3.11/site-packages/typeguard/_checkers.py", line 433, in check_union
    raise TypeCheckError(f"did not match any element in the union:\n{formatted_errors}")
typeguard.TypeCheckError: list did not match any element in the union:
  Sequence[aws_cdk.aws_ec2.ISubnet]: item 0 is not compatible with the ISubnet protocol because it has no method named '__jsii_proxy_class__'
  NoneType: is not an instance of NoneTypeTraceback (most recent call last):

Reproduction Steps

requirements.txt

aws-cdk-lib==2.162.0
constructs>=10.0.0,<11.0.0

requirements-dev.txt

pytest==6.2.5
boto3

app1/app.py

import os

from aws_cdk import (
    App,
    Environment,
    Stack,
    aws_ec2 as ec2,
    aws_ssm as ssm,
)
from constructs import Construct


class App1(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        vpc = ec2.Vpc(
            self, 'Vpc',
            max_azs=1,
            create_internet_gateway=False,
            subnet_configuration=[
                ec2.SubnetConfiguration(
                    name='PublicSubnets',
                    subnet_type=ec2.SubnetType.PUBLIC,
                    cidr_mask=26,
                ),
                ec2.SubnetConfiguration(
                    name='PrivateSubnets',
                    subnet_type=ec2.SubnetType.PRIVATE_WITH_EGRESS,
                    cidr_mask=20,
                ),
            ],
            nat_gateways=1,
            restrict_default_security_group=True,
        )
        private_subnets = ','.join([s.subnet_id for s in vpc.private_subnets])
        ssm.StringParameter(
            self, 'SubnetParam',
            parameter_name='/my/subnets',
            string_value=private_subnets,
        )


env = Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'),
                  region=os.getenv('CDK_DEFAULT_REGION'))

app = App()
App1(app, 'App1', env=env)
app.synth()

app2/app.py

import os
import boto3

from aws_cdk import (
    App,
    Environment,
    Stack,
    aws_ec2 as ec2,
)
from constructs import Construct


def get_parameter() -> list:
    ssm_client = boto3.client('ssm', region_name='us-east-2')
    response = ssm_client.get_parameter(Name='/my/subnets')
    val = response['Parameter']['Value']
    return val.split(',')


class App2(Stack):
    def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        subnet_list = get_parameter()
        subnet_construct_list = [
            ec2.Subnet.from_subnet_id(self, s, subnet_id=s) for s in subnet_list
        ]
        ec2.SubnetSelection(subnets=subnet_construct_list)  # this goes boom


env = Environment(account=os.getenv('CDK_DEFAULT_ACCOUNT'),
                  region=os.getenv('CDK_DEFAULT_REGION'))

app = App()
App2(app, 'App2', env=env)
app.synth()

Deploy:

$ python3 -m venv .venv && source .venv/bin/activate
$  pip install -r requirements.txt -r requirements-dev.txt
$  cdk deploy -vv --require-approval never --app "python3 app1/app.py"
$  cdk deploy -vv --require-approval never --app "python3 app2/app.py"

Observe the error. I also confirmed that a print statement for subnet_list prints ['subnet-0b39XXXXXX']

Possible Solution

Not sure

Additional Information/Context

Package Version


attrs 24.2.0
aws-cdk.asset-awscli-v1 2.2.206
aws-cdk.asset-kubectl-v20 2.1.3
aws-cdk.asset-node-proxy-agent-v6 2.1.0
aws-cdk.cloud-assembly-schema 38.0.1
aws-cdk-lib 2.162.0
boto3 1.35.38
botocore 1.35.38
cattrs 23.2.3
constructs 10.3.1
importlib_resources 6.4.5
iniconfig 2.0.0
jmespath 1.0.1
jsii 1.103.1
packaging 24.1
pip 24.0
pluggy 1.5.0
publication 0.0.3
py 1.11.0
pytest 6.2.5
python-dateutil 2.9.0.post0
s3transfer 0.10.3
setuptools 65.5.0
six 1.16.0
toml 0.10.2
typeguard 4.3.0
typing_extensions 4.12.2
urllib3 2.2.3

SDK version used

CDK 2.162.0 (build c8d7dd3), python 3.11, node 18 & 20

Environment details (OS name and version, etc.)

Amazon Linux 2023 & Ubuntu 20.04 on WSL

Metadata

Metadata

Assignees

Labels

bugThis issue is a bug.language/pythonRelated to Python bindingsp1

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions