{"id":21297553,"url":"https://github.com/gfyoung/py-validate","last_synced_at":"2025-07-11T18:32:34.515Z","repository":{"id":57458276,"uuid":"91914405","full_name":"gfyoung/py-validate","owner":"gfyoung","description":"Function Wrappers to Validate Arguments and Return Types","archived":false,"fork":false,"pushed_at":"2017-09-05T04:49:47.000Z","size":105,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T07:11:08.360Z","etag":null,"topics":["function-wrapper","functions","python","type-checking","validator"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gfyoung.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-05-20T20:23:42.000Z","updated_at":"2021-09-19T04:41:28.000Z","dependencies_parsed_at":"2022-09-09T22:51:32.473Z","dependency_job_id":null,"html_url":"https://github.com/gfyoung/py-validate","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"purl":"pkg:github/gfyoung/py-validate","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfyoung%2Fpy-validate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfyoung%2Fpy-validate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfyoung%2Fpy-validate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfyoung%2Fpy-validate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gfyoung","download_url":"https://codeload.github.com/gfyoung/py-validate/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gfyoung%2Fpy-validate/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":264870627,"owners_count":23676280,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["function-wrapper","functions","python","type-checking","validator"],"created_at":"2024-11-21T14:38:41.665Z","updated_at":"2025-07-11T18:32:34.106Z","avatar_url":"https://github.com/gfyoung.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/gfyoung/py-validate.svg?branch=master)](https://travis-ci.org/gfyoung/py-validate)\n\n# py-validate\nFunction wrappers for verifying Python arguments and return values.\n\n# Installation\nYou can just install via `pip`:\n~~~\npip install py_validate\n~~~\n\nAlternatively, you can download the source code and in the top directory of the code, run either:\n~~~\npip install .\n~~~\nor\n~~~\npython setup.py install\n~~~\n\n# Examples\nFunction wrappers nicely abstract away checks on inputs and outputs that can sometimes clutter implementation of the function itself, as illustrated below in this example:\n\n~~~python\ndef sum_int_float(a, b):\n    if not isinstance(a, int):\n        raise TypeError(\"Expected an integer for `a`\")\n\n    if not isinstance(b, float):\n        raise TypeError(\"Expected a float for `b`\")\n\n    return a + b\n\n\u003e\u003e\u003e sum_int_float(1.5, 1.5)\n...\nTypeError: Expected an integer for `a`\n\n\u003e\u003e\u003e sum_int_float(1, 1)\n...\nTypeError: Expected a float for `b`\n~~~\n\nHere we just want to sum an integer and a float. However, we have to include these checks for `type` to ensure that our first input is an `int` and that our second input is a `float`. These checks can obfuscate the core functionality, which is just the summation. This example isn't too bad, but now imagine if we had many such functions in our codebase. Our code would be littered with validation checks! Here is the same summation function implemented with our decorators:\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_inputs(a=int, b=float)\ndef sum_int_float(a, b):\n    return a + b\n\n\u003e\u003e\u003e sum_int_float(1.5, 1.5)\n...\nTypeError: Incorrect type for variable 'a': expected int but got float instead\n\n\u003e\u003e\u003e sum_int_float(1, 1)\n...\nTypeError: Incorrect type for variable 'b': expected float but got int instead\n~~~\n\nHere, the checks are nicely abstracted away, and we can see exactly what the function is doing assuming valid inputs.\n\nIn addition to validating inputs, we also can validate outputs. This can be useful for checking that functions behave as they are supposed to behave:\n\n~~~python\nimport py_validate as pv\n\ndef sum_helper(a, b):\n    return a + b\n\n@pv.validate_outputs(2, int)\ndef sum_int_float(a, b):\n    if a == 0:\n        # This function doesn't return two outputs\n        # as we expect the outer function to.\n        return sum_helper(a, b)\n    return a, a + b\n\n\u003e\u003e\u003e sum_int_float(0, 1)\n...\nValueError: Expected 2 items returned but got 1\n\n\u003e\u003e\u003e sum_int_float(1.5, 1)\n...\nTypeError: Incorrect type for variable 'Output 0': expected int but got float instead\n~~~\n\nThese function decorators can also be stacked, which is useful if there are a lot of inputs or outputs to check, as follows:\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_inputs(a=int)\n@pv.validate_inputs(b=float)\n@pv.validate_outputs(None, int)\ndef sum_int_float(a, b):\n    return a + b\n\n\n\u003e\u003e\u003e sum_int_float(1.5, 1.5)\n...\nTypeError: Incorrect type for variable 'a': expected int but got float instead\n\n\u003e\u003e\u003e sum_int_float(1, 1)\n...\nTypeError: Incorrect type for variable 'b': expected float but got int instead\n\n\u003e\u003e\u003e sum_int_float(1, 1.5)\n...\nTypeError: Incorrect type for variable 'Output 0': expected int but got float instead\n~~~\n\nThis library also comes with some shortcuts that can make it easier to write verification checks.\nThe following examples illustrate how to use each of the available shortcuts, which are:\n\n* **number**: the value must be a number\n* **integer**: the value must be an integer\n* **even**: the value must be an even integer\n* **odd**: the value must be an odd integer\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_inputs(a=\"number\")  # The input must be a number.\ndef increment_input(a):\n    return a + 1\n\n\u003e\u003e\u003e increment_input(\"foo\")\n...\nTypeError: Expected a number but got: 'str'\n\n\u003e\u003e\u003e increment_input(1.5)\n2.5\n\n@pv.validate_inputs(a=\"integer\")  # The input must be an integer by type.\ndef increment_input_two(a):\n    return a + 1\n\n\u003e\u003e\u003e increment_input_two(\"foo\")\n...\nTypeError: Expected an integer but got: 'str'\n\n\u003e\u003e\u003e increment_input_two(1.5)\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_two(1.0)  # The type is float.\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_two(2)\n3\n\n@pv.validate_inputs(a=\"even\")  # The input must be an even integer.\ndef increment_input_three(a):\n    return a + 1\n\n\u003e\u003e\u003e increment_input_three(\"foo\")\n...\nTypeError: Expected an integer but got: 'str'\n\n\u003e\u003e\u003e increment_input_three(1.5)\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_three(1.0)  # The type is float.\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_three(1)\n...\nValueError: Expected an even integer\n\n\u003e\u003e\u003e increment_input_three(2)\n3\n\n@pv.validate_inputs(a=\"odd\")  # The input must be an odd integer.\ndef increment_input_four(a):\n    return a + 1\n\n\u003e\u003e\u003e increment_input_four(\"foo\")\n...\nTypeError: Expected an integer but got: 'str'\n\n\u003e\u003e\u003e increment_input_four(1.5)\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_four(1.0)  # The type is float.\n...\nTypeError: Expected an integer but got: 'float'\n\n\u003e\u003e\u003e increment_input_four(2)\n...\nValueError: Expected an odd integer\n\n\u003e\u003e\u003e increment_input_four(1)\n2\n~~~\n\nThe shortcuts can also be negated if specifying the \"not\" condition is too complicated:\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_inputs(a=\"~number\")  # The input must not be a number.\ndef identity(a):\n    return a\n\n\u003e\u003e\u003e identity(1)\n...\npy_validate.backend.shortcuts.NegateFailure: Failed validation for input 'a':\nValidation for 'number' passed when it shouldn't have\n\n\u003e\u003e\u003e identity(\"foo\")\n'foo'\n~~~\n\nWhen specifying validators for input variables, do note that once validators for a variable\nhave been set, they cannot be changed. Doing so will cause an error to be raised:\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_inputs(a=int)\n@pv.validate_inputs(a=float)\ndef increment_input_five(a):\n    return a + 1\n...\nValueError : Validator(s) for input 'a' already set.\n~~~\n\nFinally, if your function happens to return multiple output variables, the default is to\nevaluate each element of the returned tuple. If you want the actual tuple object to be\nvalidated, pass in `-1` for the expected output length:\n\n~~~python\nimport py_validate as pv\n\n@pv.validate_outputs(-1, tuple)\ndef return_tuple_if_one(a):\n    if a == 1:\n        return tuple()\n    else:\n        return \"foo\"\n\n\u003e\u003e\u003e return_tuple_if_one(0)\n...\nTypeError: Incorrect type for variable 'Output 0': expected tuple but got str instead\n~~~\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgfyoung%2Fpy-validate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgfyoung%2Fpy-validate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgfyoung%2Fpy-validate/lists"}