Skip to content

Commit 42d84c9

Browse files
committed
typing Sequence and ForwardRef handling for python 3.6
1 parent e1b88ee commit 42d84c9

File tree

2 files changed

+28
-7
lines changed

2 files changed

+28
-7
lines changed

src/cloudformation_cli_python_lib/recast.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
# ignoring mypy on the import as it catches ForwardRef as invalid, and we are using it
2-
# for introspection https://docs.python.org/3/library/typing.html#typing.ForwardRef
3-
from typing import Any, Dict, ForwardRef, List, Mapping # type: ignore
1+
import typing
2+
from typing import Any, Dict, List, Mapping
43

54
from .exceptions import InvalidRequest
65

@@ -57,7 +56,7 @@ def _field_to_type(field: Any, key: str, classes: Dict[str, Any]) -> Any:
5756
if field in [int, float, str, bool]:
5857
return field
5958
# If it's a ForwardRef we need to find base type
60-
if isinstance(field, ForwardRef):
59+
if isinstance(field, get_forward_ref_type()):
6160
# Assuming codegen added an _ as a prefix, removing it and then gettting the
6261
# class from model classes
6362
return classes[field.__forward_arg__[1:]]
@@ -77,11 +76,21 @@ def _field_to_type(field: Any, key: str, classes: Dict[str, Any]) -> Any:
7776
if field in [int, float, str, bool]:
7877
return field
7978
# If it's a ForwardRef we need to find base type
80-
if isinstance(field, ForwardRef):
79+
if isinstance(field, get_forward_ref_type()):
8180
# Assuming codegen added an _ as a prefix, removing it and then gettting the
8281
# class from model classes
8382
return classes[field.__forward_arg__[1:]]
8483
# If it's not a type we don't know how to handle we bail
85-
if field._name not in ["Sequence"]: # pylint: disable=protected-access
86-
raise InvalidRequest(f"Cannot process type {field.__repr__()} for field {key}")
84+
if not str(field).startswith("typing.Sequence"):
85+
raise InvalidRequest(f"Cannot process type {field} for field {key}")
8786
return _field_to_type(field.__args__[0], key, classes)
87+
88+
89+
# pylint: disable=protected-access,no-member
90+
def get_forward_ref_type() -> Any:
91+
# ignoring mypy on the import as it catches (_)ForwardRef as invalid, use for
92+
# introspection is valid:
93+
# https://docs.python.org/3/library/typing.html#typing.ForwardRef
94+
if "ForwardRef" in dir(typing):
95+
return typing.ForwardRef # type: ignore
96+
return typing._ForwardRef # type: ignore

tests/lib/recast_test.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
# pylint: disable=protected-access
22
from typing import Any, Optional, Union
3+
from unittest.mock import patch
34

45
import pytest
56
from cloudformation_cli_python_lib.exceptions import InvalidRequest
67
from cloudformation_cli_python_lib.recast import (
78
_field_to_type,
89
_recast_lists,
910
_recast_primitive,
11+
get_forward_ref_type,
1012
recast_object,
1113
)
1214

@@ -105,3 +107,13 @@ def test_field_to_type_unhandled_types():
105107
with pytest.raises(InvalidRequest) as excinfo:
106108
_field_to_type(field, k, {})
107109
assert str(excinfo.value).startswith("Cannot process type ")
110+
111+
112+
def test_get_forward_ref_type():
113+
with patch("cloudformation_cli_python_lib.recast.typing") as mock_typing:
114+
mock_typing.ForwardRef = "3.7+"
115+
assert get_forward_ref_type() == "3.7+"
116+
with patch("cloudformation_cli_python_lib.recast.typing") as mock_typing:
117+
mock_typing._ForwardRef = "3.6"
118+
get_forward_ref_type()
119+
assert get_forward_ref_type() == "3.6"

0 commit comments

Comments
 (0)