Package: required
required: Easy multi-field validationRequired is a simple library which allows you to validate dependencies
across multiple fields. The goal is to make writing things like forms, seralizers and functions much easier by providing a declarative way to encode validation logic. It aims to:Have a declarative way to encode validation logicAllow you to maintain validation logic easilyAllow you to reuse your validation logic easilyBe flexible with what you want to validateIf this all sounds good. Read On!InstallationInstall usingpippip install requiredQuickstartYou can use required in a number of ways. The easiest way is to use thevalidatedecorator to validate inputs to function calls.fromrequiredimportvalidate@validatedefcalculate_sum(positive_number,negative_number):"""positive_number -> positive_number > 0negative_number -> negative_number < 0"""returnpositive_number+negative_number# the following will raise a validation exceptioncalculate_sum(1,1)# this will pass validationcalculate_sum(1,-1)# 0If you want to have other information in the docstring, the validation rules can be wrapped inside ofRequires { }as shown below:@validatedefcalculate_sum(positive_number,negative_number):"""Other documentation relating to calculate_sumRequires {positive_number -> positive_number > 0negative_number -> negative_number < 0}You can also put information after the requires rules"""returnpositive_number+negative_numberValidation rules are written in the doc string of the function. They look like:[param] -> [expression_1] [comparator] [expression_2]Whenparamis present, it requiresexpression_1 [comparator] expression_2to evaluate to true.The most simple expressions are just variables passed into the function to validate, however they can be more complex. See cookbook for more examples.The comparator can be one of the standard python comparator operations;==,!=,in,>=<=,>,<.CookbookThe following shows some examples for writing validation rules# Arithmetic on the objects follow normal maths rules.
# you need to put brackets to define expressions
x -> (x + 1) < 1
x -> (x - y) == 1

# A value `x` needs to be in an array
x -> x in arr

# The length of x must be 10
# see section on registering functions
x -> len(x) == 10

# The length of x and y must be the same
x -> len(x) == len(y)

# when x is present y must not be present
# TODO: not implemented in DSL yet
x -> x == <empty>

# x must be equal to the return value of a function
x -> x == func(x)

# Partial dependencies can be also specified

# when x == 1 then y must be 2
x == 1 -> y == 2

# when x == 1 then y must be set
x == 1 -> yRegistering callablesYou can register callables into the validation scope. This is useful when you want to call normal python builtins or custom callables.fromrequiredimportvalidatescoped_validate=validate.register_callables({"len":len,"abs":abs})@scoped_validatedefreturn_first_element(arr):"""arr -> len(arr) >= 1"""returnarr[0]# validation scoped callables can also be nested# len, abs and my_func are available in the second_scoped_validate decoratorsecond_scoped_validate=scoped_validate.register_callables({"my_func":my_func})# or inserted at function level@validate(callable_dict={"new_func":new_func})defother_function(var):"""var -> new_func(var) >= 1"""returnvarContributingIf you want to contribute you are most welcome! This project is distributed under theMITlicence. It is tested usingtoxagainst Python 2.7 and 3.4+