Skip to content

Instantly share code, notes, and snippets.

@MathieuDuponchelle
Last active May 18, 2017 10:10
Show Gist options
  • Save MathieuDuponchelle/1c3b6c43b565e4c4a998a7f44e84fae3 to your computer and use it in GitHub Desktop.
Save MathieuDuponchelle/1c3b6c43b565e4c4a998a7f44e84fae3 to your computer and use it in GitHub Desktop.
from functools import wraps
from schema import Schema
def function_validator(*pos_args, args_schema=None, kwargs_schema=None):
args_schema = args_schema or Schema([])
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
new_args = []
starargs = []
i = 0
for i, arg in enumerate(args):
try:
validator = pos_args[i]
new_args.append(validator.validate(arg))
except IndexError as e:
starargs = list(args[i:])
break
if starargs:
new_args.extend(args_schema.validate(starargs))
args = tuple(new_args)
if kwargs_schema:
kwargs = kwargs_schema.validate(kwargs)
return func(*args, **kwargs)
return wrapper
return decorator
def method_validator(*pos_args, args_schema=None, kwargs_schema=None):
args_schema = args_schema or Schema([])
new_pos_args = [Schema(object)]
for p in pos_args:
new_pos_args.append(p)
return function_validator(*(tuple(new_pos_args)),
args_schema=args_schema,
kwargs_schema=kwargs_schema)
def meson_method_validator(*pos_args, args_schema=None, kwargs_schema=None):
args_schema = args_schema or Schema([])
new_pos_args = [Schema(object), Schema(object)]
for p in pos_args:
new_pos_args.append(p)
return function_validator(*(tuple(new_pos_args)),
args_schema=args_schema,
kwargs_schema=kwargs_schema)
import os
from pytest import raises
from schema import Schema, SchemaError, And, Use, Optional
from schema_validator import meson_method_validator
stringListSchema = Schema([And(str, len)])
class Test:
posArgs = (stringListSchema,
Schema({'language': And(str, len),
Optional(str): object}))
@meson_method_validator(*posArgs)
def func_add_global_arguments(self, node, args, kwargs):
return True
posArgs = (stringListSchema,
Schema({}))
@meson_method_validator(*posArgs)
def func_join_paths(self, node, args, kwargs):
return True
posArgs = (Schema([os.path.exists]),
Schema({Optional('is_system'): bool,
Optional(str): object}))
@meson_method_validator(*posArgs)
def func_include_directories(self, node, args, kwargs):
return True
SE = raises(SchemaError)
def test_suite():
t = Test()
assert t.func_join_paths(None, ['lol', 'hello'], {})
with SE: t.func_join_paths(None, ['lol', ''], {})
with SE: t.func_join_paths(None, ['lol', 'hello', 42], {})
with SE: t.func_join_paths(None, ['lol', 'hello'], {'a': 42})
with SE: t.func_add_global_arguments(None, ['lol', 'hello'], {})
assert t.func_add_global_arguments(None, ['lol', 'hello'], {'language': 'C'})
assert t.func_add_global_arguments(None, ['lol', 'hello'], {'language': 'C', 'a': 42})
with SE: t.func_include_directories(None, ['/bad/path'], {})
assert t.func_include_directories(None, ['/home'], {})
with SE: t.func_include_directories(None, ['/home'], {'is_system': 42})
if __name__=='__main__':
pass
@MathieuDuponchelle
Copy link
Author

Testing is pretty rudimentary, run the test script with:

python3 -m pytest test_schema_validator.py

@bernalrs
Copy link

Are you planning to create a pull request for this item?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment