diff --git a/packages/jsii-calc/lib/compliance.ts b/packages/jsii-calc/lib/compliance.ts index 49d91b6bbc..8a21f271bd 100644 --- a/packages/jsii-calc/lib/compliance.ts +++ b/packages/jsii-calc/lib/compliance.ts @@ -2175,3 +2175,36 @@ class PrivateBell implements IBell { this.rung = true; } } + +/** + * This is here to check that we can pass a nested struct into a kwargs by specifying it as an + * in-line dictionary. This is cheating with the declared types, but Python people don't play by + * the rules much apparently. + */ +export interface RootStruct { + /** + * May not be empty. + */ + readonly stringProp: string; + readonly nestedStruct?: NestedStruct; +} +export interface NestedStruct { + /** + * When provided, must be > 0. + */ + readonly numberProp: number; +} +export class RootStructValidator { + public static validate(struct: RootStruct): void { + if (!struct.stringProp) { + throw new Error('Missing required field: stringProp'); + } + if (struct.nestedStruct) { + if (struct.nestedStruct.numberProp <= 0) { + throw new Error('numberProp must be > 0'); + } + } + } + + private constructor() { } +} diff --git a/packages/jsii-calc/test/assembly.jsii b/packages/jsii-calc/test/assembly.jsii index 951dc349a5..5550b1c509 100644 --- a/packages/jsii-calc/test/assembly.jsii +++ b/packages/jsii-calc/test/assembly.jsii @@ -6799,6 +6799,38 @@ } ] }, + "jsii-calc.NestedStruct": { + "assembly": "jsii-calc", + "datatype": true, + "docs": { + "stability": "experimental" + }, + "fqn": "jsii-calc.NestedStruct", + "kind": "interface", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2191 + }, + "name": "NestedStruct", + "properties": [ + { + "abstract": true, + "docs": { + "stability": "experimental", + "summary": "When provided, must be > 0." + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2195 + }, + "name": "numberProp", + "type": { + "primitive": "number" + } + } + ] + }, "jsii-calc.NodeStandardLibrary": { "assembly": "jsii-calc", "docs": { @@ -8215,6 +8247,90 @@ } ] }, + "jsii-calc.RootStruct": { + "assembly": "jsii-calc", + "datatype": true, + "docs": { + "remarks": "This is cheating with the declared types, but Python people don't play by\nthe rules much apparently.", + "stability": "experimental", + "summary": "This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary." + }, + "fqn": "jsii-calc.RootStruct", + "kind": "interface", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2184 + }, + "name": "RootStruct", + "properties": [ + { + "abstract": true, + "docs": { + "stability": "experimental", + "summary": "May not be empty." + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2188 + }, + "name": "stringProp", + "type": { + "primitive": "string" + } + }, + { + "abstract": true, + "docs": { + "stability": "experimental" + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2189 + }, + "name": "nestedStruct", + "optional": true, + "type": { + "fqn": "jsii-calc.NestedStruct" + } + } + ] + }, + "jsii-calc.RootStructValidator": { + "assembly": "jsii-calc", + "docs": { + "stability": "experimental" + }, + "fqn": "jsii-calc.RootStructValidator", + "kind": "class", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2197 + }, + "methods": [ + { + "docs": { + "stability": "experimental" + }, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2198 + }, + "name": "validate", + "parameters": [ + { + "name": "struct", + "type": { + "fqn": "jsii-calc.RootStruct" + } + } + ], + "static": true + } + ], + "name": "RootStructValidator" + }, "jsii-calc.RuntimeTypeChecking": { "assembly": "jsii-calc", "docs": { @@ -10797,5 +10913,5 @@ } }, "version": "0.20.3", - "fingerprint": "r/K0k7ocrPmzUuFsCAvxLY2UdNEi6r/ruaoO3PnHiCA=" + "fingerprint": "1F+uskR3++T5mjRcWge9oG3H/jJvXm1C3IhR1AwsBTE=" } diff --git a/packages/jsii-kernel/lib/serialization.ts b/packages/jsii-kernel/lib/serialization.ts index 3c87b1bea5..4961b1cb8d 100644 --- a/packages/jsii-kernel/lib/serialization.ts +++ b/packages/jsii-kernel/lib/serialization.ts @@ -360,6 +360,11 @@ export const SERIALIZERS: {[k: string]: Serializer} = { value = data; } + // Python, for example, allows using plain mapping objects instead of Structs (dyanmic typing, YOLO!) + if (api.isWireMap(value)) { + value = value[api.TOKEN_MAP]; + } + value = validateRequiredProps(value as any, namedType.fqn, props); // Return a dict COPY, we have by-value semantics anyway. diff --git a/packages/jsii-pacmak/lib/targets/python.ts b/packages/jsii-pacmak/lib/targets/python.ts index 54bfeab317..d9032d23a7 100644 --- a/packages/jsii-pacmak/lib/targets/python.ts +++ b/packages/jsii-pacmak/lib/targets/python.ts @@ -661,6 +661,13 @@ class Struct extends BasePythonClassType { code.openBlock(`def __init__(${constructorArguments.join(', ')})`); this.emitConstructorDocstring(code); + // Re-type struct arguments that were passed as "dict" + for (const member of members.filter(m => m.isStruct(this.generator))) { + // Note that "None" is NOT an instance of dict (that's convenient!) + const typeName = resolver.resolve(member.type, { ignoreOptional: true }); + code.line(`if isinstance(${member.pythonName}, dict): ${member.pythonName} = ${typeName}(**${member.pythonName})`); + } + // Required properties, those will always be put into the dict code.line('self._values = {'); for (const member of members.filter(m => !m.optional)) { @@ -719,7 +726,7 @@ class StructField implements PythonBase { public readonly pythonName: string; public readonly jsiiName: string; public readonly docs?: spec.Docs; - private readonly type: spec.OptionalValue; + public readonly type: spec.OptionalValue; public constructor(public readonly prop: spec.Property) { this.pythonName = toPythonPropertyName(prop.name); diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii index 951dc349a5..5550b1c509 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/.jsii @@ -6799,6 +6799,38 @@ } ] }, + "jsii-calc.NestedStruct": { + "assembly": "jsii-calc", + "datatype": true, + "docs": { + "stability": "experimental" + }, + "fqn": "jsii-calc.NestedStruct", + "kind": "interface", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2191 + }, + "name": "NestedStruct", + "properties": [ + { + "abstract": true, + "docs": { + "stability": "experimental", + "summary": "When provided, must be > 0." + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2195 + }, + "name": "numberProp", + "type": { + "primitive": "number" + } + } + ] + }, "jsii-calc.NodeStandardLibrary": { "assembly": "jsii-calc", "docs": { @@ -8215,6 +8247,90 @@ } ] }, + "jsii-calc.RootStruct": { + "assembly": "jsii-calc", + "datatype": true, + "docs": { + "remarks": "This is cheating with the declared types, but Python people don't play by\nthe rules much apparently.", + "stability": "experimental", + "summary": "This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary." + }, + "fqn": "jsii-calc.RootStruct", + "kind": "interface", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2184 + }, + "name": "RootStruct", + "properties": [ + { + "abstract": true, + "docs": { + "stability": "experimental", + "summary": "May not be empty." + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2188 + }, + "name": "stringProp", + "type": { + "primitive": "string" + } + }, + { + "abstract": true, + "docs": { + "stability": "experimental" + }, + "immutable": true, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2189 + }, + "name": "nestedStruct", + "optional": true, + "type": { + "fqn": "jsii-calc.NestedStruct" + } + } + ] + }, + "jsii-calc.RootStructValidator": { + "assembly": "jsii-calc", + "docs": { + "stability": "experimental" + }, + "fqn": "jsii-calc.RootStructValidator", + "kind": "class", + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2197 + }, + "methods": [ + { + "docs": { + "stability": "experimental" + }, + "locationInModule": { + "filename": "lib/compliance.ts", + "line": 2198 + }, + "name": "validate", + "parameters": [ + { + "name": "struct", + "type": { + "fqn": "jsii-calc.RootStruct" + } + } + ], + "static": true + } + ], + "name": "RootStructValidator" + }, "jsii-calc.RuntimeTypeChecking": { "assembly": "jsii-calc", "docs": { @@ -10797,5 +10913,5 @@ } }, "version": "0.20.3", - "fingerprint": "r/K0k7ocrPmzUuFsCAvxLY2UdNEi6r/ruaoO3PnHiCA=" + "fingerprint": "1F+uskR3++T5mjRcWge9oG3H/jJvXm1C3IhR1AwsBTE=" } diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/INestedStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/INestedStruct.cs new file mode 100644 index 0000000000..6071669e9f --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/INestedStruct.cs @@ -0,0 +1,21 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// stability: Experimental + /// + [JsiiInterface(nativeType: typeof(INestedStruct), fullyQualifiedName: "jsii-calc.NestedStruct")] + public interface INestedStruct + { + /// When provided, must be > 0. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "numberProp", typeJson: "{\"primitive\":\"number\"}")] + double NumberProp + { + get; + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRootStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRootStruct.cs new file mode 100644 index 0000000000..8da60016ad --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/IRootStruct.cs @@ -0,0 +1,37 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. + /// + /// This is cheating with the declared types, but Python people don't play by + /// the rules much apparently. + /// stability: Experimental + /// + [JsiiInterface(nativeType: typeof(IRootStruct), fullyQualifiedName: "jsii-calc.RootStruct")] + public interface IRootStruct + { + /// May not be empty. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "stringProp", typeJson: "{\"primitive\":\"string\"}")] + string StringProp + { + get; + } + + /// + /// stability: Experimental + /// + [JsiiProperty(name: "nestedStruct", typeJson: "{\"fqn\":\"jsii-calc.NestedStruct\"}", isOptional: true)] + [Amazon.JSII.Runtime.Deputy.JsiiOptional] + Amazon.JSII.Tests.CalculatorNamespace.INestedStruct NestedStruct + { + get + { + return null; + } + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStruct.cs new file mode 100644 index 0000000000..172b65ed76 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStruct.cs @@ -0,0 +1,22 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// stability: Experimental + /// + [JsiiByValue(fqn: "jsii-calc.NestedStruct")] + public class NestedStruct : Amazon.JSII.Tests.CalculatorNamespace.INestedStruct + { + /// When provided, must be > 0. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "numberProp", typeJson: "{\"primitive\":\"number\"}", isOverride: true)] + public double NumberProp + { + get; + set; + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStructProxy.cs new file mode 100644 index 0000000000..88ca5ac977 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/NestedStructProxy.cs @@ -0,0 +1,25 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// stability: Experimental + /// + [JsiiTypeProxy(nativeType: typeof(INestedStruct), fullyQualifiedName: "jsii-calc.NestedStruct")] + internal sealed class NestedStructProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.INestedStruct + { + private NestedStructProxy(ByRefValue reference): base(reference) + { + } + + /// When provided, must be > 0. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "numberProp", typeJson: "{\"primitive\":\"number\"}")] + public double NumberProp + { + get => GetInstanceProperty(); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStruct.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStruct.cs new file mode 100644 index 0000000000..9758519697 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStruct.cs @@ -0,0 +1,36 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. + /// + /// This is cheating with the declared types, but Python people don't play by + /// the rules much apparently. + /// stability: Experimental + /// + [JsiiByValue(fqn: "jsii-calc.RootStruct")] + public class RootStruct : Amazon.JSII.Tests.CalculatorNamespace.IRootStruct + { + /// May not be empty. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "stringProp", typeJson: "{\"primitive\":\"string\"}", isOverride: true)] + public string StringProp + { + get; + set; + } + + /// + /// stability: Experimental + /// + [JsiiOptional] + [JsiiProperty(name: "nestedStruct", typeJson: "{\"fqn\":\"jsii-calc.NestedStruct\"}", isOptional: true, isOverride: true)] + public Amazon.JSII.Tests.CalculatorNamespace.INestedStruct NestedStruct + { + get; + set; + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructProxy.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructProxy.cs new file mode 100644 index 0000000000..7816bebc5a --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructProxy.cs @@ -0,0 +1,38 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. + /// + /// This is cheating with the declared types, but Python people don't play by + /// the rules much apparently. + /// stability: Experimental + /// + [JsiiTypeProxy(nativeType: typeof(IRootStruct), fullyQualifiedName: "jsii-calc.RootStruct")] + internal sealed class RootStructProxy : DeputyBase, Amazon.JSII.Tests.CalculatorNamespace.IRootStruct + { + private RootStructProxy(ByRefValue reference): base(reference) + { + } + + /// May not be empty. + /// + /// stability: Experimental + /// + [JsiiProperty(name: "stringProp", typeJson: "{\"primitive\":\"string\"}")] + public string StringProp + { + get => GetInstanceProperty(); + } + + /// + /// stability: Experimental + /// + [JsiiOptional] + [JsiiProperty(name: "nestedStruct", typeJson: "{\"fqn\":\"jsii-calc.NestedStruct\"}", isOptional: true)] + public Amazon.JSII.Tests.CalculatorNamespace.INestedStruct NestedStruct + { + get => GetInstanceProperty(); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructValidator.cs b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructValidator.cs new file mode 100644 index 0000000000..69bfd315bf --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/dotnet/Amazon.JSII.Tests.CalculatorPackageId/Amazon/JSII/Tests/CalculatorNamespace/RootStructValidator.cs @@ -0,0 +1,28 @@ +using Amazon.JSII.Runtime.Deputy; + +namespace Amazon.JSII.Tests.CalculatorNamespace +{ + /// + /// stability: Experimental + /// + [JsiiClass(nativeType: typeof(Amazon.JSII.Tests.CalculatorNamespace.RootStructValidator), fullyQualifiedName: "jsii-calc.RootStructValidator")] + public class RootStructValidator : DeputyBase + { + protected RootStructValidator(ByRefValue reference): base(reference) + { + } + + protected RootStructValidator(DeputyProps props): base(props) + { + } + + /// + /// stability: Experimental + /// + [JsiiMethod(name: "validate", parametersJson: "[{\"name\":\"struct\",\"type\":{\"fqn\":\"jsii-calc.RootStruct\"}}]")] + public static void Validate(Amazon.JSII.Tests.CalculatorNamespace.IRootStruct @struct) + { + InvokeStaticVoidMethod(typeof(Amazon.JSII.Tests.CalculatorNamespace.RootStructValidator), new System.Type[]{typeof(Amazon.JSII.Tests.CalculatorNamespace.IRootStruct)}, new object[]{@struct}); + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java index be82ab3d32..9c27fed73b 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/$Module.java @@ -125,6 +125,7 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.LoadBalancedFargateServiceProps": return software.amazon.jsii.tests.calculator.LoadBalancedFargateServiceProps.class; case "jsii-calc.Multiply": return software.amazon.jsii.tests.calculator.Multiply.class; case "jsii-calc.Negate": return software.amazon.jsii.tests.calculator.Negate.class; + case "jsii-calc.NestedStruct": return software.amazon.jsii.tests.calculator.NestedStruct.class; case "jsii-calc.NodeStandardLibrary": return software.amazon.jsii.tests.calculator.NodeStandardLibrary.class; case "jsii-calc.NullShouldBeTreatedAsUndefined": return software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefined.class; case "jsii-calc.NullShouldBeTreatedAsUndefinedData": return software.amazon.jsii.tests.calculator.NullShouldBeTreatedAsUndefinedData.class; @@ -144,6 +145,8 @@ protected Class resolveClass(final String fqn) throws ClassNotFoundException case "jsii-calc.PythonReservedWords": return software.amazon.jsii.tests.calculator.PythonReservedWords.class; case "jsii-calc.ReferenceEnumFromScopedPackage": return software.amazon.jsii.tests.calculator.ReferenceEnumFromScopedPackage.class; case "jsii-calc.ReturnsPrivateImplementationOfInterface": return software.amazon.jsii.tests.calculator.ReturnsPrivateImplementationOfInterface.class; + case "jsii-calc.RootStruct": return software.amazon.jsii.tests.calculator.RootStruct.class; + case "jsii-calc.RootStructValidator": return software.amazon.jsii.tests.calculator.RootStructValidator.class; case "jsii-calc.RuntimeTypeChecking": return software.amazon.jsii.tests.calculator.RuntimeTypeChecking.class; case "jsii-calc.SecondLevelStruct": return software.amazon.jsii.tests.calculator.SecondLevelStruct.class; case "jsii-calc.SingleInstanceTwoTypes": return software.amazon.jsii.tests.calculator.SingleInstanceTwoTypes.class; diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NestedStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NestedStruct.java new file mode 100644 index 0000000000..8671fb1fd4 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/NestedStruct.java @@ -0,0 +1,118 @@ +package software.amazon.jsii.tests.calculator; + +/** + * EXPERIMENTAL + */ +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.NestedStruct") +@software.amazon.jsii.Jsii.Proxy(NestedStruct.Jsii$Proxy.class) +@software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) +public interface NestedStruct extends software.amazon.jsii.JsiiSerializable { + + /** + * When provided, must be > 0. + * + * EXPERIMENTAL + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + java.lang.Number getNumberProp(); + + /** + * @return a {@link Builder} of {@link NestedStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + static Builder builder() { + return new Builder(); + } + /** + * A builder for {@link NestedStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public static final class Builder { + private java.lang.Number numberProp; + + /** + * Sets the value of NumberProp + * @param numberProp When provided, must be > 0. This parameter is required. + * @return {@code this} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public Builder numberProp(java.lang.Number numberProp) { + this.numberProp = numberProp; + return this; + } + + /** + * Builds the configured instance. + * @return a new instance of {@link NestedStruct} + * @throws NullPointerException if any required attribute was not provided + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public NestedStruct build() { + return new Jsii$Proxy(numberProp); + } + } + + /** + * An implementation for {@link NestedStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements NestedStruct { + private final java.lang.Number numberProp; + + /** + * Constructor that initializes the object based on values retrieved from the JsiiObject. + * @param objRef Reference to the JSII managed object. + */ + protected Jsii$Proxy(final software.amazon.jsii.JsiiObjectRef objRef) { + super(objRef); + this.numberProp = this.jsiiGet("numberProp", java.lang.Number.class); + } + + /** + * Constructor that initializes the object based on literal property values passed by the {@link Builder}. + */ + private Jsii$Proxy(final java.lang.Number numberProp) { + super(software.amazon.jsii.JsiiObject.InitializationMode.JSII); + this.numberProp = java.util.Objects.requireNonNull(numberProp, "numberProp is required"); + } + + @Override + public java.lang.Number getNumberProp() { + return this.numberProp; + } + + @Override + public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { + final com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; + final com.fasterxml.jackson.databind.node.ObjectNode data = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + + data.set("numberProp", om.valueToTree(this.getNumberProp())); + + final com.fasterxml.jackson.databind.node.ObjectNode struct = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + struct.set("fqn", om.valueToTree("jsii-calc.NestedStruct")); + struct.set("data", data); + + final com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + obj.set("$jsii.struct", struct); + + return obj; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + NestedStruct.Jsii$Proxy that = (NestedStruct.Jsii$Proxy) o; + + return this.numberProp.equals(that.numberProp); + } + + @Override + public int hashCode() { + int result = this.numberProp.hashCode(); + return result; + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStruct.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStruct.java new file mode 100644 index 0000000000..0f00c684db --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStruct.java @@ -0,0 +1,156 @@ +package software.amazon.jsii.tests.calculator; + +/** + * This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. + * + * This is cheating with the declared types, but Python people don't play by + * the rules much apparently. + * + * EXPERIMENTAL + */ +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.RootStruct") +@software.amazon.jsii.Jsii.Proxy(RootStruct.Jsii$Proxy.class) +@software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) +public interface RootStruct extends software.amazon.jsii.JsiiSerializable { + + /** + * May not be empty. + * + * EXPERIMENTAL + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + java.lang.String getStringProp(); + + /** + * EXPERIMENTAL + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + default software.amazon.jsii.tests.calculator.NestedStruct getNestedStruct() { + return null; + } + + /** + * @return a {@link Builder} of {@link RootStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + static Builder builder() { + return new Builder(); + } + /** + * A builder for {@link RootStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public static final class Builder { + private java.lang.String stringProp; + private software.amazon.jsii.tests.calculator.NestedStruct nestedStruct; + + /** + * Sets the value of StringProp + * @param stringProp May not be empty. This parameter is required. + * @return {@code this} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public Builder stringProp(java.lang.String stringProp) { + this.stringProp = stringProp; + return this; + } + + /** + * Sets the value of NestedStruct + * @param nestedStruct the value to be set. + * @return {@code this} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public Builder nestedStruct(software.amazon.jsii.tests.calculator.NestedStruct nestedStruct) { + this.nestedStruct = nestedStruct; + return this; + } + + /** + * Builds the configured instance. + * @return a new instance of {@link RootStruct} + * @throws NullPointerException if any required attribute was not provided + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public RootStruct build() { + return new Jsii$Proxy(stringProp, nestedStruct); + } + } + + /** + * An implementation for {@link RootStruct} + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + final class Jsii$Proxy extends software.amazon.jsii.JsiiObject implements RootStruct { + private final java.lang.String stringProp; + private final software.amazon.jsii.tests.calculator.NestedStruct nestedStruct; + + /** + * Constructor that initializes the object based on values retrieved from the JsiiObject. + * @param objRef Reference to the JSII managed object. + */ + protected Jsii$Proxy(final software.amazon.jsii.JsiiObjectRef objRef) { + super(objRef); + this.stringProp = this.jsiiGet("stringProp", java.lang.String.class); + this.nestedStruct = this.jsiiGet("nestedStruct", software.amazon.jsii.tests.calculator.NestedStruct.class); + } + + /** + * Constructor that initializes the object based on literal property values passed by the {@link Builder}. + */ + private Jsii$Proxy(final java.lang.String stringProp, final software.amazon.jsii.tests.calculator.NestedStruct nestedStruct) { + super(software.amazon.jsii.JsiiObject.InitializationMode.JSII); + this.stringProp = java.util.Objects.requireNonNull(stringProp, "stringProp is required"); + this.nestedStruct = nestedStruct; + } + + @Override + public java.lang.String getStringProp() { + return this.stringProp; + } + + @Override + public software.amazon.jsii.tests.calculator.NestedStruct getNestedStruct() { + return this.nestedStruct; + } + + @Override + public com.fasterxml.jackson.databind.JsonNode $jsii$toJson() { + final com.fasterxml.jackson.databind.ObjectMapper om = software.amazon.jsii.JsiiObjectMapper.INSTANCE; + final com.fasterxml.jackson.databind.node.ObjectNode data = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + + data.set("stringProp", om.valueToTree(this.getStringProp())); + if (this.getNestedStruct() != null) { + data.set("nestedStruct", om.valueToTree(this.getNestedStruct())); + } + + final com.fasterxml.jackson.databind.node.ObjectNode struct = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + struct.set("fqn", om.valueToTree("jsii-calc.RootStruct")); + struct.set("data", data); + + final com.fasterxml.jackson.databind.node.ObjectNode obj = com.fasterxml.jackson.databind.node.JsonNodeFactory.instance.objectNode(); + obj.set("$jsii.struct", struct); + + return obj; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + RootStruct.Jsii$Proxy that = (RootStruct.Jsii$Proxy) o; + + if (!stringProp.equals(that.stringProp)) return false; + return this.nestedStruct != null ? this.nestedStruct.equals(that.nestedStruct) : that.nestedStruct == null; + } + + @Override + public int hashCode() { + int result = this.stringProp.hashCode(); + result = 31 * result + (this.nestedStruct != null ? this.nestedStruct.hashCode() : 0); + return result; + } + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStructValidator.java b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStructValidator.java new file mode 100644 index 0000000000..c6a862f870 --- /dev/null +++ b/packages/jsii-pacmak/test/expected.jsii-calc/java/src/main/java/software/amazon/jsii/tests/calculator/RootStructValidator.java @@ -0,0 +1,28 @@ +package software.amazon.jsii.tests.calculator; + +/** + * EXPERIMENTAL + */ +@javax.annotation.Generated(value = "jsii-pacmak") +@software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) +@software.amazon.jsii.Jsii(module = software.amazon.jsii.tests.calculator.$Module.class, fqn = "jsii-calc.RootStructValidator") +public class RootStructValidator extends software.amazon.jsii.JsiiObject { + + protected RootStructValidator(final software.amazon.jsii.JsiiObjectRef objRef) { + super(objRef); + } + + protected RootStructValidator(final software.amazon.jsii.JsiiObject.InitializationMode initializationMode) { + super(initializationMode); + } + + /** + * EXPERIMENTAL + * + * @param struct This parameter is required. + */ + @software.amazon.jsii.Stability(software.amazon.jsii.Stability.Level.Experimental) + public static void validate(final software.amazon.jsii.tests.calculator.RootStruct struct) { + software.amazon.jsii.JsiiObject.jsiiStaticCall(software.amazon.jsii.tests.calculator.RootStructValidator.class, "validate", Void.class, new Object[] { java.util.Objects.requireNonNull(struct, "struct is required") }); + } +} diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py index 61ab803b61..6a52bf4e90 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc/python/src/jsii_calc/__init__.py @@ -4875,6 +4875,38 @@ def value(self) -> jsii.Number: return jsii.get(self, "value") +@jsii.data_type(jsii_type="jsii-calc.NestedStruct", jsii_struct_bases=[], name_mapping={'number_prop': 'numberProp'}) +class NestedStruct(): + def __init__(self, *, number_prop: jsii.Number): + """ + :param number_prop: When provided, must be > 0. + + stability + :stability: experimental + """ + self._values = { + 'number_prop': number_prop, + } + + @property + def number_prop(self) -> jsii.Number: + """When provided, must be > 0. + + stability + :stability: experimental + """ + return self._values.get('number_prop') + + def __eq__(self, rhs) -> bool: + return isinstance(rhs, self.__class__) and rhs._values == self._values + + def __ne__(self, rhs) -> bool: + return not (rhs == self) + + def __repr__(self) -> str: + return 'NestedStruct(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items()) + + class NodeStandardLibrary(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.NodeStandardLibrary"): """Test fixture to verify that jsii modules can use the node standard library. @@ -5777,6 +5809,74 @@ def private_implementation(self) -> "IPrivatelyImplemented": return jsii.get(self, "privateImplementation") +@jsii.data_type(jsii_type="jsii-calc.RootStruct", jsii_struct_bases=[], name_mapping={'string_prop': 'stringProp', 'nested_struct': 'nestedStruct'}) +class RootStruct(): + def __init__(self, *, string_prop: str, nested_struct: typing.Optional["NestedStruct"]=None): + """This is here to check that we can pass a nested struct into a kwargs by specifying it as an in-line dictionary. + + This is cheating with the declared types, but Python people don't play by + the rules much apparently. + + :param string_prop: May not be empty. + :param nested_struct: + + stability + :stability: experimental + """ + if isinstance(nested_struct, dict): nested_struct = NestedStruct(**nested_struct) + self._values = { + 'string_prop': string_prop, + } + if nested_struct is not None: self._values["nested_struct"] = nested_struct + + @property + def string_prop(self) -> str: + """May not be empty. + + stability + :stability: experimental + """ + return self._values.get('string_prop') + + @property + def nested_struct(self) -> typing.Optional["NestedStruct"]: + """ + stability + :stability: experimental + """ + return self._values.get('nested_struct') + + def __eq__(self, rhs) -> bool: + return isinstance(rhs, self.__class__) and rhs._values == self._values + + def __ne__(self, rhs) -> bool: + return not (rhs == self) + + def __repr__(self) -> str: + return 'RootStruct(%s)' % ', '.join(k + '=' + repr(v) for k, v in self._values.items()) + + +class RootStructValidator(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.RootStructValidator"): + """ + stability + :stability: experimental + """ + @jsii.member(jsii_name="validate") + @classmethod + def validate(cls, *, string_prop: str, nested_struct: typing.Optional["NestedStruct"]=None) -> None: + """ + :param struct: - + :param string_prop: May not be empty. + :param nested_struct: + + stability + :stability: experimental + """ + struct = RootStruct(string_prop=string_prop, nested_struct=nested_struct) + + return jsii.sinvoke(cls, "validate", [struct]) + + class RuntimeTypeChecking(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.RuntimeTypeChecking"): """ stability @@ -6265,6 +6365,7 @@ def __init__(self, *, required_string: str, optional_boolean: typing.Optional[bo stability :stability: experimental """ + if isinstance(optional_struct_a, dict): optional_struct_a = StructA(**optional_struct_a) self._values = { 'required_string': required_string, } @@ -7558,6 +7659,6 @@ def parts(self, value: typing.List[scope.jsii_calc_lib.Value]): return jsii.set(self, "parts", value) -__all__ = ["AbstractClass", "AbstractClassBase", "AbstractClassReturner", "Add", "AllTypes", "AllTypesEnum", "AllowedMethodNames", "AnonymousImplementationProvider", "AsyncVirtualMethods", "AugmentableClass", "Bell", "BinaryOperation", "Calculator", "CalculatorProps", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithCollections", "ClassWithDocs", "ClassWithJavaReservedWords", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "ConstructorPassesThisOut", "Constructors", "ConsumerCanRingBell", "ConsumersOfThisCrazyTypeSystem", "DataRenderer", "DefaultedConstructorArgument", "DeprecatedClass", "DeprecatedEnum", "DeprecatedStruct", "DerivedClassHasNoProperties", "DerivedStruct", "DiamondInheritanceBaseLevelStruct", "DiamondInheritanceFirstMidLevelStruct", "DiamondInheritanceSecondMidLevelStruct", "DiamondInheritanceTopLevelStruct", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DocumentedClass", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EnumDispenser", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExperimentalClass", "ExperimentalEnum", "ExperimentalStruct", "ExportedBaseClass", "ExtendsInternalInterface", "GiveMeStructs", "Greetee", "GreetingAugmenter", "IAnonymousImplementationProvider", "IAnonymouslyImplementMe", "IAnotherPublicInterface", "IBell", "IBellRinger", "IConcreteBellRinger", "IDeprecatedInterface", "IExperimentalInterface", "IExtendsPrivateInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceImplementedByAbstractClass", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IJSII417Derived", "IJSII417PublicBaseOfBase", "IJsii487External", "IJsii487External2", "IJsii496", "IMutableObjectLiteral", "INonInternalInterface", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnsNumber", "IStableInterface", "ImplementInternalInterface", "Implementation", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "InterfacesMaker", "JSII417Derived", "JSII417PublicBaseOfBase", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "Jsii487Derived", "Jsii496Derived", "JsiiAgent", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "Old", "OptionalArgumentInvoker", "OptionalConstructorArgument", "OptionalStruct", "OptionalStructConsumer", "OverridableProtectedMember", "OverrideReturnsObject", "PartiallyInitializedThisConsumer", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RuntimeTypeChecking", "SecondLevelStruct", "SingleInstanceTwoTypes", "SingletonInt", "SingletonIntEnum", "SingletonString", "SingletonStringEnum", "StableClass", "StableEnum", "StableStruct", "StaticContext", "Statics", "StringEnum", "StripInternal", "StructA", "StructB", "StructPassing", "StructUnionConsumer", "StructWithJavaReservedWords", "Sum", "SupportsNiceJavaBuilder", "SupportsNiceJavaBuilderProps", "SupportsNiceJavaBuilderWithRequiredProps", "SyncVirtualMethods", "Thrower", "TopLevelStruct", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicInvoker", "VariadicMethod", "VirtualMethodPlayground", "VoidCallback", "WithPrivatePropertyInConstructor", "__jsii_assembly__", "composition"] +__all__ = ["AbstractClass", "AbstractClassBase", "AbstractClassReturner", "Add", "AllTypes", "AllTypesEnum", "AllowedMethodNames", "AnonymousImplementationProvider", "AsyncVirtualMethods", "AugmentableClass", "Bell", "BinaryOperation", "Calculator", "CalculatorProps", "ClassThatImplementsTheInternalInterface", "ClassThatImplementsThePrivateInterface", "ClassWithCollections", "ClassWithDocs", "ClassWithJavaReservedWords", "ClassWithMutableObjectLiteralProperty", "ClassWithPrivateConstructorAndAutomaticProperties", "ConstructorPassesThisOut", "Constructors", "ConsumerCanRingBell", "ConsumersOfThisCrazyTypeSystem", "DataRenderer", "DefaultedConstructorArgument", "DeprecatedClass", "DeprecatedEnum", "DeprecatedStruct", "DerivedClassHasNoProperties", "DerivedStruct", "DiamondInheritanceBaseLevelStruct", "DiamondInheritanceFirstMidLevelStruct", "DiamondInheritanceSecondMidLevelStruct", "DiamondInheritanceTopLevelStruct", "DoNotOverridePrivates", "DoNotRecognizeAnyAsOptional", "DocumentedClass", "DontComplainAboutVariadicAfterOptional", "DoubleTrouble", "EnumDispenser", "EraseUndefinedHashValues", "EraseUndefinedHashValuesOptions", "ExperimentalClass", "ExperimentalEnum", "ExperimentalStruct", "ExportedBaseClass", "ExtendsInternalInterface", "GiveMeStructs", "Greetee", "GreetingAugmenter", "IAnonymousImplementationProvider", "IAnonymouslyImplementMe", "IAnotherPublicInterface", "IBell", "IBellRinger", "IConcreteBellRinger", "IDeprecatedInterface", "IExperimentalInterface", "IExtendsPrivateInterface", "IFriendlier", "IFriendlyRandomGenerator", "IInterfaceImplementedByAbstractClass", "IInterfaceThatShouldNotBeADataType", "IInterfaceWithInternal", "IInterfaceWithMethods", "IInterfaceWithOptionalMethodArguments", "IInterfaceWithProperties", "IInterfaceWithPropertiesExtension", "IJSII417Derived", "IJSII417PublicBaseOfBase", "IJsii487External", "IJsii487External2", "IJsii496", "IMutableObjectLiteral", "INonInternalInterface", "IPrivatelyImplemented", "IPublicInterface", "IPublicInterface2", "IRandomNumberGenerator", "IReturnsNumber", "IStableInterface", "ImplementInternalInterface", "Implementation", "ImplementsInterfaceWithInternal", "ImplementsInterfaceWithInternalSubclass", "ImplementsPrivateInterface", "ImplictBaseOfBase", "InbetweenClass", "InterfaceInNamespaceIncludesClasses", "InterfaceInNamespaceOnlyInterface", "InterfacesMaker", "JSII417Derived", "JSII417PublicBaseOfBase", "JSObjectLiteralForInterface", "JSObjectLiteralToNative", "JSObjectLiteralToNativeClass", "JavaReservedWords", "Jsii487Derived", "Jsii496Derived", "JsiiAgent", "LoadBalancedFargateServiceProps", "Multiply", "Negate", "NestedStruct", "NodeStandardLibrary", "NullShouldBeTreatedAsUndefined", "NullShouldBeTreatedAsUndefinedData", "NumberGenerator", "ObjectRefsInCollections", "Old", "OptionalArgumentInvoker", "OptionalConstructorArgument", "OptionalStruct", "OptionalStructConsumer", "OverridableProtectedMember", "OverrideReturnsObject", "PartiallyInitializedThisConsumer", "Polymorphism", "Power", "PublicClass", "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", "RootStruct", "RootStructValidator", "RuntimeTypeChecking", "SecondLevelStruct", "SingleInstanceTwoTypes", "SingletonInt", "SingletonIntEnum", "SingletonString", "SingletonStringEnum", "StableClass", "StableEnum", "StableStruct", "StaticContext", "Statics", "StringEnum", "StripInternal", "StructA", "StructB", "StructPassing", "StructUnionConsumer", "StructWithJavaReservedWords", "Sum", "SupportsNiceJavaBuilder", "SupportsNiceJavaBuilderProps", "SupportsNiceJavaBuilderWithRequiredProps", "SyncVirtualMethods", "Thrower", "TopLevelStruct", "UnaryOperation", "UnionProperties", "UseBundledDependency", "UseCalcBase", "UsesInterfaceWithProperties", "VariadicInvoker", "VariadicMethod", "VirtualMethodPlayground", "VoidCallback", "WithPrivatePropertyInConstructor", "__jsii_assembly__", "composition"] publication.publish() diff --git a/packages/jsii-python-runtime/tests/test_compliance.py b/packages/jsii-python-runtime/tests/test_compliance.py index 7895a6cfdd..6c63c97889 100644 --- a/packages/jsii-python-runtime/tests/test_compliance.py +++ b/packages/jsii-python-runtime/tests/test_compliance.py @@ -48,6 +48,8 @@ EraseUndefinedHashValues, EraseUndefinedHashValuesOptions, VariadicMethod, + RootStruct, + RootStructValidator, StructPassing, TopLevelStruct, SecondLevelStruct, @@ -1000,6 +1002,16 @@ def test_consumer_calls_method_privateclass(): def test_consumer_calls_method_typed_as_class(): assert ConsumerCanRingBell().when_typed_as_class(PythonConcreteBellRinger()) +def test_can_pass_nested_struct_as_dict(): + # Those shouldn't raise: + RootStructValidator.validate(string_prop= 'Pickle Rick!!!') + RootStructValidator.validate(string_prop= 'Pickle Rick!!!', nested_struct= None) + RootStructValidator.validate( + string_prop= 'Pickle Rick!!!', + nested_struct= { + 'number_prop': 1337 + } + ) @jsii.implements(IBellRinger) class PythonBellRinger: diff --git a/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap b/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap index 4eeb29d4e8..5ddff0ad79 100644 --- a/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap +++ b/packages/jsii-reflect/test/__snapshots__/jsii-tree.test.js.snap @@ -1126,6 +1126,14 @@ exports[`jsii-tree --all 1`] = ` │ │ └─┬ privateImplementation property (experimental) │ │ ├── immutable │ │ └── type: jsii-calc.IPrivatelyImplemented + │ ├─┬ class RootStructValidator (experimental) + │ │ └─┬ members + │ │ └─┬ static validate(struct) method (experimental) + │ │ ├── static + │ │ ├─┬ parameters + │ │ │ └─┬ struct + │ │ │ └── type: jsii-calc.RootStruct + │ │ └── returns: void │ ├─┬ class RuntimeTypeChecking (experimental) │ │ └─┬ members │ │ ├── () initializer (experimental) @@ -1886,6 +1894,12 @@ exports[`jsii-tree --all 1`] = ` │ │ ├── abstract │ │ ├── immutable │ │ └── type: Optional + │ ├─┬ interface NestedStruct (experimental) + │ │ └─┬ members + │ │ └─┬ numberProp property (experimental) + │ │ ├── abstract + │ │ ├── immutable + │ │ └── type: number │ ├─┬ interface NullShouldBeTreatedAsUndefinedData (experimental) │ │ └─┬ members │ │ ├─┬ arrayWithThreeElementsAndUndefinedAsSecondArgument property (experimental) @@ -1902,6 +1916,16 @@ exports[`jsii-tree --all 1`] = ` │ │ ├── abstract │ │ ├── immutable │ │ └── type: Optional + │ ├─┬ interface RootStruct (experimental) + │ │ └─┬ members + │ │ ├─┬ stringProp property (experimental) + │ │ │ ├── abstract + │ │ │ ├── immutable + │ │ │ └── type: string + │ │ └─┬ nestedStruct property (experimental) + │ │ ├── abstract + │ │ ├── immutable + │ │ └── type: Optional │ ├─┬ interface SecondLevelStruct (experimental) │ │ └─┬ members │ │ ├─┬ deeperRequiredProp property (experimental) @@ -2255,6 +2279,7 @@ exports[`jsii-tree --inheritance 1`] = ` │ ├── class PythonReservedWords │ ├── class ReferenceEnumFromScopedPackage │ ├── class ReturnsPrivateImplementationOfInterface + │ ├── class RootStructValidator │ ├── class RuntimeTypeChecking │ ├── class SingleInstanceTwoTypes │ ├── class SingletonInt @@ -2354,8 +2379,10 @@ exports[`jsii-tree --inheritance 1`] = ` │ ├── interface Hello │ ├── interface Hello │ ├── interface LoadBalancedFargateServiceProps + │ ├── interface NestedStruct │ ├── interface NullShouldBeTreatedAsUndefinedData │ ├── interface OptionalStruct + │ ├── interface RootStruct │ ├── interface SecondLevelStruct │ ├── interface StableStruct │ ├── interface StructA @@ -2914,6 +2941,9 @@ exports[`jsii-tree --members 1`] = ` │ │ └─┬ members │ │ ├── () initializer │ │ └── privateImplementation property + │ ├─┬ class RootStructValidator + │ │ └─┬ members + │ │ └── static validate(struct) method │ ├─┬ class RuntimeTypeChecking │ │ └─┬ members │ │ ├── () initializer @@ -3219,6 +3249,9 @@ exports[`jsii-tree --members 1`] = ` │ │ ├── memoryMiB property │ │ ├── publicLoadBalancer property │ │ └── publicTasks property + │ ├─┬ interface NestedStruct + │ │ └─┬ members + │ │ └── numberProp property │ ├─┬ interface NullShouldBeTreatedAsUndefinedData │ │ └─┬ members │ │ ├── arrayWithThreeElementsAndUndefinedAsSecondArgument property @@ -3226,6 +3259,10 @@ exports[`jsii-tree --members 1`] = ` │ ├─┬ interface OptionalStruct │ │ └─┬ members │ │ └── field property + │ ├─┬ interface RootStruct + │ │ └─┬ members + │ │ ├── stringProp property + │ │ └── nestedStruct property │ ├─┬ interface SecondLevelStruct │ │ └─┬ members │ │ ├── deeperRequiredProp property @@ -3439,6 +3476,7 @@ exports[`jsii-tree --types 1`] = ` │ ├── class PythonReservedWords │ ├── class ReferenceEnumFromScopedPackage │ ├── class ReturnsPrivateImplementationOfInterface + │ ├── class RootStructValidator │ ├── class RuntimeTypeChecking │ ├── class SingleInstanceTwoTypes │ ├── class SingletonInt @@ -3510,8 +3548,10 @@ exports[`jsii-tree --types 1`] = ` │ ├── interface Hello │ ├── interface Hello │ ├── interface LoadBalancedFargateServiceProps + │ ├── interface NestedStruct │ ├── interface NullShouldBeTreatedAsUndefinedData │ ├── interface OptionalStruct + │ ├── interface RootStruct │ ├── interface SecondLevelStruct │ ├── interface StableStruct │ ├── interface StructA diff --git a/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap b/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap index 4609005af1..b46dddb198 100644 --- a/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap +++ b/packages/jsii-reflect/test/__snapshots__/type-system.test.js.snap @@ -90,6 +90,7 @@ Array [ "PythonReservedWords", "ReferenceEnumFromScopedPackage", "ReturnsPrivateImplementationOfInterface", + "RootStructValidator", "RuntimeTypeChecking", "SingleInstanceTwoTypes", "SingletonInt",