Today I wrote a thing called SynchronousDeferred. The target audience is made of those who are writing libraries that want to support both blocking and non-blocking interfaces. I wrote it to allow me to use python-openid in a non-blocking way. After totally refactoring it to use SynchronousDeferred, of course.

Basically the way you use it is that you write your entire library in the way you would normally write it with Twisted: use Deferreds everywhere. There are two major differences, one at the outermost parts of your library and one at the innermost, and one rule on how they interact:

  1. In your blocking entrypoints, return the result of SynchronousDeferred.synchronize() instead of the deferred itself

  2. Anywhere you would do some long-running task, wrap SynchronousDeferreds around the blocking implementations but make the non-blocking implementations return regular Deferreds.

  3. When the user is using asynchronous entrypoints, try to use asynchronous low-level APIs. When the user is using synchronous entrypoints, definitely only use synchronous (SynchronousDeferred-returning) APIs.

synchronize returns or raises the current value on a SynchronousDeferred immediately.

SynchronousDeferred doesn't have callback or errback methods like normal deferreds, as you have to pass the initial value of the Deferred straight to the constructor.

Project page:
Code browse: