From 7c164cf9388340735c8615bd85412e4b3efd7334 Mon Sep 17 00:00:00 2001 From: Adrian Chiris Date: Thu, 14 Feb 2019 14:19:01 +0200 Subject: [PATCH] Support context function argument as keyword Today, when a user uses enginefacade reader/writer decorators he/she is forced to pass the context argument as the first positional argument. performing a decorated function call with this argument passed as a keyword would lead to an out of range exception. This patch proposes to add support for the context argument to be passed as a keyword argument in decorated functions. e.g @enginefacade.reader def foo(context): ... foo(context=ctxt) <- will now be possible Change-Id: Ief0b71bf9a7eb75935612431bdcc26d33bce852d --- oslo_db/sqlalchemy/enginefacade.py | 5 ++++- oslo_db/tests/sqlalchemy/test_enginefacade.py | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/oslo_db/sqlalchemy/enginefacade.py b/oslo_db/sqlalchemy/enginefacade.py index 1cfff157..28b85967 100644 --- a/oslo_db/sqlalchemy/enginefacade.py +++ b/oslo_db/sqlalchemy/enginefacade.py @@ -1003,10 +1003,13 @@ class _TransactionContextManager(object): context_index = 1 else: context_index = 0 + context_kw = argspec.args[context_index] @functools.wraps(fn) def wrapper(*args, **kwargs): - context = args[context_index] + context = kwargs.get(context_kw, None) + if not context: + context = args[context_index] with self._transaction_scope(context): return fn(*args, **kwargs) diff --git a/oslo_db/tests/sqlalchemy/test_enginefacade.py b/oslo_db/tests/sqlalchemy/test_enginefacade.py index 12ccba62..5788fb30 100644 --- a/oslo_db/tests/sqlalchemy/test_enginefacade.py +++ b/oslo_db/tests/sqlalchemy/test_enginefacade.py @@ -519,6 +519,19 @@ class MockFacadeTest(oslo_test_base.BaseTestCase): with self._assert_reader_session(makers) as session: session.execute("test") + def test_session_reader_decorator_kwarg_call(self): + context = oslo_context.RequestContext() + + @enginefacade.reader + def go(context): + context.session.execute("test") + go(context=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") + def test_connection_reader_decorator(self): context = oslo_context.RequestContext()