From 03243e21948053f14d8b32a4744cd323a92fd190 Mon Sep 17 00:00:00 2001 From: Moin Date: Tue, 27 Dec 2016 01:24:49 +0530 Subject: [PATCH 1/4] Type checks in comparison operators Related to issue #33 --- maya.py | 55 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 25 deletions(-) diff --git a/maya.py b/maya.py index b630640..683a2e0 100644 --- a/maya.py +++ b/maya.py @@ -23,19 +23,6 @@ from tzlocal import get_localzone _EPOCH_START = (1970, 1, 1) -def validate_type_mayadt(func): - """ - Decorator to validate all the arguments to function - are of type `MayaDT` - """ - def inner(*args, **kwargs): - for arg in args + tuple(kwargs.values()): - if not isinstance(arg, MayaDT): - raise ValueError("Operation allowed only on object of type '{}'".format(MayaDT.__name__)) - return func(*args, **kwargs) - return inner - - class MayaDT(object): """The Maya Datetime object.""" @@ -50,29 +37,47 @@ class MayaDT(object): """Return's the datetime's format""" return format(self.datetime(), *args, **kwargs) - @validate_type_mayadt def __eq__(self, maya_dt): - return self._epoch == maya_dt._epoch + try: + return self._epoch == maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() == {}()'.format( + type(self).__name__, type(maya_dt).__name__)) - @validate_type_mayadt def __ne__(self, maya_dt): - return not self.__eq__(maya_dt) + try: + return self._epoch != maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() != {}()'.format( + type(self).__name__, type(maya_dt).__name__)) - @validate_type_mayadt def __lt__(self, maya_dt): - return self._epoch < maya_dt._epoch + try: + return self._epoch < maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() < {}()'.format( + type(self).__name__, type(maya_dt).__name__)) - @validate_type_mayadt def __le__(self, maya_dt): - return self.__lt__(maya_dt) or self.__eq__(maya_dt) + try: + return self._epoch <= maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() <= {}()'.format( + type(self).__name__, type(maya_dt).__name__)) - @validate_type_mayadt def __gt__(self, maya_dt): - return self._epoch > maya_dt._epoch + try: + return self._epoch > maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() > {}()'.format( + type(self).__name__, type(maya_dt).__name__)) - @validate_type_mayadt def __ge__(self, maya_dt): - return self.__gt__(maya_dt) or self.__eq__(maya_dt) + try: + return self._epoch >= maya_dt._epoch + except AttributeError: + raise TypeError('unorderable types: {}() >= {}()'.format( + type(self).__name__, type(maya_dt).__name__)) # Timezone Crap From ba9e35525c1d5f56ec7591f49a3c59d73695426c Mon Sep 17 00:00:00 2001 From: Moin Date: Thu, 29 Dec 2016 14:36:05 +0530 Subject: [PATCH 2/4] modified maya_dt obj check decorator --- maya.py | 58 ++++++++++++++++++++++++++++----------------------------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/maya.py b/maya.py index 683a2e0..7371705 100644 --- a/maya.py +++ b/maya.py @@ -37,47 +37,45 @@ class MayaDT(object): """Return's the datetime's format""" return format(self.datetime(), *args, **kwargs) + def _validate_type_mayadt(operator): + """ + Decorator to validate all the arguments to function + are of type `MayaDT` + """ + def inner(function): + def wrapper(self, *args, **kwargs): + for arg in args + tuple(kwargs.values()): + if not isinstance(arg, self.__class__): + raise TypeError('unorderable types: {}() {} {}()'.format( + type(self).__name__, operator, type(arg).__name__)) + return function(self, *args, **kwargs) + return wrapper + + return inner + + @_validate_type_mayadt('==') def __eq__(self, maya_dt): - try: - return self._epoch == maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() == {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch == maya_dt._epoch + @_validate_type_mayadt('!=') def __ne__(self, maya_dt): - try: - return self._epoch != maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() != {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch != maya_dt._epoch + @_validate_type_mayadt('<') def __lt__(self, maya_dt): - try: - return self._epoch < maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() < {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch < maya_dt._epoch + @_validate_type_mayadt('<=') def __le__(self, maya_dt): - try: - return self._epoch <= maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() <= {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch <= maya_dt._epoch + @_validate_type_mayadt('>') def __gt__(self, maya_dt): - try: - return self._epoch > maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() > {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch > maya_dt._epoch + @_validate_type_mayadt('>=') def __ge__(self, maya_dt): - try: - return self._epoch >= maya_dt._epoch - except AttributeError: - raise TypeError('unorderable types: {}() >= {}()'.format( - type(self).__name__, type(maya_dt).__name__)) + return self._epoch >= maya_dt._epoch # Timezone Crap From 21743de7900723a0884cbbc8f77c889a5a1e18ba Mon Sep 17 00:00:00 2001 From: Moin Date: Thu, 29 Dec 2016 14:42:59 +0530 Subject: [PATCH 3/4] test for AttributeError in MayaDT comparison operators --- test_maya.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test_maya.py b/test_maya.py index ad1d8b7..99b2389 100644 --- a/test_maya.py +++ b/test_maya.py @@ -138,3 +138,17 @@ def test_comparison_operations(): assert (now >= now_copy) is True assert (now >= tomorrow) is False + + # Check Exceptions + with pytest.raises(TypeError): + now == 1 + with pytest.raises(TypeError): + now != 1 + with pytest.raises(TypeError): + now < 1 + with pytest.raises(TypeError): + now <= 1 + with pytest.raises(TypeError): + now > 1 + with pytest.raises(TypeError): + now >= 1 From c9888a48e5e0cba5e2b38c121270d3ddfbc19f49 Mon Sep 17 00:00:00 2001 From: Moin Date: Thu, 29 Dec 2016 16:23:53 +0530 Subject: [PATCH 4/4] validate_class_type_arguments decorator --- maya.py | 47 ++++++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/maya.py b/maya.py index ce485f0..e7323b0 100644 --- a/maya.py +++ b/maya.py @@ -23,6 +23,26 @@ from tzlocal import get_localzone _EPOCH_START = (1970, 1, 1) +def validate_class_type_arguments(operator): + """ + Decorator to validate all the arguments to function + are of the type of calling class + """ + + def inner(function): + def wrapper(self, *args, **kwargs): + for arg in args + tuple(kwargs.values()): + if not isinstance(arg, self.__class__): + raise TypeError('unorderable types: {}() {} {}()'.format( + type(self).__name__, operator, type(arg).__name__)) + return function(self, *args, **kwargs) + + return wrapper + + return inner + + + class MayaDT(object): """The Maya Datetime object.""" @@ -40,43 +60,28 @@ class MayaDT(object): """Return's the datetime's format""" return format(self.datetime(), *args, **kwargs) - def _validate_type_mayadt(operator): - """ - Decorator to validate all the arguments to function - are of type `MayaDT` - """ - def inner(function): - def wrapper(self, *args, **kwargs): - for arg in args + tuple(kwargs.values()): - if not isinstance(arg, self.__class__): - raise TypeError('unorderable types: {}() {} {}()'.format( - type(self).__name__, operator, type(arg).__name__)) - return function(self, *args, **kwargs) - return wrapper - return inner - - @_validate_type_mayadt('==') + @validate_class_type_arguments('==') def __eq__(self, maya_dt): return self._epoch == maya_dt._epoch - @_validate_type_mayadt('!=') + @validate_class_type_arguments('!=') def __ne__(self, maya_dt): return self._epoch != maya_dt._epoch - @_validate_type_mayadt('<') + @validate_class_type_arguments('<') def __lt__(self, maya_dt): return self._epoch < maya_dt._epoch - @_validate_type_mayadt('<=') + @validate_class_type_arguments('<=') def __le__(self, maya_dt): return self._epoch <= maya_dt._epoch - @_validate_type_mayadt('>') + @validate_class_type_arguments('>') def __gt__(self, maya_dt): return self._epoch > maya_dt._epoch - @_validate_type_mayadt('>=') + @validate_class_type_arguments('>=') def __ge__(self, maya_dt): return self._epoch >= maya_dt._epoch