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’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exclude with __all__ fails on Sequence fields #9328

Open
1 task done
MatthieuSarter opened this issue Apr 26, 2024 · 1 comment
Open
1 task done

Exclude with __all__ fails on Sequence fields #9328

MatthieuSarter opened this issue Apr 26, 2024 · 1 comment
Labels
bug V2 Bug related to Pydantic V2
Milestone

Comments

@MatthieuSarter
Copy link

MatthieuSarter commented Apr 26, 2024

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

When trying to exclude subfields fields in model_dump_json on a model with fields defined as Sequence[something], serialization fails with "Error calling function serialize_sequence_via_list: ValueError: Negative indices cannot be used to exclude items on unsized iterables".

Types matching the Sequence generic type have a length and accepts negative indices according to Python doc: https://docs.python.org/3/library/stdtypes.html#sequence-types-list-tuple-range

The serialization works fine when using list[something] instead of Sequence[something], but when using this mypy forbids to override with list[subclass of something] in subclasses of the model.

This was working fine with Sequence until updating from Pydantic 2.6.x to 2.7.1.

Example Code

from typing import Sequence

from pydantic import BaseModel

exclude = {"releases": {"__all__": {"build": True}}}


class Release(BaseModel):
    version: str
    name: str
    desc: str


class BundleSeq(BaseModel):
    releases: Sequence[Release]


class BundleList(BaseModel):
    releases: list[Release]


r1 = Release(name="Foo", version="1.0", desc="Foo v1.0")
r2 = Release(name="Bar", version="2.0", desc="Bar v2.0")
b1 = BundleSeq(releases=[r1, r2])
b2 = BundleList(releases=[r1, r2])

try:
    print(b1.model_dump_json(exclude=exclude))
except Exception as e:
    print(e)

print(b2.model_dump_json(exclude=exclude))

# Output:
# Error serializing to JSON: PydanticSerializationError: Error calling function `serialize_sequence_via_list`: ValueError: Negative indices cannot be used to exclude items on unsized iterables
# {"releases":[{"version":"1.0","name":"Foo","desc":"Foo v1.0"},{"version":"2.0","name":"Bar","desc":"Bar v2.0"}]}
#
# Expected output:
# {"releases":[{"version":"1.0","name":"Foo","desc":"Foo v1.0"},{"version":"2.0","name":"Bar","desc":"Bar v2.0"}]}
# {"releases":[{"version":"1.0","name":"Foo","desc":"Foo v1.0"},{"version":"2.0","name":"Bar","desc":"Bar v2.0"}]}

Python, Pydantic & OS Version

pydantic version: 2.7.1
        pydantic-core version: 2.18.2
          pydantic-core build: profile=release pgo=true
                 install path: C:\Users\matth\AppData\Local\pypoetry\Cache\virtualenvs\[redacted]-py3.12\Lib\site-packages\pydantic
               python version: 3.12.2 (tags/v3.12.2:6abddd9, Feb  6 2024, 21:26:36) [MSC v.1937 64 bit (AMD64)]
                     platform: Windows-10-10.0.19045-SP0
             related packages: fastapi-0.110.2 mypy-1.10.0 typing_extensions-4.11.0
                       commit: unknown
@MatthieuSarter MatthieuSarter added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Apr 26, 2024
@sydney-runkle
Copy link
Member

sydney-runkle commented Apr 28, 2024

@MatthieuSarter,

Thanks for reporting this. Will work on a fix for 2.7.2! We did do some sequence validation modification from 2.6 -> 2.7, so I'm not surprised that there were some problems.

@sydney-runkle sydney-runkle removed the pending Awaiting a response / confirmation label Apr 28, 2024
@sydney-runkle sydney-runkle added this to the 2.7 fixes milestone Apr 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V2 Bug related to Pydantic V2
Projects
None yet
Development

No branches or pull requests

2 participants