greenhouse.emulation – Faking Out Third Parties

monkey-patching facilities for greenhouse’s cooperative stdlib replacements

many of the apis in greenhouse (particularly in the greenhouse.util module) have been explicitly made to match the signatures and behavior of I/O and threading related apis from the python standard library.

this module enables monkey-patching the stdlib modules to swap in the greenhouse versions, the idea being that you can cause a third-party library to use coroutines without it having to be explicitly written that way.

greenhouse.emulation.patch(*module_names)

apply monkey-patches to stdlib modules in-place

imports the relevant modules and simply overwrites attributes on the module objects themselves. those attributes may be functions, classes or other attributes.

valid arguments are:

  • __builtin__
  • Queue
  • fcntl
  • os
  • select
  • signal
  • socket
  • ssl
  • sys
  • thread
  • threading
  • time
  • zmq

with no arguments, patches everything it can in all of the above modules

Raises :ValueError if an unknown module name is provided

Note

lots more standard library modules can be made non-blocking by virtue of patching some combination of the the above (because they only block by using blocking functions defined elsewhere). a few examples:

  • subprocess works cooperatively with os and select patched
  • httplib, urllib and urllib2 will all operate cooperatively with socket and ssl patched
greenhouse.emulation.unpatch(*module_names)

undo patch()es to standard library modules

this function takes one or more module names and puts back their patched attributes to the standard library originals.

valid arguments are the same as for patch().

with no arguments, undoes all monkeypatches that have been applied

Raises :ValueError if an unknown module name is provided
greenhouse.emulation.patched(module_name)

import and return a named module with patches applied locally only

this function returns a module after importing it in such as way that it will operate cooperatively, but not overriding the module globally.

>>> green_httplib = patched("httplib")
>>> # using green_httplib will only block greenlets
>>> import httplib
>>> # using httplib will block threads/processes
>>> # both can exist simultaneously
Parameters:module_name (str) – the module’s name that is to be imported. this can be a dot-delimited name, in which case the module at the end of the path is the one that will be returned
Returns:the module indicated by module_name, imported so that it will not block globally, but also not touching existing global modules
greenhouse.emulation.patched_context(*args, **kwds)

apply emulation patches only for a specific context

Parameters:
  • module_names – var-args for the modules to patch, as in patch()
  • local – if True, unpatching is done on every switch-out, and re-patching on every switch-in, so that they are only applied for the one coroutine
Returns:

a contextmanager that patches on __enter__ and unpatches on __exit__

Previous topic

greenhouse.compat – Greenlet and Compatibility Hacks

Next topic

greenhouse.backdoor – Interpreter On A Socket

This Page