Make it possible to use enginefacade decorators with class methods

The decorator form can now be used with bound methods after a fix
for the related bug was merged. Mention this in docs and release
notes, so that people are aware of it.

A new test is added to make sure this also works with class methods
(as well as to check that the proposed decorator applying order
is actually correct).

Related-Bug: #1520195

Change-Id: Ifea08114d6d89de9d67fcae397eb94c0afc4d339
This commit is contained in:
Roman Podoliaka 2016-06-08 15:34:16 +03:00
parent 1579c7ce15
commit 8a5fbb723f
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
directly; the context must be decorated with the
:func:`oslo_db.sqlalchemy.enginefacade.transaction_context_provider`
decorator. Each function must receive the context as the first
positional argument:
decorator. Each function must receive the context argument:
.. code:: python
@ -82,6 +81,30 @@ positional argument:
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
transparently. The configuration for the connection comes from the standard
: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:
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):
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.