Reviewers: ,


Please review this at http://codereview.tryton.org/501003/

Affected files:
  M proteus/__init__.py
  M proteus/config.py
  A proteus/context.py
  A proteus/tests/test_context.py


Index: proteus/__init__.py
===================================================================

--- a/proteus/__init__.py
+++ b/proteus/__init__.py
@@ -20,6 +20,7 @@
 from types import NoneType

 import proteus.config
+from .pyson import PYSONDecoder

 _MODELS = threading.local()

@@ -211,8 +212,8 @@
         relation = Model.get(self.definition['relation'], instance._config)
         value = super(One2ManyDescriptor, self).__get__(instance, owner)
         if not isinstance(value, ModelList):
-            value = ModelList((relation(id)
-                for id in value or []), instance, self.name,
+            value = ModelList(self.definition, (relation(id) for id
+                    in value or []), instance, self.name,
                 self.definition.get('relation_field'))
             instance._values[self.name] = value
         return value
@@ -398,8 +399,9 @@
 class ModelList(list):
     'List for Model'

-    def __init__(self, sequence=None, parent=None, parent_field_name='',
-            parent_name=''):
+    def __init__(self, definition, sequence=None, parent=None,
+            parent_field_name='', parent_name=''):
+        self.model_name = definition['relation']
         if sequence is None:
             sequence = []
         self.parent = parent
@@ -407,6 +409,9 @@
             assert parent_field_name
         self.parent_field_name = parent_field_name
         self.parent_name = parent_name
+        self.domain = definition.get('domain', [])
+        self.context = definition.get('context')
+        self.add_remove = definition.get('add_remove')
         self.record_removed = set()
         self.record_deleted = set()
         result = super(ModelList, self).__init__(sequence)
@@ -497,6 +502,30 @@
         raise NotImplementedError
     sort.__doc__ = list.sort.__doc__

+    def new(self):
+        Relation = Model.get(self.model_name)
+        if self.context:
+            decoder = PYSONDecoder(_EvalEnvironment(self.parent))
+            ctx = decoder.decode(self.context)
+        else:
+            ctx = {}
+        with Relation._config.set_context(ctx):
+            new_record = Relation()
+        self.append(new_record)
+        return new_record
+
+    def find(self, condition=None, offset=0, limit=None, order=None):
+        Relation = Model.get(self.model_name)
+        decoder = PYSONDecoder(_EvalEnvironment(self.parent))
+        ctx = decoder.decode(self.context) if self.context else {}
+        if condition is None:
+            condition = []
+        add_remove_domain = (decoder.decode(self.add_remove)
+            if self.add_remove else [])
+        new_domain = self.domain + add_remove_domain + condition
+        with Relation._config.set_context(ctx):
+            return Relation.find(new_domain, offset, limit, order)
+

 class Model(object):
     'Model class for Tryton records'
@@ -684,8 +713,8 @@
                     record = relation()
                     record._default_set(vals)
                     records.append(record)
-                self._values[field] = ModelList(records, self, field,
-                        definition.get('relation_field', ''))
+                self._values[field] = ModelList(definition, records, self,
+                    field, definition.get('relation_field', ''))
             else:
                 self._values[field] = value


Index: proteus/config.py
===================================================================

--- a/proteus/config.py
+++ b/proteus/config.py
@@ -11,6 +11,8 @@
 import datetime
 import time

+from .context import ContextManager
+

 def dump_decimal(self, value, write):
     value = {'__class__': 'Decimal',
@@ -83,6 +85,16 @@
     def context(self):
         return self._context.copy()

+    def set_context(self, context=None, **kwargs):
+        ctx_manager = ContextManager(self, self.context)
+
+        if context is None:
+            context = None
+        self._context = self.context.copy()
+        self._context.update(context)
+        self._context.update(kwargs)
+        return ctx_manager
+
     def get_proxy(self, name):
         raise NotImplementedError


Index: proteus/context.py
===================================================================
new file mode 100644

--- /dev/null
+++ b/proteus/context.py
@@ -0,0 +1,15 @@
+# This file is part of Tryton.  The COPYRIGHT file at the top level of this
+# repository contains the full copyright notices and license terms.
+
+
+class ContextManager(dict):
+
+    def __init__(self, config_obj, previous_context):
+        self.config = config_obj
+        self.context = previous_context
+
+    def __enter__(self):
+        return self
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.config._context = self.context

Index: proteus/tests/test_context.py
===================================================================
new file mode 100644

--- /dev/null
+++ b/proteus/tests/test_context.py
@@ -0,0 +1,21 @@
+# This file is part of Tryton.  The COPYRIGHT file at the top level of this
+# repository contains the full copyright notices and license terms.
+
+from unittest import TestCase
+from proteus import config
+
+
+class TestContext(TestCase):
+
+    def setUp(self):
+        self.config = config.set_trytond(database_type='sqlite')
+
+    def test_config(self):
+        prev_ctx = self.config._context
+
+        with self.config.set_context({'a': 1}):
+            self.assertEqual(self.config.context['a'], 1)
+            for key, value in prev_ctx.items():
+                self.assertEqual(self.config.context[key], value)
+
+        self.assertEqual(self.config.context, prev_ctx)



--
[email protected] mailing list

Reply via email to