Python library for automated and manual runtime data type validation.
Project description
Validify
Python library for automated and manual runtime data type validation. It focuses on utilizing type hints and handling subscribed generics (e.g., list[str]). Use it manually with isvalid or add decorators to methods, functions, and classes for automatic validation.
While Python natively supports basic type validation, it does not manage complex types like list[dict[str, tuple[str, str, bool]]]. Validify simplifies this by allowing easy integration of type validation through a single decorator. Add it to your method or class, and let Validify ensure your type hints are enforced at runtime.
Contents
1 Features
2 Installation
3 Supported Data Types
4 Usage
4.1 Manual validation
4.2 Decorator for Functions
4.3 Decorator for Classes
4.4 Notes
5 Developers Guide
5.1 Contributing
5.2 Architecture
5.3 Known Issues
6 License & Contact
1 Features
- Uniform way to describe and manipulate both base and generic data types via
Descriptorclass. - Manual validation of data via
isvalidfunction. - Function signature inspection and input validation via
func.validatedecorator. - Class-level attribute validation based on type annotations via
cls.validatedecorator. - Class methods signature inspection and input validation via
cls.validatedecorator.
2 Installation
pip install pyvalidify
3 Supported Data Types
- Text Type:
str - Numeric Types:
int,float,complex - Sequence Types:
list,tuple,range - Mapping Type:
dict - Set Types:
set,frozenset - Boolean Type:
bool - Binary Types:
bytes,bytearray,memoryview - None Type:
NoneType/None - Generics - e.g.
list[str] - Unions - e.g.
str | int - Generics with unions (limited support) - e.g.
list | tuple[str | bytes, bool]
4 Usage
4.1 Manual validation
from validify import isvalid
simple_var = 2
isvalid(simple_var, int) # true
isvalid(simple_var, str) # false
complicated_var = [
{
"name": "John",
"email": "johnny1975@hotmail.com"
},
{
"name": "Dan",
"email": None
}
]
isvalid(complicated_var, list[dict[str, str]]) # false
isvalid(complicated_var, list[dict[str, str | None]]) # true
4.2 Decorator for Functions
from validify import func
@func.validate
def func(a: list[int], b: list[int], *args: str, c: bool, **kwargs: bool) -> None: ...
func([1, 2, 3], [4, 5, 6], "foo", "bar", c=True, d=False) # OK
func((1, 2, 3), (4, 5, 6), "foo", "bar", c=True, d=False) # TypeError
4.3 Decorator for Classes
from dataclasses import dataclass
from validify import cls
@dataclass
@cls.validify
class MyClass:
name: str
address: list[str]
MyClass("John", ["SY23 2JS", "3102 Bridge Street"]) # OK
MyClass("John", "SY23 2JS, 3102 Bridge Street") # TypeError
@cls.validify
class MyOtherClass:
basket: list[tuple[str, int, float]]
customer_name: str | None
def __init__(self, **items: tuple[int, float]) -> None: ...
def add_item(self, name: str, qty: int, price: float) -> None: ...
@classmethod
def from_item_list(cls, items: list[tuple[str, int, float]]) -> "MyOtherClass": ...
@staticmethod
def calcualte_total(item_prices: list[float]) -> float: ...
@property
def customer_name(self) -> str | None: ...
@customer_name.setter
def customer_name(self, val) -> None: ...
inst = MyOtherClass(chocolate=(1.5, 4.99)) # TypeError
inst.add_item("beans", "2", "2.59") # TypeError
inst = inst.from_item_list([["carrot", 5, 1.43], ["reduced fat pesto", 1, 2.99]]) # TypeError
total = MyOtherClass.calculate_total([("carrot", 5, 1.43), ("reduced fat pesto", 1, 2.99)]) # TypeError
inst.customer_name = ["Bart", "Simpson"] # TypeError
4.4 Notes
func.validatedoes not work on lambdas and abstract methods (I guess the latter is no surprise).classmethoddecorator must precedefunc.validate
5 Developers Guide
5.1 Contributing
Contributions are welcome! Please follow these steps:
- Fork the repository.
- Create a new branch for your feature or bugfix.
- Commit your changes.
- Push the branch to your fork.
- Create a pull request.
5.2 Architecture
The library can be described as service based, however, it roughly follows layered, DDD-like pattern. The below names of each layer are mearely contextual - I made them up to remember what is what, don't judge. The rules of interactions of these layers are simple: a layer can only import from beneath itself.
"service" layer #2:
decorators.py- two classesclsandfuncwith static methods
"service" layer #1:
validator.py- contains two functions:describe_type()- like Python's nativetype()andis_valid()- like Python's nativeisinstance()
"model" layer:
descriptor.py- definition of theDescriptorclass, a framework for working with datatypes.
"core" layer:
type_hints.py- describes supported types and defines functions for validating them.
5.3 Known Issues
- When describing a datatype in terms of combinations or their equivalence (see
type_description.TypeDescription.combinations()ortype_description.TypeDescription.__hash__()), unions are not being propagated outward within nested datatype. For example, consider a typelist[tuple[int | str]]. It represents a list of tuples, where tuple can hold only one element each. Valid values would be[(1,), (1,)],[("1",), ("1",)]or[(1,), ("1",)]. Respectively, they can be represented as typeslist[tuple[int]],list[tuple[str]]orlist[tuple[int] | tuple[str]]. The last expression is equivalent to the initial one - describes a list of mixed items. Unfortunately neithercombinations()nor__hash__()method describe the the relationship. The issue is to be fixed.
6 License
Validify is licensed under the MIT License. See the LICENSE file for more information.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pyvalidify-1.0.1.tar.gz.
File metadata
- Download URL: pyvalidify-1.0.1.tar.gz
- Upload date:
- Size: 15.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.1 Linux/6.5.0-1025-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
473c21b2335618fe561c1a04ecf9e552163d010eaf6b43bfe2c4cb92b6d9aed4
|
|
| MD5 |
b4ffbc96f6d90434cc85536f76ba7477
|
|
| BLAKE2b-256 |
ac8a8c0de32f0f1779368cefe54cdae51fd9afbbdf9f656486cf729dff31e328
|
File details
Details for the file pyvalidify-1.0.1-py3-none-any.whl.
File metadata
- Download URL: pyvalidify-1.0.1-py3-none-any.whl
- Upload date:
- Size: 14.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: poetry/1.8.3 CPython/3.12.1 Linux/6.5.0-1025-azure
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b2515af280a156bb9e5f71a4e9d793748b483868de0bd231ad4d58c64196eb81
|
|
| MD5 |
3ae3132c5081797fe4ebbe03d2b4b2bd
|
|
| BLAKE2b-256 |
83f625d7f7a3f5db9cce83a44594e939b6bde8ec9d1ee50ddef86172966518ec
|