Validators

Collection of methods to validate specific call arguments.

Goal: Evaluate whether a call like f(1,"s") matches any signature-pattern. A signature pattern might be defined like f(1, str). This should match any call that passes the exact value one for the first argument and any object of type str in the second.

Argument validators

We break the task down to validating a single argument. The signature of such an ArgumentValidator should look like :


source

ArgumentValidator

 ArgumentValidator (*args, **kwargs)

Interface for all argument validators.

The most flexibility can be achieved by constructing an ArgumentValidator that evaluates an arbitrary function:


source

ArgumentFunctionValidator

 ArgumentFunctionValidator (func:pymoq.core.AnyCallable[bool], name:str,
                            position:int, display:str|None=None)

Validate an argument by evaluating an arbitrary function

This could now be used like:

any_int = ArgumentFunctionValidator(lambda v: isinstance(v, int), "firstArgument", 0, display='AnyInt()')
any_int
ArgumentFunctionValidator(argument_name:firstArgument, position=0): AnyInt()
assert any_int.is_valid(1)
assert not any_int.is_valid(1.1)
assert not any_int.is_valid("string")
assert str(any_int)=='ArgumentFunctionValidator(argument_name:firstArgument, position=0): AnyInt()'

In later stages there should be convenience methods around creating such argument validators. E.g. from_type(some_type) for making the above easier.

Ease of use: Construction from arguments


source

argument_validator_from_argument

 argument_validator_from_argument (argument:Any, name:str, position:int,
                                   verbose:bool=False)
ArgumentValidator

Passing a valid ArgumentValidator simply returns it:

assert argument_validator_from_argument(any_int, any_int.name, 0) == any_int
Callable

Passing a callable constructs an ArgumentFunctionValidator:

arg_val = argument_validator_from_argument(lambda v: isinstance(v, int), 'a', 0)
arg_val
ArgumentFunctionValidator(argument_name:a, position=0): callable()
check_type = lambda v: isinstance(v, int)
check_type.display = 'any_int'

arg_val = argument_validator_from_argument(check_type, 'a', 0)
arg_val
ArgumentFunctionValidator(argument_name:a, position=0): any_int
assert isinstance(arg_val, ArgumentValidator)
assert arg_val.is_valid(1)
assert not arg_val.is_valid("1")
Type
arg_val = argument_validator_from_argument(int, name='a', position=0)
arg_val
ArgumentFunctionValidator(argument_name:a, position=0): any_int
assert isinstance(arg_val, ArgumentValidator)
assert arg_val.is_valid(1)
assert not arg_val.is_valid("1")
Non-callable, non-type

Passing a non-callable assumes that the value should be compared against, i.e. it’s a constant:

arg_val = argument_validator_from_argument(123, name='a', position=0)
arg_val
ArgumentFunctionValidator(argument_name:a, position=0): == 123
assert isinstance(arg_val, ArgumentValidator)
assert arg_val.is_valid(123)
assert not arg_val.is_valid(124)
assert str(arg_val)=='ArgumentFunctionValidator(argument_name:a, position=0): == 123'

Special Validators


source

AnyInt

 AnyInt (name:str, position:int, display:str|None=None)

Special validator that provides methods for integers

a = AnyInt('a', 0)

assert a.is_valid(1)
assert not a.is_valid("1")
a
AnyInt()
b = AnyInt('b', 1).greather_than(5)

assert b.is_valid(6)
assert not b.is_valid(5)
b
AnyInt().greather_than(5)
b = AnyInt('b', 1).greather_than_or_equal(5)

assert b.is_valid(5)
assert not b.is_valid(4)
b
AnyInt().greather_than_or_equal(5)
c = AnyInt('c', 2).less_than(5)

assert c.is_valid(4)
assert not c.is_valid(5)
c
AnyInt().less_than(5)
c = AnyInt('c', 2).less_than_or_equal(5)

assert c.is_valid(5)
assert not c.is_valid(6)
c
AnyInt().less_than_or_equal(5)

Build library