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
