From 6cd4903911651434486e15d42986489dd83dbabb Mon Sep 17 00:00:00 2001 From: Rico Huijbers Date: Fri, 19 Apr 2019 11:32:38 +0200 Subject: [PATCH] feat(jsii-pacmak): add Python docstrings (#470) Add support for docstrings to the Python generator. --- packages/jsii-pacmak/lib/markdown.ts | 166 +++++ packages/jsii-pacmak/lib/targets/python.ts | 183 +++++- packages/jsii-pacmak/package-lock.json | 35 +- packages/jsii-pacmak/package.json | 5 +- .../expected.jsii-calc-base/python/setup.py | 2 +- .../src/scope/jsii_calc_base/__init__.py | 5 + .../expected.jsii-calc-lib/python/setup.py | 2 +- .../src/scope/jsii_calc_lib/__init__.py | 48 ++ .../test/expected.jsii-calc/python/setup.py | 2 +- .../python/src/jsii_calc/__init__.py | 605 ++++++++++++++++++ packages/jsii-pacmak/test/test.python.ts | 171 +++++ 11 files changed, 1202 insertions(+), 22 deletions(-) create mode 100644 packages/jsii-pacmak/lib/markdown.ts create mode 100644 packages/jsii-pacmak/test/test.python.ts diff --git a/packages/jsii-pacmak/lib/markdown.ts b/packages/jsii-pacmak/lib/markdown.ts new file mode 100644 index 0000000000..d2577ff698 --- /dev/null +++ b/packages/jsii-pacmak/lib/markdown.ts @@ -0,0 +1,166 @@ +import commonmark = require('commonmark'); + +/** + * Convert MarkDown to RST + * + * This is hard, and I'm doing it very hackily to get something out quickly. + * + * Preferably, the next person to look at this should a little more OO + * instead of procedural. + */ +export function md2rst(text: string) { + const parser = new commonmark.Parser({ smart: false }); + const ast = parser.parse(text); + + const ret = new Array(); + + let indent = 0; + function line(...xs: string[]) { + for (const x of xs) { + ret.push((' '.repeat(indent) + x).trimRight()); + } + } + + function directive(name: string, opening: boolean) { + if (opening) { + line(`.. ${name}::`); + brk(); + indent += 3; + } else { + indent -= 3; + } + } + + function brk() { + if (ret.length > 0 && ret[ret.length - 1].trim() !== '') { ret.push(''); } + } + + function textOf(node: commonmark.Node) { + return node.literal || ''; + } + + let para = new Paragraph(); // Where to accumulate text fragments + let lastParaLine: number; // Where the last paragraph ended, in order to add :: + let nextParaPrefix: string | undefined; + + pump(ast, { + block_quote(_node, entering) { + directive('epigraph', entering); + }, + + heading(node, _entering) { + line(node.literal || ''); + line(headings[node.level - 1].repeat(textOf(node).length)); + }, + + paragraph(node, entering) { + if (entering) { + para = new Paragraph(nextParaPrefix); + nextParaPrefix = undefined; + } else { + // Don't break inside list item + if (node.parent == null || node.parent.type !== 'item') { + brk(); + } + line(...para.lines()); + lastParaLine = ret.length - 1; + } + }, + + text(node) { para.add(textOf(node)); }, + softbreak() { para.newline(); }, + linebreak() { para.newline(); }, + thematic_break() { line('------'); }, + code(node) { para.add('``' + textOf(node) + '``'); }, + strong() { para.add('**'); }, + emph() { para.add('*'); }, + + list() { + brk(); + }, + + link(node, entering) { + if (entering) { + para.add('`'); + } else { + para.add(' <' + (node.destination || '') + '>`_'); + } + }, + + item(node, _entering) { + // AST hierarchy looks like list -> item -> paragraph -> text + if (node.listType === 'bullet') { + nextParaPrefix = '- '; + } else { + nextParaPrefix = `${node.listStart}. `; + } + + }, + + code_block(node) { + // Poke a double :: at the end of the previous line as per ReST "literal block" syntax. + if (lastParaLine !== undefined) { + const lastLine = ret[lastParaLine]; + ret[lastParaLine] = lastLine.replace(/[\W]$/, '::'); + if (ret[lastParaLine] === lastLine) { ret[lastParaLine] = lastLine + '::'; } + } else { + line('Example::'); + } + + brk(); + + indent += 3; + + for (const l of textOf(node).split('\n')) { + line(l); + } + + indent -= 3; + } + + }); + + return ret.join('\n').trimRight(); +} + +class Paragraph { + private readonly parts = new Array(); + + constructor(text?: string) { + if (text !== undefined) { this.parts.push(text); } + } + + public add(text: string) { + this.parts.push(text); + } + + public newline() { + this.parts.push('\n'); + } + + public lines(): string[] { + return this.parts.length > 0 ? this.toString().split('\n') : []; + } + + public toString() { + return this.parts.join('').trimRight(); + } +} + +const headings = ['=', '-', '^', '"']; + +type Handler = (node: commonmark.Node, entering: boolean) => void; +type Handlers = {[key in commonmark.NodeType]?: Handler }; + +function pump(ast: commonmark.Node, handlers: Handlers) { + const walker = ast.walker(); + let event = walker.next(); + while (event) { + const h = handlers[event.node.type]; + if (h) { + h(event.node, event.entering); + } + + event = walker.next(); + } +} \ No newline at end of file diff --git a/packages/jsii-pacmak/lib/targets/python.ts b/packages/jsii-pacmak/lib/targets/python.ts index ecfdd90e4c..1aba2ca687 100644 --- a/packages/jsii-pacmak/lib/targets/python.ts +++ b/packages/jsii-pacmak/lib/targets/python.ts @@ -4,6 +4,7 @@ import { CodeMaker, toSnakeCase } from 'codemaker'; import * as escapeStringRegexp from 'escape-string-regexp'; import * as spec from 'jsii-spec'; import { Generator, GeneratorOptions } from '../generator'; +import { md2rst } from '../markdown'; import { Target, TargetOptions } from '../target'; import { shell } from '../util'; @@ -129,6 +130,19 @@ const sortMembers = (sortable: PythonBase[], resolver: TypeResolver): PythonBase return sorted; }; +/** + * Iterates over an iterable, yielding true for every element after the first + * + * Useful for separating item lists. + */ +function* separate(xs: Iterable): IterableIterator<[T, boolean]> { + let sep = false; + for (const x of xs) { + yield [x, sep]; + sep = true; + } +} + const recurseForNamedTypeReferences = (typeRef: spec.TypeReference): spec.NamedTypeReference[] => { if (spec.isPrimitiveTypeReference(typeRef)) { return []; @@ -181,7 +195,7 @@ abstract class BasePythonClassType implements PythonType, ISortableType { protected bases: spec.TypeReference[]; protected members: PythonBase[]; - constructor(name: string, fqn: string, opts: PythonTypeOpts) { + constructor(name: string, fqn: string, opts: PythonTypeOpts, protected readonly docs: spec.Docs | undefined) { const { bases = [], } = opts; @@ -234,6 +248,7 @@ abstract class BasePythonClassType implements PythonType, ISortableType { const bases = classParams.length > 0 ? `(${classParams.join(", ")})` : ""; code.openBlock(`class ${this.name}${bases}`); + emitDocString(code, this.docs); this.emitPreamble(code, resolver); @@ -282,6 +297,7 @@ abstract class BaseMethod implements PythonBase { private readonly jsName: string | undefined, private readonly parameters: spec.Parameter[], private readonly returns?: spec.OptionalValue, + private readonly docs?: spec.Docs, opts: BaseMethodOpts = {}) { this.abstract = !!opts.abstract; this.liftedProp = opts.liftedProp; @@ -332,6 +348,8 @@ abstract class BaseMethod implements PythonBase { pythonParams.push(`${paramName}: ${paramType}${paramDefault}`); } + const documentableArgs = [...this.parameters]; + // If we have a lifted parameter, then we'll drop the last argument to our params // and then we'll lift all of the params of the lifted type as keyword arguments // to the function. @@ -354,6 +372,9 @@ abstract class BaseMethod implements PythonBase { pythonParams.push(`${paramName}: ${paramType}${paramDefault}`); } } + + // Document them as keyword arguments + documentableArgs.push(...liftedProperties); } else if (this.parameters.length >= 1 && this.parameters[this.parameters.length - 1].variadic) { // Another situation we could be in, is that instead of having a plain parameter // we have a variadic parameter where we need to expand the last parameter as a @@ -383,6 +404,7 @@ abstract class BaseMethod implements PythonBase { } code.openBlock(`def ${this.name}(${pythonParams.join(", ")}) -> ${returnType}`); + emitDocString(code, this.docs, { arguments: documentableArgs }); this.emitBody(code, resolver, renderAbstract, forceEmitBody); code.closeBlock(); } @@ -501,6 +523,7 @@ abstract class BaseProperty implements PythonBase { constructor(public readonly name: string, private readonly jsName: string, private readonly type: spec.OptionalValue, + private readonly docs: spec.Docs | undefined, opts: BasePropertyOpts = {}) { const { abstract = false, @@ -521,6 +544,7 @@ abstract class BaseProperty implements PythonBase { code.line("@abc.abstractmethod"); } code.openBlock(`def ${this.name}(${this.implicitParameter}) -> ${pythonType}`); + emitDocString(code, this.docs); if ((this.shouldEmitBody || forceEmitBody) && (!renderAbstract || !this.abstract)) { code.line(`return jsii.${this.jsiiGetMethod}(${this.implicitParameter}, "${this.jsName}")`); } else { @@ -556,6 +580,7 @@ class Interface extends BasePythonClassType { resolver = this.fqn ? resolver.bind(this.fqn) : resolver; const proxyBases: string[] = this.bases.map(b => `jsii.proxy_for(${resolver.resolve({ type: b })})`); code.openBlock(`class ${this.getProxyClassName()}(${proxyBases.join(", ")})`); + emitDocString(code, this.docs); code.line(`__jsii_type__ = "${this.fqn}"`); if (this.members.length > 0) { @@ -639,7 +664,9 @@ class TypedDict extends BasePythonClassType { // Now we'll emit the mandatory members. code.line(`@jsii.data_type(jsii_type="${this.fqn}")`); code.openBlock(`class ${this.name}(_${this.name})`); - for (const member of sortMembers(mandatoryMembers, resolver)) { + emitDocString(code, this.docs); + for (const [member, sep] of separate(sortMembers(mandatoryMembers, resolver))) { + if (sep) { code.line(''); } member.emit(code, resolver); } code.closeBlock(); @@ -654,10 +681,12 @@ class TypedDict extends BasePythonClassType { } else { code.openBlock(`class ${this.name}(${classParams.join(", ")})`); } + emitDocString(code, this.docs); // Finally we'll just iterate over and emit all of our members. if (this.members.length > 0) { - for (const member of sortMembers(this.members, resolver)) { + for (const [member, sep] of separate(sortMembers(this.members, resolver))) { + if (sep) { code.line(''); } member.emit(code, resolver); } } else { @@ -681,7 +710,9 @@ class TypedDict extends BasePythonClassType { class TypedDictProperty implements PythonBase { constructor(public readonly name: string, - private readonly type: spec.OptionalValue) {} + private readonly type: spec.OptionalValue, + private readonly docs: spec.Docs | undefined, + ) {} public get optional(): boolean { return !!this.type.optional; @@ -693,6 +724,7 @@ class TypedDictProperty implements PythonBase { { forwardReferences: false, ignoreOptional: true } ); code.line(`${this.name}: ${resolvedType}`); + emitDocString(code, this.docs); } } @@ -708,8 +740,8 @@ class Class extends BasePythonClassType { private abstractBases: spec.ClassType[]; private interfaces: spec.NamedTypeReference[]; - constructor(name: string, fqn: string, opts: ClassOpts) { - super(name, fqn, opts); + constructor(name: string, fqn: string, opts: ClassOpts, docs: spec.Docs | undefined) { + super(name, fqn, opts, docs); const { abstract = false, interfaces = [], abstractBases = [] } = opts; @@ -864,18 +896,14 @@ class Enum extends BasePythonClassType { } class EnumMember implements PythonBase { - - public readonly name: string; - - private readonly value: string; - - constructor(name: string, value: string) { + constructor(public readonly name: string, private readonly value: string, private readonly docs: spec.Docs | undefined) { this.name = name; this.value = value; } public emit(code: CodeMaker, _resolver: TypeResolver) { code.line(`${this.name} = "${this.value}"`); + emitDocString(code, this.docs); } } @@ -1070,6 +1098,9 @@ class Package { code.line(this.metadata.readme !== undefined ? this.metadata.readme.markdown : ""); code.closeFile("README.md"); + // Strip " (build abcdef)" from the jsii version + const jsiiVersionSimple = this.metadata.jsiiVersion.replace(/ .*$/, ''); + const setupKwargs = { name: this.name, version: this.version, @@ -1086,7 +1117,7 @@ class Package { packages: modules.map(m => m.name), package_data: packageData, python_requires: ">=3.6", - install_requires: ["jsii", "publication>=0.0.3"].concat(dependencies), + install_requires: [`jsii~=${jsiiVersionSimple}`, "publication>=0.0.3"].concat(dependencies), }; // We Need a setup.py to make this Package, actually a Package. @@ -1420,6 +1451,7 @@ class PythonGenerator extends Generator { toPythonIdentifier(ns.replace(/^.+\.([^\.]+)$/, "$1")), ns, {}, + undefined, ), ); } @@ -1433,8 +1465,9 @@ class PythonGenerator extends Generator { abstract, bases: (cls.base && [this.findType(cls.base)]) || [], interfaces: cls.interfaces && cls.interfaces.map(base => this.findType(base)), - abstractBases: abstract ? this.getAbstractBases(cls) : [] - } + abstractBases: abstract ? this.getAbstractBases(cls) : [], + }, + cls.docs, ); if (cls.initializer !== undefined) { @@ -1446,6 +1479,7 @@ class PythonGenerator extends Generator { undefined, parameters, undefined, + cls.initializer.docs, { liftedProp: this.getliftedProp(cls.initializer), parent: cls }, ) ); @@ -1463,6 +1497,7 @@ class PythonGenerator extends Generator { method.name, parameters, method.returns, + method.docs, { abstract: method.abstract, liftedProp: this.getliftedProp(method) }, ) ); @@ -1474,6 +1509,7 @@ class PythonGenerator extends Generator { toPythonPropertyName(prop.name, prop.const), prop.name, prop, + prop.docs, { abstract: prop.abstract, immutable: prop.immutable }, ) ); @@ -1489,6 +1525,7 @@ class PythonGenerator extends Generator { method.name, parameters, method.returns, + method.docs, { abstract: method.abstract, liftedProp: this.getliftedProp(method) }, ) ); @@ -1499,6 +1536,7 @@ class PythonGenerator extends Generator { method.name, parameters, method.returns, + method.docs, { abstract: method.abstract, liftedProp: this.getliftedProp(method) }, ) ); @@ -1511,6 +1549,7 @@ class PythonGenerator extends Generator { toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, + prop.docs, { abstract: prop.abstract, immutable: prop.immutable }, ) ); @@ -1528,12 +1567,14 @@ class PythonGenerator extends Generator { toPythonIdentifier(ifc.name), ifc.fqn, { bases: ifc.interfaces && ifc.interfaces.map(base => this.findType(base)) }, + ifc.docs, ); } else { iface = new Interface( toPythonIdentifier(ifc.name), ifc.fqn, { bases: ifc.interfaces && ifc.interfaces.map(base => this.findType(base)) }, + ifc.docs, ); } @@ -1551,6 +1592,7 @@ class PythonGenerator extends Generator { method.name, parameters, method.returns, + method.docs, { liftedProp: this.getliftedProp(method) }, ) ); @@ -1563,12 +1605,14 @@ class PythonGenerator extends Generator { ifaceProperty = new TypedDictProperty( toPythonIdentifier(prop.name), prop, + prop.docs, ); } else { ifaceProperty = new InterfaceProperty( toPythonPropertyName(prop.name, prop.const, prop.protected), prop.name, prop, + prop.docs, { immutable: prop.immutable }, ); } @@ -1577,7 +1621,7 @@ class PythonGenerator extends Generator { } protected onBeginEnum(enm: spec.EnumType) { - this.addPythonType(new Enum(toPythonIdentifier(enm.name), enm.fqn, {})); + this.addPythonType(new Enum(toPythonIdentifier(enm.name), enm.fqn, {}, enm.docs)); } protected onEnumMember(enm: spec.EnumType, member: spec.EnumMember) { @@ -1585,6 +1629,7 @@ class PythonGenerator extends Generator { new EnumMember( toPythonIdentifier(member.name), member.name, + member.docs, ) ); } @@ -1673,3 +1718,109 @@ class PythonGenerator extends Generator { return abstractBases; } } + +/** + * Positional argument or keyword parameter + */ +interface DocumentableArgument { + name: string; + docs?: spec.Docs; +} + +function emitDocString(code: CodeMaker, docs: spec.Docs | undefined, options: { + arguments?: DocumentableArgument[] + } = {}) { + if ((!docs || Object.keys(docs).length === 0) && !options.arguments) { return; } + if (!docs) { docs = {}; } + + const lines = new Array(); + + if (docs.summary) { + lines.push(md2rst(docs.summary)); + brk(); + } else { + lines.push(''); + } + + function brk() { + if (lines.length > 0 && lines[lines.length - 1].trim() !== '') { lines.push(''); } + } + + function block(heading: string, content: string, doBrk = true) { + if (doBrk) { brk(); } + lines.push(heading); + for (const line of md2rst(content).split('\n')) { + lines.push(` ${line}`); + } + if (doBrk) { brk(); } + } + + if (docs.remarks) { + brk(); + lines.push(...md2rst(docs.remarks || '').split('\n')); + brk(); + } + + if (options.arguments && options.arguments.length > 0) { + brk(); + lines.push('Arguments:'); + for (const param of options.arguments) { + // Add a line for every argument. Even if there is no description, we need + // the docstring so that the Sphinx extension can add the type annotations. + lines.push(` ${param.name}: ${onelineDescription(param.docs)}`); + } + brk(); + } + + if (docs.default) { block('Default:', docs.default); } + if (docs.returns) { block('Returns:', docs.returns); } + if (docs.deprecated) { block('Deprecated:', docs.deprecated); } + if (docs.see) { block('See:', docs.see, false); } + if (docs.stability === spec.Stability.Experimental) { block('Stability:', docs.stability, false); } + if (docs.subclassable) { block('Subclassable:', 'Yes'); } + + for (const [k, v] of Object.entries(docs.custom || {})) { + block(k + ':', v, false); + } + + if (docs.example) { + brk(); + lines.push('Example::'); + for (const line of docs.example.split('\n')) { + lines.push(` ${line}`); + } + brk(); + } + + while (lines.length > 0 && lines[lines.length - 1] === '') { lines.pop(); } + + if (lines.length === 0) { return; } + + if (lines.length === 1) { + code.line(`"""${lines[0]}"""`); + return; + } + + code.line(`"""${lines[0]}`); + lines.splice(0, 1); + + for (const line of lines) { + code.line(line); + } + + code.line(`"""`); +} + +/** + * Render a one-line description of the given docs, used for method arguments and inlined properties + */ +function onelineDescription(docs: spec.Docs | undefined) { + // Only consider a subset of fields here, we don't have a lot of formatting space + if (!docs) { return '-'; } + + const parts = []; + if (docs.summary) { parts.push(md2rst(docs.summary)); } + if (docs.remarks) { parts.push(md2rst(docs.remarks)); } + if (docs.default) { parts.push(`Default: ${md2rst(docs.default)}`); } + return parts.join(' ').replace(/\s+/g, ' '); +} \ No newline at end of file diff --git a/packages/jsii-pacmak/package-lock.json b/packages/jsii-pacmak/package-lock.json index 89d8f9096e..f27e052d67 100644 --- a/packages/jsii-pacmak/package-lock.json +++ b/packages/jsii-pacmak/package-lock.json @@ -117,6 +117,12 @@ "integrity": "sha1-5zZWSMG0ITalnH1QQGN7O1yDthQ=", "dev": true }, + "@types/commonmark": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@types/commonmark/-/commonmark-0.27.3.tgz", + "integrity": "sha512-aFY6ZuOsvNcTkDfFDLhMtZwBfVn+j0NoPbJ3Khm1ewvQ33VWzNjABif49icrTpObZvELXjAK1z6eaTkNR3sMBg==", + "dev": true + }, "@types/escape-string-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@types/escape-string-regexp/-/escape-string-regexp-1.0.0.tgz", @@ -400,6 +406,17 @@ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, + "commonmark": { + "version": "0.29.0", + "resolved": "https://registry.npmjs.org/commonmark/-/commonmark-0.29.0.tgz", + "integrity": "sha512-Wc3kvAIm0EK85pHsM95Fev31wEN6/zQpwd2qcLDL8psjHRoUFvUeGHevIJAdToWUuFoX8WI/gmeDauqy32xgJQ==", + "requires": { + "entities": "~ 1.1.1", + "mdurl": "~ 1.0.1", + "minimist": "~ 1.2.0", + "string.prototype.repeat": "^0.2.0" + } + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -508,6 +525,11 @@ "once": "^1.4.0" } }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" + }, "escape-string-regexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", @@ -943,6 +965,11 @@ "p-defer": "^1.0.0" } }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, "mem": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/mem/-/mem-4.2.0.tgz", @@ -985,8 +1012,7 @@ "minimist": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" }, "minipass": { "version": "2.3.5", @@ -2441,6 +2467,11 @@ } } }, + "string.prototype.repeat": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-0.2.0.tgz", + "integrity": "sha1-q6Nt4I3O5qWjN9SbLqHaGyj8Ds8=" + }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", diff --git a/packages/jsii-pacmak/package.json b/packages/jsii-pacmak/package.json index 0585e2c11a..b6520375b0 100644 --- a/packages/jsii-pacmak/package.json +++ b/packages/jsii-pacmak/package.json @@ -12,7 +12,7 @@ "build": "npm run gen && tsc --build && chmod +x bin/jsii-pacmak && tslint -p .", "watch": "tsc --build -w", "lint": "tslint -p . --force", - "test": "/bin/bash test/diff-test.sh && /bin/bash test/build-test.sh", + "test": "/bin/bash test/diff-test.sh && /bin/bash test/build-test.sh && nodeunit test/test.*.js", "package": "package-js" }, "keywords": [ @@ -27,6 +27,7 @@ "jsii-spec": "^0.10.2", "spdx-license-list": "^6.0.0", "xmlbuilder": "^12.0.0", + "commonmark": "^0.29.0", "yargs": "^13.2.2" }, "devDependencies": { @@ -34,6 +35,8 @@ "@types/clone": "^0.1.30", "@types/escape-string-regexp": "^1.0.0", "@types/fs-extra": "^5.0.5", + "@types/node": "^8.10.43", + "@types/commonmark": "^0.27.3", "@types/nodeunit": "^0.0.30", "@types/xmlbuilder": "^11.0.1", "@types/yargs": "^13.0.0", diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/setup.py b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/setup.py index 7e881ae1f5..942fc19cd0 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/setup.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/setup.py @@ -29,7 +29,7 @@ }, "python_requires": ">=3.6", "install_requires": [ - "jsii", + "jsii~=0.10.1", "publication>=0.0.3", "scope.jsii-calc-base-of-base~=0.10.2" ] diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py index 301742483e..745af9bc02 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-base/python/src/scope/jsii_calc_base/__init__.py @@ -12,6 +12,7 @@ import scope.jsii_calc_base_of_base __jsii_assembly__ = jsii.JSIIAssembly.load("@scope/jsii-calc-base", "0.10.2", __name__, "jsii-calc-base@0.10.2.jsii.tgz") class Base(metaclass=jsii.JSIIAbstractClass, jsii_type="@scope/jsii-calc-base.Base"): + """A base class.""" @staticmethod def __jsii_proxy_class__(): return _BaseProxy @@ -21,6 +22,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="typeName") def type_name(self) -> typing.Any: + """ + Returns: + the name of the class (to verify native type names are created for derived classes). + """ return jsii.invoke(self, "typeName", []) diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/setup.py b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/setup.py index 3c3436ec96..c97d7191a6 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/setup.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/setup.py @@ -29,7 +29,7 @@ }, "python_requires": ">=3.6", "install_requires": [ - "jsii", + "jsii~=0.10.1", "publication>=0.0.3", "scope.jsii-calc-base~=0.10.2" ] diff --git a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py index ddb15bdda3..e96c965b3e 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc-lib/python/src/scope/jsii_calc_lib/__init__.py @@ -13,11 +13,13 @@ __jsii_assembly__ = jsii.JSIIAssembly.load("@scope/jsii-calc-lib", "0.10.2", __name__, "jsii-calc-lib@0.10.2.jsii.tgz") @jsii.enum(jsii_type="@scope/jsii-calc-lib.EnumFromScopedModule") class EnumFromScopedModule(enum.Enum): + """Check that enums from @scoped packages can be references. See awslabs/jsii#138.""" Value1 = "Value1" Value2 = "Value2" @jsii.interface(jsii_type="@scope/jsii-calc-lib.IDoublable") class IDoublable(jsii.compat.Protocol): + """The general contract for a concrete number.""" @staticmethod def __jsii_proxy_class__(): return _IDoublableProxy @@ -29,6 +31,7 @@ def double_value(self) -> jsii.Number: class _IDoublableProxy(): + """The general contract for a concrete number.""" __jsii_type__ = "@scope/jsii-calc-lib.IDoublable" @property @jsii.member(jsii_name="doubleValue") @@ -38,24 +41,41 @@ def double_value(self) -> jsii.Number: @jsii.interface(jsii_type="@scope/jsii-calc-lib.IFriendly") class IFriendly(jsii.compat.Protocol): + """Applies to classes that are considered friendly. + + These classes can be greeted with + a "hello" or "goodbye" blessing and they will respond back in a fun and friendly manner. + """ @staticmethod def __jsii_proxy_class__(): return _IFriendlyProxy @jsii.member(jsii_name="hello") def hello(self) -> str: + """Say hello!""" ... class _IFriendlyProxy(): + """Applies to classes that are considered friendly. + + These classes can be greeted with + a "hello" or "goodbye" blessing and they will respond back in a fun and friendly manner. + """ __jsii_type__ = "@scope/jsii-calc-lib.IFriendly" @jsii.member(jsii_name="hello") def hello(self) -> str: + """Say hello!""" return jsii.invoke(self, "hello", []) @jsii.interface(jsii_type="@scope/jsii-calc-lib.IThreeLevelsInterface") class IThreeLevelsInterface(scope.jsii_calc_base.IBaseInterface, jsii.compat.Protocol): + """Interface that inherits from packages 2 levels up the tree. + + Their presence validates that .NET/Java/jsii-reflect can track all fields + far enough up the tree. + """ @staticmethod def __jsii_proxy_class__(): return _IThreeLevelsInterfaceProxy @@ -66,6 +86,11 @@ def baz(self) -> None: class _IThreeLevelsInterfaceProxy(jsii.proxy_for(scope.jsii_calc_base.IBaseInterface)): + """Interface that inherits from packages 2 levels up the tree. + + Their presence validates that .NET/Java/jsii-reflect can track all fields + far enough up the tree. + """ __jsii_type__ = "@scope/jsii-calc-lib.IThreeLevelsInterface" @jsii.member(jsii_name="baz") def baz(self) -> None: @@ -77,16 +102,25 @@ class _MyFirstStruct(jsii.compat.TypedDict, total=False): @jsii.data_type(jsii_type="@scope/jsii-calc-lib.MyFirstStruct") class MyFirstStruct(_MyFirstStruct): + """This is the first struct we have created in jsii.""" anumber: jsii.Number + """An awesome number value.""" + astring: str + """A string value.""" @jsii.data_type(jsii_type="@scope/jsii-calc-lib.StructWithOnlyOptionals") class StructWithOnlyOptionals(jsii.compat.TypedDict, total=False): + """This is a struct with only optional properties.""" optional1: str + """The first optional!""" + optional2: jsii.Number + optional3: bool class Value(scope.jsii_calc_base.Base, metaclass=jsii.JSIIAbstractClass, jsii_type="@scope/jsii-calc-lib.Value"): + """Abstract class which represents a numeric value.""" @staticmethod def __jsii_proxy_class__(): return _ValueProxy @@ -96,12 +130,14 @@ def __init__(self) -> None: @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) @property @jsii.member(jsii_name="value") @abc.abstractmethod def value(self) -> jsii.Number: + """The value.""" ... @@ -109,26 +145,36 @@ class _ValueProxy(Value, jsii.proxy_for(scope.jsii_calc_base.Base)): @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The value.""" return jsii.get(self, "value") @jsii.implements(IDoublable) class Number(Value, metaclass=jsii.JSIIMeta, jsii_type="@scope/jsii-calc-lib.Number"): + """Represents a concrete number.""" def __init__(self, value: jsii.Number) -> None: + """Creates a Number object. + + Arguments: + value: The number. + """ jsii.create(Number, self, [value]) @property @jsii.member(jsii_name="doubleValue") def double_value(self) -> jsii.Number: + """The number multiplied by 2.""" return jsii.get(self, "doubleValue") @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The number.""" return jsii.get(self, "value") class Operation(Value, metaclass=jsii.JSIIAbstractClass, jsii_type="@scope/jsii-calc-lib.Operation"): + """Represents an operation on values.""" @staticmethod def __jsii_proxy_class__(): return _OperationProxy @@ -139,12 +185,14 @@ def __init__(self) -> None: @jsii.member(jsii_name="toString") @abc.abstractmethod def to_string(self) -> str: + """String representation of the value.""" ... class _OperationProxy(Operation, jsii.proxy_for(Value)): @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) diff --git a/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py b/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py index bbdc939928..77110008de 100644 --- a/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py +++ b/packages/jsii-pacmak/test/expected.jsii-calc/python/setup.py @@ -29,7 +29,7 @@ }, "python_requires": ">=3.6", "install_requires": [ - "jsii", + "jsii~=0.10.1", "publication>=0.0.3", "scope.jsii-calc-base~=0.10.2", "scope.jsii-calc-base-of-base~=0.10.2", 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 8427b07726..186ac27ab9 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 @@ -54,11 +54,20 @@ def return_abstract_from_property(self) -> "AbstractClassBase": class AllTypes(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.AllTypes"): + """This class includes property for all types supported by jsii. + + The setters will validate + that the value set is of the expected type and throw otherwise. + """ def __init__(self) -> None: jsii.create(AllTypes, self, []) @jsii.member(jsii_name="anyIn") def any_in(self, inp: typing.Any) -> None: + """ + Arguments: + inp: - + """ return jsii.invoke(self, "anyIn", [inp]) @jsii.member(jsii_name="anyOut") @@ -67,6 +76,10 @@ def any_out(self) -> typing.Any: @jsii.member(jsii_name="enumMethod") def enum_method(self, value: "StringEnum") -> "StringEnum": + """ + Arguments: + value: - + """ return jsii.invoke(self, "enumMethod", [value]) @property @@ -249,18 +262,40 @@ def __init__(self) -> None: @jsii.member(jsii_name="getBar") def get_bar(self, _p1: str, _p2: jsii.Number) -> None: + """ + Arguments: + _p1: - + _p2: - + """ return jsii.invoke(self, "getBar", [_p1, _p2]) @jsii.member(jsii_name="getFoo") def get_foo(self, with_param: str) -> str: + """getXxx() is not allowed (see negatives), but getXxx(a, ...) is okay. + + Arguments: + withParam: - + """ return jsii.invoke(self, "getFoo", [with_param]) @jsii.member(jsii_name="setBar") def set_bar(self, _x: str, _y: jsii.Number, _z: bool) -> None: + """ + Arguments: + _x: - + _y: - + _z: - + """ return jsii.invoke(self, "setBar", [_x, _y, _z]) @jsii.member(jsii_name="setFoo") def set_foo(self, _x: str, _y: jsii.Number) -> None: + """setFoo(x) is not allowed (see negatives), but setXxx(a, b, ...) is okay. + + Arguments: + _x: - + _y: - + """ return jsii.invoke(self, "setFoo", [_x, _y]) @@ -274,10 +309,17 @@ def call_me(self) -> jsii.Number: @jsii.member(jsii_name="callMe2") def call_me2(self) -> jsii.Number: + """Just calls "overrideMeToo".""" return jsii.ainvoke(self, "callMe2", []) @jsii.member(jsii_name="callMeDoublePromise") def call_me_double_promise(self) -> jsii.Number: + """This method calls the "callMe" async method indirectly, which will then invoke a virtual method. + + This is a "double promise" situation, which + means that callbacks are not going to be available immediate, but only + after an "immediates" cycle. + """ return jsii.ainvoke(self, "callMeDoublePromise", []) @jsii.member(jsii_name="dontOverrideMe") @@ -286,6 +328,10 @@ def dont_override_me(self) -> jsii.Number: @jsii.member(jsii_name="overrideMe") def override_me(self, mult: jsii.Number) -> jsii.Number: + """ + Arguments: + mult: - + """ return jsii.ainvoke(self, "overrideMe", [mult]) @jsii.member(jsii_name="overrideMeToo") @@ -308,25 +354,35 @@ def method_two(self) -> None: @jsii.implements(scope.jsii_calc_lib.IFriendly) class BinaryOperation(scope.jsii_calc_lib.Operation, metaclass=jsii.JSIIAbstractClass, jsii_type="jsii-calc.BinaryOperation"): + """Represents an operation with two operands.""" @staticmethod def __jsii_proxy_class__(): return _BinaryOperationProxy def __init__(self, lhs: scope.jsii_calc_lib.Value, rhs: scope.jsii_calc_lib.Value) -> None: + """Creates a BinaryOperation. + + Arguments: + lhs: Left-hand side operand. + rhs: Right-hand side operand. + """ jsii.create(BinaryOperation, self, [lhs, rhs]) @jsii.member(jsii_name="hello") def hello(self) -> str: + """Say hello!""" return jsii.invoke(self, "hello", []) @property @jsii.member(jsii_name="lhs") def lhs(self) -> scope.jsii_calc_lib.Value: + """Left-hand side operand.""" return jsii.get(self, "lhs") @property @jsii.member(jsii_name="rhs") def rhs(self) -> scope.jsii_calc_lib.Value: + """Right-hand side operand.""" return jsii.get(self, "rhs") @@ -334,25 +390,52 @@ class _BinaryOperationProxy(BinaryOperation, jsii.proxy_for(scope.jsii_calc_lib. pass class Add(BinaryOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Add"): + """The "+" binary operation.""" def __init__(self, lhs: scope.jsii_calc_lib.Value, rhs: scope.jsii_calc_lib.Value) -> None: + """Creates a BinaryOperation. + + Arguments: + lhs: Left-hand side operand. + rhs: Right-hand side operand. + """ jsii.create(Add, self, [lhs, rhs]) @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The value.""" return jsii.get(self, "value") @jsii.data_type(jsii_type="jsii-calc.CalculatorProps") class CalculatorProps(jsii.compat.TypedDict, total=False): + """Properties for Calculator.""" initialValue: jsii.Number + maximumValue: jsii.Number class ClassWithDocs(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ClassWithDocs"): + """This class has docs. + + The docs are great. They're a bunch of tags. + + Deprecated: + Use something else please + + See: + https://aws.amazon.com/ + customAttribute: + hasAValue + + Example:: + function anExample() { + } + """ def __init__(self) -> None: jsii.create(ClassWithDocs, self, []) @@ -373,6 +456,10 @@ def mutable_object(self, value: "IMutableObjectLiteral"): class ConstructorPassesThisOut(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ConstructorPassesThisOut"): def __init__(self, consumer: "PartiallyInitializedThisConsumer") -> None: + """ + Arguments: + consumer: - + """ jsii.create(ConstructorPassesThisOut, self, [consumer]) @@ -422,15 +509,29 @@ def __init__(self) -> None: @jsii.member(jsii_name="consumeAnotherPublicInterface") def consume_another_public_interface(self, obj: "IAnotherPublicInterface") -> str: + """ + Arguments: + obj: - + """ return jsii.invoke(self, "consumeAnotherPublicInterface", [obj]) @jsii.member(jsii_name="consumeNonInternalInterface") def consume_non_internal_interface(self, obj: "INonInternalInterface") -> typing.Any: + """ + Arguments: + obj: - + """ return jsii.invoke(self, "consumeNonInternalInterface", [obj]) class DefaultedConstructorArgument(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.DefaultedConstructorArgument"): def __init__(self, arg1: typing.Optional[jsii.Number]=None, arg2: typing.Optional[str]=None, arg3: typing.Optional[datetime.datetime]=None) -> None: + """ + Arguments: + arg1: - + arg2: - + arg3: - + """ jsii.create(DefaultedConstructorArgument, self, [arg1, arg2, arg3]) @property @@ -472,14 +573,19 @@ def __init__(self) -> None: class _DerivedStruct(scope.jsii_calc_lib.MyFirstStruct, jsii.compat.TypedDict, total=False): anotherOptional: typing.Mapping[str,scope.jsii_calc_lib.Value] + """This is optional.""" optionalAny: typing.Any optionalArray: typing.List[str] @jsii.data_type(jsii_type="jsii-calc.DerivedStruct") class DerivedStruct(_DerivedStruct): + """A struct which derives from another struct.""" anotherRequired: datetime.datetime + bool: bool + nonPrimitive: "DoubleTrouble" + """An example of a non primitive property.""" class DoNotOverridePrivates(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.DoNotOverridePrivates"): def __init__(self) -> None: @@ -487,6 +593,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="changePrivatePropertyValue") def change_private_property_value(self, new_value: str) -> None: + """ + Arguments: + newValue: - + """ return jsii.invoke(self, "changePrivatePropertyValue", [new_value]) @jsii.member(jsii_name="privateMethodValue") @@ -499,20 +609,46 @@ def private_property_value(self) -> str: class DoNotRecognizeAnyAsOptional(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.DoNotRecognizeAnyAsOptional"): + """jsii#284: do not recognize "any" as an optional argument.""" def __init__(self) -> None: jsii.create(DoNotRecognizeAnyAsOptional, self, []) @jsii.member(jsii_name="method") def method(self, _required_any: typing.Any, _optional_any: typing.Any=None, _optional_string: typing.Optional[str]=None) -> None: + """ + Arguments: + _requiredAny: - + _optionalAny: - + _optionalString: - + """ return jsii.invoke(self, "method", [_required_any, _optional_any, _optional_string]) class DocumentedClass(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.DocumentedClass"): + """Here's the first line of the TSDoc comment. + + This is the meat of the TSDoc comment. It may contain + multiple lines and multiple paragraphs. + + Multiple paragraphs are separated by an empty line. + """ def __init__(self) -> None: jsii.create(DocumentedClass, self, []) @jsii.member(jsii_name="greet") def greet(self, *, name: typing.Optional[str]=None) -> jsii.Number: + """Greet the indicated person. + + This will print out a friendly greeting intended for + the indicated person. + + Arguments: + greetee: The person to be greeted. + name: The name of the greetee. Default: world + + Returns: + A number that everyone knows very well + """ greetee: Greetee = {} if name is not None: @@ -522,6 +658,11 @@ def greet(self, *, name: typing.Optional[str]=None) -> jsii.Number: @jsii.member(jsii_name="hola") def hola(self) -> None: + """Say ¡Hola! + + Stability: + experimental + """ return jsii.invoke(self, "hola", []) @@ -531,6 +672,11 @@ def __init__(self) -> None: @jsii.member(jsii_name="optionalAndVariadic") def optional_and_variadic(self, optional: typing.Optional[str]=None, *things: str) -> str: + """ + Arguments: + optional: - + things: - + """ return jsii.invoke(self, "optionalAndVariadic", [optional, things]) @@ -541,26 +687,42 @@ def __init__(self) -> None: @jsii.member(jsii_name="doesKeyExist") @classmethod def does_key_exist(cls, opts: "EraseUndefinedHashValuesOptions", key: str) -> bool: + """Returns ``true`` if ``key`` is defined in ``opts``. + + Used to check that undefined/null hash values + are being erased when sending values from native code to JS. + + Arguments: + opts: - + key: - + """ return jsii.sinvoke(cls, "doesKeyExist", [opts, key]) @jsii.member(jsii_name="prop1IsNull") @classmethod def prop1_is_null(cls) -> typing.Any: + """We expect "prop1" to be erased.""" return jsii.sinvoke(cls, "prop1IsNull", []) @jsii.member(jsii_name="prop2IsUndefined") @classmethod def prop2_is_undefined(cls) -> typing.Any: + """We expect "prop2" to be erased.""" return jsii.sinvoke(cls, "prop2IsUndefined", []) @jsii.data_type(jsii_type="jsii-calc.EraseUndefinedHashValuesOptions") class EraseUndefinedHashValuesOptions(jsii.compat.TypedDict, total=False): option1: str + option2: str class ExportedBaseClass(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ExportedBaseClass"): def __init__(self, success: bool) -> None: + """ + Arguments: + success: - + """ jsii.create(ExportedBaseClass, self, [success]) @property @@ -572,6 +734,7 @@ def success(self) -> bool: @jsii.data_type(jsii_type="jsii-calc.ExtendsInternalInterface") class ExtendsInternalInterface(jsii.compat.TypedDict): boom: bool + prop: str class GiveMeStructs(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.GiveMeStructs"): @@ -580,6 +743,20 @@ def __init__(self) -> None: @jsii.member(jsii_name="derivedToFirst") def derived_to_first(self, *, another_required: datetime.datetime, bool: bool, non_primitive: "DoubleTrouble", another_optional: typing.Optional[typing.Mapping[str,scope.jsii_calc_lib.Value]]=None, optional_any: typing.Any=None, optional_array: typing.Optional[typing.List[str]]=None, anumber: jsii.Number, astring: str, first_optional: typing.Optional[typing.List[str]]=None) -> scope.jsii_calc_lib.MyFirstStruct: + """Accepts a struct of type DerivedStruct and returns a struct of type FirstStruct. + + Arguments: + derived: - + anotherRequired: - + bool: - + nonPrimitive: An example of a non primitive property. + anotherOptional: This is optional. + optionalAny: - + optionalArray: - + anumber: An awesome number value. + astring: A string value. + firstOptional: - + """ derived: DerivedStruct = {"anotherRequired": another_required, "bool": bool, "nonPrimitive": non_primitive, "anumber": anumber, "astring": astring} if another_optional is not None: @@ -598,6 +775,20 @@ def derived_to_first(self, *, another_required: datetime.datetime, bool: bool, n @jsii.member(jsii_name="readDerivedNonPrimitive") def read_derived_non_primitive(self, *, another_required: datetime.datetime, bool: bool, non_primitive: "DoubleTrouble", another_optional: typing.Optional[typing.Mapping[str,scope.jsii_calc_lib.Value]]=None, optional_any: typing.Any=None, optional_array: typing.Optional[typing.List[str]]=None, anumber: jsii.Number, astring: str, first_optional: typing.Optional[typing.List[str]]=None) -> "DoubleTrouble": + """Returns the boolean from a DerivedStruct struct. + + Arguments: + derived: - + anotherRequired: - + bool: - + nonPrimitive: An example of a non primitive property. + anotherOptional: This is optional. + optionalAny: - + optionalArray: - + anumber: An awesome number value. + astring: A string value. + firstOptional: - + """ derived: DerivedStruct = {"anotherRequired": another_required, "bool": bool, "nonPrimitive": non_primitive, "anumber": anumber, "astring": astring} if another_optional is not None: @@ -616,6 +807,14 @@ def read_derived_non_primitive(self, *, another_required: datetime.datetime, boo @jsii.member(jsii_name="readFirstNumber") def read_first_number(self, *, anumber: jsii.Number, astring: str, first_optional: typing.Optional[typing.List[str]]=None) -> jsii.Number: + """Returns the "anumber" from a MyFirstStruct struct; + + Arguments: + first: - + anumber: An awesome number value. + astring: A string value. + firstOptional: - + """ first: scope.jsii_calc_lib.MyFirstStruct = {"anumber": anumber, "astring": astring} if first_optional is not None: @@ -631,7 +830,13 @@ def struct_literal(self) -> scope.jsii_calc_lib.StructWithOnlyOptionals: @jsii.data_type(jsii_type="jsii-calc.Greetee") class Greetee(jsii.compat.TypedDict, total=False): + """These are some arguments you can pass to a method.""" name: str + """The name of the greetee. + + Default: + world + """ class GreetingAugmenter(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.GreetingAugmenter"): def __init__(self) -> None: @@ -639,6 +844,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="betterGreeting") def better_greeting(self, friendly: scope.jsii_calc_lib.IFriendly) -> str: + """ + Arguments: + friendly: - + """ return jsii.invoke(self, "betterGreeting", [friendly]) @@ -710,32 +919,47 @@ def private(self, value: str): @jsii.interface(jsii_type="jsii-calc.IFriendlier") class IFriendlier(scope.jsii_calc_lib.IFriendly, jsii.compat.Protocol): + """Even friendlier classes can implement this interface.""" @staticmethod def __jsii_proxy_class__(): return _IFriendlierProxy @jsii.member(jsii_name="farewell") def farewell(self) -> str: + """Say farewell.""" ... @jsii.member(jsii_name="goodbye") def goodbye(self) -> str: + """Say goodbye. + + Returns: + A goodbye blessing. + """ ... class _IFriendlierProxy(jsii.proxy_for(scope.jsii_calc_lib.IFriendly)): + """Even friendlier classes can implement this interface.""" __jsii_type__ = "jsii-calc.IFriendlier" @jsii.member(jsii_name="farewell") def farewell(self) -> str: + """Say farewell.""" return jsii.invoke(self, "farewell", []) @jsii.member(jsii_name="goodbye") def goodbye(self) -> str: + """Say goodbye. + + Returns: + A goodbye blessing. + """ return jsii.invoke(self, "goodbye", []) @jsii.interface(jsii_type="jsii-calc.IInterfaceImplementedByAbstractClass") class IInterfaceImplementedByAbstractClass(jsii.compat.Protocol): + """awslabs/jsii#220 Abstract return type.""" @staticmethod def __jsii_proxy_class__(): return _IInterfaceImplementedByAbstractClassProxy @@ -747,6 +971,7 @@ def prop_from_interface(self) -> str: class _IInterfaceImplementedByAbstractClassProxy(): + """awslabs/jsii#220 Abstract return type.""" __jsii_type__ = "jsii-calc.IInterfaceImplementedByAbstractClass" @property @jsii.member(jsii_name="propFromInterface") @@ -766,6 +991,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="abstractMethod") @abc.abstractmethod def abstract_method(self, name: str) -> str: + """ + Arguments: + name: - + """ ... @jsii.member(jsii_name="nonAbstractMethod") @@ -781,6 +1010,10 @@ def prop_from_interface(self) -> str: class _AbstractClassProxy(AbstractClass, jsii.proxy_for(AbstractClassBase)): @jsii.member(jsii_name="abstractMethod") def abstract_method(self, name: str) -> str: + """ + Arguments: + name: - + """ return jsii.invoke(self, "abstractMethod", [name]) @@ -832,6 +1065,7 @@ def do_things(self) -> None: @jsii.interface(jsii_type="jsii-calc.IInterfaceThatShouldNotBeADataType") class IInterfaceThatShouldNotBeADataType(IInterfaceWithMethods, jsii.compat.Protocol): + """Even though this interface has only properties, it is disqualified from being a datatype because it inherits from an interface that is not a datatype.""" @staticmethod def __jsii_proxy_class__(): return _IInterfaceThatShouldNotBeADataTypeProxy @@ -843,6 +1077,7 @@ def other_value(self) -> str: class _IInterfaceThatShouldNotBeADataTypeProxy(jsii.proxy_for(IInterfaceWithMethods)): + """Even though this interface has only properties, it is disqualified from being a datatype because it inherits from an interface that is not a datatype.""" __jsii_type__ = "jsii-calc.IInterfaceThatShouldNotBeADataType" @property @jsii.member(jsii_name="otherValue") @@ -852,19 +1087,31 @@ def other_value(self) -> str: @jsii.interface(jsii_type="jsii-calc.IInterfaceWithOptionalMethodArguments") class IInterfaceWithOptionalMethodArguments(jsii.compat.Protocol): + """awslabs/jsii#175 Interface proxies (and builders) do not respect optional arguments in methods.""" @staticmethod def __jsii_proxy_class__(): return _IInterfaceWithOptionalMethodArgumentsProxy @jsii.member(jsii_name="hello") def hello(self, arg1: str, arg2: typing.Optional[jsii.Number]=None) -> None: + """ + Arguments: + arg1: - + arg2: - + """ ... class _IInterfaceWithOptionalMethodArgumentsProxy(): + """awslabs/jsii#175 Interface proxies (and builders) do not respect optional arguments in methods.""" __jsii_type__ = "jsii-calc.IInterfaceWithOptionalMethodArguments" @jsii.member(jsii_name="hello") def hello(self, arg1: str, arg2: typing.Optional[jsii.Number]=None) -> None: + """ + Arguments: + arg1: - + arg2: - + """ return jsii.invoke(self, "hello", [arg1, arg2]) @@ -908,9 +1155,15 @@ def read_write_string(self, value: str): @jsii.implements(IInterfaceWithProperties) class ClassWithPrivateConstructorAndAutomaticProperties(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ClassWithPrivateConstructorAndAutomaticProperties"): + """Class that implements interface properties automatically, but using a private constructor.""" @jsii.member(jsii_name="create") @classmethod def create(cls, read_only_string: str, read_write_string: str) -> "ClassWithPrivateConstructorAndAutomaticProperties": + """ + Arguments: + readOnlyString: - + readWriteString: - + """ return jsii.sinvoke(cls, "create", [read_only_string, read_write_string]) @property @@ -1236,19 +1489,31 @@ def ciao(self) -> str: @jsii.interface(jsii_type="jsii-calc.IRandomNumberGenerator") class IRandomNumberGenerator(jsii.compat.Protocol): + """Generates random numbers.""" @staticmethod def __jsii_proxy_class__(): return _IRandomNumberGeneratorProxy @jsii.member(jsii_name="next") def next(self) -> jsii.Number: + """Returns another random number. + + Returns: + A random number. + """ ... class _IRandomNumberGeneratorProxy(): + """Generates random numbers.""" __jsii_type__ = "jsii-calc.IRandomNumberGenerator" @jsii.member(jsii_name="next") def next(self) -> jsii.Number: + """Returns another random number. + + Returns: + A random number. + """ return jsii.invoke(self, "next", []) @@ -1271,10 +1536,12 @@ def __init__(self) -> None: @jsii.member(jsii_name="hello") def hello(self) -> str: + """Say hello!""" return jsii.invoke(self, "hello", []) @jsii.member(jsii_name="next") def next(self) -> jsii.Number: + """Returns another random number.""" return jsii.invoke(self, "next", []) @@ -1400,6 +1667,10 @@ def has_root(self) -> bool: class JSII417Derived(JSII417PublicBaseOfBase, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.JSII417Derived"): def __init__(self, property: str) -> None: + """ + Arguments: + property: - + """ jsii.create(JSII417Derived, self, [property]) @jsii.member(jsii_name="bar") @@ -1684,82 +1955,178 @@ def while_(self, value: str): class JsiiAgent(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.JsiiAgent"): + """Host runtime version should be set via JSII_AGENT.""" def __init__(self) -> None: jsii.create(JsiiAgent, self, []) @classproperty @jsii.member(jsii_name="jsiiAgent") def jsii_agent(cls) -> typing.Optional[str]: + """Returns the value of the JSII_AGENT environment variable.""" return jsii.sget(cls, "jsiiAgent") @jsii.data_type(jsii_type="jsii-calc.LoadBalancedFargateServiceProps") class LoadBalancedFargateServiceProps(jsii.compat.TypedDict, total=False): + """jsii#298: show default values in sphinx documentation, and respect newlines.""" containerPort: jsii.Number + """The container port of the application load balancer attached to your Fargate service. + + Corresponds to container port mapping. + + Default: + 80 + """ + cpu: str + """The number of cpu units used by the task. Valid values, which determines your range of valid values for the memory parameter: 256 (.25 vCPU) - Available memory values: 0.5GB, 1GB, 2GB 512 (.5 vCPU) - Available memory values: 1GB, 2GB, 3GB, 4GB 1024 (1 vCPU) - Available memory values: 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB 2048 (2 vCPU) - Available memory values: Between 4GB and 16GB in 1GB increments 4096 (4 vCPU) - Available memory values: Between 8GB and 30GB in 1GB increments. + + This default is set in the underlying FargateTaskDefinition construct. + + Default: + 256 + """ + memoryMiB: str + """The amount (in MiB) of memory used by the task. + + This field is required and you must use one of the following values, which determines your range of valid values + for the cpu parameter: + + 0.5GB, 1GB, 2GB - Available cpu values: 256 (.25 vCPU) + + 1GB, 2GB, 3GB, 4GB - Available cpu values: 512 (.5 vCPU) + + 2GB, 3GB, 4GB, 5GB, 6GB, 7GB, 8GB - Available cpu values: 1024 (1 vCPU) + + Between 4GB and 16GB in 1GB increments - Available cpu values: 2048 (2 vCPU) + + Between 8GB and 30GB in 1GB increments - Available cpu values: 4096 (4 vCPU) + + This default is set in the underlying FargateTaskDefinition construct. + + Default: + 512 + """ + publicLoadBalancer: bool + """Determines whether the Application Load Balancer will be internet-facing. + + Default: + true + """ + publicTasks: bool + """Determines whether your Fargate Service will be assigned a public IP address. + + Default: + false + """ @jsii.implements(IFriendlier, IRandomNumberGenerator) class Multiply(BinaryOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Multiply"): + """The "*" binary operation.""" def __init__(self, lhs: scope.jsii_calc_lib.Value, rhs: scope.jsii_calc_lib.Value) -> None: + """Creates a BinaryOperation. + + Arguments: + lhs: Left-hand side operand. + rhs: Right-hand side operand. + """ jsii.create(Multiply, self, [lhs, rhs]) @jsii.member(jsii_name="farewell") def farewell(self) -> str: + """Say farewell.""" return jsii.invoke(self, "farewell", []) @jsii.member(jsii_name="goodbye") def goodbye(self) -> str: + """Say goodbye.""" return jsii.invoke(self, "goodbye", []) @jsii.member(jsii_name="next") def next(self) -> jsii.Number: + """Returns another random number.""" return jsii.invoke(self, "next", []) @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The value.""" return jsii.get(self, "value") class NodeStandardLibrary(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.NodeStandardLibrary"): + """Test fixture to verify that jsii modules can use the node standard library.""" def __init__(self) -> None: jsii.create(NodeStandardLibrary, self, []) @jsii.member(jsii_name="cryptoSha256") def crypto_sha256(self) -> str: + """Uses node.js "crypto" module to calculate sha256 of a string. + + Returns: + "6a2da20943931e9834fc12cfe5bb47bbd9ae43489a30726962b576f4e3993e50" + """ return jsii.invoke(self, "cryptoSha256", []) @jsii.member(jsii_name="fsReadFile") def fs_read_file(self) -> str: + """Reads a local resource file (resource.txt) asynchronously. + + Returns: + "Hello, resource!" + """ return jsii.ainvoke(self, "fsReadFile", []) @jsii.member(jsii_name="fsReadFileSync") def fs_read_file_sync(self) -> str: + """Sync version of fsReadFile. + + Returns: + "Hello, resource! SYNC!" + """ return jsii.invoke(self, "fsReadFileSync", []) @property @jsii.member(jsii_name="osPlatform") def os_platform(self) -> str: + """Returns the current os.platform() from the "os" node module.""" return jsii.get(self, "osPlatform") class NullShouldBeTreatedAsUndefined(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.NullShouldBeTreatedAsUndefined"): + """jsii#282, aws-cdk#157: null should be treated as "undefined".""" def __init__(self, _param1: str, optional: typing.Any=None) -> None: + """ + Arguments: + _param1: - + optional: - + """ jsii.create(NullShouldBeTreatedAsUndefined, self, [_param1, optional]) @jsii.member(jsii_name="giveMeUndefined") def give_me_undefined(self, value: typing.Any=None) -> None: + """ + Arguments: + value: - + """ return jsii.invoke(self, "giveMeUndefined", [value]) @jsii.member(jsii_name="giveMeUndefinedInsideAnObject") def give_me_undefined_inside_an_object(self, *, array_with_three_elements_and_undefined_as_second_argument: typing.List[typing.Any], this_should_be_undefined: typing.Any=None) -> None: + """ + Arguments: + input: - + arrayWithThreeElementsAndUndefinedAsSecondArgument: - + thisShouldBeUndefined: - + """ input: NullShouldBeTreatedAsUndefinedData = {"arrayWithThreeElementsAndUndefinedAsSecondArgument": array_with_three_elements_and_undefined_as_second_argument} if this_should_be_undefined is not None: @@ -1789,11 +2156,20 @@ class NullShouldBeTreatedAsUndefinedData(_NullShouldBeTreatedAsUndefinedData): arrayWithThreeElementsAndUndefinedAsSecondArgument: typing.List[typing.Any] class NumberGenerator(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.NumberGenerator"): + """This allows us to test that a reference can be stored for objects that implement interfaces.""" def __init__(self, generator: "IRandomNumberGenerator") -> None: + """ + Arguments: + generator: - + """ jsii.create(NumberGenerator, self, [generator]) @jsii.member(jsii_name="isSameGenerator") def is_same_generator(self, gen: "IRandomNumberGenerator") -> bool: + """ + Arguments: + gen: - + """ return jsii.invoke(self, "isSameGenerator", [gen]) @jsii.member(jsii_name="nextTimes100") @@ -1811,29 +2187,52 @@ def generator(self, value: "IRandomNumberGenerator"): class ObjectRefsInCollections(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ObjectRefsInCollections"): + """Verify that object references can be passed inside collections.""" def __init__(self) -> None: jsii.create(ObjectRefsInCollections, self, []) @jsii.member(jsii_name="sumFromArray") def sum_from_array(self, values: typing.List[scope.jsii_calc_lib.Value]) -> jsii.Number: + """Returns the sum of all values. + + Arguments: + values: - + """ return jsii.invoke(self, "sumFromArray", [values]) @jsii.member(jsii_name="sumFromMap") def sum_from_map(self, values: typing.Mapping[str,scope.jsii_calc_lib.Value]) -> jsii.Number: + """Returns the sum of all values in a map. + + Arguments: + values: - + """ return jsii.invoke(self, "sumFromMap", [values]) class Old(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Old"): + """Old class. + + Deprecated: + Use the new class + """ def __init__(self) -> None: jsii.create(Old, self, []) @jsii.member(jsii_name="doAThing") def do_a_thing(self) -> None: + """Doo wop that thing.""" return jsii.invoke(self, "doAThing", []) class OptionalConstructorArgument(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.OptionalConstructorArgument"): def __init__(self, arg1: jsii.Number, arg2: str, arg3: typing.Optional[datetime.datetime]=None) -> None: + """ + Arguments: + arg1: - + arg2: - + arg3: - + """ jsii.create(OptionalConstructorArgument, self, [arg1, arg2, arg3]) @property @@ -1858,6 +2257,11 @@ class OptionalStruct(jsii.compat.TypedDict, total=False): class OptionalStructConsumer(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.OptionalStructConsumer"): def __init__(self, *, field: typing.Optional[str]=None) -> None: + """ + Arguments: + optionalStruct: - + field: - + """ optional_struct: OptionalStruct = {} if field is not None: @@ -1882,6 +2286,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="test") def test(self, obj: "IReturnsNumber") -> jsii.Number: + """ + Arguments: + obj: - + """ return jsii.invoke(self, "test", [obj]) @@ -1896,12 +2304,24 @@ def __init__(self) -> None: @jsii.member(jsii_name="consumePartiallyInitializedThis") @abc.abstractmethod def consume_partially_initialized_this(self, obj: "ConstructorPassesThisOut", dt: datetime.datetime, ev: "AllTypesEnum") -> str: + """ + Arguments: + obj: - + dt: - + ev: - + """ ... class _PartiallyInitializedThisConsumerProxy(PartiallyInitializedThisConsumer): @jsii.member(jsii_name="consumePartiallyInitializedThis") def consume_partially_initialized_this(self, obj: "ConstructorPassesThisOut", dt: datetime.datetime, ev: "AllTypesEnum") -> str: + """ + Arguments: + obj: - + dt: - + ev: - + """ return jsii.invoke(self, "consumePartiallyInitializedThis", [obj, dt, ev]) @@ -1911,6 +2331,10 @@ def __init__(self) -> None: @jsii.member(jsii_name="sayHello") def say_hello(self, friendly: scope.jsii_calc_lib.IFriendly) -> str: + """ + Arguments: + friendly: - + """ return jsii.invoke(self, "sayHello", [friendly]) @@ -2067,6 +2491,7 @@ def yield_(self) -> None: class ReferenceEnumFromScopedPackage(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ReferenceEnumFromScopedPackage"): + """See awslabs/jsii#138.""" def __init__(self) -> None: jsii.create(ReferenceEnumFromScopedPackage, self, []) @@ -2076,6 +2501,10 @@ def load_foo(self) -> typing.Optional[scope.jsii_calc_lib.EnumFromScopedModule]: @jsii.member(jsii_name="saveFoo") def save_foo(self, value: scope.jsii_calc_lib.EnumFromScopedModule) -> None: + """ + Arguments: + value: - + """ return jsii.invoke(self, "saveFoo", [value]) @property @@ -2089,6 +2518,14 @@ def foo(self, value: typing.Optional[scope.jsii_calc_lib.EnumFromScopedModule]): class ReturnsPrivateImplementationOfInterface(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.ReturnsPrivateImplementationOfInterface"): + """Helps ensure the JSII kernel & runtime cooperate correctly when an un-exported instance of a class is returned with a declared type that is an exported interface, and the instance inherits from an exported class. + + Returns: + an instance of an un-exported class that extends ``ExportedBaseClass``, declared as ``IPrivatelyImplemented``. + + See: + https://github.com/awslabs/jsii/issues/320 + """ def __init__(self) -> None: jsii.create(ReturnsPrivateImplementationOfInterface, self, []) @@ -2104,18 +2541,41 @@ def __init__(self) -> None: @jsii.member(jsii_name="methodWithDefaultedArguments") def method_with_defaulted_arguments(self, arg1: typing.Optional[jsii.Number]=None, arg2: typing.Optional[str]=None, arg3: typing.Optional[datetime.datetime]=None) -> None: + """ + Arguments: + arg1: - + arg2: - + arg3: - + """ return jsii.invoke(self, "methodWithDefaultedArguments", [arg1, arg2, arg3]) @jsii.member(jsii_name="methodWithOptionalAnyArgument") def method_with_optional_any_argument(self, arg: typing.Any=None) -> None: + """ + Arguments: + arg: - + """ return jsii.invoke(self, "methodWithOptionalAnyArgument", [arg]) @jsii.member(jsii_name="methodWithOptionalArguments") def method_with_optional_arguments(self, arg1: jsii.Number, arg2: str, arg3: typing.Optional[datetime.datetime]=None) -> None: + """Used to verify verification of number of method arguments. + + Arguments: + arg1: - + arg2: - + arg3: - + """ return jsii.invoke(self, "methodWithOptionalArguments", [arg1, arg2, arg3]) class SingleInstanceTwoTypes(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.SingleInstanceTwoTypes"): + """Test that a single instance can be returned under two different FQNs. + + JSII clients can instantiate 2 different strongly-typed wrappers for the same + object. Unfortunately, this will break object equality, but if we didn't do + this it would break runtime type checks in the JVM or CLR. + """ def __init__(self) -> None: jsii.create(SingleInstanceTwoTypes, self, []) @@ -2129,6 +2589,10 @@ def interface2(self) -> "IPublicInterface": class StaticContext(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.StaticContext"): + """This is used to validate the ability to use ``this`` from within a static context. + + https://github.com/awslabs/aws-cdk/issues/2304 + """ @jsii.member(jsii_name="canAccessStaticContext") @classmethod def can_access_static_context(cls) -> bool: @@ -2146,11 +2610,20 @@ def static_variable(cls, value: bool): class Statics(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Statics"): def __init__(self, value: str) -> None: + """ + Arguments: + value: - + """ jsii.create(Statics, self, [value]) @jsii.member(jsii_name="staticMethod") @classmethod def static_method(cls, name: str) -> str: + """Jsdocs for static method. + + Arguments: + name: The name of the person to say hello to. + """ return jsii.sinvoke(cls, "staticMethod", [name]) @jsii.member(jsii_name="justMethod") @@ -2160,6 +2633,7 @@ def just_method(self) -> str: @classproperty @jsii.member(jsii_name="BAR") def BAR(cls) -> jsii.Number: + """Constants may also use all-caps.""" return jsii.sget(cls, "BAR") @classproperty @@ -2170,16 +2644,19 @@ def CONST_OBJ(cls) -> "DoubleTrouble": @classproperty @jsii.member(jsii_name="Foo") def FOO(cls) -> str: + """Jsdocs for static property.""" return jsii.sget(cls, "Foo") @classproperty @jsii.member(jsii_name="zooBar") def ZOO_BAR(cls) -> typing.Mapping[str,str]: + """Constants can also use camelCase.""" return jsii.sget(cls, "zooBar") @classproperty @jsii.member(jsii_name="instance") def instance(cls) -> "Statics": + """Jsdocs for static getter. Jsdocs for static setter.""" return jsii.sget(cls, "instance") @instance.setter @@ -2235,10 +2712,18 @@ def caller_is_method(self) -> jsii.Number: @jsii.member(jsii_name="modifyOtherProperty") def modify_other_property(self, value: str) -> None: + """ + Arguments: + value: - + """ return jsii.invoke(self, "modifyOtherProperty", [value]) @jsii.member(jsii_name="modifyValueOfTheProperty") def modify_value_of_the_property(self, value: str) -> None: + """ + Arguments: + value: - + """ return jsii.invoke(self, "modifyValueOfTheProperty", [value]) @jsii.member(jsii_name="readA") @@ -2259,10 +2744,18 @@ def retrieve_value_of_the_property(self) -> str: @jsii.member(jsii_name="virtualMethod") def virtual_method(self, n: jsii.Number) -> jsii.Number: + """ + Arguments: + n: - + """ return jsii.invoke(self, "virtualMethod", [n]) @jsii.member(jsii_name="writeA") def write_a(self, value: jsii.Number) -> None: + """ + Arguments: + value: - + """ return jsii.invoke(self, "writeA", [value]) @property @@ -2326,11 +2819,16 @@ def throw_error(self) -> None: class UnaryOperation(scope.jsii_calc_lib.Operation, metaclass=jsii.JSIIAbstractClass, jsii_type="jsii-calc.UnaryOperation"): + """An operation on a single operand.""" @staticmethod def __jsii_proxy_class__(): return _UnaryOperationProxy def __init__(self, operand: scope.jsii_calc_lib.Value) -> None: + """ + Arguments: + operand: - + """ jsii.create(UnaryOperation, self, [operand]) @property @@ -2344,28 +2842,38 @@ class _UnaryOperationProxy(UnaryOperation, jsii.proxy_for(scope.jsii_calc_lib.Op @jsii.implements(IFriendlier) class Negate(UnaryOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Negate"): + """The negation operation ("-value").""" def __init__(self, operand: scope.jsii_calc_lib.Value) -> None: + """ + Arguments: + operand: - + """ jsii.create(Negate, self, [operand]) @jsii.member(jsii_name="farewell") def farewell(self) -> str: + """Say farewell.""" return jsii.invoke(self, "farewell", []) @jsii.member(jsii_name="goodbye") def goodbye(self) -> str: + """Say goodbye.""" return jsii.invoke(self, "goodbye", []) @jsii.member(jsii_name="hello") def hello(self) -> str: + """Say hello!""" return jsii.invoke(self, "hello", []) @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The value.""" return jsii.get(self, "value") @@ -2386,6 +2894,7 @@ def value(self) -> typing.Any: class UseCalcBase(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.UseCalcBase"): + """Depend on a type from jsii-calc-base as a test for awslabs/jsii#128.""" def __init__(self) -> None: jsii.create(UseCalcBase, self, []) @@ -2396,6 +2905,10 @@ def hello(self) -> scope.jsii_calc_base.Base: class UsesInterfaceWithProperties(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.UsesInterfaceWithProperties"): def __init__(self, obj: "IInterfaceWithProperties") -> None: + """ + Arguments: + obj: - + """ jsii.create(UsesInterfaceWithProperties, self, [obj]) @jsii.member(jsii_name="justRead") @@ -2404,10 +2917,18 @@ def just_read(self) -> str: @jsii.member(jsii_name="readStringAndNumber") def read_string_and_number(self, ext: "IInterfaceWithPropertiesExtension") -> str: + """ + Arguments: + ext: - + """ return jsii.invoke(self, "readStringAndNumber", [ext]) @jsii.member(jsii_name="writeAndRead") def write_and_read(self, value: str) -> str: + """ + Arguments: + value: - + """ return jsii.invoke(self, "writeAndRead", [value]) @property @@ -2418,10 +2939,19 @@ def obj(self) -> "IInterfaceWithProperties": class VariadicMethod(metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.VariadicMethod"): def __init__(self, *prefix: jsii.Number) -> None: + """ + Arguments: + prefix: a prefix that will be use for all values returned by ``#asArray``. + """ jsii.create(VariadicMethod, self, [prefix]) @jsii.member(jsii_name="asArray") def as_array(self, first: jsii.Number, *others: jsii.Number) -> typing.List[jsii.Number]: + """ + Arguments: + first: the first element of the array to be returned (after the ``prefix`` provided at construction time). + others: other elements to be included in the array. + """ return jsii.invoke(self, "asArray", [first, others]) @@ -2431,22 +2961,42 @@ def __init__(self) -> None: @jsii.member(jsii_name="overrideMeAsync") def override_me_async(self, index: jsii.Number) -> jsii.Number: + """ + Arguments: + index: - + """ return jsii.ainvoke(self, "overrideMeAsync", [index]) @jsii.member(jsii_name="overrideMeSync") def override_me_sync(self, index: jsii.Number) -> jsii.Number: + """ + Arguments: + index: - + """ return jsii.invoke(self, "overrideMeSync", [index]) @jsii.member(jsii_name="parallelSumAsync") def parallel_sum_async(self, count: jsii.Number) -> jsii.Number: + """ + Arguments: + count: - + """ return jsii.ainvoke(self, "parallelSumAsync", [count]) @jsii.member(jsii_name="serialSumAsync") def serial_sum_async(self, count: jsii.Number) -> jsii.Number: + """ + Arguments: + count: - + """ return jsii.ainvoke(self, "serialSumAsync", [count]) @jsii.member(jsii_name="sumSync") def sum_sync(self, count: jsii.Number) -> jsii.Number: + """ + Arguments: + count: - + """ return jsii.invoke(self, "sumSync", [count]) @@ -2481,6 +3031,7 @@ def _override_me(self) -> None: class composition: class CompositeOperation(scope.jsii_calc_lib.Operation, metaclass=jsii.JSIIAbstractClass, jsii_type="jsii-calc.composition.CompositeOperation"): + """Abstract operation composed from an expression of other operations.""" @staticmethod def __jsii_proxy_class__(): return _CompositeOperationProxy @@ -2490,22 +3041,26 @@ def __init__(self) -> None: @jsii.member(jsii_name="toString") def to_string(self) -> str: + """String representation of the value.""" return jsii.invoke(self, "toString", []) @property @jsii.member(jsii_name="expression") @abc.abstractmethod def expression(self) -> scope.jsii_calc_lib.Value: + """The expression that this operation consists of. Must be implemented by derived classes.""" ... @property @jsii.member(jsii_name="value") def value(self) -> jsii.Number: + """The value.""" return jsii.get(self, "value") @property @jsii.member(jsii_name="decorationPostfixes") def decoration_postfixes(self) -> typing.List[str]: + """A set of postfixes to include in a decorated .toString().""" return jsii.get(self, "decorationPostfixes") @decoration_postfixes.setter @@ -2515,6 +3070,7 @@ def decoration_postfixes(self, value: typing.List[str]): @property @jsii.member(jsii_name="decorationPrefixes") def decoration_prefixes(self) -> typing.List[str]: + """A set of prefixes to include in a decorated .toString().""" return jsii.get(self, "decorationPrefixes") @decoration_prefixes.setter @@ -2524,6 +3080,7 @@ def decoration_prefixes(self, value: typing.List[str]): @property @jsii.member(jsii_name="stringStyle") def string_style(self) -> "CompositionStringStyle": + """The .toString() style.""" return jsii.get(self, "stringStyle") @string_style.setter @@ -2532,20 +3089,32 @@ def string_style(self, value: "CompositionStringStyle"): @jsii.enum(jsii_type="jsii-calc.composition.CompositeOperation.CompositionStringStyle") class CompositionStringStyle(enum.Enum): + """Style of .toString() output for CompositeOperation.""" Normal = "Normal" + """Normal string expression.""" Decorated = "Decorated" + """Decorated string expression.""" class _CompositeOperationProxy(CompositeOperation, jsii.proxy_for(scope.jsii_calc_lib.Operation)): @property @jsii.member(jsii_name="expression") def expression(self) -> scope.jsii_calc_lib.Value: + """The expression that this operation consists of. Must be implemented by derived classes.""" return jsii.get(self, "expression") class Calculator(composition.CompositeOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Calculator"): + """A calculator which maintains a current value and allows adding operations.""" def __init__(self, *, initial_value: typing.Optional[jsii.Number]=None, maximum_value: typing.Optional[jsii.Number]=None) -> None: + """Creates a Calculator object. + + Arguments: + props: Initialization properties. + initialValue: - + maximumValue: - + """ props: CalculatorProps = {} if initial_value is not None: @@ -2558,42 +3127,63 @@ def __init__(self, *, initial_value: typing.Optional[jsii.Number]=None, maximum_ @jsii.member(jsii_name="add") def add(self, value: jsii.Number) -> None: + """Adds a number to the current value. + + Arguments: + value: - + """ return jsii.invoke(self, "add", [value]) @jsii.member(jsii_name="mul") def mul(self, value: jsii.Number) -> None: + """Multiplies the current value by a number. + + Arguments: + value: - + """ return jsii.invoke(self, "mul", [value]) @jsii.member(jsii_name="neg") def neg(self) -> None: + """Negates the current value.""" return jsii.invoke(self, "neg", []) @jsii.member(jsii_name="pow") def pow(self, value: jsii.Number) -> None: + """Raises the current value by a power. + + Arguments: + value: - + """ return jsii.invoke(self, "pow", [value]) @jsii.member(jsii_name="readUnionValue") def read_union_value(self) -> jsii.Number: + """Returns teh value of the union property (if defined).""" return jsii.invoke(self, "readUnionValue", []) @property @jsii.member(jsii_name="expression") def expression(self) -> scope.jsii_calc_lib.Value: + """Returns the expression.""" return jsii.get(self, "expression") @property @jsii.member(jsii_name="operationsLog") def operations_log(self) -> typing.List[scope.jsii_calc_lib.Value]: + """A log of all operations.""" return jsii.get(self, "operationsLog") @property @jsii.member(jsii_name="operationsMap") def operations_map(self) -> typing.Mapping[str,typing.List[scope.jsii_calc_lib.Value]]: + """A map of per operation name of all operations performed.""" return jsii.get(self, "operationsMap") @property @jsii.member(jsii_name="curr") def curr(self) -> scope.jsii_calc_lib.Value: + """The current value.""" return jsii.get(self, "curr") @curr.setter @@ -2603,6 +3193,7 @@ def curr(self, value: scope.jsii_calc_lib.Value): @property @jsii.member(jsii_name="maxValue") def max_value(self) -> typing.Optional[jsii.Number]: + """The maximum value allows in this calculator.""" return jsii.get(self, "maxValue") @max_value.setter @@ -2612,6 +3203,7 @@ def max_value(self, value: typing.Optional[jsii.Number]): @property @jsii.member(jsii_name="unionProperty") def union_property(self) -> typing.Optional[typing.Union[typing.Optional["Add"], typing.Optional["Multiply"], typing.Optional["Power"]]]: + """Example of a property that accepts a union of types.""" return jsii.get(self, "unionProperty") @union_property.setter @@ -2620,37 +3212,50 @@ def union_property(self, value: typing.Optional[typing.Union[typing.Optional["Ad class Power(composition.CompositeOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Power"): + """The power operation.""" def __init__(self, base: scope.jsii_calc_lib.Value, pow: scope.jsii_calc_lib.Value) -> None: + """Creates a Power operation. + + Arguments: + base: The base of the power. + pow: The number of times to multiply. + """ jsii.create(Power, self, [base, pow]) @property @jsii.member(jsii_name="base") def base(self) -> scope.jsii_calc_lib.Value: + """The base of the power.""" return jsii.get(self, "base") @property @jsii.member(jsii_name="expression") def expression(self) -> scope.jsii_calc_lib.Value: + """The expression that this operation consists of. Must be implemented by derived classes.""" return jsii.get(self, "expression") @property @jsii.member(jsii_name="pow") def pow(self) -> scope.jsii_calc_lib.Value: + """The number of times to multiply.""" return jsii.get(self, "pow") class Sum(composition.CompositeOperation, metaclass=jsii.JSIIMeta, jsii_type="jsii-calc.Sum"): + """An operation that sums multiple values.""" def __init__(self) -> None: jsii.create(Sum, self, []) @property @jsii.member(jsii_name="expression") def expression(self) -> scope.jsii_calc_lib.Value: + """The expression that this operation consists of. Must be implemented by derived classes.""" return jsii.get(self, "expression") @property @jsii.member(jsii_name="parts") def parts(self) -> typing.List[scope.jsii_calc_lib.Value]: + """The parts to sum.""" return jsii.get(self, "parts") @parts.setter diff --git a/packages/jsii-pacmak/test/test.python.ts b/packages/jsii-pacmak/test/test.python.ts new file mode 100644 index 0000000000..fd29dd82f0 --- /dev/null +++ b/packages/jsii-pacmak/test/test.python.ts @@ -0,0 +1,171 @@ +import { Test } from 'nodeunit'; +import { md2rst } from '../lib/markdown'; + +export = { + 'code to literal blocks'(test: Test) { + converts(test, [ + 'Here is an example:', + '', + '```', + 'example', + 'line 2', + '```' + ], [ + 'Here is an example::', + '', + ' example', + ' line 2' + ]); + + test.done(); + }, + + 'code to literal blocks with text after it as well'(test: Test) { + converts(test, [ + 'Here is an example:', + '', + '```', + 'example', + 'line 2', + '```', + 'Continuing our regularly scheduled programming.' + ], [ + 'Here is an example::', + '', + ' example', + ' line 2', + '', + 'Continuing our regularly scheduled programming.' + ]); + + test.done(); + }, + + 'code to literal blocks without separating line'(test: Test) { + converts(test, [ + 'Here is an example:', + '```', + 'example', + 'line 2', + '```' + ], [ + 'Here is an example::', + '', + ' example', + ' line 2' + ]); + + test.done(); + }, + + 'code to literal blocks without preceding colon'(test: Test) { + converts(test, [ + 'Here is an example.', + '```', + 'example', + 'line 2', + '```' + ], [ + 'Here is an example::', + '', + ' example', + ' line 2' + ]); + + test.done(); + }, + + 'code to literal blocks without preceding line adds the word Example'(test: Test) { + converts(test, [ + '```', + 'example', + 'line 2', + '```' + ], [ + 'Example::', + '', + ' example', + ' line 2' + ]); + + test.done(); + }, + + 'blocks to blocks'(test: Test) { + converts(test, [ + 'This is a long ongoing piece of text and I have not idea how this will', + 'be broken down into lines. Let\'s just try it and we will see.', + ], [ + 'This is a long ongoing piece of text and I have not idea how this will', + 'be broken down into lines. Let\'s just try it and we will see.', + ]); + + test.done(); + }, + + 'backticks to double backticks'(test: Test) { + converts(test, [ + 'This is `literal` code', + ], [ + 'This is ``literal`` code', + ]); + + test.done(); + }, + + 'style markup'(test: Test) { + converts(test, [ + 'text is *emphasized* or **strong**', + ], [ + 'text is *emphasized* or **strong**', + ]); + + test.done(); + }, + + 'hyperlink formatting'(test: Test) { + converts(test, [ + 'this is a [markdown](http://example.com/) hyperlink', + ], [ + 'this is a `markdown `_ hyperlink', + ]); + + test.done(); + }, + + 'bulleted list'(test: Test) { + converts(test, [ + 'This is a bulleted list:', + '* one', + '* two', + ], [ + 'This is a bulleted list:', + '', + '- one', + '- two', + ]); + + test.done(); + }, + + 'numbered list'(test: Test) { + converts(test, [ + 'This is a numbered list:', + '1. one', + '2. two', + ], [ + 'This is a numbered list:', + '', + '1. one', + '2. two', + ]); + + test.done(); + }, +}; + +function converts(test: Test, input: string[], output: string[]) { + const converted = md2rst(input.join('\n')); + + test.deepEqual(converted.split('\n'), output); +} \ No newline at end of file