jsii-pacmak 1.62.0 → 1.63.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/jest.config.mjs CHANGED
@@ -2,4 +2,5 @@ import { overriddenConfig } from '../../jest.config.mjs';
2
2
 
3
3
  export default overriddenConfig({
4
4
  coveragePathIgnorePatterns: ['/node_modules/', '<rootDir>/test'],
5
+ watchPathIgnorePatterns: ['.*\\.tsx?$'],
5
6
  });
@@ -103,9 +103,12 @@ class GoTypeRef {
103
103
  ret.push(...this.typeMap.value.dependencies);
104
104
  break;
105
105
  case 'union':
106
- for (const t of this.typeMap.value) {
107
- ret.push(...t.dependencies);
108
- }
106
+ // Unions ultimately result in `interface{}` being rendered, so no import is needed. We
107
+ // hence ignore them entirely here for now. In the future, we may want to inject specific
108
+ // runtime type checks around use of unions, which may result in imports being useful.
109
+ // for (const t of this.typeMap.value) {
110
+ // ret.push(...t.dependencies);
111
+ // }
109
112
  break;
110
113
  case 'void':
111
114
  case 'primitive':
@@ -295,7 +295,7 @@ class BasePythonClassType {
295
295
  }
296
296
  }
297
297
  class BaseMethod {
298
- constructor(generator, pythonName, jsName, parameters, returns, docs, isStatic, opts) {
298
+ constructor(generator, pythonName, jsName, parameters, returns, docs, isStatic, pythonParent, opts) {
299
299
  this.generator = generator;
300
300
  this.pythonName = pythonName;
301
301
  this.jsName = jsName;
@@ -303,6 +303,7 @@ class BaseMethod {
303
303
  this.returns = returns;
304
304
  this.docs = docs;
305
305
  this.isStatic = isStatic;
306
+ this.pythonParent = pythonParent;
306
307
  this.classAsFirstParameter = false;
307
308
  this.returnFromJSIIMethod = true;
308
309
  this.shouldEmitBody = true;
@@ -442,6 +443,10 @@ class BaseMethod {
442
443
  arguments: documentableArgs,
443
444
  documentableItem: `method-${this.pythonName}`,
444
445
  });
446
+ if ((this.shouldEmitBody || forceEmitBody) &&
447
+ (!renderAbstract || !this.abstract)) {
448
+ emitParameterTypeChecks(code, pythonParams.slice(1), `${this.pythonParent.pythonName}.${this.pythonName}`);
449
+ }
445
450
  this.emitBody(code, context, renderAbstract, forceEmitBody, liftedPropNames, pythonParams[0], returnType);
446
451
  code.closeBlock();
447
452
  }
@@ -541,12 +546,13 @@ class BaseMethod {
541
546
  }
542
547
  }
543
548
  class BaseProperty {
544
- constructor(generator, pythonName, jsName, type, docs, opts) {
549
+ constructor(generator, pythonName, jsName, type, docs, pythonParent, opts) {
545
550
  this.generator = generator;
546
551
  this.pythonName = pythonName;
547
552
  this.jsName = jsName;
548
553
  this.type = type;
549
554
  this.docs = docs;
555
+ this.pythonParent = pythonParent;
550
556
  this.shouldEmitBody = true;
551
557
  const { abstract = false, immutable = false, isStatic = false } = opts;
552
558
  this.abstract = abstract;
@@ -573,6 +579,7 @@ class BaseProperty {
573
579
  this.generator.emitDocString(code, this.apiLocation, this.docs, {
574
580
  documentableItem: `prop-${this.pythonName}`,
575
581
  });
582
+ // NOTE: No parameters to validate here, this is a getter...
576
583
  if ((this.shouldEmitBody || forceEmitBody) &&
577
584
  (!renderAbstract || !this.abstract)) {
578
585
  code.line(`return typing.cast(${pythonType}, jsii.${this.jsiiGetMethod}(${this.implicitParameter}, "${this.jsName}"))`);
@@ -590,6 +597,11 @@ class BaseProperty {
590
597
  openSignature(code, 'def', this.pythonName, [this.implicitParameter, `value: ${pythonType}`], false, 'None');
591
598
  if ((this.shouldEmitBody || forceEmitBody) &&
592
599
  (!renderAbstract || !this.abstract)) {
600
+ emitParameterTypeChecks(code, [`value: ${pythonType}`],
601
+ // In order to get a property accessor, we must resort to getting the
602
+ // attribute on the type, instead of the value (where the getter would
603
+ // be implicitly invoked for us...)
604
+ `getattr(${this.pythonParent.pythonName}, ${JSON.stringify(this.pythonName)}).fset`);
593
605
  code.line(`jsii.${this.jsiiSetMethod}(${this.implicitParameter}, "${this.jsName}", value)`);
594
606
  }
595
607
  else {
@@ -724,7 +736,7 @@ class Struct extends BasePythonClassType {
724
736
  : [implicitParameter];
725
737
  openSignature(code, 'def', '__init__', constructorArguments, false, 'None');
726
738
  this.emitConstructorDocstring(code);
727
- // Re-type struct arguments that were passed as "dict"
739
+ // Re-type struct arguments that were passed as "dict". Do this before validating argument types...
728
740
  for (const member of members.filter((m) => m.isStruct(this.generator))) {
729
741
  // Note that "None" is NOT an instance of dict (that's convenient!)
730
742
  const typeName = (0, type_name_1.toTypeName)(member.type.type).pythonType({
@@ -735,6 +747,7 @@ class Struct extends BasePythonClassType {
735
747
  code.line(`${member.pythonName} = ${typeName}(**${member.pythonName})`);
736
748
  code.closeBlock();
737
749
  }
750
+ emitParameterTypeChecks(code, kwargs, `${this.pythonName}.__init__`);
738
751
  // Required properties, those will always be put into the dict
739
752
  assignDictionary(code, `${implicitParameter}._values: typing.Dict[str, typing.Any]`, members
740
753
  .filter((m) => !m.optional)
@@ -763,6 +776,7 @@ class Struct extends BasePythonClassType {
763
776
  code.line('@builtins.property');
764
777
  openSignature(code, 'def', member.pythonName, ['self'], true, pythonType);
765
778
  member.emitDocString(code);
779
+ // NOTE: No parameter to validate here, this is a getter.
766
780
  code.line(`result = self._values.get(${JSON.stringify(member.pythonName)})`);
767
781
  if (!member.optional) {
768
782
  // Add an assertion to maye MyPY happy!
@@ -1099,6 +1113,8 @@ class PythonModule {
1099
1113
  code.line('import jsii');
1100
1114
  code.line('import publication');
1101
1115
  code.line('import typing_extensions');
1116
+ code.line();
1117
+ code.line('from typeguard import check_type');
1102
1118
  // Determine if we need to write out the kernel load line.
1103
1119
  if (this.loadAssembly) {
1104
1120
  this.emitDependencyImports(code);
@@ -1376,6 +1392,7 @@ class Package {
1376
1392
  install_requires: [
1377
1393
  `jsii${(0, version_utils_1.toPythonVersionRange)(`^${jsiiVersionSimple}`)}`,
1378
1394
  'publication>=0.0.3',
1395
+ 'typeguard~=2.13.3',
1379
1396
  ]
1380
1397
  .concat(dependencies)
1381
1398
  .sort(),
@@ -1756,21 +1773,23 @@ class PythonGenerator extends generator_1.Generator {
1756
1773
  if (cls.initializer !== undefined) {
1757
1774
  const { parameters = [] } = cls.initializer;
1758
1775
  klass.addMember(new Initializer(this, '__init__', undefined, parameters, undefined, cls.initializer.docs, false, // Never static
1759
- { liftedProp: this.getliftedProp(cls.initializer), parent: cls }));
1776
+ klass, { liftedProp: this.getliftedProp(cls.initializer), parent: cls }));
1760
1777
  }
1761
1778
  this.addPythonType(klass);
1762
1779
  }
1763
1780
  onStaticMethod(cls, method) {
1764
1781
  const { parameters = [] } = method;
1765
- this.getPythonType(cls.fqn).addMember(new StaticMethod(this, toPythonMethodName(method.name), method.name, parameters, method.returns, method.docs, true, // Always static
1766
- {
1782
+ const klass = this.getPythonType(cls.fqn);
1783
+ klass.addMember(new StaticMethod(this, toPythonMethodName(method.name), method.name, parameters, method.returns, method.docs, true, // Always static
1784
+ klass, {
1767
1785
  abstract: method.abstract,
1768
1786
  liftedProp: this.getliftedProp(method),
1769
1787
  parent: cls,
1770
1788
  }));
1771
1789
  }
1772
1790
  onStaticProperty(cls, prop) {
1773
- this.getPythonType(cls.fqn).addMember(new StaticProperty(this, toPythonPropertyName(prop.name, prop.const), prop.name, prop, prop.docs, {
1791
+ const klass = this.getPythonType(cls.fqn);
1792
+ klass.addMember(new StaticProperty(this, toPythonPropertyName(prop.name, prop.const), prop.name, prop, prop.docs, klass, {
1774
1793
  abstract: prop.abstract,
1775
1794
  immutable: prop.immutable,
1776
1795
  isStatic: prop.static,
@@ -1779,15 +1798,16 @@ class PythonGenerator extends generator_1.Generator {
1779
1798
  }
1780
1799
  onMethod(cls, method) {
1781
1800
  const { parameters = [] } = method;
1801
+ const klass = this.getPythonType(cls.fqn);
1782
1802
  if (method.async) {
1783
- this.getPythonType(cls.fqn).addMember(new AsyncMethod(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, {
1803
+ klass.addMember(new AsyncMethod(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, klass, {
1784
1804
  abstract: method.abstract,
1785
1805
  liftedProp: this.getliftedProp(method),
1786
1806
  parent: cls,
1787
1807
  }));
1788
1808
  }
1789
1809
  else {
1790
- this.getPythonType(cls.fqn).addMember(new Method(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, {
1810
+ klass.addMember(new Method(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, klass, {
1791
1811
  abstract: method.abstract,
1792
1812
  liftedProp: this.getliftedProp(method),
1793
1813
  parent: cls,
@@ -1795,7 +1815,8 @@ class PythonGenerator extends generator_1.Generator {
1795
1815
  }
1796
1816
  }
1797
1817
  onProperty(cls, prop) {
1798
- this.getPythonType(cls.fqn).addMember(new Property(this, toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, prop.docs, {
1818
+ const klass = this.getPythonType(cls.fqn);
1819
+ klass.addMember(new Property(this, toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, prop.docs, klass, {
1799
1820
  abstract: prop.abstract,
1800
1821
  immutable: prop.immutable,
1801
1822
  isStatic: prop.static,
@@ -1820,17 +1841,19 @@ class PythonGenerator extends generator_1.Generator {
1820
1841
  }
1821
1842
  onInterfaceMethod(ifc, method) {
1822
1843
  const { parameters = [] } = method;
1823
- this.getPythonType(ifc.fqn).addMember(new InterfaceMethod(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, { liftedProp: this.getliftedProp(method), parent: ifc }));
1844
+ const klass = this.getPythonType(ifc.fqn);
1845
+ klass.addMember(new InterfaceMethod(this, toPythonMethodName(method.name, method.protected), method.name, parameters, method.returns, method.docs, !!method.static, klass, { liftedProp: this.getliftedProp(method), parent: ifc }));
1824
1846
  }
1825
1847
  onInterfaceProperty(ifc, prop) {
1826
1848
  let ifaceProperty;
1849
+ const klass = this.getPythonType(ifc.fqn);
1827
1850
  if (ifc.datatype) {
1828
1851
  ifaceProperty = new StructField(this, prop, ifc);
1829
1852
  }
1830
1853
  else {
1831
- ifaceProperty = new InterfaceProperty(this, toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, prop.docs, { immutable: prop.immutable, isStatic: prop.static, parent: ifc });
1854
+ ifaceProperty = new InterfaceProperty(this, toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, prop.docs, klass, { immutable: prop.immutable, isStatic: prop.static, parent: ifc });
1832
1855
  }
1833
- this.getPythonType(ifc.fqn).addMember(ifaceProperty);
1856
+ klass.addMember(ifaceProperty);
1834
1857
  }
1835
1858
  onBeginEnum(enm) {
1836
1859
  this.addPythonType(new Enum(this, (0, util_2.toPythonIdentifier)(enm.name), enm, enm.fqn, {}, enm.docs));
@@ -1988,6 +2011,50 @@ function openSignature(code, keyword, name, params, trailingComma = false, retur
1988
2011
  code.unindent(false);
1989
2012
  code.openBlock(`)${suffix}`);
1990
2013
  }
2014
+ /**
2015
+ * Emits runtime type checking code for parameters.
2016
+ *
2017
+ * @param code the CodeMaker to use for emitting code.
2018
+ * @param params the parameter signatures to be type-checked.
2019
+ * @param typedEntity the type-annotated entity.
2020
+ */
2021
+ function emitParameterTypeChecks(code, params, typedEntity) {
2022
+ const paramInfo = params.map((param) => {
2023
+ const [name] = param.split(/\s*[:=]\s*/, 1);
2024
+ if (name === '*') {
2025
+ return { kwargsMark: true };
2026
+ }
2027
+ else if (name.startsWith('*')) {
2028
+ return { name: name.slice(1), is_rest: true };
2029
+ }
2030
+ return { name };
2031
+ });
2032
+ const typesVar = slugifyAsNeeded('type_hints', paramInfo
2033
+ .filter((param) => param.name != null)
2034
+ .map((param) => param.name.split(/\s*:\s*/)[0]));
2035
+ let openedBlock = false;
2036
+ for (const { is_rest, kwargsMark, name } of paramInfo) {
2037
+ if (kwargsMark) {
2038
+ // This is the keyword-args separator, we won't check keyword arguments here because the kwargs will be rolled
2039
+ // up into a struct instance, and that struct's constructor will be checking again...
2040
+ break;
2041
+ }
2042
+ if (!openedBlock) {
2043
+ code.openBlock('if __debug__');
2044
+ code.line(`${typesVar} = typing.get_type_hints(${typedEntity})`);
2045
+ openedBlock = true;
2046
+ }
2047
+ let expectedType = `${typesVar}[${JSON.stringify(name)}]`;
2048
+ if (is_rest) {
2049
+ // This is a vararg, so the value will appear as a tuple.
2050
+ expectedType = `typing.Tuple[${expectedType}, ...]`;
2051
+ }
2052
+ code.line(`check_type(argname=${JSON.stringify(`argument ${name}`)}, value=${name}, expected_type=${expectedType})`);
2053
+ }
2054
+ if (openedBlock) {
2055
+ code.closeBlock();
2056
+ }
2057
+ }
1991
2058
  function assignCallResult(code, variable, funct, params) {
1992
2059
  const prefix = `${variable} = ${funct}(`;
1993
2060
  const suffix = ')';
package/lib/version.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /** The short version number for this JSII compiler (e.g: `X.Y.Z`) */
2
- export declare const VERSION = "1.62.0";
2
+ export declare const VERSION = "1.63.0";
3
3
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
4
- export declare const VERSION_DESC = "1.62.0 (build 293ac17)";
4
+ export declare const VERSION_DESC = "1.63.0 (build 7c24e36)";
5
5
  //# sourceMappingURL=version.d.ts.map
package/lib/version.js CHANGED
@@ -1,9 +1,9 @@
1
1
  "use strict";
2
- // Generated at 2022-07-12T18:04:59Z by generate.sh
2
+ // Generated at 2022-07-26T16:29:28Z by generate.sh
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.VERSION_DESC = exports.VERSION = void 0;
5
5
  /** The short version number for this JSII compiler (e.g: `X.Y.Z`) */
6
- exports.VERSION = '1.62.0';
6
+ exports.VERSION = '1.63.0';
7
7
  /** The qualified version number for this JSII compiler (e.g: `X.Y.Z (build #######)`) */
8
- exports.VERSION_DESC = '1.62.0 (build 293ac17)';
8
+ exports.VERSION_DESC = '1.63.0 (build 7c24e36)';
9
9
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jsii-pacmak",
3
- "version": "1.62.0",
3
+ "version": "1.63.0",
4
4
  "description": "A code generation framework for jsii backend languages",
5
5
  "license": "Apache-2.0",
6
6
  "author": {
@@ -37,31 +37,31 @@
37
37
  "package": "package-js"
38
38
  },
39
39
  "dependencies": {
40
- "@jsii/check-node": "1.62.0",
41
- "@jsii/spec": "^1.62.0",
40
+ "@jsii/check-node": "1.63.0",
41
+ "@jsii/spec": "^1.63.0",
42
42
  "clone": "^2.1.2",
43
- "codemaker": "^1.62.0",
43
+ "codemaker": "^1.63.0",
44
44
  "commonmark": "^0.30.0",
45
45
  "escape-string-regexp": "^4.0.0",
46
46
  "fs-extra": "^10.1.0",
47
- "jsii-reflect": "^1.62.0",
48
- "jsii-rosetta": "^1.62.0",
47
+ "jsii-reflect": "^1.63.0",
48
+ "jsii-rosetta": "^1.63.0",
49
49
  "semver": "^7.3.7",
50
50
  "spdx-license-list": "^6.6.0",
51
51
  "xmlbuilder": "^15.1.1",
52
52
  "yargs": "^16.2.0"
53
53
  },
54
54
  "devDependencies": {
55
- "@jsii/dotnet-runtime": "^1.62.0",
56
- "@jsii/java-runtime": "^1.62.0",
57
- "@jsii/go-runtime": "^1.62.0",
58
- "@scope/jsii-calc-lib": "^1.62.0",
55
+ "@jsii/dotnet-runtime": "^1.63.0",
56
+ "@jsii/java-runtime": "^1.63.0",
57
+ "@jsii/go-runtime": "^1.63.0",
58
+ "@scope/jsii-calc-lib": "^1.63.0",
59
59
  "@types/clone": "^2.1.1",
60
60
  "@types/commonmark": "^0.27.5",
61
61
  "@types/fs-extra": "^9.0.13",
62
62
  "@types/semver": "^7.3.10",
63
- "jsii": "^1.62.0",
64
- "jsii-build-tools": "^1.62.0",
63
+ "jsii": "^1.63.0",
64
+ "jsii-build-tools": "^1.63.0",
65
65
  "jsii-calc": "^3.20.120"
66
66
  },
67
67
  "keywords": [