Skip to content

Commit

Permalink
Use "real" forward refs if possible, even with forwardReferences = false
Browse files Browse the repository at this point in the history
  • Loading branch information
dstufft committed Oct 25, 2018
1 parent 7e7bbc7 commit 6a2ec91
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion packages/jsii-pacmak/lib/targets/python.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ interface PythonType extends PythonBase {
addMember(member: PythonBase): void;
}

function isPythonType(arg: PythonBase): arg is PythonType {
return (arg as any).fqn !== undefined;
}

interface ISortableType {
dependsOn(resolver: TypeResolver): spec.NamedTypeReference[];
}
Expand Down Expand Up @@ -229,6 +233,10 @@ abstract class BasePythonClassType implements PythonType, ISortableType {
if (this.members.length > 0) {
for (const member of sortMembers(this.members, resolver)) {
member.emit(code, resolver);

if (isPythonType(member)) {
resolver.markTypeEmitted(member);
}
}
} else {
code.line("pass");
Expand Down Expand Up @@ -528,13 +536,21 @@ class TypedDict extends BasePythonClassType {
code.openBlock(`class _${this.name}(${classParams.concat(["total=False"]).join(", ")})`);
for (const member of optionalMembers) {
member.emit(code, resolver);

if (isPythonType(member)) {
resolver.markTypeEmitted(member);
}
}
code.closeBlock();

// Now we'll emit the mandatory members.
code.openBlock(`class ${this.name}(_${this.name})`);
for (const member of sortMembers(mandatoryMembers, resolver)) {
member.emit(code, resolver);

if (isPythonType(member)) {
resolver.markTypeEmitted(member);
}
}
code.closeBlock();
} else {
Expand All @@ -551,6 +567,10 @@ class TypedDict extends BasePythonClassType {
if (this.members.length > 0) {
for (const member of sortMembers(this.members, resolver)) {
member.emit(code, resolver);

if (isPythonType(member)) {
resolver.markTypeEmitted(member);
}
}
} else {
code.line("pass");
Expand Down Expand Up @@ -741,6 +761,10 @@ class Module implements PythonType {
// Emit all of our members.
for (const member of sortMembers(this.members, resolver)) {
member.emit(code, resolver);

if (isPythonType(member)) {
resolver.markTypeEmitted(member);
}
}

// Whatever names we've exported, we'll write out our __all__ that lists them.
Expand Down Expand Up @@ -916,10 +940,12 @@ class TypeResolver {
private readonly stdTypesRe = new RegExp("^(datetime\.datetime|typing\.[A-Z][a-z]+|jsii\.Number)$");
private readonly boundRe: RegExp;
private readonly moduleRe = new RegExp("^((?:[^A-Z\.][^\.]+\.)*(?:[^A-Z\.][^\.]+))\.([A-Z].+)$");
private readonly emitted: Set<string>;

constructor(types: Map<string, PythonType>, boundTo?: string) {
this.types = types;
this.boundTo = boundTo !== undefined ? this.toPythonFQN(boundTo) : boundTo;
this.emitted = new Set();

if (this.boundTo !== undefined) {
this.boundRe = new RegExp(`^(${escapeStringRegexp(this.boundTo)})\.(.+)$`);
Expand Down Expand Up @@ -958,6 +984,12 @@ class TypeResolver {
return modules;
}

public markTypeEmitted(type: PythonType) {
if (type.fqn) {
this.emitted.add(this.toPythonFQN(type.fqn));
}
}

public resolve(
typeRef: spec.TypeReference,
opts: TypeResolverOpts = { forwardReferences: true, ignoreOptional: false }): string {
Expand Down Expand Up @@ -1002,7 +1034,7 @@ class TypeResolver {
// We have special logic here for checking if our thing is actually *in*
// our module, behond what we've already done, because our other logic will
// work for submodules, but this can't.
if (!forwardReferences && this.isInModule(innerType)) {
if (!forwardReferences && this.isInModule(innerType) && !this.emitted.has(innerType)) {
pythonType = pythonType.replace(re, `$1"${innerType}"$2`);
}

Expand Down

0 comments on commit 6a2ec91

Please sign in to comment.