def patch_module(target_module, source_module, items=None, _warnings=None, _notify_did_subscribers=True): """ patch_module(target_module, source_module, items=None) Replace attributes in *target_module* with the attributes of the same name in *source_module*. The *source_module* can provide some attributes to customize the process: * ``__implements__`` is a list of attribute names to copy; if not present, the *items* keyword argument is mandatory. * ``_gevent_will_monkey_patch(target_module, items, warn, **kwargs)`` * ``_gevent_did_monkey_patch(target_module, items, warn, **kwargs)`` These two functions in the *source_module* are called *if* they exist, before and after copying attributes, respectively. The "will" function may modify *items*. The value of *warn* is a function that should be called with a single string argument to issue a warning to the user. If the "will" function raises :exc:`gevent.events.DoNotPatch`, no patching will be done. These functions are called before any event subscribers or plugins. :keyword list items: A list of attribute names to replace. If not given, this will be taken from the *source_module* ``__implements__`` attribute. :return: A true value if patching was done, a false value if patching was canceled. .. versionadded:: 1.3b1 """ from gevent import events if items is None: items = getattr(source_module, '__implements__', None) if items is None: raise AttributeError('%r does not have __implements__' % source_module) try: __call_module_hook(source_module, 'will', target_module, items, _warnings) _notify_patch( events.GeventWillPatchModuleEvent(target_module.__name__, source_module, target_module, items), _warnings) except events.DoNotPatch: return False for attr in items: patch_item(target_module, attr, getattr(source_module, attr)) __call_module_hook(source_module, 'did', target_module, items, _warnings) if _notify_did_subscribers: # We allow turning off the broadcast of the 'did' event for the benefit # of our internal functions which need to do additional work (besides copying # attributes) before their patch can be considered complete. _notify_patch( events.GeventDidPatchModuleEvent(target_module.__name__, source_module, target_module) ) return True
def patch_sys(stdin=True, stdout=True, stderr=True): """ Patch sys.std[in,out,err] to use a cooperative IO via a threadpool. This is relatively dangerous and can have unintended consequences such as hanging the process or `misinterpreting control keys`_ when :func:`input` and :func:`raw_input` are used. :func:`patch_all` does *not* call this function by default. This method does nothing on Python 3. The Python 3 interpreter wants to flush the TextIOWrapper objects that make up stderr/stdout at shutdown time, but using a threadpool at that time leads to a hang. .. _`misinterpreting control keys`: https://github.com/gevent/gevent/issues/274 """ # test__issue6.py demonstrates the hang if these lines are removed; # strangely enough that test passes even without monkey-patching sys if PY3: items = None else: items = set([('stdin' if stdin else None), ('stdout' if stdout else None), ('stderr' if stderr else None)]) items.discard(None) items = list(items) if not items: return from gevent import events _notify_patch(events.GeventWillPatchModuleEvent('sys', None, sys, items)) for item in items: _patch_sys_std(item) _notify_patch(events.GeventDidPatchModuleEvent('sys', None, sys))