summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Podoliaka <rpodolyaka@mirantis.com>2016-06-08 15:34:16 +0300
committerRoman Podoliaka <rpodolyaka@mirantis.com>2016-06-27 17:22:01 +0300
commit8a5fbb723f234c89630360bca24aa91160edd8e0 (patch)
tree52dad5e007aa2393a96badfacede08dd1f9e303d
parent1579c7ce1526a952d74faeaad3e0ad1719604221 (diff)
downloadoslo-db-8a5fbb723f234c89630360bca24aa91160edd8e0.tar.gz
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
-rw-r--r--doc/source/usage.rst27
-rw-r--r--oslo_db/tests/sqlalchemy/test_enginefacade.py15
-rw-r--r--releasenotes/notes/enginefacade_decorators-4660862fe22d2669.yaml6
3 files changed, 46 insertions, 2 deletions
diff --git a/doc/source/usage.rst b/doc/source/usage.rst
index 98a74b0..448afaa 100644
--- a/doc/source/usage.rst
+++ b/doc/source/usage.rst
@@ -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
diff --git a/oslo_db/tests/sqlalchemy/test_enginefacade.py b/oslo_db/tests/sqlalchemy/test_enginefacade.py
index 7f77c28..d27f7bf 100644
--- a/oslo_db/tests/sqlalchemy/test_enginefacade.py
+++ b/oslo_db/tests/sqlalchemy/test_enginefacade.py
@@ -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
diff --git a/releasenotes/notes/enginefacade_decorators-4660862fe22d2669.yaml b/releasenotes/notes/enginefacade_decorators-4660862fe22d2669.yaml
new file mode 100644
index 0000000..e176f28
--- /dev/null
+++ b/releasenotes/notes/enginefacade_decorators-4660862fe22d2669.yaml
@@ -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.