def spawn_raw(function, *args, **kwargs): """ Create a new :class:`greenlet.greenlet` object and schedule it to run ``function(*args, **kwargs)``. This returns a raw :class:`~greenlet.greenlet` which does not have all the useful methods that :class:`gevent.Greenlet` has. Typically, applications should prefer :func:`~gevent.spawn`, but this method may occasionally be useful as an optimization if there are many greenlets involved. .. versionchanged:: 1.1a3 Verify that ``function`` is callable, raising a TypeError if not. Previously, the spawned greenlet would have failed the first time it was switched to. .. versionchanged:: 1.1b1 If *function* is not callable, immediately raise a :exc:`TypeError` instead of spawning a greenlet that will raise an uncaught TypeError. .. versionchanged:: 1.1rc2 Accept keyword arguments for ``function`` as previously (incorrectly) documented. Note that this may incur an additional expense. .. versionchanged:: 1.3a2 Populate the ``spawning_greenlet`` and ``spawn_tree_locals`` attributes of the returned greenlet. """ if not callable(function): raise TypeError("function must be callable") # The hub is always the parent. hub = get_hub() # The callback class object that we use to run this doesn't # accept kwargs (and those objects are heavily used, as well as being # implemented twice in core.ppyx and corecffi.py) so do it with a partial if kwargs: function = _functools_partial(function, *args, **kwargs) g = RawGreenlet(function, hub) hub.loop.run_callback(g.switch) else: g = RawGreenlet(function, hub) hub.loop.run_callback(g.switch, *args) # See greenlet.py's Greenlet class. We capture the cheap # parts to maintain the tree structure, but we do not capture # the stack because that's too expensive. current = getcurrent() g.spawning_greenlet = wref(current) # See Greenlet for how trees are maintained. try: g.spawn_tree_locals = current.spawn_tree_locals except AttributeError: g.spawn_tree_locals = {} if current.parent: current.spawn_tree_locals = g.spawn_tree_locals return g
def test_forest_fake_parent(self): from greenlet import greenlet as RawGreenlet def t4(): # Ignore this one, make the child the parent, # and don't be a child of the hub. c = RawGreenlet(util.GreenletTree.current_tree) c.parent.greenlet_tree_is_ignored = True c.greenlet_tree_is_root = True return c.switch() g = RawGreenlet(t4) tree = g.switch() tree_format = tree.format(details={ 'running_stacks': False, 'spawning_stacks': False }) value = self._normalize_tree_format(tree_format) expected = """\ <greenlet.greenlet object at X>; not running : Parent: <greenlet.greenlet object at X> """.strip() self.assertEqual(expected, value)
def t4(): # Ignore this one, make the child the parent, # and don't be a child of the hub. c = RawGreenlet(util.GreenletTree.current_tree) c.parent.greenlet_tree_is_ignored = True c.greenlet_tree_is_root = True return c.switch()
def spawn_raw(function, *args, **kwargs): """ Create a new :class:`greenlet.greenlet` object and schedule it to run ``function(*args, **kwargs)``. This returns a raw :class:`~greenlet.greenlet` which does not have all the useful methods that :class:`gevent.Greenlet` has. Typically, applications should prefer :func:`~gevent.spawn`, but this method may occasionally be useful as an optimization if there are many greenlets involved. .. versionchanged:: 1.1b1 If *function* is not callable, immediately raise a :exc:`TypeError` instead of spawning a greenlet that will raise an uncaught TypeError. .. versionchanged:: 1.1rc2 Accept keyword arguments for ``function`` as previously (incorrectly) documented. Note that this may incur an additional expense. .. versionchanged:: 1.1a3 Verify that ``function`` is callable, raising a TypeError if not. Previously, the spawned greenlet would have failed the first time it was switched to. """ if not callable(function): raise TypeError("function must be callable") hub = get_hub() # The callback class object that we use to run this doesn't # accept kwargs (and those objects are heavily used, as well as being # implemented twice in core.ppyx and corecffi.py) so do it with a partial if kwargs: function = _functools_partial(function, *args, **kwargs) g = RawGreenlet(function, hub) hub.loop.run_callback(g.switch) else: g = RawGreenlet(function, hub) hub.loop.run_callback(g.switch, *args) return g