# Copyright 2016-2020, Pulumi Corporation. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import unittest from enum import Enum from typing import Any, Dict, List, NamedTuple, Mapping, Optional, Sequence from pulumi.runtime import rpc import pulumi camel_case_to_snake_case = { "firstArg": "first_arg", "secondArg": "second_arg", } def translate_output_property(prop: str) -> str: return camel_case_to_snake_case.get(prop) or prop @pulumi.output_type class Foo(dict): first_arg: str = pulumi.property("firstArg") second_arg: float = pulumi.property("secondArg") def _translate_property(self, prop: str) -> str: return camel_case_to_snake_case.get(prop) or prop @pulumi.output_type class Bar(dict): third_arg: Foo = pulumi.property("thirdArg") third_optional_arg: Optional[Foo] = pulumi.property("thirdOptionalArg") fourth_arg: Dict[str, Foo] = pulumi.property("fourthArg") fourth_optional_arg: Dict[str, Optional[Foo]] = pulumi.property("fourthOptionalArg") fifth_arg: List[Foo] = pulumi.property("fifthArg") fifth_optional_arg: List[Optional[Foo]] = pulumi.property("fifthOptionalArg") sixth_arg: Dict[str, List[Foo]] = pulumi.property("sixthArg") sixth_optional_arg: Dict[str, Optional[List[Foo]]] = pulumi.property("sixthOptionalArg") sixth_optional_optional_arg: Dict[str, Optional[List[Optional[Foo]]]] = pulumi.property("sixthOptionalOptionalArg") seventh_arg: List[Dict[str, Foo]] = pulumi.property("seventhArg") seventh_optional_arg: List[Optional[Dict[str, Foo]]] = pulumi.property("seventhOptionalArg") seventh_optional_optional_arg: List[Optional[Dict[str, Optional[Foo]]]] = pulumi.property("seventhOptionalOptionalArg") eighth_arg: List[Dict[str, List[Foo]]] = pulumi.property("eighthArg") eighth_optional_arg: List[Optional[Dict[str, List[Foo]]]] = pulumi.property("eighthOptionalArg") eighth_optional_optional_arg: List[Optional[Dict[str, Optional[List[Foo]]]]] = pulumi.property("eighthOptionalOptionalArg") eighth_optional_optional_optional_arg: List[Optional[Dict[str, Optional[List[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 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, third_arg: Foo, third_optional_arg: Optional[Foo], fourth_arg: Dict[str, Foo], fourth_optional_arg: Dict[str, Optional[Foo]], fifth_arg: List[Foo], fifth_optional_arg: List[Optional[Foo]], sixth_arg: Dict[str, List[Foo]], sixth_optional_arg: Dict[str, Optional[List[Foo]]], sixth_optional_optional_arg: Dict[str, Optional[List[Optional[Foo]]]], seventh_arg: List[Dict[str, Foo]], seventh_optional_arg: List[Optional[Dict[str, Foo]]], seventh_optional_optional_arg: List[Optional[Dict[str, Optional[Foo]]]], eighth_arg: List[Dict[str, List[Foo]]], eighth_optional_arg: List[Optional[Dict[str, List[Foo]]]], eighth_optional_optional_arg: List[Optional[Dict[str, Optional[List[Foo]]]]], eighth_optional_optional_optional_arg: List[Optional[Dict[str, Optional[List[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) -> Dict[str, Foo]: ... @property @pulumi.getter(name="fourthOptionalArg") def fourth_optional_arg(self) -> Dict[str, Optional[Foo]]: ... @property @pulumi.getter(name="fifthArg") def fifth_arg(self) -> List[Foo]: ... @property @pulumi.getter(name="fifthOptionalArg") def fifth_optional_arg(self) -> List[Optional[Foo]]: ... @property @pulumi.getter(name="sixthArg") def sixth_arg(self) -> Dict[str, List[Foo]]: ... @property @pulumi.getter(name="sixthOptionalArg") def sixth_optional_arg(self) -> Dict[str, Optional[List[Foo]]]: ... @property @pulumi.getter(name="sixthOptionalOptionalArg") def sixth_optional_optional_arg(self) -> Dict[str, Optional[List[Optional[Foo]]]]: ... @property @pulumi.getter(name="seventhArg") def seventh_arg(self) -> List[Dict[str, Foo]]: ... @property @pulumi.getter(name="seventhOptionalArg") def seventh_optional_arg(self) -> List[Optional[Dict[str, Foo]]]: ... @property @pulumi.getter(name="seventhOptionalOptionalArg") def seventh_optional_optional_arg(self) -> List[Optional[Dict[str, Optional[Foo]]]]: ... @property @pulumi.getter(name="eighthArg") def eighth_arg(self) -> List[Dict[str, List[Foo]]]: ... @property @pulumi.getter(name="eighthOptionalArg") def eighth_optional_arg(self) -> List[Optional[Dict[str, List[Foo]]]]: ... @property @pulumi.getter(name="eighthOptionalOptionalArg") def eighth_optional_optional_arg(self) -> List[Optional[Dict[str, Optional[List[Foo]]]]]: ... @property @pulumi.getter(name="eighthOptionalOptionalOptionalArg") def eighth_optional_optional_optional_arg(self) -> List[Optional[Dict[str, Optional[List[Optional[Foo]]]]]]: ... def _translate_property(self, prop: str) -> str: 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") @pulumi.output_type class InvalidTypeDeclaredStr(dict): def __init__(self, value: str): pulumi.set(self, "value", value) @property @pulumi.getter def value(self) -> str: ... @pulumi.output_type class InvalidTypeOptionalStr(dict): value: Optional[str] = pulumi.property("value") @pulumi.output_type class InvalidTypeDeclaredOptionalStr(dict): def __init__(self, value: Optional[str]): pulumi.set(self, "value", value) @property @pulumi.getter def value(self) -> Optional[str]: ... @pulumi.output_type 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]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]]): pulumi.set(self, "value", value) @property @pulumi.getter 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]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]): pulumi.set(self, "value", value) @property @pulumi.getter 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]]]): pulumi.set(self, "value", value) @property @pulumi.getter 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: Dict[str, Any] value_dict_mapping: Mapping[str, Any] value_list_list: List[Any] value_list_sequence: Sequence[Any] value_str: Any class ContainerColor(str, Enum): RED = "red" BLUE = "blue" class ContainerSize(int, Enum): FOUR_INCH = 4 SIX_INCH = 6 class ContainerBrightness(float, Enum): ZERO_POINT_ONE = 0.1 ONE_POINT_ZERO = 1.0 class TranslateOutputPropertiesTests(unittest.TestCase): def test_str_enum(self): result = rpc.translate_output_properties("red", translate_output_property, ContainerColor) self.assertIsInstance(result, ContainerColor) self.assertIsInstance(result, Enum) self.assertEqual(result, "red") self.assertEqual(result, ContainerColor.RED) def test_int_enum(self): result = rpc.translate_output_properties(4, translate_output_property, ContainerSize) self.assertIsInstance(result, ContainerSize) self.assertIsInstance(result, Enum) self.assertEqual(result, 4) self.assertEqual(result, ContainerSize.FOUR_INCH) def test_float_enum(self): result = rpc.translate_output_properties(0.1, translate_output_property, ContainerBrightness) self.assertIsInstance(result, ContainerBrightness) self.assertIsInstance(result, Enum) self.assertEqual(result, 0.1) self.assertEqual(result, ContainerBrightness.ZERO_POINT_ONE) def test_translate(self): output = { "firstArg": "hello", "secondArg": 42, } result = rpc.translate_output_properties(output, translate_output_property, Foo) self.assertIsInstance(result, Foo) self.assertEqual(result.first_arg, "hello") self.assertEqual(result["first_arg"], "hello") self.assertEqual(result.second_arg, 42) self.assertEqual(result["second_arg"], 42) def test_nested_types(self): def assertFoo(val, first_arg, second_arg): self.assertIsInstance(val, Foo) self.assertEqual(val.first_arg, first_arg) self.assertEqual(val["first_arg"], first_arg) self.assertEqual(val.second_arg, second_arg) self.assertEqual(val["second_arg"], second_arg) output = { "thirdArg": { "firstArg": "hello", "secondArg": 42, }, "thirdOptionalArg": { "firstArg": "hello-opt", "secondArg": 142, }, "fourthArg": { "foo": { "firstArg": "hi", "secondArg": 41, }, }, "fourthOptionalArg": { "foo": { "firstArg": "hi-opt", "secondArg": 141, }, }, "fifthArg": [{ "firstArg": "bye", "secondArg": 40, }], "fifthOptionalArg": [{ "firstArg": "bye-opt", "secondArg": 140, }], "sixthArg": { "bar": [{ "firstArg": "goodbye", "secondArg": 39, }], }, "sixthOptionalArg": { "bar": [{ "firstArg": "goodbye-opt", "secondArg": 139, }], }, "sixthOptionalOptionalArg": { "bar": [{ "firstArg": "goodbye-opt-opt", "secondArg": 1139, }], }, "seventhArg": [{ "baz": { "firstArg": "adios", "secondArg": 38, }, }], "seventhOptionalArg": [{ "baz": { "firstArg": "adios-opt", "secondArg": 138, }, }], "seventhOptionalOptionalArg": [{ "baz": { "firstArg": "adios-opt-opt", "secondArg": 1138, }, }], "eighthArg": [{ "blah": [{ "firstArg": "farewell", "secondArg": 37, }], }], "eighthOptionalArg": [{ "blah": [{ "firstArg": "farewell-opt", "secondArg": 137, }], }], "eighthOptionalOptionalArg": [{ "blah": [{ "firstArg": "farewell-opt-opt", "secondArg": 1137, }], }], "eighthOptionalOptionalOptionalArg": [{ "blah": [{ "firstArg": "farewell-opt-opt-opt", "secondArg": 11137, }], }], } for typ in [Bar, BarMappingSequence, BarDeclared, BarMappingSequenceDeclared]: result = rpc.translate_output_properties(output, translate_output_property, typ) self.assertIsInstance(result, typ) self.assertIs(result.third_arg, result["thirdArg"]) assertFoo(result.third_arg, "hello", 42) self.assertIs(result.third_optional_arg, result["thirdOptionalArg"]) assertFoo(result.third_optional_arg, "hello-opt", 142) self.assertIs(result.fourth_arg, result["fourthArg"]) assertFoo(result.fourth_arg["foo"], "hi", 41) self.assertIs(result.fourth_optional_arg, result["fourthOptionalArg"]) assertFoo(result.fourth_optional_arg["foo"], "hi-opt", 141) self.assertIs(result.fifth_arg, result["fifthArg"]) assertFoo(result.fifth_arg[0], "bye", 40) self.assertIs(result.fifth_optional_arg, result["fifthOptionalArg"]) assertFoo(result.fifth_optional_arg[0], "bye-opt", 140) self.assertIs(result.sixth_arg, result["sixthArg"]) assertFoo(result.sixth_arg["bar"][0], "goodbye", 39) self.assertIs(result.sixth_optional_arg, result["sixthOptionalArg"]) assertFoo(result.sixth_optional_arg["bar"][0], "goodbye-opt", 139) self.assertIs(result.sixth_optional_optional_arg, result["sixthOptionalOptionalArg"]) assertFoo(result.sixth_optional_optional_arg["bar"][0], "goodbye-opt-opt", 1139) self.assertIs(result.seventh_arg, result["seventhArg"]) assertFoo(result.seventh_arg[0]["baz"], "adios", 38) self.assertIs(result.seventh_optional_arg, result["seventhOptionalArg"]) assertFoo(result.seventh_optional_arg[0]["baz"], "adios-opt", 138) self.assertIs(result.seventh_optional_optional_arg, result["seventhOptionalOptionalArg"]) assertFoo(result.seventh_optional_optional_arg[0]["baz"], "adios-opt-opt", 1138) self.assertIs(result.eighth_arg, result["eighthArg"]) assertFoo(result.eighth_arg[0]["blah"][0], "farewell", 37) self.assertIs(result.eighth_optional_arg, result["eighthOptionalArg"]) assertFoo(result.eighth_optional_arg[0]["blah"][0], "farewell-opt", 137) self.assertIs(result.eighth_optional_optional_arg, result["eighthOptionalOptionalArg"]) assertFoo(result.eighth_optional_optional_arg[0]["blah"][0], "farewell-opt-opt", 1137) 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) def test_nested_types_raises(self): dict_value = { "firstArg": "hello", "secondArg": 42, } list_value = ["hello"] tests = [ (InvalidTypeStr, dict_value), (InvalidTypeDeclaredStr, dict_value), (InvalidTypeOptionalStr, dict_value), (InvalidTypeDeclaredOptionalStr, dict_value), (InvalidTypeStr, list_value), (InvalidTypeDeclaredStr, list_value), (InvalidTypeOptionalStr, list_value), (InvalidTypeDeclaredOptionalStr, list_value), (InvalidTypeDictStr, {"foo": dict_value}), (InvalidTypeDeclaredDictStr, {"foo": dict_value}), (InvalidTypeOptionalDictStr, {"foo": dict_value}), (InvalidTypeDeclaredOptionalDictStr, {"foo": dict_value}), (InvalidTypeDictOptionalStr, {"foo": dict_value}), (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}), (InvalidTypeOptionalDictStr, {"foo": list_value}), (InvalidTypeDeclaredOptionalDictStr, {"foo": list_value}), (InvalidTypeDictOptionalStr, {"foo": list_value}), (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]), (InvalidTypeOptionalListStr, [dict_value]), (InvalidTypeDeclaredOptionalListStr, [dict_value]), (InvalidTypeListOptionalStr, [dict_value]), (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]), (InvalidTypeOptionalListStr, [list_value]), (InvalidTypeDeclaredOptionalListStr, [list_value]), (InvalidTypeListOptionalStr, [list_value]), (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: outputs = [ {"value": value}, {"value": {rpc._special_sig_key: rpc._special_secret_sig, "value": value}}, ] for output in outputs: with self.assertRaises(AssertionError): rpc.translate_output_properties(output, translate_output_property, typ) def test_any(self): output = { "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) self.assertIsInstance(result, OutputTypeWithAny) 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) def test_int(self): @pulumi.output_type class OutputTypeWithInt(dict): value_dict: Dict[str, int] value_mapping: Mapping[str, int] value_list: List[int] value_sequence: Sequence[int] value_int: int output = { "value_dict": {"hello": 42.0}, "value_mapping": {"world": 100.0}, "value_list": [42.0], "value_sequence": [100.0], "value_int": 50.0, } result = rpc.translate_output_properties(output, translate_output_property, OutputTypeWithInt) self.assertIsInstance(result, OutputTypeWithInt) self.assertEqual({"hello": 42}, result.value_dict) self.assertIsInstance(result.value_dict["hello"], int) self.assertEqual({"world": 100}, result.value_mapping) self.assertIsInstance(result.value_mapping["world"], int) self.assertEqual([42], result.value_list) self.assertIsInstance(result.value_list[0], int) self.assertEqual([100], result.value_sequence) self.assertIsInstance(result.value_sequence[0], int) self.assertEqual(50, result.value_int) self.assertIsInstance(result.value_int, int) def test_individual_values(self): @pulumi.output_type class MyOutput: first_arg: str = pulumi.property("firstArg") second_arg: int = pulumi.property("secondArg") def __init__(self, first_arg: str, second_arg: int): pulumi.set(self, "first_arg", first_arg) pulumi.set(self, "second_arg", second_arg) def _translate_property(self, prop: str) -> str: return camel_case_to_snake_case.get(prop) or prop class TestCase(NamedTuple): output: Any typ: type expected: Any testcases = [ TestCase( { "firstArg": "hello", "secondArg": 42, }, MyOutput, MyOutput("hello", 42), ), TestCase( { "foo": { "firstArg": "hi", "secondArg": 41, }, }, Mapping[str, MyOutput], { "foo": MyOutput("hi", 41), }, ), TestCase( [{ "firstArg": "bye", "secondArg": 40, }], Sequence[MyOutput], [MyOutput("bye", 40)], ), TestCase( { "bar": [{ "firstArg": "goodbye", "secondArg": 39, }], }, Mapping[str, Sequence[MyOutput]], { "bar": [MyOutput("goodbye", 39)], } ), TestCase( [{ "baz": { "firstArg": "adios", "secondArg": 38, }, }], Sequence[Mapping[str, MyOutput]], [{ "baz": MyOutput("adios", 38), }] ), TestCase( [{ "blah": [{ "firstArg": "farewell", "secondArg": 37, }], }], Sequence[Mapping[str, Sequence[MyOutput]]], [{ "blah": [MyOutput("farewell", 37)], }], ), ] for case in testcases: actual = rpc.translate_output_properties(case.output, translate_output_property, case.typ) self.assertEqual(case.expected, actual) for case in testcases: wrapped_output = {rpc._special_sig_key: rpc._special_secret_sig, "value": case.output} actual = rpc.translate_output_properties(wrapped_output, translate_output_property, case.typ) wrapped_expected = {rpc._special_sig_key: rpc. _special_secret_sig, "value": case.expected} self.assertEqual(wrapped_expected, actual)