Skip to content

Commit

Permalink
Add validator for all required parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
tomgross committed Feb 19, 2020
1 parent 1b0d9de commit 15c53d3
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 18 deletions.
4 changes: 2 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ Changelog
1.0a7 (unreleased)
------------------

- Nothing changed yet.

- Consistently use MIT licences
[tomgross]

1.0a6 (2019-01-18)
------------------
Expand Down
27 changes: 22 additions & 5 deletions src/pcloud/tests/test_validate.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
import pytest
from pcloud.validate import RequiredParameterCheck
from pcloud.validate import MODE_AND


@RequiredParameterCheck(('path', 'folderid'))
def foo(self, path=None, folderid=None, bar=None):
return (path, folderid, bar)
def foo(path=None, folderid=None, bar=None):
return path, folderid, bar


@RequiredParameterCheck(('path', 'folderid'), mode=MODE_AND)
def foo_all(path=None, folderid=None, bar=None):
return path, folderid, bar


class TestPathIdentifier(object):

def test_validiate_path(self):
assert foo(None, path='/', bar='x') == ('/', None, 'x')
assert foo(path='/', bar='x') == ('/', None, 'x')

def test_validiate_folderid(self):
assert foo(None, folderid='0') == (None, '0', None)
assert foo(folderid='0') == (None, '0', None)

def test_validiate_nothing(self):
with pytest.raises(ValueError):
foo(None, bar='something')
foo(bar='something')

def test_validiate_all_path(self):
with pytest.raises(ValueError):
foo_all(path='/', bar='x')

def test_validiate_all_folderid(self):
with pytest.raises(ValueError):
foo_all(folderid='0') == (None, '0', None)

def test_validiate_all(self):
foo_all(folderid='0', path='/') == ('/', '0', None)
23 changes: 12 additions & 11 deletions src/pcloud/validate.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
""" Validators and decorators
"""

MODE_OR = 0
MODE_AND = 1


class RequiredParameterCheck(object):
""" A decorator that checks function parameter
""" A decorator that checks if at least on named parameter is present
"""

def __init__(self, required):
self.required = required
def __init__(self, required, mode=MODE_OR):
self.required = sorted(required)
self.mode = mode

def __call__(self, func):
def wrapper(*args, **kwargs):
found_paramater = False
for req in self.required:
if req in kwargs:
found_paramater = True
break
if found_paramater:
found_paramater = sorted([req for req in self.required if req in kwargs])
if self.mode == MODE_OR and found_paramater:
return func(*args, **kwargs)
elif self.mode == MODE_AND and found_paramater == self.required:
return func(*args, **kwargs)
else:
raise ValueError('One required parameter `%s` is missing',
', '.join(self.required))
raise ValueError(f"One required parameter `{ ', '.join(self.required)}` is missing: {found_paramater}")
wrapper.__name__ = func.__name__
wrapper.__dict__.update(func.__dict__)
wrapper.__doc__ = func.__doc__
Expand Down
1 change: 1 addition & 0 deletions test_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ pytest >= 2.8
tox
wheel
flake8
fs

0 comments on commit 15c53d3

Please sign in to comment.