workers-runtime-sdk 1.6.4__tar.gz → 1.6.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.
Files changed (26) hide show
  1. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/CHANGELOG.md +9 -0
  2. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/PKG-INFO +1 -1
  3. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/pyproject.toml +1 -1
  4. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/rpc.py +49 -21
  5. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/uv.lock +1 -1
  6. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/.gitignore +0 -0
  7. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/AGENTS.md +0 -0
  8. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/README.md +0 -0
  9. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/_cloudflare_compat_flags.pyi +0 -0
  10. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/_pyodide_entrypoint_helper.pyi +0 -0
  11. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/_workers_sdk_entropy_import_context.pth +0 -0
  12. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/_workers_sdk_entropy_import_context.py +0 -0
  13. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/_workers_sdk_entropy_import_context_loader.py +0 -0
  14. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/asgi.py +0 -0
  15. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/__init__.py +0 -0
  16. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/blob.py +0 -0
  17. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/entrypoints.py +0 -0
  18. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/fetch.py +0 -0
  19. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/formdata.py +0 -0
  20. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/py.typed +0 -0
  21. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/request.py +0 -0
  22. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/response.py +0 -0
  23. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/types.py +0 -0
  24. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/utils.py +0 -0
  25. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/workflows.py +0 -0
  26. {workers_runtime_sdk-1.6.4 → workers_runtime_sdk-1.6.5}/src/workers/wsgi.py +0 -0
@@ -2,6 +2,15 @@
2
2
 
3
3
  <!-- version list -->
4
4
 
5
+ ## v1.6.5 (2026-08-03)
6
+
7
+ ### Bug Fixes
8
+
9
+ - Fix function object returned from RPC to be a callable
10
+ ([#160](https://github.com/cloudflare/workers-py/pull/160),
11
+ [`1019d7e`](https://github.com/cloudflare/workers-py/commit/1019d7e74d824db38328a0a25a7bf09956a7f961))
12
+
13
+
5
14
  ## v1.6.4 (2026-07-30)
6
15
 
7
16
  ### Bug Fixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: workers-runtime-sdk
3
- Version: 1.6.4
3
+ Version: 1.6.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.6.4"
7
+ version = "1.6.5"
8
8
  description = "Python SDK for Cloudflare Workers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -255,22 +255,30 @@ class _BindingWrapper:
255
255
  js_type = _get_js_constructor_name(jsobj)
256
256
  return js_type and js_type not in _JS_PASSTHROUGH_TYPES
257
257
 
258
+ def _wrap_js_value(self, value):
259
+ """
260
+ Wrap JSProxy returned from RPC calls with a
261
+ proper wrapper class.
262
+ """
263
+ if not self._should_wrap_nested_attribute(value):
264
+ return value
265
+
266
+ # A function or RpcTarget returned over RPC arrives as a callable JsRpcStub.
267
+ # Boxing it in a wrapper that has __call__ allows it to be called.
268
+ if callable(value):
269
+ return _RpcStubWrapper(value)
270
+
271
+ return self.__class__(value)
272
+
258
273
  def _convert_result(self, result):
259
274
  converted = python_from_rpc(result)
260
275
 
261
276
  # After python_from_rpc, some objects may still be JsProxy objects.
262
277
  # We need to wrap them with _BindingWrapper (or a subclass of it) again
263
278
  # to ensure that accessing attributes on them will be properly converted.
264
- if self._should_wrap_nested_attribute(converted):
265
- return self.__class__(converted)
266
279
  if isinstance(converted, list):
267
- return [
268
- self.__class__(item)
269
- if self._should_wrap_nested_attribute(item)
270
- else item
271
- for item in converted
272
- ]
273
- return converted
280
+ return [self._wrap_js_value(item) for item in converted]
281
+ return self._wrap_js_value(converted)
274
282
 
275
283
  @staticmethod
276
284
  def _convert_args(args, kwargs):
@@ -278,6 +286,17 @@ class _BindingWrapper:
278
286
  js_kwargs = {k: python_to_rpc(v) for k, v in kwargs.items()}
279
287
  return js_args, js_kwargs
280
288
 
289
+ def _conver_and_invoke(self, fn, args, kwargs):
290
+ js_args, js_kwargs = self._convert_args(args, kwargs)
291
+ result = fn(*js_args, **js_kwargs)
292
+ if hasattr(result, "then") and callable(result.then):
293
+
294
+ async def await_and_convert():
295
+ return self._convert_result(await result)
296
+
297
+ return await_and_convert()
298
+ return self._convert_result(result)
299
+
281
300
  def _getattr_helper(self, name):
282
301
  attr = getattr(self._binding, name)
283
302
 
@@ -285,15 +304,7 @@ class _BindingWrapper:
285
304
  return self._convert_result(attr)
286
305
 
287
306
  def wrapper(*args, **kwargs):
288
- js_args, js_kwargs = self._convert_args(args, kwargs)
289
- result = attr(*js_args, **js_kwargs)
290
- if hasattr(result, "then") and callable(result.then):
291
-
292
- async def await_and_convert():
293
- return self._convert_result(await result)
294
-
295
- return await_and_convert()
296
- return self._convert_result(result)
307
+ return self._conver_and_invoke(attr, args, kwargs)
297
308
 
298
309
  return wrapper
299
310
 
@@ -314,11 +325,28 @@ class _BindingWrapper:
314
325
  for item in binding:
315
326
  yield self._convert_result(item)
316
327
 
328
+ def __bool__(self):
329
+ return self._binding is not None
330
+
317
331
  def __len__(self):
318
- binding = self._binding
319
- if not hasattr(binding, "length"):
332
+ length = getattr(self._binding, "length", None)
333
+ # RPC object always returns true for attribute lookup,
334
+ # so make sure it is actually a numeric length.
335
+ if not isinstance(length, int):
320
336
  raise TypeError(f"'{self._real_name}' object has no len()")
321
- return binding.length
337
+ return length
338
+
339
+
340
+ class _RpcStubWrapper(_BindingWrapper):
341
+ """
342
+ A function or RpcTarget received over RPC.
343
+
344
+ Calling is always allowed but the server will reject it
345
+ if the target turns out not to be callable.
346
+ """
347
+
348
+ def __call__(self, *args, **kwargs):
349
+ return self._conver_and_invoke(self._binding, args, kwargs)
322
350
 
323
351
 
324
352
  class _FetcherWrapper(_BindingWrapper):
@@ -229,7 +229,7 @@ wheels = [
229
229
 
230
230
  [[package]]
231
231
  name = "workers-runtime-sdk"
232
- version = "1.6.4"
232
+ version = "1.6.5"
233
233
  source = { editable = "." }
234
234
 
235
235
  [package.dev-dependencies]