From 2f233c6170c4a9777d030dc4fda2ee579af65f2d Mon Sep 17 00:00:00 2001 From: Wes Okes Date: Fri, 6 Apr 2018 16:04:47 -0400 Subject: [PATCH 1/5] handle type error for py3 --- .gitignore | 2 ++ docs/release_notes.rst | 4 ++++ kmatch/kmatch.py | 12 ++++++++++-- kmatch/tests/kmatch_tests.py | 24 ++++++++++++++++++++++++ kmatch/version.py | 2 +- 5 files changed, 41 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index f1f5093..4075854 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ docs/_build/ # IPython Notebook .ipynb_checkpoints/ + +.eggs diff --git a/docs/release_notes.rst b/docs/release_notes.rst index bc59623..322c2e2 100644 --- a/docs/release_notes.rst +++ b/docs/release_notes.rst @@ -1,6 +1,10 @@ Release Notes ============= +v0.2.0 +------ +* Handle data type mismatch comparisons and return False + v0.1.7 ------ * Python 3.6 support diff --git a/kmatch/kmatch.py b/kmatch/kmatch.py index 5689687..7a6d43f 100644 --- a/kmatch/kmatch.py +++ b/kmatch/kmatch.py @@ -28,7 +28,7 @@ class K(object): '!?': lambda key, value: key not in value, } - def __init__(self, p, suppress_key_errors=False): + def __init__(self, p, suppress_key_errors=False, suppress_exceptions=False): """ Sets the pattern, performs validation on the pattern, and compiles its regexs if it has any. @@ -36,11 +36,14 @@ def __init__(self, p, suppress_key_errors=False): :type p: list :param suppress_key_errors: Suppress KeyError exceptions on filters and return False instead :type suppress_key_errors: bool + :param suppress_exceptions: Suppress all exceptions on filters and return False instead + :type suppress_exceptions: bool :raises: :class:`ValueError ` on an invalid pattern or regex """ self._raw_pattern = deepcopy(p) self._compiled_pattern = deepcopy(p) self._suppress_key_errors = suppress_key_errors + self._suppress_exceptions = suppress_exceptions # Validate the pattern is in the appropriate format self._validate(self._compiled_pattern) @@ -112,7 +115,12 @@ def _match(self, p, value): else: return self._match_key_filter(p, value) except KeyError: - if self._suppress_key_errors: + if self._suppress_key_errors or self._suppress_exceptions: + return False + else: + raise + except TypeError: + if self._suppress_exceptions: return False else: raise diff --git a/kmatch/tests/kmatch_tests.py b/kmatch/tests/kmatch_tests.py index 38433c7..4af6368 100644 --- a/kmatch/tests/kmatch_tests.py +++ b/kmatch/tests/kmatch_tests.py @@ -1,3 +1,4 @@ +from sys import version from unittest import TestCase from mock import patch @@ -91,6 +92,9 @@ def test_basic_nonexistence_false(self): def test_basic_suppress_key_errors(self): self.assertFalse(K(['==', 'k', 3], suppress_key_errors=True).match({})) + def test_basic_suppress_exceptions(self): + self.assertFalse(K(['==', 'k', 3], suppress_exceptions=True).match({})) + def test_not_field_true(self): self.assertTrue(K([ '!', ['>=', 'f', 3], @@ -104,6 +108,26 @@ def test_compound_suppress_key_errors_gte_true(self): ] ], suppress_key_errors=True).match({'f': 6})) + def test_compound_suppress_exceptions_gte_true(self): + self.assertTrue(K([ + '|', [ + ['==', 'f1', 5], + ['>', 'f', 5], + ] + ], suppress_exceptions=True).match({'f': 6})) + + def test_type_exception(self): + """ + Handles different data type comparisons in py3 + """ + if version[0] == 3: + with self.assertRaises(TypeError): + self.assertFalse(K(['>=', 'k', 3]).match({'k': None})) + with self.assertRaises(TypeError): + self.assertFalse(K(['>=', 'k', 3]).match({'k': ''})) + self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': None})) + self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': ''})) + def test_compound_existence_gte_true(self): self.assertTrue(K([ '&', [ diff --git a/kmatch/version.py b/kmatch/version.py index 124e462..7fd229a 100644 --- a/kmatch/version.py +++ b/kmatch/version.py @@ -1 +1 @@ -__version__ = '0.1.7' +__version__ = '0.2.0' From 47557d0f26ed7a2185f84a2be41f000eb49afdb9 Mon Sep 17 00:00:00 2001 From: Wes Okes Date: Fri, 6 Apr 2018 16:14:17 -0400 Subject: [PATCH 2/5] coverage report --- .travis.yml | 5 +++-- setup.cfg | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5219d7d..71a46bf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,11 @@ python: - '3.5' - '3.6' install: - - pip install coveralls flake8 nose>=1.3.0 + - pip install coveralls coverage flake8 nose>=1.3.0 - python setup.py install script: - flake8 . - - python setup.py nosetests + - coverage run setup.py test + - coverage report --fail-under=100 after_success: coveralls diff --git a/setup.cfg b/setup.cfg index 6bbba05..55c4463 100644 --- a/setup.cfg +++ b/setup.cfg @@ -7,4 +7,4 @@ cover-package=kmatch max-line-length = 120 exclude = docs,env,*.egg max-complexity = 10 -ignore = E402 +ignore = E402,E722 From 322ba12bc381f0ab7321edf7e370610a1fb890c7 Mon Sep 17 00:00:00 2001 From: Wes Okes Date: Fri, 6 Apr 2018 16:37:28 -0400 Subject: [PATCH 3/5] fix version testing --- .travis.yml | 5 ++--- kmatch/tests/kmatch_tests.py | 17 ++++++++++++++--- setup.py | 1 + 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 71a46bf..5219d7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,11 +6,10 @@ python: - '3.5' - '3.6' install: - - pip install coveralls coverage flake8 nose>=1.3.0 + - pip install coveralls flake8 nose>=1.3.0 - python setup.py install script: - flake8 . - - coverage run setup.py test - - coverage report --fail-under=100 + - python setup.py nosetests after_success: coveralls diff --git a/kmatch/tests/kmatch_tests.py b/kmatch/tests/kmatch_tests.py index 4af6368..113dc01 100644 --- a/kmatch/tests/kmatch_tests.py +++ b/kmatch/tests/kmatch_tests.py @@ -120,11 +120,22 @@ def test_type_exception(self): """ Handles different data type comparisons in py3 """ - if version[0] == 3: + if version[0] == '2': # pragma: no cover + with patch('kmatch.K._match_value_filter') as mock_match_value_filter: + mock_match_value_filter.side_effect = TypeError + + with self.assertRaises(TypeError): + K(['>=', 'k', 3]).match({'k': None}) + with self.assertRaises(TypeError): + K(['>=', 'k', 3]).match({'k': ''}) + self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': None})) + self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': ''})) + + if version[0] == '3': # pragma: no cover with self.assertRaises(TypeError): - self.assertFalse(K(['>=', 'k', 3]).match({'k': None})) + K(['>=', 'k', 3]).match({'k': None}) with self.assertRaises(TypeError): - self.assertFalse(K(['>=', 'k', 3]).match({'k': ''})) + K(['>=', 'k', 3]).match({'k': ''}) self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': None})) self.assertFalse(K(['>=', 'k', 3], suppress_exceptions=True).match({'k': ''})) diff --git a/setup.py b/setup.py index b3178ff..228bfae 100644 --- a/setup.py +++ b/setup.py @@ -32,6 +32,7 @@ def get_version(): 'Programming Language :: Python :: 3.3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', 'Intended Audience :: Developers', 'License :: OSI Approved :: MIT License', 'Operating System :: OS Independent', From 183d5493bd1f64ecebceac5591b51d4184c74910 Mon Sep 17 00:00:00 2001 From: Wes Okes Date: Fri, 6 Apr 2018 16:45:07 -0400 Subject: [PATCH 4/5] all exceptions --- kmatch/kmatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmatch/kmatch.py b/kmatch/kmatch.py index 7a6d43f..8ca78fe 100644 --- a/kmatch/kmatch.py +++ b/kmatch/kmatch.py @@ -119,7 +119,7 @@ def _match(self, p, value): return False else: raise - except TypeError: + except Exception: if self._suppress_exceptions: return False else: From 8df8019047f242ac16a35aaf61cf709e2e61a258 Mon Sep 17 00:00:00 2001 From: Wes Okes Date: Fri, 6 Apr 2018 16:52:03 -0400 Subject: [PATCH 5/5] revert to type error --- kmatch/kmatch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kmatch/kmatch.py b/kmatch/kmatch.py index 8ca78fe..7a6d43f 100644 --- a/kmatch/kmatch.py +++ b/kmatch/kmatch.py @@ -119,7 +119,7 @@ def _match(self, p, value): return False else: raise - except Exception: + except TypeError: if self._suppress_exceptions: return False else: