in packages/jsii-pacmak/lib/targets/python.ts [1439:1503]
public emit(code: CodeMaker, context: EmitContext) {
// First we emit our implments decorator
if (this.interfaces.length > 0) {
const interfaces: string[] = this.interfaces.map((b) =>
toTypeName(b).pythonType({ ...context, typeAnnotation: false }),
);
code.line(`@jsii.implements(${interfaces.join(', ')})`);
}
// Then we do our normal class logic for emitting our members.
super.emit(code, context);
// Then, if our class is Abstract, we have to go through and redo all of
// this logic, except only emiting abstract methods and properties as non
// abstract, and subclassing our initial class.
if (this.abstract) {
context = nestedContext(context, this.fqn);
const proxyBases = [this.pythonName];
for (const base of this.abstractBases) {
// "# type: ignore[misc]" because MyPy cannot check dynamic base classes (naturally)
proxyBases.push(
`jsii.proxy_for(${toTypeName(base).pythonType({
...context,
typeAnnotation: false,
})}) # type: ignore[misc]`,
);
}
code.line();
code.line();
openSignature(code, 'class', this.proxyClassName, proxyBases);
// Filter our list of members to *only* be abstract members, and not any
// other types.
const abstractMembers = this.members.filter(
(m) =>
(m instanceof BaseMethod || m instanceof BaseProperty) && m.abstract,
);
if (abstractMembers.length > 0) {
let first = true;
for (const member of abstractMembers) {
if (this.separateMembers) {
if (first) {
first = false;
} else {
code.line();
}
}
member.emit(code, context, { renderAbstract: false });
}
} else {
code.line('pass');
}
code.closeBlock();
code.line();
code.line(
'# Adding a "__jsii_proxy_class__(): typing.Type" function to the abstract class',
);
code.line(
`typing.cast(typing.Any, ${this.pythonName}).__jsii_proxy_class__ = lambda : ${this.proxyClassName}`,
);
}
}