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

Regression in ByteSize error after migrating to pydantic 2.6 #8676

Closed
1 task done
Tracked by #8671
mardiros opened this issue Jan 30, 2024 · 4 comments · Fixed by #8681
Closed
1 task done
Tracked by #8671

Regression in ByteSize error after migrating to pydantic 2.6 #8676

mardiros opened this issue Jan 30, 2024 · 4 comments · Fixed by #8681
Assignees
Labels
bug V2 Bug related to Pydantic V2

Comments

@mardiros
Copy link

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

Hi, I prefer to starts by a small thank you for your work, you did an amazing job with this library.

Here is a detailed description of the issue.

validation errors regression

In pydantic 2.6, for some reason the 'loc' of errors is now ('byte_size', 'constrained-str')
and not ('byte_size') for the ByteSize type. The error msg is also not clean.

The example works on pydantic 3.5.3 but failed with pydantic 2.6.0

Migrate to pydantic 2.6

$ poetry install

Package operations: 0 installs, 2 updates, 0 removals

  • Updating pydantic-core (2.14.6 -> 2.16.1)
  • Updating pydantic (2.5.3 -> 2.6.0)

[...]

Tests Results:


tests/helpers/test_pydantic_2_6_migration.py::test_bytes_errors_format[invalid unit] PASSED
tests/helpers/test_pydantic_2_6_migration.py::test_bytes_errors_format[Not a Number] FAILED
_________________________________ test_bytes_errors_format[Not a Number] _________________________________

params = {'expected': [{'input': 'tenMib', 'loc': ('byte_size',), 'msg': 'could not parse value and unit from byte string', 'type': 'byte_size'}], 'input': 'tenMib'}

    @pytest.mark.parametrize(
        "params",
        [
            pytest.param(
                {
                    "input": "4x",
                    "expected": [
                        {
                            "ctx": {"unit": "x"},
                            "input": "4x",
                            "loc": ("byte_size",),
                            "msg": "could not interpret byte unit: x",
                            "type": "byte_size_unit",
                        },
                    ],
                },
                id="invalid unit",
            ),
            pytest.param(
                {
                    "input": "tenMib",
                    "expected": [
                        {
                            "input": "tenMib",
                            "loc": ("byte_size",),
                            "msg": "could not parse value and unit from byte string",
                            "type": "byte_size",
                        },
                    ],
                },
                id="Not a Number",
            ),
        ],
    )
    def test_bytes_errors_format(params):
        with pytest.raises(ValidationError) as exc:
            PydanticBytes.model_validate({"byte_size": params["input"]})

>       assert exc.value.errors() == params["expected"]
E       assert [{'type': 'string_pattern_mismatch', 'loc': ('byte_size', 'constrained-str'), 'msg': "String should match pattern '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'", 'input': 'tenMib', 'ctx': {'pattern': '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'}, 'url': 'https://errors.pydantic.dev/2.6/v/string_pattern_mismatch'}, {'type': 'int
_parsing', 'loc': ('byte_size', 'constrained-int'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'input': 'tenMib', 'url': 'https://errors.pydantic.dev/2.6/v/int_parsing'}] == [{'input': 'tenMib', 'loc': ('byte_size',), 'msg': 'could not parse value and unit from byte string', 'type'
: 'byte_size'}]
E         At index 0 diff: {'type': 'string_pattern_mismatch', 'loc': ('byte_size', 'constrained-str'), 'msg': "String should match pattern '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'", 'input': 'tenMib', 'ctx': {'pattern': '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'}, 'url': 'https://errors.pydantic.dev/2.6/v/string_pattern_mismatch'} !=
{'input': 'tenMib', 'loc': ('byte_size',), 'msg': 'could not parse value and unit from byte string', 'type': 'byte_size'}
E         Left contains one more item: {'input': 'tenMib', 'loc': ('byte_size', 'constrained-int'), 'msg': 'Input should be a valid integer, unable to parse string as an integer', 'type': 'int_parsing', ...}
E         Full diff:
E           [
E         +  {'ctx': {'pattern': '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'},
E         +   'input': 'tenMib',
E         +   'loc': ('byte_size',
E         +           'constrained-str'),
E         +   'msg': "String should match pattern '^\\s*(\\d*\\.?\\d+)\\s*(\\w+)?'",
E         +   'type': 'string_pattern_mismatch',
E         +   'url': 'https://errors.pydantic.dev/2.6/v/string_pattern_mismatch'},
E            {'input': 'tenMib',
E         -   'loc': ('byte_size',),
E         ?                       --
E         +   'loc': ('byte_size',
E         -   'msg': 'could not parse value and unit from byte string',
E         -   'type': 'byte_size'},
E         +           'constrained-int'),
E         +   'msg': 'Input should be a valid integer, unable to parse string as an '
E         +          'integer',
E         +   'type': 'int_parsing',
E         +   'url': 'https://errors.pydantic.dev/2.6/v/int_parsing'},
E           ]

sequoia/base3/tests/helpers/test_pydantic_2_6_migration.py:47: AssertionError

Example Code

import pytest
from pydantic import BaseModel, ByteSize, Field, ValidationError


class PydanticBytes(BaseModel):
    byte_size: ByteSize = Field()


@pytest.mark.parametrize(
    "params",
    [
        pytest.param(
            {
                "input": "4x",
                "expected": [
                    {
                        "ctx": {"unit": "x"},
                        "input": "4x",
                        "loc": ("byte_size",),
                        "msg": "could not interpret byte unit: x",
                        "type": "byte_size_unit",
                    },
                ],
            },
            id="invalid unit",
        ),
        pytest.param(
            {
                "input": "tenMib",
                "expected": [
                    {
                        "input": "tenMib",
                        "loc": ("byte_size",),
                        "msg": "could not parse value and unit from byte string",
                        "type": "byte_size",
                    },
                ],
            },
            id="Not a Number",
        ),
    ],
)
def test_bytes_errors_format(params):
    with pytest.raises(ValidationError) as exc:
        PydanticBytes.model_validate({"byte_size": params["input"]})

    assert exc.value.errors() == params["expected"]

Python, Pydantic & OS Version

pydantic version: 2.6.0
        pydantic-core version: 2.16.1
          pydantic-core build: profile=release pgo=true
                 install path: /home/guillaume/.cache/pypoetry/virtualenvs/sequoia-base3-oGZ-ftSE-py3.11/lib/python3.11/site-packages/pydantic
               python version: 3.11.6 (main, Nov 14 2023, 09:36:21) [GCC 13.2.1 20230801]
                     platform: Linux-6.7.0-arch3-1-x86_64-with-glibc2.38
             related packages: typing_extensions-4.7.1
                       commit: unknown
@mardiros mardiros added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Jan 30, 2024
@sydney-runkle
Copy link
Member

@mardiros,

Thanks for the report. We'll look into a fix for this to be included in a patch release soon!

@sydney-runkle sydney-runkle removed the pending Awaiting a response / confirmation label Jan 30, 2024
@sydney-runkle sydney-runkle self-assigned this Jan 30, 2024
@sydney-runkle
Copy link
Member

Broken in this PR: https://github.com/pydantic/pydantic/pull/8537/files

@sydney-runkle
Copy link
Member

@mardiros,

I've opened a PR that should fix this issue. Thanks for bringing this to our attention!

@mardiros
Copy link
Author

Thanks for the reactivity. Awesome job!

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

Successfully merging a pull request may close this issue.

2 participants