Skip to content

Commit 6f1c9c0

Browse files
authored
fix: Python's abstract class proxies now inherit from parent's proxy
1 parent af1346f commit 6f1c9c0

4 files changed

Lines changed: 40 additions & 4 deletions

File tree

packages/jsii-pacmak/lib/targets/python.ts

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -682,20 +682,23 @@ class TypedDictProperty implements PythonBase {
682682
interface ClassOpts extends PythonTypeOpts {
683683
abstract?: boolean;
684684
interfaces?: spec.NamedTypeReference[];
685+
abstractBases?: spec.ClassType[];
685686
}
686687

687688
class Class extends BasePythonClassType {
688689

689690
private abstract: boolean;
691+
private abstractBases: spec.ClassType[];
690692
private interfaces: spec.NamedTypeReference[];
691693

692694
constructor(name: string, fqn: string, opts: ClassOpts) {
693695
super(name, fqn, opts);
694696

695-
const { abstract = false, interfaces = [] } = opts;
697+
const { abstract = false, interfaces = [], abstractBases = [] } = opts;
696698

697699
this.abstract = abstract;
698700
this.interfaces = interfaces;
701+
this.abstractBases = abstractBases;
699702
}
700703

701704
public dependsOn(resolver: TypeResolver): PythonType[] {
@@ -744,7 +747,13 @@ class Class extends BasePythonClassType {
744747
// abstract, and subclassing our initial class.
745748
if (this.abstract) {
746749
resolver = this.fqn ? resolver.bind(this.fqn) : resolver;
747-
code.openBlock(`class ${this.getProxyClassName()}(${this.name})`);
750+
751+
const proxyBases: string[] = [this.name];
752+
for (const base of this.abstractBases) {
753+
proxyBases.push(`jsii.proxy_for(${resolver.resolve(base)})`);
754+
}
755+
756+
code.openBlock(`class ${this.getProxyClassName()}(${proxyBases.join(', ')})`);
748757

749758
// Filter our list of members to *only* be abstract members, and not any
750759
// other types.
@@ -1372,7 +1381,8 @@ class PythonGenerator extends Generator {
13721381
const klass = new Class(
13731382
toPythonIdentifier(cls.name),
13741383
cls.fqn,
1375-
{ abstract, bases: cls.base !== undefined ? [cls.base] : [], interfaces: cls.interfaces }
1384+
{ abstract, bases: cls.base !== undefined ? [cls.base] : [], interfaces: cls.interfaces,
1385+
abstractBases: abstract ? this.getAbstractBases(cls) : [] }
13761386
);
13771387

13781388
if (cls.initializer !== undefined) {
@@ -1580,4 +1590,22 @@ class PythonGenerator extends Generator {
15801590

15811591
return undefined;
15821592
}
1593+
1594+
private getAbstractBases(cls: spec.ClassType): spec.ClassType[] {
1595+
const abstractBases: spec.ClassType[] = [];
1596+
1597+
if (cls.base !== undefined) {
1598+
const base = this.findType(cls.base.fqn);
1599+
1600+
if (!spec.isClassType(base)) {
1601+
throw new Error("Class inheritence that isn't a class?");
1602+
}
1603+
1604+
if (base.abstract) {
1605+
abstractBases.push(base);
1606+
}
1607+
}
1608+
1609+
return abstractBases;
1610+
}
15831611
}

packages/jsii-python-runtime/src/jsii/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
implements,
1111
member,
1212
kernel,
13+
proxy_for,
1314
)
1415

1516

@@ -44,6 +45,7 @@
4445
"implements",
4546
"member",
4647
"kernel",
48+
"proxy_for",
4749
"load",
4850
"create",
4951
"delete",

packages/jsii-python-runtime/src/jsii/_runtime.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,3 +107,10 @@ def deco(cls):
107107
return cls
108108

109109
return deco
110+
111+
112+
def proxy_for(abstract_class):
113+
if not hasattr(abstract_class, "__jsii_proxy_class__"):
114+
raise TypeError(f"{abstract_class} is not a JSII Abstract class.")
115+
116+
return abstract_class.__jsii_proxy_class__()

packages/jsii-python-runtime/tests/test_compliance.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,6 @@ def test_nodeStandardLibrary():
807807
)
808808

809809

810-
@xfail_abstract_class
811810
def test_returnAbstract():
812811
obj = AbstractClassReturner()
813812
obj2 = obj.give_me_abstract()

0 commit comments

Comments
 (0)