Merge "Remove deprecated wrappertask decorator"
This commit is contained in:
commit
f0a9eb61fe
@ -11,11 +11,9 @@
|
|||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import functools
|
|
||||||
import sys
|
import sys
|
||||||
import types
|
import types
|
||||||
|
|
||||||
import debtcollector
|
|
||||||
import eventlet
|
import eventlet
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import encodeutils
|
from oslo_utils import encodeutils
|
||||||
@ -294,61 +292,6 @@ class TaskRunner(object):
|
|||||||
return self.__nonzero__()
|
return self.__nonzero__()
|
||||||
|
|
||||||
|
|
||||||
@debtcollector.removals.remove(message="Use the Python 3 'yield from' keyword "
|
|
||||||
"in place of 'yield', instead of "
|
|
||||||
"decorating with @wrappertask.",
|
|
||||||
stacklevel=1)
|
|
||||||
def wrappertask(task):
|
|
||||||
"""Decorator for a task that needs to drive a subtask.
|
|
||||||
|
|
||||||
This is essentially a replacement for the Python 3-only "yield from"
|
|
||||||
keyword (PEP 380), using the "yield" keyword that is supported in
|
|
||||||
Python 2. For example::
|
|
||||||
|
|
||||||
@wrappertask
|
|
||||||
def parent_task(self):
|
|
||||||
self.setup()
|
|
||||||
|
|
||||||
yield self.child_task()
|
|
||||||
|
|
||||||
self.cleanup()
|
|
||||||
"""
|
|
||||||
|
|
||||||
@functools.wraps(task)
|
|
||||||
def wrapper(*args, **kwargs):
|
|
||||||
# This could be simplified by using 'yield from' for the parent loop
|
|
||||||
# as well, but not without adding yet another frame to the stack
|
|
||||||
# for the subtasks.
|
|
||||||
parent = task(*args, **kwargs)
|
|
||||||
|
|
||||||
try:
|
|
||||||
subtask = next(parent)
|
|
||||||
except StopIteration:
|
|
||||||
return
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
if isinstance(subtask, types.GeneratorType):
|
|
||||||
yield from subtask
|
|
||||||
else:
|
|
||||||
yield subtask
|
|
||||||
except GeneratorExit:
|
|
||||||
parent.close()
|
|
||||||
raise
|
|
||||||
except: # noqa
|
|
||||||
try:
|
|
||||||
subtask = parent.throw(*sys.exc_info())
|
|
||||||
except StopIteration:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
subtask = next(parent)
|
|
||||||
except StopIteration:
|
|
||||||
return
|
|
||||||
|
|
||||||
return wrapper
|
|
||||||
|
|
||||||
|
|
||||||
class DependencyTaskGroup(object):
|
class DependencyTaskGroup(object):
|
||||||
"""Task which manages group of subtasks that have ordering dependencies."""
|
"""Task which manages group of subtasks that have ordering dependencies."""
|
||||||
|
|
||||||
|
@ -1289,419 +1289,3 @@ class DescriptionTest(common.HeatTestCase):
|
|||||||
scheduler.task_description(C().m))
|
scheduler.task_description(C().m))
|
||||||
self.assertEqual(u'\u2665',
|
self.assertEqual(u'\u2665',
|
||||||
scheduler.task_description(C()))
|
scheduler.task_description(C()))
|
||||||
|
|
||||||
|
|
||||||
class WrapperTaskTest(common.HeatTestCase):
|
|
||||||
|
|
||||||
def setUp(self):
|
|
||||||
super(WrapperTaskTest, self).setUp()
|
|
||||||
|
|
||||||
def test_wrap(self):
|
|
||||||
child_tasks = [DummyTask() for i in range(3)]
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def task():
|
|
||||||
for child_task in child_tasks:
|
|
||||||
yield child_task()
|
|
||||||
|
|
||||||
yield
|
|
||||||
|
|
||||||
for child_task in child_tasks:
|
|
||||||
child_task.do_step = mock.Mock(return_value=None)
|
|
||||||
self.patchobject(scheduler.TaskRunner, '_sleep', return_value=None)
|
|
||||||
|
|
||||||
scheduler.TaskRunner(task)()
|
|
||||||
|
|
||||||
for child_task in child_tasks:
|
|
||||||
child_task.do_step.assert_has_calls([mock.call(1), mock.call(2),
|
|
||||||
mock.call(3)])
|
|
||||||
self.assertEqual(3, child_task.do_step.call_count)
|
|
||||||
scheduler.TaskRunner._sleep.assert_any_call(0)
|
|
||||||
scheduler.TaskRunner._sleep.assert_called_with(1)
|
|
||||||
self.assertEqual(1 + len(child_tasks) * 3,
|
|
||||||
scheduler.TaskRunner._sleep.call_count)
|
|
||||||
|
|
||||||
def test_parent_yield_value(self):
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
yield
|
|
||||||
yield 3
|
|
||||||
yield iter([1, 2, 4])
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
|
|
||||||
self.assertIsNone(next(task))
|
|
||||||
self.assertEqual(3, next(task))
|
|
||||||
self.assertEqual([1, 2, 4], list(next(task)))
|
|
||||||
|
|
||||||
def test_child_yield_value(self):
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
yield 3
|
|
||||||
yield iter([1, 2, 4])
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
yield child_task()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
|
|
||||||
self.assertIsNone(next(task))
|
|
||||||
self.assertEqual(3, next(task))
|
|
||||||
self.assertEqual([1, 2, 4], list(next(task)))
|
|
||||||
|
|
||||||
def test_child_exception(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
|
|
||||||
raise MyException()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except MyException:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(MyException, next, task)
|
|
||||||
|
|
||||||
def test_child_exception_exit(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
|
|
||||||
raise MyException()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except MyException:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, next, task)
|
|
||||||
|
|
||||||
def test_child_exception_swallow(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
|
|
||||||
raise MyException()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except MyException:
|
|
||||||
yield
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
yield
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
next(task)
|
|
||||||
|
|
||||||
def test_child_exception_swallow_next(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
|
|
||||||
raise MyException()
|
|
||||||
|
|
||||||
dummy = DummyTask()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except MyException:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
yield dummy()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
|
|
||||||
dummy.do_step = mock.Mock(return_value=None)
|
|
||||||
for i in range(1, dummy.num_steps + 1):
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, next, task)
|
|
||||||
|
|
||||||
dummy.do_step.assert_has_calls([mock.call(i)
|
|
||||||
for i in range(1,
|
|
||||||
dummy.num_steps + 1)])
|
|
||||||
self.assertEqual(dummy.num_steps, dummy.do_step.call_count)
|
|
||||||
|
|
||||||
def test_thrown_exception_swallow_next(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
dummy = DummyTask()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except MyException:
|
|
||||||
yield dummy()
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in child_task')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
yield child_task()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
|
|
||||||
dummy.do_step = mock.Mock(return_value=None)
|
|
||||||
|
|
||||||
next(task)
|
|
||||||
task.throw(MyException)
|
|
||||||
|
|
||||||
for i in range(2, dummy.num_steps + 1):
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, next, task)
|
|
||||||
|
|
||||||
dummy.do_step.assert_has_calls([mock.call(i)
|
|
||||||
for i in range(1,
|
|
||||||
dummy.num_steps + 1)])
|
|
||||||
self.assertEqual(dummy.num_steps, dummy.do_step.call_count)
|
|
||||||
|
|
||||||
def test_thrown_exception_raise(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
dummy = DummyTask()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except MyException:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in child_task')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except MyException:
|
|
||||||
yield dummy()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
|
|
||||||
dummy.do_step = mock.Mock(return_value=None)
|
|
||||||
|
|
||||||
next(task)
|
|
||||||
task.throw(MyException)
|
|
||||||
|
|
||||||
for i in range(2, dummy.num_steps + 1):
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, next, task)
|
|
||||||
|
|
||||||
dummy.do_step.assert_has_calls([mock.call(i)
|
|
||||||
for i in range(1,
|
|
||||||
dummy.num_steps + 1)])
|
|
||||||
self.assertEqual(dummy.num_steps, dummy.do_step.call_count)
|
|
||||||
|
|
||||||
def test_thrown_exception_exit(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
dummy = DummyTask()
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except MyException:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in child_task')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
yield child_task()
|
|
||||||
yield dummy()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
|
|
||||||
dummy.do_step = mock.Mock(return_value=None)
|
|
||||||
|
|
||||||
next(task)
|
|
||||||
task.throw(MyException)
|
|
||||||
|
|
||||||
for i in range(2, dummy.num_steps + 1):
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, next, task)
|
|
||||||
|
|
||||||
dummy.do_step.assert_has_calls([mock.call(i)
|
|
||||||
for i in range(1,
|
|
||||||
dummy.num_steps + 1)])
|
|
||||||
self.assertEqual(dummy.num_steps, dummy.do_step.call_count)
|
|
||||||
|
|
||||||
def test_parent_exception(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def child_task():
|
|
||||||
yield
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
yield child_task()
|
|
||||||
raise MyException()
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(MyException, next, task)
|
|
||||||
|
|
||||||
def test_parent_throw(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield DummyTask()()
|
|
||||||
except MyException:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(MyException, task.throw, MyException())
|
|
||||||
|
|
||||||
def test_parent_throw_exit(self):
|
|
||||||
class MyException(Exception):
|
|
||||||
pass
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield DummyTask()()
|
|
||||||
except MyException:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('No exception raised in parent_task')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
self.assertRaises(StopIteration, task.throw, MyException())
|
|
||||||
|
|
||||||
def test_parent_cancel(self):
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except GeneratorExit:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('parent_task not closed')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
task.close()
|
|
||||||
|
|
||||||
def test_parent_cancel_exit(self):
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except GeneratorExit:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('parent_task not closed')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
task.close()
|
|
||||||
|
|
||||||
def test_cancel(self):
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except GeneratorExit:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('child_task not closed')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except GeneratorExit:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('parent_task not closed')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
task.close()
|
|
||||||
|
|
||||||
def test_cancel_exit(self):
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except GeneratorExit:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('child_task not closed')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except GeneratorExit:
|
|
||||||
raise
|
|
||||||
else:
|
|
||||||
self.fail('parent_task not closed')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
task.close()
|
|
||||||
|
|
||||||
def test_cancel_parent_exit(self):
|
|
||||||
def child_task():
|
|
||||||
try:
|
|
||||||
yield
|
|
||||||
except GeneratorExit:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('child_task not closed')
|
|
||||||
|
|
||||||
@scheduler.wrappertask
|
|
||||||
def parent_task():
|
|
||||||
try:
|
|
||||||
yield child_task()
|
|
||||||
except GeneratorExit:
|
|
||||||
return
|
|
||||||
else:
|
|
||||||
self.fail('parent_task not closed')
|
|
||||||
|
|
||||||
task = parent_task()
|
|
||||||
next(task)
|
|
||||||
task.close()
|
|
||||||
|
@ -2,7 +2,6 @@ pbr>=3.1.1 # Apache-2.0
|
|||||||
alembic>=1.8.0 # MIT
|
alembic>=1.8.0 # MIT
|
||||||
croniter>=0.3.4 # MIT License
|
croniter>=0.3.4 # MIT License
|
||||||
cryptography>=2.5 # BSD/Apache-2.0
|
cryptography>=2.5 # BSD/Apache-2.0
|
||||||
debtcollector>=1.19.0 # Apache-2.0
|
|
||||||
eventlet!=0.18.3,!=0.20.1,!=0.21.0,!=0.23.0,!=0.25.0,>=0.18.2 # MIT
|
eventlet!=0.18.3,!=0.20.1,!=0.21.0,!=0.23.0,!=0.25.0,>=0.18.2 # MIT
|
||||||
keystoneauth1>=3.18.0 # Apache-2.0
|
keystoneauth1>=3.18.0 # Apache-2.0
|
||||||
keystonemiddleware>=5.1.0 # Apache-2.0
|
keystonemiddleware>=5.1.0 # Apache-2.0
|
||||||
|
Loading…
Reference in New Issue
Block a user