Skip to content

Handle equality exceptions from exclude_default as False when serializing #10547

Open
pydantic/pydantic-core
#1490
@sneakers-the-rat

Description

@sneakers-the-rat

Initial Checks

  • I have searched Google & GitHub for similar requests and couldn't find anything
  • I have read and followed the docs and still think this feature is missing

Description

I was very pleased to see that there was already an option to exclude_defaults when dumping models. I don't expect to get tight control over how defaults are compared, but I feel like one additional case would make it even better:

When using custom types (in particular numpy arrays with a pydantic-compatible wrapper), sometimes they either don't define __eq__ or have special conditions like numpy arrays with "the truth value of an array with more than one element is ambiguous."

Specifically take this example, assuming that the ndarray type works as expected otherwise:

class MyModel(BaseModel):
    array: Optional[NDArray] = None

if an array is provided, model_dump<_json>(exclude_defaults=True) will fail because bool(None == np.array(data)) raises the ambiguous bool ValueError.

What do you think about treating exceptions raised by __eq__ when deciding whether something is equal to the defaults as being "not equal to the default"? I think that would just be one change here: https://github.com/pydantic/pydantic-core/blob/e3eff5cb8a6dae8914e3831b00c690d9dee4b740/src/serializers/fields.rs#L78-L80 to catch the exception and return False instead.

I think that would be more intuitive than not (if two things can't be meaningfully compared, my assumption would be that they are not equal), and lower complexity than trying to handle all the possible ways things can be compared, or being able to pass a custom lambda like lambda x,y: np.array_equal(x, y) into the dump method.

Not a perfect fix, but a step in the right direction and not introducing any footguns i can think of. what ya think?

Affected Components

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions