feat: allow invalid output fields to be dropped instead of raising#248
feat: allow invalid output fields to be dropped instead of raising#248haneug wants to merge 2 commits into
Conversation
timmyte
left a comment
There was a problem hiding this comment.
Thanks for adding this feature. That's a very good idea.
It would be great if you could generally document your code more extensively, as it does introduce new concepts, which are not trivial.
What is not clear to me: You are saying, that in non-strict mode invalid keys are set to None? But what if their default value is not None?
| return handler(data) | ||
| except ValidationError as e: | ||
| # > Default is strict is set to True and the error is just raised | ||
| if (info.context or {}).get("strict", True): |
There was a problem hiding this comment.
- Please add comments, why are you even looking for
stricthere.
Please explain that you are looking for the method parameter. - I would also add
strictas class variable, instead of hard-coding the default here.
So the expression turns into:
(info.context or {}).get("strict", cls.strict)
| if (info.context or {}).get("strict", True): | ||
| raise | ||
| if not isinstance(data, dict): | ||
| raise |
There was a problem hiding this comment.
Why is the exception also raise under this condition? Please extend the code documentation here.
| raise | ||
| if not isinstance(data, dict): | ||
| raise | ||
| bad_keys = {str(error["loc"][0]) for error in e.errors() if error["loc"]} |
There was a problem hiding this comment.
What are bad_keys? Please add comment describing the need to check this condition here as well.
| bad_keys = {str(error["loc"][0]) for error in e.errors() if error["loc"]} | ||
| if not bad_keys: | ||
| raise | ||
| cleaned = {k: v for k, v in data.items() if str(k) not in bad_keys} |
There was a problem hiding this comment.
What is cleaned?
Please add comments.
| result = handler(cleaned) # re-raises if required fields are missing | ||
| warnings.warn( | ||
| f"{cls.__name__}: dropped fields due to validation errors: {bad_keys}", | ||
| stacklevel=2, |
There was a problem hiding this comment.
Why explicitly stacklevel=2?
Please document this in the code.
| strict: bool, default: True | ||
| If True, a ValidationError is raised when any field in the parsed output cannot be validated. | ||
| If False, fields that fail validation are silently set to None and a UserWarning is emitted. | ||
| Only takes effect when `parse=True`; otherwise pass `strict` directly to `Output.parse()`. |
There was a problem hiding this comment.
| strict: bool, default: True | |
| If True, a ValidationError is raised when any field in the parsed output cannot be validated. | |
| If False, fields that fail validation are silently set to None and a UserWarning is emitted. | |
| Only takes effect when `parse=True`; otherwise pass `strict` directly to `Output.parse()`. | |
| strict: bool, default: True | |
| If `True`, a `ValidationError` is raised when any field in the parsed output cannot be validated. | |
| If `False`, fields that fail validation are silently set to `None` and a `UserWarning` is emitted. | |
| Only takes effect when `parse=True`; otherwise pass `strict` directly to `Output.parse()`. |
| strict: bool, default: True | ||
| If True, a ValidationError is raised when any field in the parsed output cannot be validated. | ||
| If False, fields that fail validation are silently set to None and a UserWarning is emitted. |
There was a problem hiding this comment.
| strict: bool, default: True | |
| If True, a ValidationError is raised when any field in the parsed output cannot be validated. | |
| If False, fields that fail validation are silently set to None and a UserWarning is emitted. | |
| strict: bool, default: True | |
| If `True`, a `ValidationError` is raised when any field in the parsed output cannot be validated. | |
| If `False`, fields that fail validation are silently set to `None` and a `UserWarning` is emitted. |
| If True, a ValidationError is raised when any field cannot be validated. | ||
| If False, fields that fail validation are set to None and a UserWarning is emitted. |
There was a problem hiding this comment.
| If True, a ValidationError is raised when any field cannot be validated. | |
| If False, fields that fail validation are set to None and a UserWarning is emitted. | |
| If `True`, a `ValidationError` is raised when any field cannot be validated. | |
| If `False`, fields that fail validation are set to `None` and a `UserWarning` is emitted. |
| If True, a ValidationError is raised when any field cannot be validated. | ||
| If False, fields that fail validation are set to None and a UserWarning is emitted. |
There was a problem hiding this comment.
| If True, a ValidationError is raised when any field cannot be validated. | |
| If False, fields that fail validation are set to None and a UserWarning is emitted. | |
| If `True`, a `ValidationError` is raised when any field cannot be validated. | |
| If `False`, fields that fail validation are set to `None` and a `UserWarning` is emitted. |
| assert result.calculation_info is not None | ||
| assert result.calculation_info.charge is None | ||
| assert result.calculation_info.mult == 1 | ||
| assert any("charge" in str(w.message) for w in caught) |
There was a problem hiding this comment.
Please document the test mechanism with charge more extensively. It's not trivial. Thanks!
Closes Issues
Closes None
Description
strict=TruetoOutput.__init__()and toOutput.parse()which allows to drop the fields where Pydantic validation fail when it is set toFalse. This way we do not switch the current behavior but have the option for a less strict output generation.Release Notes
(Project adheres to Keep a Changelog; Every entry should start in upper-case and end with
(#<pr-id>); Remove sections that don't apply)Added
Output.parse(),Output.parse_property(),Output.parse_gbw(), andOutput.__init__()now accept astrictparameter (default True). When set to False, output fields that fail Pydantic validation are silently set to None and a UserWarning is emitted instead of raising a ValidationError.