Let enginefacade._TransactionContextManager look for context

The previous behavior was to assume that a RequestContext was the first
argument of the wrapped method. This has meant creating staticmethods
within classes in order to be wrapped properly. It's not always
desirable to do so and should not be necessary.

Change-Id: I76b0d9c80dd7841c1333f8b8a2ccdd15e55dfcff
Closes-bug: 1520195
This commit is contained in:
Andrew Laski
2016-03-17 16:58:18 -04:00
parent 045a6fb9fb
commit f98cb90f2b
2 changed files with 20 additions and 1 deletions

View File

@@ -13,6 +13,7 @@
import contextlib
import functools
import inspect
import operator
import threading
import warnings
@@ -700,10 +701,15 @@ class _TransactionContextManager(object):
def __call__(self, fn):
"""Decorate a function."""
argspec = inspect.getargspec(fn)
if argspec.args[0] == 'self' or argspec.args[0] == 'cls':
context_index = 1
else:
context_index = 0
@functools.wraps(fn)
def wrapper(*args, **kwargs):
context = args[0]
context = args[context_index]
with self._transaction_scope(context):
return fn(*args, **kwargs)

View File

@@ -1004,6 +1004,19 @@ class MockFacadeTest(oslo_test_base.BaseTestCase):
getattr, context, 'transaction_ctx'
)
def test_context_found_for_bound_method(self):
context = oslo_context.RequestContext()
@enginefacade.reader
def go(self, context):
context.session.execute("test")
go(self, context)
with self._assert_engines() as engines:
with self._assert_makers(engines) as makers:
with self._assert_reader_session(makers) as session:
session.execute("test")
class SynchronousReaderWSlaveMockFacadeTest(MockFacadeTest):
synchronous_reader = True