Open philip-bl opened 9 months ago
Hello!
You can override the default hooks for those types to be anything you like. Cattrs is based on function composition to this is how problems are usually solved.
A simple solution would be like this:
from cattrs import Converter
c = Converter()
def structure_int(val, _) -> int:
if not isinstance(val, int):
raise ValueError("Not an int")
return val
c.register_structure_hook(int, structure_int)
c.structure("1", int) # Error
You can get fancier by making use of the fact structure hooks receive their target type as their second argument, like this:
c = Converter()
def validate_type(val, type):
if not isinstance(val, type):
raise ValueError(f"Not a {type}")
return val
c.register_structure_hook(int, validate_type)
c.register_structure_hook(float, validate_type)
c.register_structure_hook(str, validate_type)
c.register_structure_hook(bool, validate_type)
c.structure("1", bool)
These rules propagate to collections, attrs classes etc.
I'm planning a strategy to make this easier, probably in the next version.
I want to use cattrs to structure dicts and other stuff to attrs. However, I am unhappy with the default behaviour that if attrs expects an
int
,float
,str
,bool
or something like that, it casts the object to that type usingint()
,float()
,str()
, orbool()
respectively. I want cattrs to structure containers such as sequences, dicts, etc. but I don't want it to typecast base types - I want it to error out instead if the types don't match. How can I do this?