Merge "Make it possible to use enginefacade decorators with class methods"

This commit is contained in:
Jenkins 2016-06-29 22:04:56 +00:00 committed by Gerrit Code Review
commit 581e1d13dc
3 changed files with 46 additions and 2 deletions

View File

@ -48,8 +48,7 @@ The context manager form is as follows:
The decorator form accesses attributes off the user-defined context The decorator form accesses attributes off the user-defined context
directly; the context must be decorated with the directly; the context must be decorated with the
:func:`oslo_db.sqlalchemy.enginefacade.transaction_context_provider` :func:`oslo_db.sqlalchemy.enginefacade.transaction_context_provider`
decorator. Each function must receive the context as the first decorator. Each function must receive the context argument:
positional argument:
.. code:: python .. code:: python
@ -82,6 +81,30 @@ positional argument:
raised otherwise. raised otherwise.
The decorator form can also be used with class and instance methods which
implicitly receive the first positional argument:
.. code:: python
class DatabaseAccessLayer(object):
@classmethod
@enginefacade.reader
def some_reader_api_function(cls, context):
return context.session.query(SomeClass).all()
@enginefacade.writer
def some_writer_api_function(self, context, x, y):
context.session.add(SomeClass(x, y))
.. note:: Note that enginefacade decorators must be applied **before**
`classmethod`, otherwise you will get a ``TypeError`` at import time
(as enginefacade will try to use ``inspect.getargspec()`` on a descriptor,
not on a bound method, please refer to the `Data Model
<https://docs.python.org/3/reference/datamodel.html#data-model>`_ section
of the Python Language Reference for details).
The scope of transaction and connectivity for both approaches is managed The scope of transaction and connectivity for both approaches is managed
transparently. The configuration for the connection comes from the standard transparently. The configuration for the connection comes from the standard
:obj:`oslo_config.cfg.CONF` collection. Additional configurations can be :obj:`oslo_config.cfg.CONF` collection. Additional configurations can be

View File

@ -1017,6 +1017,21 @@ class MockFacadeTest(oslo_test_base.BaseTestCase):
with self._assert_reader_session(makers) as session: with self._assert_reader_session(makers) as session:
session.execute("test") session.execute("test")
def test_context_found_for_class_method(self):
context = oslo_context.RequestContext()
class Spam(object):
@classmethod
@enginefacade.reader
def go(cls, context):
context.session.execute("test")
Spam.go(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): class SynchronousReaderWSlaveMockFacadeTest(MockFacadeTest):
synchronous_reader = True synchronous_reader = True

View File

@ -0,0 +1,6 @@
---
features:
- enginefacade decorators can now be used for class and instance methods,
which implicitly receive the first positional argument. Previously, it
was required that all decorated functions receive a context value as the
first argument.