-
Notifications
You must be signed in to change notification settings - Fork 103
Make client.py typecheck under pyright #628
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -35,7 +35,7 @@ | |
import google.protobuf.duration_pb2 | ||
import google.protobuf.json_format | ||
import google.protobuf.timestamp_pb2 | ||
from typing_extensions import Concatenate, TypedDict | ||
from typing_extensions import Concatenate, Required, TypedDict | ||
|
||
import temporalio.api.common.v1 | ||
import temporalio.api.enums.v1 | ||
|
@@ -1112,12 +1112,12 @@ async def get_worker_task_reachability( | |
class ClientConfig(TypedDict, total=False): | ||
"""TypedDict of config originally passed to :py:meth:`Client`.""" | ||
|
||
service_client: temporalio.service.ServiceClient | ||
namespace: str | ||
data_converter: temporalio.converter.DataConverter | ||
interceptors: Sequence[Interceptor] | ||
default_workflow_query_reject_condition: Optional[ | ||
temporalio.common.QueryRejectCondition | ||
service_client: Required[temporalio.service.ServiceClient] | ||
namespace: Required[str] | ||
data_converter: Required[temporalio.converter.DataConverter] | ||
interceptors: Required[Sequence[Interceptor]] | ||
default_workflow_query_reject_condition: Required[ | ||
Optional[temporalio.common.QueryRejectCondition] | ||
] | ||
|
||
|
||
|
@@ -1797,7 +1797,7 @@ async def execute_update( | |
MultiParamSpec, LocalReturnType | ||
], | ||
*, | ||
args: MultiParamSpec.args, | ||
args: MultiParamSpec.args, # pyright: ignore | ||
id: Optional[str] = None, | ||
rpc_metadata: Mapping[str, str] = {}, | ||
rpc_timeout: Optional[timedelta] = None, | ||
|
@@ -1906,7 +1906,7 @@ async def start_update( | |
MultiParamSpec, LocalReturnType | ||
], | ||
*, | ||
args: MultiParamSpec.args, | ||
args: MultiParamSpec.args, # pyright: ignore | ||
wait_for_stage: WorkflowUpdateStage, | ||
id: Optional[str] = None, | ||
rpc_metadata: Mapping[str, str] = {}, | ||
|
@@ -3233,7 +3233,7 @@ class ScheduleActionStartWorkflow(ScheduleAction): | |
headers: Optional[Mapping[str, temporalio.api.common.v1.Payload]] | ||
|
||
@staticmethod | ||
def _from_proto( | ||
def _from_proto( # pyright: ignore | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hrmm, I wonder if this is the same thing we ignore in the system-agnostic way below and pyright just cares about the line the declaration started instead of the param. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that's right. It's a bit silly having a cluster of type-ignore annotations for different type-checkers but I played around with a few variations and this is what passed. |
||
info: temporalio.api.workflow.v1.NewWorkflowExecutionInfo, # type: ignore[override] | ||
) -> ScheduleActionStartWorkflow: | ||
return ScheduleActionStartWorkflow("<unset>", raw_info=info) | ||
|
@@ -3482,7 +3482,6 @@ async def _to_proto( | |
return action | ||
|
||
|
||
@dataclass | ||
class ScheduleOverlapPolicy(IntEnum): | ||
"""Controls what happens when a workflow would be started by a schedule but | ||
one is already running. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh, weird, you think Required would be the default...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, there's a fair amount of reading material on the topic for anyone so-inclined.
https://peps.python.org/pep-0655/
https://typing.readthedocs.io/en/latest/spec/typeddict.html#required-notrequired
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hrmm, I am trying to remember why I did
total=False
here. Technically all of these config values are optional if you're using it as a typesafe way to provide parameters toClient.__init__
. I wonder if I expected someone to do something like:This PR would break that use case. Also it means that if we ever add fields to
__init__
we cannot make them required here if we want to be compatible with people that may be using this type. If we are ok breaking this use case, then I wonder if we should just removetotal=False
. I can't think of a reason thattotal=False
should be there if every field isRequired
, can anyone else? Or if we want to allow these to be optional, no need for these new annotations.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, I'm not sure I should have merged without resolving this conversation. May need to revisit this. E.g. in features repo we attempt to do
https://github.com/temporalio/features/blob/bump-sdk-version/bin/main/update/client_interceptor/feature.py#L66
which isn't passing type checks.