workers-runtime-sdk 1.1.3__tar.gz → 1.1.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,6 +2,28 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.1.5 (2026-05-19)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Wrap DurableObject.abort() so that python cleanup can be done before abort
10
+ ([#106](https://github.com/cloudflare/workers-py/pull/106),
11
+ [`bf6acf2`](https://github.com/cloudflare/workers-py/commit/bf6acf24429fb1525f34334ff2cefffa45b287ef))
12
+
13
+ - **runtime-sdk**: Wrap DO.abort() to cleanup stale tasks before abortion
14
+ ([#106](https://github.com/cloudflare/workers-py/pull/106),
15
+ [`bf6acf2`](https://github.com/cloudflare/workers-py/commit/bf6acf24429fb1525f34334ff2cefffa45b287ef))
16
+
17
+
18
+ ## v1.1.4 (2026-05-06)
19
+
20
+ ### Bug Fixes
21
+
22
+ - Make pth file not warn when run in native Python
23
+ ([#100](https://github.com/cloudflare/workers-py/pull/100),
24
+ [`3c60df6`](https://github.com/cloudflare/workers-py/commit/3c60df6fd59c3ab65adeb5216feee3d52345ebb7))
25
+
26
+
5
27
  ## v1.1.3 (2026-05-04)
6
28
 
7
29
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workers-runtime-sdk
3
- Version: 1.1.3
3
+ Version: 1.1.5
4
4
  Summary: Python SDK for Cloudflare Workers
5
5
  Project-URL: Homepage, https://github.com/cloudflare/workers-py
6
6
  Project-URL: Bug Tracker, https://github.com/cloudflare/workers-py/issues
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "workers-runtime-sdk"
7
- version = "1.1.3"
7
+ version = "1.1.5"
8
8
  description = "Python SDK for Cloudflare Workers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.12"
@@ -0,0 +1 @@
1
+ import _workers_sdk_entropy_import_context_loader
@@ -0,0 +1,13 @@
1
+ """
2
+ Loader shim for _workers_sdk_entropy_import_context.
3
+
4
+ This module is imported by the .pth file on every Python startup. The entropy
5
+ context patches depend on the `_cloudflare` package, which only exists inside
6
+ the workers runtime. When running outside of the workers runtime, `_cloudflare`
7
+ is not available, so we silently skip loading the patches.
8
+ """
9
+
10
+ import importlib.util
11
+
12
+ if importlib.util.find_spec("_cloudflare") is not None:
13
+ import _workers_sdk_entropy_import_context # noqa: F401
@@ -25,9 +25,6 @@ import _cloudflare_compat_flags
25
25
  # Get globals modules and import function from the entrypoint-helper
26
26
  import _pyodide_entrypoint_helper
27
27
  import js
28
-
29
- if TYPE_CHECKING:
30
- from js import DurableObjectState, Env, ExecutionContext
31
28
  import pyodide.http
32
29
  from js import Object
33
30
  from pyodide import __version__ as pyodide_version
@@ -35,6 +32,7 @@ from pyodide.ffi import (
35
32
  JsBuffer,
36
33
  JsException,
37
34
  JsProxy,
35
+ create_once_callable,
38
36
  create_proxy,
39
37
  destroy_proxies,
40
38
  to_js,
@@ -43,6 +41,9 @@ from pyodide.http import pyfetch
43
41
 
44
42
  from workers.workflows import NonRetryableError
45
43
 
44
+ if TYPE_CHECKING:
45
+ from js import DurableObjectState, Env, ExecutionContext
46
+
46
47
 
47
48
  class Context(Protocol):
48
49
  def waitUntil(self, other: Awaitable[Any]) -> None: ...
@@ -1064,6 +1065,39 @@ class _DurableObjectNamespaceWrapper:
1064
1065
  )
1065
1066
 
1066
1067
 
1068
+ class DurableObjectAbort(BaseException):
1069
+ pass
1070
+
1071
+
1072
+ class DurableObjectContext:
1073
+ def __init__(self, ctx: "DurableObjectState"):
1074
+ self._ctx = ctx
1075
+
1076
+ def __getattr__(self, name: str):
1077
+ result = getattr(self._ctx, name)
1078
+ setattr(self, name, result)
1079
+ return result
1080
+
1081
+ def abort(self, reason: str | None = None):
1082
+ # DurableObjectState.abort() terminates JS execution immediately. If Python
1083
+ # calls it synchronously while asyncio is still running the task in the event loop,
1084
+ # V8 unwinds the stack before asyncio can run its task-exit cleanup, leaving
1085
+ # stale task state behind for the next request.
1086
+ #
1087
+ # Therefore, we queue the real abort into a microtask so Python can unwind first,
1088
+ # then raise BaseException to stop user code without being swallowed by
1089
+ # `except Exception` handlers.
1090
+ ctx = self._ctx
1091
+
1092
+ if reason is None:
1093
+ callback = create_once_callable(lambda: ctx.abort())
1094
+ else:
1095
+ callback = create_once_callable(lambda: ctx.abort(reason))
1096
+
1097
+ js.queueMicrotask(callback)
1098
+ raise DurableObjectAbort(reason or "Durable Object abort requested")
1099
+
1100
+
1067
1101
  class _WorkflowInstanceWrapper:
1068
1102
  def __init__(self, binding):
1069
1103
  self._binding = binding
@@ -1331,10 +1365,12 @@ def _wrap_subclass(cls):
1331
1365
  original_init = cls.__init__
1332
1366
 
1333
1367
  def wrapped_init(self, *args, **kwargs):
1368
+ args = list(args)
1334
1369
  if len(args) > 0:
1335
1370
  _pyodide_entrypoint_helper.patchWaitUntil(args[0])
1371
+ if issubclass(cls, DurableObject):
1372
+ args[0] = DurableObjectContext(args[0])
1336
1373
  if len(args) > 1:
1337
- args = list(args)
1338
1374
  args[1] = _EnvWrapper(args[1])
1339
1375
 
1340
1376
  original_init(self, *args, **kwargs)
@@ -1374,7 +1410,7 @@ class DurableObject:
1374
1410
  Base class used to define a Durable Object.
1375
1411
  """
1376
1412
 
1377
- ctx: "DurableObjectState"
1413
+ ctx: "DurableObjectContext"
1378
1414
  env: "Env"
1379
1415
 
1380
1416
  def __init__(self, ctx: "DurableObjectState", env: "Env"):
@@ -1 +0,0 @@
1
- import _workers_sdk_entropy_import_context