Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix bug re custom_init on members of Union #1076

Merged
merged 2 commits into from Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/validators/model.rs
Expand Up @@ -257,7 +257,10 @@ impl ModelValidator {
// this work with from_attributes, and would essentially allow you to
// handle init vars by adding them to the __init__ signature.
if let Some(kwargs) = input.as_kwargs(py) {
return Ok(self.class.call(py, (), Some(kwargs))?);
return self
.class
.call(py, (), Some(kwargs))
.map_err(|e| convert_err(py, e, input));
}
}

Expand Down
45 changes: 45 additions & 0 deletions tests/validators/test_model_init.py
Expand Up @@ -479,3 +479,48 @@ def _wrap_validator(cls, v, validator, info):
gc.collect()

assert ref() is None


def test_model_custom_init_with_union() -> None:
class A:
def __init__(self, **kwargs):
assert 'a' in kwargs
self.a = kwargs.get('a')

class B:
def __init__(self, **kwargs):
assert 'b' in kwargs
self.b = kwargs.get('b')

schema = {
'type': 'union',
'choices': [
{
'type': 'model',
'cls': A,
'schema': {
'type': 'model-fields',
'fields': {'a': {'type': 'model-field', 'schema': {'type': 'bool'}}},
'model_name': 'A',
},
'custom_init': True,
'ref': '__main__.A:4947206928',
},
{
'type': 'model',
'cls': B,
'schema': {
'type': 'model-fields',
'fields': {'b': {'type': 'model-field', 'schema': {'type': 'bool'}}},
'model_name': 'B',
},
'custom_init': True,
'ref': '__main__.B:4679932848',
},
],
}

validator = SchemaValidator(schema)

assert validator.validate_python({'a': False}).a is False
assert validator.validate_python({'b': True}).b is True