[sdk/python] Add support for Sequence (#5282)
We currently emit array types as `List[T]` for Python, but `List[T]` is invariant, which causes type checkers like mypy to produce errors when values like `["foo", "bar"]` are passed as args typed as `List[pulumi.Input[str]]` (since `Input[str]` is an alias for `Union[T, Awaitable[T], Output[T]]`. To address this, we should move to using [`Sequence[T]`](https://docs.python.org/3/library/typing.html#typing.Sequence) which is covariant, and does not have this problem. We actually already do this for `Dict` vs. `Mapping`, emitting map types as `Mapping[str, T]` rather than `Dict[str, T]` because `Mapping[str, T]` is covariant for the value. This change makes us consistent for array types. These are the SDK changes necessary to support `Sequence[T]`.
This commit is contained in:
parent
6cc095be07
commit
d0ba9fbdcd
|
@ -14,6 +14,9 @@ CHANGELOG
|
|||
- Fix Go SDK plugin acquisition for programs with vendored dependencies
|
||||
[#5286](https://github.com/pulumi/pulumi/pull/5286)
|
||||
|
||||
- Python SDK: Add support for `Sequence[T]` for array types
|
||||
[#5282](https://github.com/pulumi/pulumi/pull/5282)
|
||||
|
||||
## 2.9.2 (2020-08-31)
|
||||
|
||||
- Alpha version of the Automation API for Go
|
||||
|
|
|
@ -17,10 +17,10 @@ out of RPC calls.
|
|||
"""
|
||||
import sys
|
||||
import asyncio
|
||||
import collections
|
||||
from collections import abc
|
||||
import functools
|
||||
import inspect
|
||||
from typing import List, Any, Callable, Dict, Mapping, Optional, Tuple, Union, TYPE_CHECKING, cast, get_type_hints
|
||||
from typing import List, Any, Callable, Dict, Mapping, Optional, Sequence, TYPE_CHECKING, cast
|
||||
|
||||
from google.protobuf import struct_pb2
|
||||
import six
|
||||
|
@ -92,7 +92,9 @@ async def serialize_property(value: 'Input[Any]',
|
|||
Serializes a single Input into a form suitable for remoting to the engine, awaiting
|
||||
any futures required to do so.
|
||||
"""
|
||||
if isinstance(value, list):
|
||||
# Exclude some built-in types that are instances of Sequence that we don't want to treat as sequences here.
|
||||
# From: https://github.com/python/cpython/blob/master/Lib/_collections_abc.py
|
||||
if isinstance(value, abc.Sequence) and not isinstance(value, (tuple, str, range, memoryview, bytes, bytearray)):
|
||||
props = []
|
||||
for elem in value:
|
||||
props.append(await serialize_property(elem, deps, input_transformer))
|
||||
|
@ -125,7 +127,7 @@ async def serialize_property(value: 'Input[Any]',
|
|||
remote_asset = cast('RemoteAsset', value)
|
||||
obj["uri"] = await serialize_property(remote_asset.uri, deps, input_transformer)
|
||||
else:
|
||||
raise AssertionError(f"unknown asset type: {value}")
|
||||
raise AssertionError(f"unknown asset type: {value!r}")
|
||||
|
||||
return obj
|
||||
|
||||
|
@ -147,7 +149,7 @@ async def serialize_property(value: 'Input[Any]',
|
|||
remote_archive = cast('RemoteArchive', value)
|
||||
obj["uri"] = await serialize_property(remote_archive.uri, deps, input_transformer)
|
||||
else:
|
||||
raise AssertionError(f"unknown archive type: {value}")
|
||||
raise AssertionError(f"unknown archive type: {value!r}")
|
||||
|
||||
return obj
|
||||
|
||||
|
@ -194,7 +196,7 @@ async def serialize_property(value: 'Input[Any]',
|
|||
value = _types.input_type_to_dict(value)
|
||||
transform_keys = False
|
||||
|
||||
if isinstance(value, Mapping): # pylint: disable=bad-option-value,isinstance-second-argument-not-valid-type
|
||||
if isinstance(value, abc.Mapping):
|
||||
obj = {}
|
||||
for k, v in value.items():
|
||||
transformed_key = k
|
||||
|
@ -426,7 +428,7 @@ def translate_output_properties(output: Any,
|
|||
# If typ is a dict, get the type for its values, to pass
|
||||
# along for each key.
|
||||
origin = _types.get_origin(typ)
|
||||
if typ is dict or origin in {dict, Dict, Mapping, collections.abc.Mapping}:
|
||||
if typ is dict or origin in {dict, Dict, Mapping, abc.Mapping}:
|
||||
args = _types.get_args(typ)
|
||||
if len(args) == 2 and args[0] is str:
|
||||
get_type = lambda k: args[1]
|
||||
|
@ -456,7 +458,7 @@ def translate_output_properties(output: Any,
|
|||
# If typ is a list, get the type for its values, to pass
|
||||
# along for each item.
|
||||
origin = _types.get_origin(typ)
|
||||
if typ is list or origin in {list, List}:
|
||||
if typ is list or origin in {list, List, Sequence, abc.Sequence}:
|
||||
args = _types.get_args(typ)
|
||||
if len(args) == 1:
|
||||
element_type = args[0]
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
import asyncio
|
||||
import unittest
|
||||
from typing import Any, Optional
|
||||
from typing import Any, Dict, List, Mapping, Optional, Sequence
|
||||
|
||||
from google.protobuf import struct_pb2
|
||||
from pulumi.resource import CustomResource
|
||||
|
@ -274,6 +274,26 @@ class NextSerializationTests(unittest.TestCase):
|
|||
self.assertIsNotNone(error)
|
||||
self.assertEqual("unexpected input of type MyClass", str(error))
|
||||
|
||||
@async_test
|
||||
async def test_string(self):
|
||||
# Ensure strings are serialized as strings (and not sequences).
|
||||
prop = await rpc.serialize_property("hello world", [])
|
||||
self.assertEqual("hello world", prop)
|
||||
|
||||
@async_test
|
||||
async def test_unsupported_sequences(self):
|
||||
cases = [
|
||||
("hi", 42),
|
||||
range(10),
|
||||
memoryview(bytes(10)),
|
||||
bytes(10),
|
||||
bytearray(10),
|
||||
]
|
||||
|
||||
for case in cases:
|
||||
with self.assertRaises(ValueError):
|
||||
await rpc.serialize_property(case, [])
|
||||
|
||||
@async_test
|
||||
async def test_distinguished_unknown_output(self):
|
||||
fut = asyncio.Future()
|
||||
|
@ -530,7 +550,7 @@ class NextSerializationTests(unittest.TestCase):
|
|||
settings.SETTINGS.dry_run = True
|
||||
|
||||
out = self.create_output(0, is_known=False)
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=false, is_secret=True))
|
||||
r = out.apply(lambda v: self.create_output("inner", is_known=False, is_secret=True))
|
||||
|
||||
self.assertFalse(await r.is_known())
|
||||
self.assertFalse(await r.is_secret())
|
||||
|
@ -937,6 +957,23 @@ class FooArgs:
|
|||
pulumi.set(self, "first_arg", first_arg)
|
||||
pulumi.set(self, "second_arg", second_arg)
|
||||
|
||||
@input_type
|
||||
class ListDictInputArgs:
|
||||
a: List[Input[str]]
|
||||
b: Sequence[Input[str]]
|
||||
c: Dict[str, Input[str]]
|
||||
d: Mapping[str, Input[str]]
|
||||
|
||||
def __init__(self,
|
||||
a: List[Input[str]],
|
||||
b: Sequence[Input[str]],
|
||||
c: Dict[str, Input[str]],
|
||||
d: Mapping[str, Input[str]]):
|
||||
pulumi.set(self, "a", a)
|
||||
pulumi.set(self, "b", b)
|
||||
pulumi.set(self, "c", c)
|
||||
pulumi.set(self, "d", d)
|
||||
|
||||
|
||||
@input_type
|
||||
class BarArgs:
|
||||
|
@ -951,7 +988,18 @@ class InputTypeSerializationTests(unittest.TestCase):
|
|||
async def test_simple_input_type(self):
|
||||
it = FooArgs(first_arg="hello", second_arg=42)
|
||||
prop = await rpc.serialize_property(it, [])
|
||||
self.assertDictEqual(prop, {"firstArg": "hello", "secondArg": 42})
|
||||
self.assertEqual({"firstArg": "hello", "secondArg": 42}, prop)
|
||||
|
||||
@async_test
|
||||
async def test_list_dict_input_type(self):
|
||||
it = ListDictInputArgs(a=["hi"], b=["there"], c={"hello": "world"}, d={"foo": "bar"})
|
||||
prop = await rpc.serialize_property(it, [])
|
||||
self.assertEqual({
|
||||
"a": ["hi"],
|
||||
"b": ["there"],
|
||||
"c": {"hello": "world"},
|
||||
"d": {"foo": "bar"}
|
||||
}, prop)
|
||||
|
||||
@async_test
|
||||
async def test_input_type_with_dict_property(self):
|
||||
|
@ -964,11 +1012,11 @@ class InputTypeSerializationTests(unittest.TestCase):
|
|||
|
||||
it = BarArgs({"foo_bar": "hello", "foo_baz": "world"})
|
||||
prop = await rpc.serialize_property(it, [], transformer)
|
||||
# Input type keys are not be transformed, but keys of nested
|
||||
# Input type keys are not transformed, but keys of nested
|
||||
# dicts are still transformed.
|
||||
self.assertDictEqual(prop, {
|
||||
self.assertEqual({
|
||||
"tagArgs": {
|
||||
"c": "hello",
|
||||
"foo_baz": "world",
|
||||
},
|
||||
})
|
||||
}, prop)
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
import unittest
|
||||
from typing import Any, Dict, List, Mapping, Optional
|
||||
from typing import Any, Dict, List, Mapping, Optional, Sequence
|
||||
|
||||
from pulumi.runtime import rpc
|
||||
import pulumi
|
||||
|
@ -65,6 +65,34 @@ class Bar(dict):
|
|||
return camel_case_to_snake_case.get(prop) or prop
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class BarMappingSequence(dict):
|
||||
third_arg: Foo = pulumi.property("thirdArg")
|
||||
third_optional_arg: Optional[Foo] = pulumi.property("thirdOptionalArg")
|
||||
|
||||
fourth_arg: Mapping[str, Foo] = pulumi.property("fourthArg")
|
||||
fourth_optional_arg: Mapping[str, Optional[Foo]] = pulumi.property("fourthOptionalArg")
|
||||
|
||||
fifth_arg: Sequence[Foo] = pulumi.property("fifthArg")
|
||||
fifth_optional_arg: Sequence[Optional[Foo]] = pulumi.property("fifthOptionalArg")
|
||||
|
||||
sixth_arg: Mapping[str, Sequence[Foo]] = pulumi.property("sixthArg")
|
||||
sixth_optional_arg: Mapping[str, Optional[Sequence[Foo]]] = pulumi.property("sixthOptionalArg")
|
||||
sixth_optional_optional_arg: Mapping[str, Optional[Sequence[Optional[Foo]]]] = pulumi.property("sixthOptionalOptionalArg")
|
||||
|
||||
seventh_arg: Sequence[Mapping[str, Foo]] = pulumi.property("seventhArg")
|
||||
seventh_optional_arg: Sequence[Optional[Mapping[str, Foo]]] = pulumi.property("seventhOptionalArg")
|
||||
seventh_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Foo]]]] = pulumi.property("seventhOptionalOptionalArg")
|
||||
|
||||
eighth_arg: Sequence[Mapping[str, Sequence[Foo]]] = pulumi.property("eighthArg")
|
||||
eighth_optional_arg: Sequence[Optional[Mapping[str, Sequence[Foo]]]] = pulumi.property("eighthOptionalArg")
|
||||
eighth_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Sequence[Foo]]]]] = pulumi.property("eighthOptionalOptionalArg")
|
||||
eighth_optional_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Sequence[Optional[Foo]]]]]] = pulumi.property("eighthOptionalOptionalOptionalArg")
|
||||
|
||||
def _translate_property(self, prop: str) -> str:
|
||||
return camel_case_to_snake_case.get(prop) or prop
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class BarDeclared(dict):
|
||||
def __init__(self,
|
||||
|
@ -185,6 +213,126 @@ class BarDeclared(dict):
|
|||
return camel_case_to_snake_case.get(prop) or prop
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class BarMappingSequenceDeclared(dict):
|
||||
def __init__(self,
|
||||
third_arg: Foo,
|
||||
third_optional_arg: Optional[Foo],
|
||||
fourth_arg: Mapping[str, Foo],
|
||||
fourth_optional_arg: Dict[str, Optional[Foo]],
|
||||
fifth_arg: Sequence[Foo],
|
||||
fifth_optional_arg: Sequence[Optional[Foo]],
|
||||
sixth_arg: Mapping[str, Sequence[Foo]],
|
||||
sixth_optional_arg: Mapping[str, Optional[Sequence[Foo]]],
|
||||
sixth_optional_optional_arg: Mapping[str, Optional[Sequence[Optional[Foo]]]],
|
||||
seventh_arg: Sequence[Mapping[str, Foo]],
|
||||
seventh_optional_arg: Sequence[Optional[Mapping[str, Foo]]],
|
||||
seventh_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Foo]]]],
|
||||
eighth_arg: Sequence[Mapping[str, Sequence[Foo]]],
|
||||
eighth_optional_arg: Sequence[Optional[Mapping[str, Sequence[Foo]]]],
|
||||
eighth_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Sequence[Foo]]]]],
|
||||
eighth_optional_optional_optional_arg: Sequence[Optional[Mapping[str, Optional[Sequence[Optional[Foo]]]]]]):
|
||||
pulumi.set(self, "third_arg", third_arg)
|
||||
pulumi.set(self, "third_optional_arg", third_optional_arg)
|
||||
pulumi.set(self, "fourth_arg", fourth_arg)
|
||||
pulumi.set(self, "fourth_optional_arg", fourth_optional_arg)
|
||||
pulumi.set(self, "fifth_arg", fifth_arg)
|
||||
pulumi.set(self, "fifth_optional_arg", fifth_optional_arg)
|
||||
pulumi.set(self, "sixth_arg", sixth_arg)
|
||||
pulumi.set(self, "sixth_optional_arg", sixth_optional_arg)
|
||||
pulumi.set(self, "sixth_optional_optional_arg", sixth_optional_optional_arg)
|
||||
pulumi.set(self, "seventh_arg", seventh_arg)
|
||||
pulumi.set(self, "seventh_optional_arg", seventh_optional_arg)
|
||||
pulumi.set(self, "seventh_optional_optional_arg", seventh_optional_optional_arg)
|
||||
pulumi.set(self, "eighth_arg", eighth_arg)
|
||||
pulumi.set(self, "eighth_optional_arg", eighth_optional_arg)
|
||||
pulumi.set(self, "eighth_optional_optional_arg", eighth_optional_optional_arg)
|
||||
pulumi.set(self, "eighth_optional_optional_optional_arg", eighth_optional_optional_optional_arg)
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="thirdArg")
|
||||
def third_arg(self) -> Foo:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="thirdOptionalArg")
|
||||
def third_optional_arg(self) -> Optional[Foo]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="fourthArg")
|
||||
def fourth_arg(self) -> Mapping[str, Foo]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="fourthOptionalArg")
|
||||
def fourth_optional_arg(self) -> Mapping[str, Optional[Foo]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="fifthArg")
|
||||
def fifth_arg(self) -> Sequence[Foo]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="fifthOptionalArg")
|
||||
def fifth_optional_arg(self) -> Sequence[Optional[Foo]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="sixthArg")
|
||||
def sixth_arg(self) -> Mapping[str, Sequence[Foo]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="sixthOptionalArg")
|
||||
def sixth_optional_arg(self) -> Mapping[str, Optional[Sequence[Foo]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="sixthOptionalOptionalArg")
|
||||
def sixth_optional_optional_arg(self) -> Mapping[str, Optional[Sequence[Optional[Foo]]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="seventhArg")
|
||||
def seventh_arg(self) -> Sequence[Mapping[str, Foo]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="seventhOptionalArg")
|
||||
def seventh_optional_arg(self) -> Sequence[Optional[Mapping[str, Foo]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="seventhOptionalOptionalArg")
|
||||
def seventh_optional_optional_arg(self) -> Sequence[Optional[Mapping[str, Optional[Foo]]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="eighthArg")
|
||||
def eighth_arg(self) -> Sequence[Mapping[str, Sequence[Foo]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="eighthOptionalArg")
|
||||
def eighth_optional_arg(self) -> Sequence[Optional[Mapping[str, Sequence[Foo]]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="eighthOptionalOptionalArg")
|
||||
def eighth_optional_optional_arg(self) -> Sequence[Optional[Mapping[str, Optional[Sequence[Foo]]]]]:
|
||||
...
|
||||
|
||||
@property
|
||||
@pulumi.getter(name="eighthOptionalOptionalOptionalArg")
|
||||
def eighth_optional_optional_optional_arg(self) -> Sequence[Optional[Mapping[str, Optional[Sequence[Optional[Foo]]]]]]:
|
||||
...
|
||||
|
||||
def _translate_property(self, prop: str) -> str:
|
||||
return camel_case_to_snake_case.get(prop) or prop
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeStr(dict):
|
||||
value: str = pulumi.property("value")
|
||||
|
@ -217,6 +365,10 @@ class InvalidTypeDeclaredOptionalStr(dict):
|
|||
class InvalidTypeDictStr(dict):
|
||||
value: Dict[str, str] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeMappingStr(dict):
|
||||
value: Mapping[str, str] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredDictStr(dict):
|
||||
def __init__(self, value: Dict[str, str]):
|
||||
|
@ -227,10 +379,24 @@ class InvalidTypeDeclaredDictStr(dict):
|
|||
def value(self) -> Dict[str, str]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredMappingStr(dict):
|
||||
def __init__(self, value: Mapping[str, str]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Mapping[str, str]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalDictStr(dict):
|
||||
value: Optional[Dict[str, str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalMappingStr(dict):
|
||||
value: Optional[Mapping[str, str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalDictStr(dict):
|
||||
def __init__(self, value: Optional[Dict[str, str]]):
|
||||
|
@ -241,10 +407,24 @@ class InvalidTypeDeclaredOptionalDictStr(dict):
|
|||
def value(self) -> Optional[Dict[str, str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalMappingStr(dict):
|
||||
def __init__(self, value: Optional[Mapping[str, str]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Optional[Mapping[str, str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDictOptionalStr(dict):
|
||||
value: Dict[str, Optional[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeMappingOptionalStr(dict):
|
||||
value: Mapping[str, Optional[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredDictOptionalStr(dict):
|
||||
def __init__(self, value: Dict[str, Optional[str]]):
|
||||
|
@ -255,10 +435,24 @@ class InvalidTypeDeclaredDictOptionalStr(dict):
|
|||
def value(self) -> Dict[str, Optional[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredMappingOptionalStr(dict):
|
||||
def __init__(self, value: Mapping[str, Optional[str]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Mapping[str, Optional[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalDictOptionalStr(dict):
|
||||
value: Optional[Dict[str, Optional[str]]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalMappingOptionalStr(dict):
|
||||
value: Optional[Mapping[str, Optional[str]]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalDictOptionalStr(dict):
|
||||
def __init__(self, value: Optional[Dict[str, Optional[str]]]):
|
||||
|
@ -269,10 +463,25 @@ class InvalidTypeDeclaredOptionalDictOptionalStr(dict):
|
|||
def value(self) -> Optional[Dict[str, Optional[str]]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalMappingOptionalStr(dict):
|
||||
def __init__(self, value: Optional[Mapping[str, Optional[str]]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Optional[Mapping[str, Optional[str]]]:
|
||||
...
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeListStr(dict):
|
||||
value: List[str] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeSequenceStr(dict):
|
||||
value: Sequence[str] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredListStr(dict):
|
||||
def __init__(self, value: List[str]):
|
||||
|
@ -283,10 +492,24 @@ class InvalidTypeDeclaredListStr(dict):
|
|||
def value(self) -> List[str]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredSequenceStr(dict):
|
||||
def __init__(self, value: Sequence[str]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Sequence[str]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalListStr(dict):
|
||||
value: Optional[List[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalSequenceStr(dict):
|
||||
value: Optional[Sequence[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalListStr(dict):
|
||||
def __init__(self, value: Optional[List[str]]):
|
||||
|
@ -297,10 +520,24 @@ class InvalidTypeDeclaredOptionalListStr(dict):
|
|||
def value(self) -> Optional[List[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalSequenceStr(dict):
|
||||
def __init__(self, value: Optional[Sequence[str]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Optional[Sequence[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeListOptionalStr(dict):
|
||||
value: List[Optional[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeSequenceOptionalStr(dict):
|
||||
value: Sequence[Optional[str]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredListOptionalStr(dict):
|
||||
def __init__(self, value: List[Optional[str]]):
|
||||
|
@ -311,10 +548,24 @@ class InvalidTypeDeclaredListOptionalStr(dict):
|
|||
def value(self) -> List[Optional[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredSequenceOptionalStr(dict):
|
||||
def __init__(self, value: Sequence[Optional[str]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Sequence[Optional[str]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalListOptionalStr(dict):
|
||||
value: Optional[List[Optional[str]]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeOptionalSequenceOptionalStr(dict):
|
||||
value: Optional[Sequence[Optional[str]]] = pulumi.property("value")
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalListOptionalStr(dict):
|
||||
def __init__(self, value: Optional[List[Optional[str]]]):
|
||||
|
@ -325,13 +576,25 @@ class InvalidTypeDeclaredOptionalListOptionalStr(dict):
|
|||
def value(self) -> Optional[List[Optional[str]]]:
|
||||
...
|
||||
|
||||
@pulumi.output_type
|
||||
class InvalidTypeDeclaredOptionalSequenceOptionalStr(dict):
|
||||
def __init__(self, value: Optional[Sequence[Optional[str]]]):
|
||||
pulumi.set(self, "value", value)
|
||||
|
||||
@property
|
||||
@pulumi.getter
|
||||
def value(self) -> Optional[Sequence[Optional[str]]]:
|
||||
...
|
||||
|
||||
|
||||
@pulumi.output_type
|
||||
class OutputTypeWithAny(dict):
|
||||
value_dict: Any
|
||||
value_list: Any
|
||||
value_dict_dict: Mapping[str, Any]
|
||||
value_dict_dict: Dict[str, Any]
|
||||
value_dict_mapping: Mapping[str, Any]
|
||||
value_list_list: List[Any]
|
||||
value_list_sequence: Sequence[Any]
|
||||
value_str: Any
|
||||
|
||||
|
||||
|
@ -492,7 +755,7 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
self.assertIs(result.eighth_optional_optional_optional_arg, result["eighthOptionalOptionalOptionalArg"])
|
||||
assertFoo(result.eighth_optional_optional_optional_arg[0]["blah"][0], "farewell-opt-opt-opt", 11137)
|
||||
|
||||
for typ in [Bar, BarDeclared]:
|
||||
for typ in [Bar, BarMappingSequence, BarDeclared, BarMappingSequenceDeclared]:
|
||||
run_test(output)
|
||||
run_test(convert_properties_to_secrets(output))
|
||||
|
||||
|
@ -522,6 +785,14 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
(InvalidTypeDeclaredDictOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeOptionalDictOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeDeclaredOptionalDictOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeMappingStr, {"foo": dict_value}),
|
||||
(InvalidTypeDeclaredMappingStr, {"foo": dict_value}),
|
||||
(InvalidTypeOptionalMappingStr, {"foo": dict_value}),
|
||||
(InvalidTypeDeclaredOptionalMappingStr, {"foo": dict_value}),
|
||||
(InvalidTypeMappingOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeDeclaredMappingOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeOptionalMappingOptionalStr, {"foo": dict_value}),
|
||||
(InvalidTypeDeclaredOptionalMappingOptionalStr, {"foo": dict_value}),
|
||||
|
||||
(InvalidTypeDictStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredDictStr, {"foo": list_value}),
|
||||
|
@ -531,6 +802,14 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
(InvalidTypeDeclaredDictOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeOptionalDictOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredOptionalDictOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeMappingStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredMappingStr, {"foo": list_value}),
|
||||
(InvalidTypeOptionalMappingStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredOptionalMappingStr, {"foo": list_value}),
|
||||
(InvalidTypeMappingOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredMappingOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeOptionalMappingOptionalStr, {"foo": list_value}),
|
||||
(InvalidTypeDeclaredOptionalMappingOptionalStr, {"foo": list_value}),
|
||||
|
||||
(InvalidTypeListStr, [dict_value]),
|
||||
(InvalidTypeDeclaredListStr, [dict_value]),
|
||||
|
@ -540,6 +819,14 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
(InvalidTypeDeclaredListOptionalStr, [dict_value]),
|
||||
(InvalidTypeOptionalListOptionalStr, [dict_value]),
|
||||
(InvalidTypeDeclaredOptionalListOptionalStr, [dict_value]),
|
||||
(InvalidTypeSequenceStr, [dict_value]),
|
||||
(InvalidTypeDeclaredSequenceStr, [dict_value]),
|
||||
(InvalidTypeOptionalSequenceStr, [dict_value]),
|
||||
(InvalidTypeDeclaredOptionalSequenceStr, [dict_value]),
|
||||
(InvalidTypeSequenceOptionalStr, [dict_value]),
|
||||
(InvalidTypeDeclaredSequenceOptionalStr, [dict_value]),
|
||||
(InvalidTypeOptionalSequenceOptionalStr, [dict_value]),
|
||||
(InvalidTypeDeclaredOptionalSequenceOptionalStr, [dict_value]),
|
||||
|
||||
(InvalidTypeListStr, [list_value]),
|
||||
(InvalidTypeDeclaredListStr, [list_value]),
|
||||
|
@ -549,6 +836,14 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
(InvalidTypeDeclaredListOptionalStr, [list_value]),
|
||||
(InvalidTypeOptionalListOptionalStr, [list_value]),
|
||||
(InvalidTypeDeclaredOptionalListOptionalStr, [list_value]),
|
||||
(InvalidTypeSequenceStr, [list_value]),
|
||||
(InvalidTypeDeclaredSequenceStr, [list_value]),
|
||||
(InvalidTypeOptionalSequenceStr, [list_value]),
|
||||
(InvalidTypeDeclaredOptionalSequenceStr, [list_value]),
|
||||
(InvalidTypeSequenceOptionalStr, [list_value]),
|
||||
(InvalidTypeDeclaredSequenceOptionalStr, [list_value]),
|
||||
(InvalidTypeOptionalSequenceOptionalStr, [list_value]),
|
||||
(InvalidTypeDeclaredOptionalSequenceOptionalStr, [list_value]),
|
||||
]
|
||||
|
||||
for typ, value in tests:
|
||||
|
@ -565,7 +860,9 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
"value_dict": {"hello": "world"},
|
||||
"value_list": ["hello"],
|
||||
"value_dict_dict": {"value": {"hello": "world"}},
|
||||
"value_dict_mapping": {"value": {"hello": "world"}},
|
||||
"value_list_list": [["hello"]],
|
||||
"value_list_sequence": [["hello"]],
|
||||
"value_str": "hello",
|
||||
}
|
||||
result = rpc.translate_output_properties(output, translate_output_property, OutputTypeWithAny)
|
||||
|
@ -573,5 +870,7 @@ class TranslateOutputPropertiesTests(unittest.TestCase):
|
|||
self.assertEqual({"hello": "world"}, result.value_dict)
|
||||
self.assertEqual(["hello"], result.value_list)
|
||||
self.assertEqual({"value": {"hello": "world"}}, result.value_dict_dict)
|
||||
self.assertEqual({"value": {"hello": "world"}}, result.value_dict_mapping)
|
||||
self.assertEqual([["hello"]], result.value_list_list)
|
||||
self.assertEqual([["hello"]], result.value_list_sequence)
|
||||
self.assertEqual("hello", result.value_str)
|
||||
|
|
Loading…
Reference in a new issue