Загрузить файлы в «venv/Lib/site-packages/greenlet/tests»
This commit is contained in:
@@ -0,0 +1,47 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
If we have a run callable passed to the constructor or set as an
|
||||||
|
attribute, but we don't actually use that (because ``__getattribute__``
|
||||||
|
or the like interferes), then when we clear callable before beginning
|
||||||
|
to run, there's an opportunity for Python code to run.
|
||||||
|
|
||||||
|
"""
|
||||||
|
import greenlet
|
||||||
|
|
||||||
|
g = None
|
||||||
|
main = greenlet.getcurrent()
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
class RunCallable:
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
results.append(('RunCallable', '__del__'))
|
||||||
|
main.switch('from RunCallable')
|
||||||
|
|
||||||
|
|
||||||
|
class G(greenlet.greenlet):
|
||||||
|
|
||||||
|
def __getattribute__(self, name):
|
||||||
|
if name == 'run':
|
||||||
|
results.append(('G.__getattribute__', 'run'))
|
||||||
|
return run_func
|
||||||
|
return object.__getattribute__(self, name)
|
||||||
|
|
||||||
|
|
||||||
|
def run_func():
|
||||||
|
results.append(('run_func', 'enter'))
|
||||||
|
|
||||||
|
|
||||||
|
g = G(RunCallable())
|
||||||
|
# Try to start G. It will get to the point where it deletes
|
||||||
|
# its run callable C++ variable in inner_bootstrap. That triggers
|
||||||
|
# the __del__ method, which switches back to main before g
|
||||||
|
# actually even starts running.
|
||||||
|
x = g.switch()
|
||||||
|
results.append(('main: g.switch()', x))
|
||||||
|
# In the C++ code, this results in g->g_switch() appearing to return, even though
|
||||||
|
# it has yet to run.
|
||||||
|
print('In main with', x, flush=True)
|
||||||
|
g.switch()
|
||||||
|
print('RESULTS', results)
|
||||||
33
venv/Lib/site-packages/greenlet/tests/fail_cpp_exception.py
Normal file
33
venv/Lib/site-packages/greenlet/tests/fail_cpp_exception.py
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
Helper for testing a C++ exception throw aborts the process.
|
||||||
|
|
||||||
|
Takes one argument, the name of the function in :mod:`_test_extension_cpp` to call.
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import greenlet
|
||||||
|
from greenlet.tests import _test_extension_cpp
|
||||||
|
print('fail_cpp_exception is running')
|
||||||
|
|
||||||
|
def run_unhandled_exception_in_greenlet_aborts():
|
||||||
|
def _():
|
||||||
|
_test_extension_cpp.test_exception_switch_and_do_in_g2(
|
||||||
|
_test_extension_cpp.test_exception_throw_nonstd
|
||||||
|
)
|
||||||
|
g1 = greenlet.greenlet(_)
|
||||||
|
g1.switch()
|
||||||
|
|
||||||
|
|
||||||
|
func_name = sys.argv[1]
|
||||||
|
try:
|
||||||
|
func = getattr(_test_extension_cpp, func_name)
|
||||||
|
except AttributeError:
|
||||||
|
if func_name == run_unhandled_exception_in_greenlet_aborts.__name__:
|
||||||
|
func = run_unhandled_exception_in_greenlet_aborts
|
||||||
|
elif func_name == 'run_as_greenlet_target':
|
||||||
|
g = greenlet.greenlet(_test_extension_cpp.test_exception_throw_std)
|
||||||
|
func = g.switch
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
print('raising', func, flush=True)
|
||||||
|
func()
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
"""
|
||||||
|
Testing initialstub throwing an already started exception.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import greenlet
|
||||||
|
|
||||||
|
a = None
|
||||||
|
b = None
|
||||||
|
c = None
|
||||||
|
main = greenlet.getcurrent()
|
||||||
|
|
||||||
|
# If we switch into a dead greenlet,
|
||||||
|
# we go looking for its parents.
|
||||||
|
# if a parent is not yet started, we start it.
|
||||||
|
|
||||||
|
results = []
|
||||||
|
|
||||||
|
def a_run(*args):
|
||||||
|
#results.append('A')
|
||||||
|
results.append(('Begin A', args))
|
||||||
|
|
||||||
|
|
||||||
|
def c_run():
|
||||||
|
results.append('Begin C')
|
||||||
|
b.switch('From C')
|
||||||
|
results.append('C done')
|
||||||
|
|
||||||
|
class A(greenlet.greenlet): pass
|
||||||
|
|
||||||
|
class B(greenlet.greenlet):
|
||||||
|
doing_it = False
|
||||||
|
def __getattribute__(self, name):
|
||||||
|
if name == 'run' and not self.doing_it:
|
||||||
|
assert greenlet.getcurrent() is c
|
||||||
|
self.doing_it = True
|
||||||
|
results.append('Switch to b from B.__getattribute__ in '
|
||||||
|
+ type(greenlet.getcurrent()).__name__)
|
||||||
|
b.switch()
|
||||||
|
results.append('B.__getattribute__ back from main in '
|
||||||
|
+ type(greenlet.getcurrent()).__name__)
|
||||||
|
if name == 'run':
|
||||||
|
name = '_B_run'
|
||||||
|
return object.__getattribute__(self, name)
|
||||||
|
|
||||||
|
def _B_run(self, *arg):
|
||||||
|
results.append(('Begin B', arg))
|
||||||
|
results.append('_B_run switching to main')
|
||||||
|
main.switch('From B')
|
||||||
|
|
||||||
|
class C(greenlet.greenlet):
|
||||||
|
pass
|
||||||
|
a = A(a_run)
|
||||||
|
b = B(parent=a)
|
||||||
|
c = C(c_run, b)
|
||||||
|
|
||||||
|
# Start a child; while running, it will start B,
|
||||||
|
# but starting B will ALSO start B.
|
||||||
|
result = c.switch()
|
||||||
|
results.append(('main from c', result))
|
||||||
|
|
||||||
|
# Switch back to C, which was in the middle of switching
|
||||||
|
# already. This will throw the ``GreenletStartedWhileInPython``
|
||||||
|
# exception, which results in parent A getting started (B is finished)
|
||||||
|
c.switch()
|
||||||
|
|
||||||
|
results.append(('A dead?', a.dead, 'B dead?', b.dead, 'C dead?', c.dead))
|
||||||
|
|
||||||
|
# A and B should both be dead now.
|
||||||
|
assert a.dead
|
||||||
|
assert b.dead
|
||||||
|
assert not c.dead
|
||||||
|
|
||||||
|
result = c.switch()
|
||||||
|
results.append(('main from c.2', result))
|
||||||
|
# Now C is dead
|
||||||
|
assert c.dead
|
||||||
|
|
||||||
|
print("RESULTS:", results)
|
||||||
29
venv/Lib/site-packages/greenlet/tests/fail_slp_switch.py
Normal file
29
venv/Lib/site-packages/greenlet/tests/fail_slp_switch.py
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
"""
|
||||||
|
A test helper for seeing what happens when slp_switch()
|
||||||
|
fails.
|
||||||
|
"""
|
||||||
|
# pragma: no cover
|
||||||
|
|
||||||
|
import greenlet
|
||||||
|
|
||||||
|
|
||||||
|
print('fail_slp_switch is running', flush=True)
|
||||||
|
|
||||||
|
runs = []
|
||||||
|
def func():
|
||||||
|
runs.append(1)
|
||||||
|
greenlet.getcurrent().parent.switch()
|
||||||
|
runs.append(2)
|
||||||
|
greenlet.getcurrent().parent.switch()
|
||||||
|
runs.append(3)
|
||||||
|
|
||||||
|
g = greenlet._greenlet.UnswitchableGreenlet(func)
|
||||||
|
g.switch()
|
||||||
|
assert runs == [1]
|
||||||
|
g.switch()
|
||||||
|
assert runs == [1, 2]
|
||||||
|
g.force_slp_switch_error = True
|
||||||
|
|
||||||
|
# This should crash.
|
||||||
|
g.switch()
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
"""
|
||||||
|
Uses a trace function to switch greenlets at unexpected times.
|
||||||
|
|
||||||
|
In the trace function, we switch from the current greenlet to another
|
||||||
|
greenlet, which switches
|
||||||
|
"""
|
||||||
|
import greenlet
|
||||||
|
|
||||||
|
g1 = None
|
||||||
|
g2 = None
|
||||||
|
|
||||||
|
switch_to_g2 = False
|
||||||
|
|
||||||
|
def tracefunc(*args):
|
||||||
|
print('TRACE', *args)
|
||||||
|
global switch_to_g2
|
||||||
|
if switch_to_g2:
|
||||||
|
switch_to_g2 = False
|
||||||
|
g2.switch()
|
||||||
|
print('\tLEAVE TRACE', *args)
|
||||||
|
|
||||||
|
def g1_run():
|
||||||
|
print('In g1_run')
|
||||||
|
global switch_to_g2
|
||||||
|
switch_to_g2 = True
|
||||||
|
from_parent = greenlet.getcurrent().parent.switch()
|
||||||
|
print('Return to g1_run')
|
||||||
|
print('From parent', from_parent)
|
||||||
|
|
||||||
|
def g2_run():
|
||||||
|
#g1.switch()
|
||||||
|
greenlet.getcurrent().parent.switch()
|
||||||
|
|
||||||
|
greenlet.settrace(tracefunc)
|
||||||
|
|
||||||
|
g1 = greenlet.greenlet(g1_run)
|
||||||
|
g2 = greenlet.greenlet(g2_run)
|
||||||
|
|
||||||
|
# This switch didn't actually finish!
|
||||||
|
# And if it did, it would raise TypeError
|
||||||
|
# because g1_run() doesn't take any arguments.
|
||||||
|
g1.switch(1)
|
||||||
|
print('Back in main')
|
||||||
|
g1.switch(2)
|
||||||
Reference in New Issue
Block a user