From b8e7bd9e16d212a6896413f7b7261d94a176f916 Mon Sep 17 00:00:00 2001 From: Jace Browning Date: Thu, 28 Apr 2016 20:50:59 -0400 Subject: [PATCH 1/3] Run custom __init__ in dictionaries --- tests/test_nested_attributes.py | 20 ++++++++++++++++---- yorm/types/containers.py | 6 ++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/tests/test_nested_attributes.py b/tests/test_nested_attributes.py index a2749c9..61178ec 100644 --- a/tests/test_nested_attributes.py +++ b/tests/test_nested_attributes.py @@ -5,15 +5,22 @@ from unittest.mock import patch import logging +from expecter import expect + import yorm from . import strip @yorm.attr(status=yorm.types.Boolean) +@yorm.attr(checked=yorm.types.Integer) class StatusDictionary(yorm.types.Dictionary): - pass + def __init__(self, status, checked): + self.status = status + self.checked = checked + if self.checked == 42: + raise RuntimeError @yorm.attr(all=yorm.types.Float) @@ -309,17 +316,17 @@ def test_alias_list(self): def test_alias_dict(self): var5_ref = self.sample.var5 self._log_ref('var5', self.sample.var5, var5_ref) - assert {'status': False} == self.sample.var5 + assert {'status': False, 'checked': 0} == self.sample.var5 logging.info("Setting status=True in var5_ref...") var5_ref['status'] = True self._log_ref('var5', self.sample.var5, var5_ref) - assert {'status': True} == self.sample.var5 + assert {'status': True, 'checked': 0} == self.sample.var5 logging.info("Setting status=False in var5_ref...") var5_ref['status'] = False self._log_ref('var5', self.sample.var5, var5_ref) - assert {'status': False} == self.sample.var5 + assert {'status': False, 'checked': 0} == self.sample.var5 def test_alias_dict_in_list(self): top = Top() @@ -340,3 +347,8 @@ def test_alias_list_in_dict(self): ref2 = top.nested_dict.nested_list_2 assert id(ref1) == id(top.nested_dict) assert id(ref2) == id(top.nested_dict.nested_list_2) + + def test_custom_init_is_invoked(self): + self.sample.__mapper__.text = "var5:\n checked: 42" + with expect.raises(RuntimeError): + print(self.sample.var5) diff --git a/yorm/types/containers.py b/yorm/types/containers.py index 32b2716..c7b302c 100644 --- a/yorm/types/containers.py +++ b/yorm/types/containers.py @@ -79,6 +79,12 @@ def update_value(self, data, *, auto_track=True): msg = "Default value for missing nested object attribute: %s = %r" log.info(msg, name, value[name]) + # Execute custom __init__ validations + try: + cls(**value) + except TypeError as exception: + log.warning(exception) + # Apply the new value self.clear() self.update(value) From f5e5b4fed92376b443e486daa7ec187b346b0543 Mon Sep 17 00:00:00 2001 From: Jace Browning Date: Thu, 28 Apr 2016 20:51:12 -0400 Subject: [PATCH 2/3] Bump version to 0.8.1 --- CHANGES.md | 4 ++++ yorm/__init__.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index cdd9706..c0f7910 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,9 @@ # Revision History +## 0.8.1 (2016/04/28) + +- Now invoking `__init__` in `Dictionary` converters to run custom validations. + ## 0.8 (2016/04/14) - Replaced all utility functions with ORM-like tools. diff --git a/yorm/__init__.py b/yorm/__init__.py index 3b91a2b..089d4d0 100644 --- a/yorm/__init__.py +++ b/yorm/__init__.py @@ -3,7 +3,7 @@ import sys __project__ = 'YORM' -__version__ = '0.8' +__version__ = '0.8.1' VERSION = __project__ + '-' + __version__ From 8c87875bbadb80b1dea47907343196cc0b5d7e44 Mon Sep 17 00:00:00 2001 From: Jace Browning Date: Thu, 28 Apr 2016 21:07:07 -0400 Subject: [PATCH 3/3] Add context to the Dictionary __init__ warning --- yorm/__init__.py | 2 +- yorm/types/containers.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/yorm/__init__.py b/yorm/__init__.py index 089d4d0..c15e6bd 100644 --- a/yorm/__init__.py +++ b/yorm/__init__.py @@ -3,7 +3,7 @@ import sys __project__ = 'YORM' -__version__ = '0.8.1' +__version__ = '0.8.1.post1' VERSION = __project__ + '-' + __version__ diff --git a/yorm/types/containers.py b/yorm/types/containers.py index c7b302c..51b09b9 100644 --- a/yorm/types/containers.py +++ b/yorm/types/containers.py @@ -83,7 +83,7 @@ def update_value(self, data, *, auto_track=True): try: cls(**value) except TypeError as exception: - log.warning(exception) + log.warning("%s: %s", cls.__name__, exception) # Apply the new value self.clear()