pulumi/sdk/python/lib/test/test_types_input_type_types.py
Justin Van Patten 1112c513c0 [sdk/python] Improved dict key translation support (#6695)
This change addresses Python dictionary key translation issues. When the
type of `props` passed to the resource is decorated with `@input_type`,
the type's and resource's property name metadata will be used for dict
key translations instead of the resource's `translate_input_property`
and `translate_output_property` methods.

The generated provider SDKs will be updated to opt-in to this new
behavior:

- FIX: Keys in user-defined dicts will no longer be unintentionally
  translated/modified.

- BREAKING: Dictionary keys in nested output classes are now
  consistently snake_case. If accessing camelCase keys from such output
  classes, move to accessing the values via the snake_case property
  getters (or snake_case keys). Generated SDKs will log a warning
  when accessing camelCase keys.

When serializing inputs:

  - If a value is a dict and the associated type is an input type, the
    dict's keys will be translated based on the input type's property
    name metadata.

  - If a value is a dict and the associated type is a dict (or Mapping),
    the dict's keys will _not_ be translated.

When resolving outputs:

  - If a value is a dict and the associated type is an output type, the
    dict's keys will be translated based on the output type's property
    name metadata.

  - If a value is a dict and the associated type is a dict (or Mapping),
    the dict's keys will _not_ be translated.
2021-04-14 19:32:18 +01:00

128 lines
2.8 KiB
Python

# Copyright 2016-2021, 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 typing import Optional
from pulumi._types import input_type_types
import pulumi
@pulumi.input_type
class Foo:
@property
@pulumi.getter()
def bar(self) -> pulumi.Input[str]:
...
@pulumi.input_type
class MySimpleInputType:
a: str
b: Optional[str]
c: pulumi.Input[str]
d: Optional[pulumi.Input[str]]
e: Foo
f: Optional[Foo]
g: pulumi.Input[Foo]
h: Optional[pulumi.Input[Foo]]
i: pulumi.InputType[Foo]
j: Optional[pulumi.InputType[Foo]]
k: pulumi.Input[pulumi.InputType[Foo]]
l: Optional[pulumi.Input[pulumi.InputType[Foo]]]
@pulumi.input_type
class MyPropertiesInputType:
@property
@pulumi.getter()
def a(self) -> str:
...
@property
@pulumi.getter()
def b(self) -> Optional[str]:
...
@property
@pulumi.getter()
def c(self) -> pulumi.Input[str]:
...
@property
@pulumi.getter()
def d(self) -> Optional[pulumi.Input[str]]:
...
@property
@pulumi.getter()
def e(self) -> Foo:
...
@property
@pulumi.getter()
def f(self) -> Optional[Foo]:
...
@property
@pulumi.getter()
def g(self) -> pulumi.Input[Foo]:
...
@property
@pulumi.getter()
def h(self) -> Optional[pulumi.Input[Foo]]:
...
@property
@pulumi.getter()
def i(self) -> pulumi.InputType[Foo]:
...
@property
@pulumi.getter()
def j(self) -> Optional[pulumi.InputType[Foo]]:
...
@property
@pulumi.getter()
def k(self) -> pulumi.Input[pulumi.InputType[Foo]]:
...
@property
@pulumi.getter()
def l(self) -> Optional[pulumi.Input[pulumi.InputType[Foo]]]:
...
class InputTypeTypesTests(unittest.TestCase):
def test_input_type_types(self):
expected = {
"a": str,
"b": str,
"c": str,
"d": str,
"e": Foo,
"f": Foo,
"g": Foo,
"h": Foo,
"i": Foo,
"j": Foo,
"k": Foo,
"l": Foo,
}
self.assertEqual(expected, input_type_types(MySimpleInputType))
self.assertEqual(expected, input_type_types(MyPropertiesInputType))