-
Notifications
You must be signed in to change notification settings - Fork 268
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Add unique
constraint to list?
#296
Comments
I may be confused but, why About the |
equality.
Well, the question is whether |
Ok, I understood. I think it's okay and is up to the developer whether to use it or not. I'll try to do an implementation as a draft or as a reference. |
Great, thank you. |
Q: You are doing this in python? Or rust? (Asking out of curiosity >> I want to learn how this stuff works.) |
this needs to be in rust since the list validator is all written in rust, see pydantic-core/src/validators/list.rs Line 96 in 9e54f78
|
After the removal of |
Yeah, this one was an unfortunate loss for me; I just want a |
I think this is a way you can achieve this in v2: from typing import Annotated
from pydantic import BaseModel, AfterValidator, PlainSerializer
def require_sorted_unique(v):
if v != sorted(set(v)):
raise ValueError('not sorted unique')
return v
RequireSortUniqueDuringValidation = AfterValidator(require_sorted_unique)
SortUniqueDuringValidation = AfterValidator(lambda v: sorted(set(v)))
SortUniqueDuringSerialization = PlainSerializer(lambda v: sorted(set(v)))
class Model(BaseModel):
x: Annotated[list[int], SortUniqueDuringValidation]
y: Annotated[list[int], SortUniqueDuringSerialization]
z: Annotated[list[int], RequireSortUniqueDuringValidation]
some_ints = [5, 5, 4, 4, 3, 3, 2, 2, 1, 1]
m = Model(x=some_ints, y=some_ints, z=[])
print(m)
# > x=[1, 2, 3, 4, 5] y=[5, 5, 4, 4, 3, 3, 2, 2, 1, 1] z=[]
print(m.model_dump())
# > {'x': [1, 2, 3, 4, 5], 'y': [1, 2, 3, 4, 5], 'z': []}
Model(x=[], y=[], z=[5, 4])
"""
pydantic_core._pydantic_core.ValidationError: 1 validation error for Model
z
Value error, not sorted unique [type=value_error, input_value=[5, 4], input_type=list]
For further information visit https://errors.pydantic.dev/2.0.2/v/value_error
""" Does that work for you? |
@dmontagu the simplicity of the conlist implementation vs your solution is difficult to beat. I have some experience in pydantic now and it still took me too long to understand what your solution actually entails. I am definitely in favour of getting the conlist working again as it was. |
Here is a real use case. MongoDB + Pydantic. class Document:
unique_elements: set[int] Using bson.errors.InvalidDocument: cannot encode object: set(), of type: <class 'set'> It would be convenient to have something like class Document:
unique_elements: Annotated[list[int, ListConstraints(unique_items=True)] Of course I can add a validator (or to use a workaround above #296 (comment)) class Document:
unique_elements: list[int]
@model_validator
# validate here that `unique_elements` has only unique elements... but restricting a At the worst case, #296 (comment) can be added to the package but with a warning in the documentation that this is a potentially slow operation (pure Python). |
In my case I use Now,
Are there any critical issues with this option? I can try to create an PR to return it back. |
See #820 (comment), I think this solves all of the requirements and will be about as fast as it can be. |
Before we had Note that Edit: I changed my mind, we should follow @adriangb's example. |
@adriangb, do you think we should leave this open? |
I think this can be closed as a WontFix given the alternatives offered. |
Closing, if someone really wants this built into pydantic-core, we would of course be willing to review a PR. BTW, #820 (comment) won't work in the case of inputs which are not hashable, so a full solution would have to compare equality of every pair of items in the list, which I think would have performance of |
I'm not sure about this, it would need to have minimal or no impact on performance when switched off.
Some questions if we are to support it:
unique
only on the list validator or on tuple, set, frozenset and general iterables as we build the vec?unique
check onset
andfrozenset
validators - this would have minimal performance impact as it would involve simply checking that the length of the input before and after creating the set, but sets loose order so won't be sufficient for some scenarioslist[int]
and a few other types, we could do something pretty performant with anAHashSet
but a general case will require some fairly slow python.The text was updated successfully, but these errors were encountered: