[RFC]typed: Turn DictValue into a Validation class
- Dominant language
- Python
- Stars
- 4.3k
- Forks
- 347
- Avg merge
- 2d 2h
- Merged PRs (30d)
- 1
Description
Currently, DictValue is just a pass-through proxy to return a dictionary with default values.
```python
class Person(DictValue):
name: str
team: str = "A"
assert Person() == {"team": "A"}
```
This was made this way to allow `person: Person = Person(name="foo")` and the defaults defined on the class would be inherited.
## Proposed change
```python
class Settings(Dynaconf):
person: Person = Person() # OK! defaults will be applied, lazy validation will require name
person: Person = Person(name="foo") # OK! defaults will be applied, type will be `dict`
person: Person = {"name": "foo"} # Ok! end result will be same as above
person: Person # partially required (person.name is required)
```
In the case the type defined default value for all fields
```python
class Person(DictValue):
name: str = "foo"
team: str = "A"
class Settings(Dynaconf):
person: Person
```
Not required, because `Person` has defaults for all its fields!
---
How validation be performed?
On `DictValue.__new__` check all annotated values are passed, then return a complete `dict`
How will the `main.extract_defaults...` get only the default values from `DictValue` type?
Implement a class method named `get_defaults()` that will return only the k,v pairs with defaults defined (the process currently performed on `__new__` and then change the calls on the main.extract function.
---
How will user declare that `person` is not required?
```python
person: NotRequired[Person]
```
Can be omitted, if not informed key will be absent, if informed, defaults will be applied from the schema.
---
```python
person: Person = Person(name="foo")
```
Not required because there is a default value informed, so user can omit and settings will have default applied.
---
How to require that person is completely informed on settings sources?
Do not define default values on the subtype.
```python
class Person(DictValue):
name: str
team: str
class Settings(Dynaconf):
person: Person
```
If no person is loaded: `ValidationError: person is required`
Contributor guide
Assessment
This issue has not been assessed yet.