Загрузить файлы в «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