Repository navigation
Conversation
This was referenced Oct 28, 2026
This was referenced Oct 28, 2026
moetemp
force-pushed
the
moe/up/system-nexus-generic-interceptors
branch
from
October 29, 2026 04:00
5c03b49 to
e3c7d8a
Compare
moetemp
force-pushed
the
moe/up/python-unknown-enum-number
branch
from
October 29, 2026 06:28
11c4295 to
44f3b6d
Compare
moetemp
force-pushed
the
moe/up/system-nexus-generic-interceptors
branch
from
October 29, 2026 06:28
e3c7d8a to
0fe04d5
Compare
moetemp
force-pushed
the
moe/up/python-unknown-enum-number
branch
from
October 29, 2026 07:00
44f3b6d to
517b216
Compare
moetemp
force-pushed
the
moe/up/system-nexus-generic-interceptors
branch
from
October 29, 2026 07:00
0fe04d5 to
3c0cbb6
Compare
The sample takes Brook's WIT, on the Stream protos of temporalio/api#895 at 482ec010. No SDK has those protos, so the sample projects hold their bindings. Only .NET generates the service, since Python and TypeScript panic on the read item's oneof.
Python and TypeScript panic on it, so their outputs keep their previous content. .NET types each case as the raw proto message, not as its record.
Variant planning kept such a case as the raw proto message. Python and TypeScript then panicked on a message conversion that wasn't model-shaped, and .NET typed the case as the proto class. The case plans as the record, as a record field does. A .NET case record names its payload's model in full, since it hides a model of its own name. Brook's stream service generates for TypeScript, and its .NET read item holds the records.
nexgen maps every temporal/... proto to a temporalio module. The Stream protos aren't in temporalio yet, so the service's imports don't resolve, and basedpyright skips it.
nexgen ships `proto/nexus/options.proto`, whose `nexus.python_module` file option names the Python module of a file's messages and enums. nexgen reads it from the raw descriptor bytes, since prost drops extension fields. The stream sample's protos set it, so Python imports them from the sample's streamprotos package, and basedpyright checks the stream service.
A proto-backed request holds a 64-bit integer as a `Long`, but a resource method took a number. A Brook offset doesn't fit in a number. A resource field or method param that a proto message of the request reads is a `Long`, so it goes into the request as it is. A 64-bit map key there is a string, as in the request model. Brook's stream service type-checks.
Python's client of a service with no endpoint sets up a flattened record at the module indent, so its services.py doesn't parse and the Python output keeps its previous content.
The setup of a @nexus.flatten-in-api record always took the indent of a module function. In a method of the client of a service with no endpoint, the code then left the method body, and services.py didn't parse. The user-service client generates its update_profile method.
Before planning, a proto-backed record is named by its proto type, so the walk for a resource's type parameters stopped there. nexgen then wrote generic models for a resource class that isn't generic, and the code didn't compile. The checks of the resource and of the operations that its methods bind both walk through protos.
The flag has the name of the user's own email, with another type. Today's output fills the flag with the user's email.
A resource method filled each request field from the resource field or param of the same name, whatever its type. So the user's own email went into the notify request's email flag. A source binds only when its type is the field's type, or the inner type of an optional field.
Python renders a bare `*` with no keyword parameter after it, in the user-service client method and in the type-showcase operation function. So those files don't parse, and the Python output keeps its previous content.
Python refuses a bare `*` with no parameter after it. An unpacked operation with an empty request rendered one, in the client of a service with no endpoint and in an operation function. The user-service client generates its `notify_all` method, and type-showcase its `ping` function.
Python's client method takes the docstring indent of a module function, so its services.py doesn't parse and the Python output keeps its previous content.
The client of a service with no endpoint took the docstring indent of a module function, so a documented or experimental operation broke the module. The user-service client generates with the doc of `notify_all`.
Proto3 enums are open. Python fails the whole message on a Stream status that it doesn't know. TypeScript and .NET pass the number through, and their tests pin it.
Proto3 enums are open, but a generated Python enum raised `ValueError` on a number that it didn't know, so the whole message failed. A newer server's Producer kind stopped an old reader's poll loop. The enum now makes a member named `Unknown<number>` with that value, as TypeScript and .NET pass the number through.
Its System Nexus interceptors name the generic models without type arguments. basedpyright refuses the Python one. The TypeScript one names a type parameter that isn't in scope, so `tsc` fails.
An interceptor handles every type argument of an operation's models. Python named a generic model with no type arguments, which basedpyright refuses. TypeScript named the operation's own type parameter, which isn't in scope. Both erase them, as the service definition does. The Python terminal still passes the model's class as the output type, since the SDK decodes with it.
moetemp
force-pushed
the
moe/up/system-nexus-generic-interceptors
branch
from
October 29, 2026 07:35
3c0cbb6 to
fd062d3
Compare
moetemp
force-pushed
the
moe/up/python-unknown-enum-number
branch
from
October 29, 2026 09:29
2509f52 to
6aa1acb
Compare
Contributor
Author
|
Closing this. moetemp#78 takes the fix, where the stream sample needs it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed?
This PR makes the Python and TypeScript System Nexus interceptors name a generic model with its type arguments erased, as the service definition does. Python writes
models.ValueRequest[typing.Any]. The TypeScript hook takesValueRequest<unknown>, so a hook narrows a value before it uses it.The Python terminal still passes the model's class as
output_type, since the SDK's JSON converter can't decode with a parameterized alias.The first commit gives
multi-operation-servicea genericValueOperationwith today's output, and the second is the fix.The .NET System Nexus dispatch still rejects each concrete type argument of a generic model. Its interceptor partial needs an sdk-dotnet that isn't released, so nothing can compile it yet, and that fix waits for one.
It's based on #321.
Why?
One interceptor handles every type argument of an operation. Python named the model with no type arguments, which
basedpyrightrefused, and TypeScript named a type parameter that isn't in scope. Generic resources (moetemp#78) have generic System Nexus models, so they need this.How did you test it?
Link to a test plan if any -
At the first commit,
basedpyrightandtscfail on the sample's interceptors. A new Python test decodes a generic result with the output type that the terminal passes.