[Bug] An activity method with an annotated `self` receives its arguments without their types
Maintainer antworten meist innerhalb von 1 Tag
Bewertung
Dieses Issue wurde noch nicht bewertet.
Beschreibung
Package: temporalio 1.35.0, the latest release, and main (d488ff5).
What happens
An activity defined as a method, async def m(self, loc: Loc), receives loc as a Loc. The same method with an annotated receiver, such as self: Self in a module with from __future__ import annotations, receives loc as a plain dict.
_type_hints_from_func in temporalio/common.py skips the first parameter only when it is named self and is unannotated, or its annotation's text is typing.Self:
if (
index == 0
and value.name == "self"
and (
value.annotation is inspect.Parameter.empty
or str(value.annotation) == "typing.Self"
)
):
continue
Under postponed annotations the text is Self, so arg_types gets an entry for the receiver. The Worker then has two types for one argument, and worker/_activity.py falls back to decoding without types (arg_types is not None and len(arg_types) != len(start.input)). The same holds for self: T with a TypeVar bound to the class, self: "Svc", and typing_extensions.Self on Python 3.10. It affects workflow.execute_activity_method and anything else that runs a registered bound method.
Reproduction
One file. It uses a local dev server (temporal CLI on PATH) and exits 1 when the method annotated self: Self receives a dict.
"""An activity method whose `self` is annotated receives its other arguments without their types.
Exits 1 when the method annotated `self: Self` receives a dict instead of a `Loc`.
"""
from __future__ import annotations
import asyncio
import dataclasses
import shutil
import sys
import uuid
from datetime import timedelta
from typing import Self
from temporalio import activity, workflow
from temporalio.testing import WorkflowEnvironment
from temporalio.worker import UnsandboxedWorkflowRunner, Worker
@dataclasses.dataclass
class Loc:
city: str
class Svc:
@activity.defn
async def plain(self, loc: Loc) -> str:
return type(loc).__name__
@activity.defn
async def annotated(self: Self, loc: Loc) -> str:
return type(loc).__name__
@workflow.defn
class LocWorkflow:
@workflow.run
async def run(self) -> list[str]:
timeout = timedelta(seconds=10)
return [
await workflow.execute_activity_method(
Svc.plain, Loc("Rome"), start_to_close_timeout=timeout
),
await workflow.execute_activity_method(
Svc.annotated, Loc("Rome"), start_to_close_timeout=timeout
),
]
async def main() -> None:
svc = Svc()
async with await WorkflowEnvironment.start_local(
dev_server_existing_path=shutil.which("temporal")
) as env:
async with Worker(
env.client,
task_queue="tq",
workflows=[LocWorkflow],
activities=[svc.plain, svc.annotated],
workflow_runner=UnsandboxedWorkflowRunner(),
):
plain, annotated = await env.client.execute_workflow(
LocWorkflow.run, id=str(uuid.uuid4()), task_queue="tq"
)
print(f"plain(self, loc: Loc) received: {plain}")
print(f"annotated(self: Self, loc: Loc) received: {annotated}")
sys.exit(0 if annotated == "Loc" else 1)
if __name__ == "__main__":
asyncio.run(main())
Output:
Python 3.13.16 temporalio 1.35.0
$ python annotated_self.py
plain(self, loc: Loc) received: Loc
annotated(self: Self, loc: Loc) received: dict
exit 1
Expected
The Worker registers the method bound to an instance, which supplies self however it is annotated. So annotated should receive a Loc, as plain does.
Proposed fix
When the first parameter is named self, skip it whatever its annotation, as for an unannotated self.
Found while reviewing temporalio/ai-integrations#206, which builds agent tools from activity methods.
- Vorherrschende Sprache
- Python
- Sterne
- 1.2k
- Forks
- 285
- Ø Merge
- 1 T. 23 Std.
- Gemergte PRs (30 T.)
- 89
Entwicklungsumgebung
- Kein Dockerfile und keine Docker-Compose-Datei
- Keine Pull-Request-Vorlage
- Beitragsleitfaden lesen
Erste Schritte
- Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
- Forken Sie das Repository und arbeiten Sie in einem Branch.
- Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.
Mehr aus temporalio/sdk-python
-
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 18/100
temporalio/sdk-python#2080 ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug] Sandboxed datetime hints can fail decoding and drop signalsEvtl. vergeben @VegetarianOrc hat das heute übernommen. Offen
temporalio/sdk-python#2072 · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug] TaskGroup cancellation of mixed Temporal operations can break replayEvtl. vergeben @VegetarianOrc hat das heute übernommen. Offen
temporalio/sdk-python#2069 · 1 zugewiesene Person ·
Maintainer antworten meist innerhalb von 1 Tag
-
sdk-python
Schwierigkeit 4/5 3-5 Tage Anfängerfreundlichkeit 22/100
temporalio/sdk-python#2067 · 2 Kommentare ·
Maintainer antworten meist innerhalb von 1 Tag
-
[Bug] lambda_worker otel.apply_defaults leaks a span exporter thread and gRPC channel on every warm invocationEvtl. vergeben @avanish-garg hat das vor 6 Tagen übernommen. Offenbug sdk-python
Schwierigkeit 4/5 1-2 Tage Anfängerfreundlichkeit 30/100
temporalio/sdk-python#2040 ·
Maintainer antworten meist innerhalb von 1 Tag
Alle Issues in temporalio/sdk-python
Ähnliche Issues
-
area:cli bug difficulty:1
Schwierigkeit 1/5 1-3 Stunden Anfängerfreundlichkeit 87/100
MakazhanAlpamys/Soup#2491 · 1 Kommentar ·
Maintainer antworten meist innerhalb von 1 Tag
-
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
microsoft/onnxscript#3155 ·
Maintainer antworten meist innerhalb von 4 Tagen
-
IFEval nth-paragraph checker reads the wrong paragraph when a blank separator is presentEvtl. vergeben @chetana1410 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 82/100
EleutherAI/lm-evaluation-harness#4530 ·
Maintainer antworten meist innerhalb von 1 Tag
-
bug
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 84/100
Maintainer antworten meist innerhalb von 1 Tag
-
sv_SE vat_id() has 14 digits: the "16" organisation number prefix is keptEvtl. vergeben @kevin9327 hat das heute übernommen. Offen
Schwierigkeit 2/5 1-3 Stunden Anfängerfreundlichkeit 76/100
Maintainer antworten meist innerhalb von 19 Tagen