Skip to content

Conversation

@rix0rrr
Copy link
Contributor

@rix0rrr rix0rrr commented Oct 30, 2025

In the situation of 2 modules that use each other's types, all languages are able to cope except Python. For Python, jsii-pacmak generates reciprocal import statements (at the top) which lead to a (failing) import from an incomplete module.

To solve this, we render all type signatures strictly in quotes, and gate all imports that are only being done for type declarations behind an

if typing.TYPE_CHECKING:
   ...

gate.

Implementation notes

  • Python module members now classify their requiredImports() into "run-time imports" and "typing imports".
  • All type annotations are now emitted as strings; this simplifies things so we don't have to check whether a reference is a forward reference or not. This means we can also remove the code related to tracking emitted values. Also, the quoting logic was ill-distributed throughout the UserType.toPythonName() function, we centralize it a bit.
    • This surfaced a bug in Python's typing.get_type_hints() function which has a bug when it comes to resolving forward references (ref). Changing typing.Dict to builtins.dict seems to solve that, but this strictly requires Python >= 3.9 (importing will now fail on 3.8 or earlier).
  • The intersection helper types used to be "specially" emitted in a complex dance of emitting and then emitting the types. Instead, we've refactored that to make them "regular" module members, which get added to the module during a new preEmit() phase. We use a new method visitTypes() to make sure we visit all types used in all module members.
    • This necessitates making it clear whether members should be exported or not; previously all members used to be exported but now they no longer are.
  • We used to call toTypeName() a bunch during emission; in most classes the result of that conversion is now stored in a class field.

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

In the situation of 2 modules that use each other's types, all languages
are able to cope except Python. For Python, `jsii-pacmak` generates
reciprocal `import` statements (at the top) which lead to a (failing)
import from an incomplete module.

To solve this, we render all type signatures strictly in quotes, and
gate all imports that are only being done for type declarations
behind an

```py
if typing.TYPE_CHECKING:
   ...
```

gate.
@rix0rrr rix0rrr requested review from a team October 30, 2025 15:04
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Oct 30, 2025
@rix0rrr
Copy link
Contributor Author

rix0rrr commented Nov 7, 2025

We will most likely abandon this effort. It doesn't work yet and still won't really help for Go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

contribution/core This is a PR that came from AWS.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant