Python · Design

Design

1.0.0-rc.1 · 60202332

The binding is a thin native layer, and every rule below follows from that.

  • Processing stays native. Parameter binding, percent-decoding, conversion, reply serialization and the blocking client calls run in the extension, and ucall/__init__.py only re-exports it. A handler’s signature is resolved once at registration, so a request costs a table walk and one call, and a typed handler never sees a Request object at all.
  • Verbs share one name across languages. take_call, take_calls, take_batch, take_batches, submit and take_completed name the same calls in Python and Rust.
  • Ownership follows the request. A reply consumes its Request, a released request answers 500, views over a body pin it until released, and a Response frees itself.
  • Handlers never stop a loop. An exception inside a handler or an authorizer reaches sys.unraisablehook and answers 500 or rejects the peer, and Ctrl+C raised inside one is re-armed for the main thread.
  • Blocking stays simple. Every method looks as it would without asynchrony, and only a reply with file or path parts answers a Deferred.
  • Deferred replies are symmetric through language idioms. A Deferred owns its outcome: wait() blocks, await borrows the running loop’s executor, and releasing it waits, as releasing any owner does. The verbs that may defer exist only on a DetachedRequest, so by type no polling thread waits on its own loop.
  • No extra cost until used. Bytes-only replies keep their outcome on the stack, up to sixteen reply parts lay out on the stack, and a Deferred is the one allocation a file reply adds.
  • No life of its own. The binding starts no threads, keeps no global state beyond imported helpers, and needs no async runtime, so it drops into any threading model.
  • Statuses and modes are enums. ucall.Status, Backend, CPUClass, Security, Verb, BodyDelivery and LogLevel are enum.IntEnum classes, so nothing is ever compared as a string.