Skip to content
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

[Feature Request] Drop 3.8 support, confirm 3.13 support #672

Open
cretz opened this issue Oct 15, 2024 · 3 comments · May be fixed by #694
Open

[Feature Request] Drop 3.8 support, confirm 3.13 support #672

cretz opened this issue Oct 15, 2024 · 3 comments · May be fixed by #694
Labels
enhancement New feature or request

Comments

@cretz
Copy link
Member

cretz commented Oct 15, 2024

Describe the solution you'd like

See #398 (PR #422) where we did this for 3.7/3.12. Can see the several things that were done there and similar should be done here.

@josh-berry
Copy link
Contributor

I happened to discover by accident that grpcio does not yet support Python 3.13 because it apparently depends on some C APIs that have been removed. So it seems unlikely we'd be able to support it without updating grpcio (if a fix is available; it may already be)

@cretz
Copy link
Member Author

cretz commented Nov 21, 2024

grpcio is an optional dependency. We only added it because we do generate the gRPC stubs in the temporalio.api.workflowservice.v1.service_pb2_grpc and technically allow users to use that module if they want pure Python gRPC clients or servers even though we don't use it in the SDK. We do use it in tests to implement a custom gRPC server and figured "why not let users use the generated gRPC stuff too" in addition to protos. We may be able to remove this stuff if we have to (otherwise we may be able to upgrade it, it all depends on how old of a protobuf library we need to support).

@cretz cretz linked a pull request Nov 25, 2024 that will close this issue
@sciyoshi
Copy link

sciyoshi commented Dec 4, 2024

Tracebacks are currently broken in Python 3.13. The original traceback for an exception happening in a workflow is clobbered and instead the following error is shown:

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/_workflow.py", line 260, in _handle_activation
    completion = await asyncio.wait_for(
                 ^^^^^^^^^^^^^^^^^^^^^^^
        activate_task, self._deadlock_timeout_seconds
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^

  File "/usr/local/lib/python3.13/asyncio/tasks.py", line 507, in wait_for
    return await fut
           ^^^^^^^^^

  File "/usr/local/lib/python3.13/concurrent/futures/thread.py", line 58, in run
    result = self.fn(*self.args, **self.kwargs)

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/workflow_sandbox/_runner.py", line 160, in activate
    self._run_code(
    ~~~~~~~~~~~~~~^
        "with __temporal_importer.applied():\n"
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    ...<2 lines>...
        __temporal_activation=act,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/workflow_sandbox/_runner.py", line 176, in _run_code
    exec(code, self.globals_and_locals, self.globals_and_locals)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "<string>", line 2, in <module>

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/workflow_sandbox/_in_sandbox.py", line 81, in activate
    return self.instance.activate(act)
           ~~~~~~~~~~~~~~~~~~~~~~^^^^^

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/_workflow_instance.py", line 411, in activate
    logger.warning(
    ~~~~~~~~~~~~~~^
        f"Failed activation on workflow {self._info.workflow_type} with ID {self._info.workflow_id} and run ID {self._info.run_id}",
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        exc_info=activation_err,
        ^^^^^^^^^^^^^^^^^^^^^^^^
        extra={"temporal_workflow": self._info._logger_details()},
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    )
    ^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1531, in warning
    self._log(WARNING, msg, args, **kwargs)
    ~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1664, in _log
    self.handle(record)
    ~~~~~~~~~~~^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1680, in handle
    self.callHandlers(record)
    ~~~~~~~~~~~~~~~~~^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1744, in callHandlers
    lastResort.handle(record)
    ~~~~~~~~~~~~~~~~~^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1026, in handle
    self.emit(record)
    ~~~~~~~~~^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1158, in emit
    self.handleError(record)
    ~~~~~~~~~~~~~~~~^^^^^^^^

  File "/usr/local/lib/python3.13/logging/__init__.py", line 1075, in handleError
    traceback.print_exception(exc, limit=None, file=sys.stderr)
    ~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.13/traceback.py", line 129, in print_exception
    te = TracebackException(type(value), value, tb, limit=limit, compact=True)

  File "/usr/local/lib/python3.13/traceback.py", line 1044, in __init__
    self.stack = StackSummary._extract_from_extended_frame_gen(
                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^
        _walk_tb_with_full_positions(exc_traceback),
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        limit=limit, lookup_lines=lookup_lines,
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        capture_locals=capture_locals)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.13/traceback.py", line 492, in _extract_from_extended_frame_gen
    f.line

  File "/usr/local/lib/python3.13/traceback.py", line 369, in line
    self._set_lines()
    ~~~~~~~~~~~~~~~^^

  File "/usr/local/lib/python3.13/traceback.py", line 350, in _set_lines
    lines.append(linecache.getline(self.filename, lineno).rstrip())
                 ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^

  File "/usr/local/lib/python3.13/linecache.py", line 25, in getline
    lines = getlines(filename, module_globals)

  File "/usr/local/lib/python3.13/linecache.py", line 41, in getlines
    return updatecache(filename, module_globals)

  File "/usr/local/lib/python3.13/linecache.py", line 100, in updatecache
    stat = os.stat(fullname)

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/workflow_sandbox/_restrictions.py", line 964, in __call__
    state.assert_child_not_restricted("__call__")
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^

  File "/code/.venv/lib/python3.13/site-packages/temporalio/worker/workflow_sandbox/_restrictions.py", line 792, in assert_child_not_restricted
    raise RestrictedWorkflowAccessError(
        f"{self.name}.{name}", override_message=matcher.leaf_message
    )

The error message occurs from an attempt to access linecache inside the original exception, leading to this:

Cannot access os.stat.__call__ from inside a workflow. If this is code from a module not used in a workflow or known to only be used deterministically from a workflow, mark the import as pass through.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants