Skip to main content

Generic validation decorators.

Project description

Generic Validation For Python

Python docs

Checking the input arguments of a function is a common task. It allows the software designer to stop the flow of execution if an error occured and to display information detailing the error.

Python provides decorators that can be used to add extra functionality to a function. The package gvalidate provides the function validate that can be used to easily create argument validating decorators while avoiding most of the required boilerplate.

Installation

To install the package gvalidate use the command:

$ pip install gvalidate

Usage

This section demonstrates how to use the function validate to define validation decorators.

1. Generic Validation Decorators

The example below shows how to define a decorator that will validate the arguments of the decorated function and raise an exception of type ValueError if any argument does not pass validation.

The most important ingredient is the function provided as validator. This function must accept one argument (the one being validated) and return a boolean. If it returns False validation fails. The function validate is generic in the sense that we can pass any function with the required signature as a validator.

In the example shown below all arguments of the function box_dimensions are validated using a lambda function.

from gvalidate.generic_validators import validate

@validate(validator = lambda x: x > 0,
          message='Dimensions must be positive.' # Optional, default: ''
          error_type=ValueError,                 # Optional, default: ValueError
          enable_warnings=True,                  # Optional, default: True
          )
def box_dimensions(length, height, width):
  pass

To validate only certain function arguments these must be passed as a tuple via the parameter argument_names. In the example below only the arguments length and height are validated.

from gvalidate.generic_validators import validate

@validate(validator = lambda x: x > 0,
          argument_names = ('length', 'height'),
          message='Dimensions must be positive.' # Optional, default: ''
          error_type=ValueError,                 # Optional, default: ValueError
          enable_warnings=True,                  # Optional, default: True
          )
def box_dimensions_2(length, height, width):
  pass

Note: To validate a single argument one a string containing the argument name may specified via the parameter argument_names.

Calling the function box_dimensions with negative arguments causes an exception to be raised:

box_dimensions(-1, 10, 20)
# ... stack trace will be printed here
ValueError: ('Invalid argument in function box_dimensions: length = -10.'
             'Dimensions must be positive.')

The argument message passed to the decorator is appended to the message attached to the exception. In the example above message was: 'Dimensions must be positive'.

2. Concrete Validation Decorators

In the example above, we defined a validating decorator on the spot using the generic method validate. To reuse a validating decorator one may define a separate function.

In the example below the decorator validate_callable checks if the specified arguments are callable.

def validate_callable(argument_names: tuple = (), enable_warnings=True):
    '''
    Raises an exception if any argument in `argument_names` is not callable.
    '''
    return validate(
        validator=lambda input: callable(input),
        argument_names = (),
        message='Must be callable.',
        enable_warnings=enable_warnings,
        )

# Using the decorator defined above.
@validate_callable('callback')
def function_with_a_callback(id: int, callback: callable):
    pass

Ready made validation decorators can be found in the modules:

  • function_validators
  • numerical_validators
  • string_validators

3. Disabling Warnings

Any invalid argument name listed in the tuple argument_names will be silently ignored if enable_warnings is explicitly set to False. Consider the function below:

from gvalidate.generic_validators import validate

@validate(argument_names = ('aeg',),
             validator = lambda x: x > 0,
             message='Age must be positive.',
             enable_warnings=False
             )
def person_data(age, name):
  pass

Calling the function with the arguments: person_data(age = -10, name = 'Anna') will pass validation since the argument name aeg specified in the decorator does not exist.

Nested Validators

Several decorators performing validation may be applied to the same function. In that case, validation starts with the top-most decorator. Stacking decorators allows fine grained validation.

In the example below, we check that length is positive and callback is callable:

@gv.validate_positive('length')
@gv.validate_callable('callback')
def g(length, callback):
    '''
    Used to test nested validation decorators.
    '''
    pass

Note: Stacked decorators are in fact nested decorators. To allow access to the signature of the decorated function from within nested decorators functools.wraps was used. For more details check out the implementation of validate.

Testing

To run the tests clone the project source code available at gvalidate using the command:

$ git clone https://github.com/simphotonics/gvalidate.git

The command above will create a directory called gvalidate. It is recommended to create a separate environment before proceeding.

Then navigate to the directory gvalidate and use the commands:

$ make init
$ make test

The first command will install pytest and the local package gvalidate. The second command will run the unit tests located in the directory tests.

Contributing

Contributions are welcome. To add validators that are useful to you or other users please create a pull request or request to be added as a collaborator.

The following steps should be considered when creating a pull request:

  1. Add validators to existing modules for example string_validators or alternatively create a new module.

  2. Document the added functions. Add a doc entry to the top of the module. Add a doc entry to __init__.py if a new module was added. Consider adding documentation to README.md.

  3. Add tests to unit test the added functions.

Features and bugs

Please file feature requests and bugs at the issue tracker.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gvalidate-0.0.1.tar.gz (9.8 kB view details)

Uploaded Source

Built Distribution

gvalidate-0.0.1-py3-none-any.whl (8.7 kB view details)

Uploaded Python 3

File details

Details for the file gvalidate-0.0.1.tar.gz.

File metadata

  • Download URL: gvalidate-0.0.1.tar.gz
  • Upload date:
  • Size: 9.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.0 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for gvalidate-0.0.1.tar.gz
Algorithm Hash digest
SHA256 bf13306627952c2d99dec67a35fcf247fdbd3180d3d75dd76e9f2fb17be849cd
MD5 c8dc9d054bc4ca3abae9e0b81d193bba
BLAKE2b-256 7ef0c2ba9b87a94af41950bc1a86e2a2d209295658535d7a965578fa4dc6ea37

See more details on using hashes here.

File details

Details for the file gvalidate-0.0.1-py3-none-any.whl.

File metadata

  • Download URL: gvalidate-0.0.1-py3-none-any.whl
  • Upload date:
  • Size: 8.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.7.0 importlib_metadata/4.8.2 pkginfo/1.8.2 requests/2.26.0 requests-toolbelt/0.9.1 tqdm/4.62.3 CPython/3.8.10

File hashes

Hashes for gvalidate-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 1ddfcfae93fd819b3c9f8e3ac1d09b908891de47fef3cf4ef606947369b93a29
MD5 0caca2e534986e1710a9b46a4943d3e0
BLAKE2b-256 5df019c0432bc3b11efa5c515bf6f6756bc5aba8945936d50d80a66aae55ff65

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page