Skip to content

Commit d0080cf

Browse files
committed
feat: implement dataclasses support for voluptuous schemas
Resolves GitHub issue #409 by adding comprehensive dataclasses support: Features: - DataclassSchema class for automatic schema creation from dataclasses - create_dataclass_schema() function for functional API - is_dataclass() utility for dataclass detection - Automatic type validation from dataclass field annotations - Support for default values and default_factory functions - Seamless integration with existing voluptuous validators - Type annotation handling for List[T], Optional[T], etc. - Full backward compatibility with existing schemas Implementation: - Added voluptuous/dataclasses_support.py with core functionality - Added comprehensive test suite (19 tests covering all scenarios) - Added examples/dataclasses_example.py with usage examples - Updated README.md with documentation and examples - Integrated into main voluptuous module with graceful fallback Code Quality: - All tests pass (162 existing + 19 new = 181 total) - Zero flake8 violations - Zero mypy type errors - Black and isort formatting applied - Requires Python 3.7+ for dataclasses support Breaking Changes: None Backward Compatibility: Full
1 parent c5b63f8 commit d0080cf

5 files changed

Lines changed: 1291 additions & 0 deletions

File tree

README.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,115 @@ cross-field validator will not run:
688688
schema({'password': '123', 'password_again': 1337})
689689
```
690690

691+
## Dataclasses Support
692+
693+
*Requires Python 3.7+ for dataclasses support.*
694+
695+
Voluptuous provides built-in support for Python dataclasses, allowing you to automatically create schemas from dataclass definitions with optional additional validation constraints.
696+
697+
### Basic Dataclass Schema
698+
699+
```python
700+
from dataclasses import dataclass
701+
from voluptuous import DataclassSchema
702+
703+
@dataclass
704+
class Person:
705+
name: str
706+
age: int
707+
active: bool = True
708+
709+
# Create schema from dataclass
710+
schema = DataclassSchema(Person)
711+
712+
# Validate and create dataclass instance
713+
result = schema({'name': 'John Doe', 'age': 30, 'active': False})
714+
# Returns: Person(name='John Doe', age=30, active=False)
715+
```
716+
717+
### Dataclass with Additional Constraints
718+
719+
You can add validation constraints on top of the basic type checking:
720+
721+
```python
722+
from voluptuous import DataclassSchema, All, Length, Range, Email
723+
724+
@dataclass
725+
class User:
726+
username: str
727+
email: str
728+
age: int = 18
729+
730+
# Add validation constraints
731+
schema = DataclassSchema(User, {
732+
'username': All(str, Length(min=3, max=20)),
733+
'email': Email(),
734+
'age': Range(min=13, max=120)
735+
})
736+
737+
result = schema({
738+
'username': 'john_doe',
739+
'email': 'john@example.com',
740+
'age': 25
741+
})
742+
# Returns: User(username='john_doe', email='john@example.com', age=25)
743+
```
744+
745+
### Nested Dataclass Validation
746+
747+
Dataclass schemas can be nested for complex data structures:
748+
749+
```python
750+
@dataclass
751+
class Address:
752+
street: str
753+
city: str
754+
zipcode: str
755+
756+
@dataclass
757+
class Person:
758+
name: str
759+
address: dict # Will be validated as Address
760+
761+
address_schema = DataclassSchema(Address)
762+
person_schema = DataclassSchema(Person, {
763+
'address': address_schema
764+
})
765+
766+
result = person_schema({
767+
'name': 'Alice',
768+
'address': {
769+
'street': '123 Main St',
770+
'city': 'Anytown',
771+
'zipcode': '12345'
772+
}
773+
})
774+
# Returns: Person with nested Address dataclass instance
775+
```
776+
777+
### Alternative Function API
778+
779+
You can also use the `create_dataclass_schema` function:
780+
781+
```python
782+
from voluptuous import create_dataclass_schema
783+
784+
schema = create_dataclass_schema(Person, {
785+
'name': Length(min=1, max=100),
786+
'age': Range(min=0, max=150)
787+
})
788+
```
789+
790+
### Key Features
791+
792+
- **Automatic type validation** from dataclass field annotations
793+
- **Default value support** including `default_factory` functions
794+
- **Seamless integration** with existing voluptuous validators
795+
- **Type annotation handling** for `List[T]`, `Optional[T]`, etc.
796+
- **Full backward compatibility** with existing voluptuous schemas
797+
798+
For more examples, see `examples/dataclasses_example.py`.
799+
691800
## Running tests
692801

693802
Voluptuous is using `pytest`:

0 commit comments

Comments
 (0)