Most of these answers aren't right. The appropriate way to do this is to validate your arguments in the class's __new__
method, and return None
if validation fails or ins
if validation succeeds.
Here's what you're looking for:
import pytest # for testing
class ValidatedModel:
def __init__(self, *, name=None):
self.name = name
@classmethod
def _validate(cls, *args, **kwargs):
try:
assert not args
assert list(kwargs.keys()) == ['name']
assert len(kwargs['name']) > 5 and len(kwargs['name']) < 10
except AssertionError:
return False
return True
def __new__(cls, *args, **kwargs):
if cls._validate(*args, **kwargs):
return super().__new__(cls)
class TestValidatedModel:
def test_success(self):
vm = ValidatedModel(name='william')
assert isinstance(vm, ValidatedModel)
def test_kwarg_fail_unexpected_kwarg(self):
vm = ValidatedModel(name='william', gender='M')
assert vm is None
def test_kwarg_fail_name_length_short(self):
vm = ValidatedModel(name='bill')
assert vm is None
def test_kwarg_fail_name_length_long(self):
vm = ValidatedModel(name='william johnson')
assert vm is None
def test_no_name_kwarg(self):
vm = ValidatedModel()
assert vm is None
Obviously you can replace the _validate
method with your own implementation.