Skip to content

Commit

Permalink
Update HISTORY.rst
Browse files Browse the repository at this point in the history
  • Loading branch information
rnag committed Nov 25, 2024
1 parent 6f6c51a commit 417fa8b
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 3 deletions.
20 changes: 20 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,26 @@
History
=======

0.30.0 (2024-11-25)
-------------------

**Features and Improvements**

- **Conditional Field Skipping**: Omit fields during JSON serialization based on user-defined conditions.
- Introduced new :class:`Meta` settings:
- :attr:`skip_if` — Skips all fields matching a condition.
- :attr:`skip_defaults_if` — Skips fields with default values matching a condition.
- Added per-field controls using :func:`SkipIf()` annotations.
- Introduced the :func:`skip_if_field` wrapper for maximum flexibility.

- **New Helper Class**: :class:`JSONPyWizard`
- A ``JSONWizard`` helper to disable *camelCase* transformation and keep keys as-is.

- **Typing Improvements**: Added more ``*.pyi`` files for enhanced type checking and IDE support.

- **Documentation Updates**:
- Added details about upcoming changes in the next major release, ``v1.0``.

0.29.3 (2024-11-24)
-------------------

Expand Down
36 changes: 34 additions & 2 deletions dataclass_wizard/dumpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
)
from .utils.dict_helper import NestedDict
from .utils.function_builder import FunctionBuilder
# noinspection PyProtectedMember
from .utils.dataclass_compat import _set_new_attribute
from .utils.string_conv import to_camel_case

Expand Down Expand Up @@ -254,8 +255,23 @@ class C:

def finalize_skip_if(skip_if: Condition,
operand_1: str,
conditional: str):
conditional: str) -> str:
"""
Finalizes the skip condition by generating the appropriate string based on the condition.
Args:
skip_if (Condition): The condition to evaluate, containing truthiness and operation info.
operand_1 (str): The primary operand for the condition (e.g., a variable or value).
conditional (str): The conditional operator to use (e.g., '==', '!=').
Returns:
str: The resulting skip condition as a string.
Example:
>>> cond = Condition(t_or_f=True, op='+', val=None)
>>> finalize_skip_if(cond, 'my_var', '==')
'my_var'
"""
if skip_if.t_or_f:
return operand_1 if skip_if.op == '+' else f'not {operand_1}'

Expand All @@ -264,8 +280,24 @@ def finalize_skip_if(skip_if: Condition,

def get_skip_if_condition(skip_if: Condition,
_locals: dict[str, Any],
operand_2: str):
operand_2: str) -> 'str | bool':
"""
Retrieves the skip condition based on the provided `Condition` object.
Args:
skip_if (Condition): The condition to evaluate.
_locals (dict[str, Any]): A dictionary of local variables for condition evaluation.
operand_2 (str): The secondary operand (e.g., a variable or value).
Returns:
Any: The result of the evaluated condition or a string representation for custom values.
Example:
>>> cond = Condition(t_or_f=False, op='==', val=10)
>>> locals_dict = {}
>>> get_skip_if_condition(cond, locals_dict, 'other_var')
'== other_var'
"""
if skip_if is None:
return False

Expand Down
17 changes: 16 additions & 1 deletion tests/unit/test_load.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from dataclass_wizard import *
from dataclass_wizard.constants import TAG
from dataclass_wizard.errors import (
ParseError, MissingFields, UnknownJSONKey, MissingData
ParseError, MissingFields, UnknownJSONKey, MissingData, InvalidConditionError
)
from dataclass_wizard.models import Extras, _PatternBase
from dataclass_wizard.parsers import (
Expand Down Expand Up @@ -2426,3 +2426,18 @@ class SkipExample(JSONWizard):
# Test with truthy `my_str` and `my_bool` should include the field
obj = SkipExample(my_str="", my_bool=True)
assert obj.to_dict() == {'myStr': '', 'myBool': True}


def test_invalid_condition_annotation_raises_error():
"""
Test that using a Condition (e.g., LT) directly as a field annotation
without wrapping it in SkipIf() raises an InvalidConditionError.
"""
with pytest.raises(InvalidConditionError, match="Wrap conditions inside SkipIf()"):

@dataclass
class Example(JSONWizard):
my_field: Annotated[int, LT(5)] # Invalid: LT is not wrapped in SkipIf.

# Attempt to serialize an instance, which should raise the error.
Example(my_field=3).to_dict()

0 comments on commit 417fa8b

Please sign in to comment.