This is what I have. I believe there are two problems here - the Literal and the None.
from attrs import frozen, field
from attrs.validators import instance_of
OK_ARGS = ['a', 'b']
@field
class MyClass:
my_field: Literal[OK_ARGS] | None = field(validator=instance_of((Literal[OK_ARGS], None)))
Error:
TypeError: Subscripted generics cannot be used with class and instance checks
Edit: I've made a workaround with a custom validator. Not that pretty however:
def _validator_literal_or_none(literal_type):
def inner(instance, attribute, value):
if (isinstance(value, str) and (value in literal_type)) or (value is None):
pass
else:
raise ValueError(f'You need to provide a None, or a string in this list: {literal_type}')
return inner
You can’t do isinstance()
checks on Literals/Nones and that’s what the is_instance
Validator is using internally (it predates those typing features by far).
While we’ve resisted adding a complete implementation of the typing language due to its complexity, having one dedicated to such cases mind be worth exploring if you’d like to open an issue.