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

Unexpected Config Error with discriminator #4773

Closed
5 of 15 tasks
gluhar2006 opened this issue Nov 22, 2022 · 9 comments
Closed
5 of 15 tasks

Unexpected Config Error with discriminator #4773

gluhar2006 opened this issue Nov 22, 2022 · 9 comments
Assignees
Labels
bug V1 Bug related to Pydantic V1.X unconfirmed Bug not yet confirmed as valid/applicable

Comments

@gluhar2006
Copy link

Initial Checks

  • I have searched GitHub for a duplicate issue and I'm sure this is something new
  • I have searched Google & StackOverflow for a solution and couldn't find anything
  • I have read and followed the docs and still think this is a bug
  • I am confident that the issue is with pydantic (not my code, or another library in the ecosystem like FastAPI or mypy)

Description

Discriminator validation.

Expected: ValidationError when passing list or dict as discriminator.

Received: ConfigError.

Example Code

from typing import Literal

import pydantic


class Model1(pydantic.BaseModel):
    target: Literal["t1"]
    a: int


class Model2(pydantic.BaseModel):
    target: Literal["t2"]
    b: int


class Foo(pydantic.BaseModel):
    foo: Model1 | Model2 = pydantic.Field(discriminator="target")


# Foo(**{"foo": {"target": []}})
Foo(**{"foo": {"target": {}}})

Python, Pydantic & OS Version

pydantic version: 1.10.2
            pydantic compiled: True
                 install path: /home/.../lib/python3.10/site-packages/pydantic
               python version: 3.10.8 (main, Oct 19 2022, 10:31:59) [GCC 9.4.0]
                     platform: Linux-5.15.0-53-generic-x86_64-with-glibc2.31
     optional deps. installed: ['typing-extensions']

Affected Components

@gluhar2006 gluhar2006 added bug V1 Bug related to Pydantic V1.X unconfirmed Bug not yet confirmed as valid/applicable labels Nov 22, 2022
@PrettyWood
Copy link
Member

The real error is there TypeError: unhashable type: 'list' but TypeError is caught to raise a ConfigError indeed.

@gluhar2006
Copy link
Author

I wrote about error, which received by user.
I just didn't understand https://github.com/pydantic/pydantic/blob/v1.10.2/pydantic/fields.py#L1124 otherwise I would have created PR, not issue

@fatelei
Copy link

fatelei commented Jan 17, 2023

I wrote about error, which received by user. I just didn't understand https://github.com/pydantic/pydantic/blob/v1.10.2/pydantic/fields.py#L1124 otherwise I would have created PR, not issue

discriminator decide target can be Model1 or Model2

example

Foo(foo={'target': 't1', 'a': 1})  # this is Model1
Foo(foo={'target': 't2', 'b': 1})  # this is Model2

Usage below is not right

Foo(**{"foo": {"target": {}}})

@fatelei
Copy link

fatelei commented Jan 17, 2023

this is not a bug

@gluhar2006
Copy link
Author

this is not a bug

You mean that I need to validate target field separately or something else?

Usage below is not right

Why do you think so?

@fatelei
Copy link

fatelei commented Jan 17, 2023

Foo(foo={'target': 't2', 'b': 1})

target should not be {}, target should be one of t1 / t2

@gluhar2006
Copy link
Author

gluhar2006 commented Jan 17, 2023

target should not be {}, target should be one of t1 / t2

sounds weird

In this case how to explain that all works correctly with

Foo(**{"foo": {"target": 123}})?

@derek-globus
Copy link

The bug report seems to be about the error handling itself.

Foo(**{"foo": {"target": 123}})

raises a ValidationError indicating the document failed validation

Foo(**{"foo": {"target": []}})

raises a ConfigError indicating the Model is incorrect


Both documents should be invalid and thus should both raise ValidationErrors

kurtmckee added a commit to kurtmckee/pr-pydantic that referenced this issue Mar 2, 2023
kurtmckee added a commit to kurtmckee/pr-pydantic that referenced this issue Mar 2, 2023
kurtmckee added a commit to kurtmckee/pr-pydantic that referenced this issue Mar 2, 2023
kurtmckee added a commit to kurtmckee/pr-pydantic that referenced this issue Mar 2, 2023
dmontagu added a commit that referenced this issue Mar 8, 2023
* Demonstrate #4773

* Raise `ValidationError` for unhashable discriminator values

Fixes #4773

* Update tests/test_discrimated_union.py

* Update pydantic/fields.py

---------

Co-authored-by: Hasan Ramezani <hasan.r67@gmail.com>
Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>
@adriangb
Copy link
Member

This will be fixed when we release v2:

from typing import Literal

import pydantic


class Model1(pydantic.BaseModel):
    target: Literal['t1']
    a: int


class Model2(pydantic.BaseModel):
    target: Literal['t2']
    b: int


class Foo(pydantic.BaseModel):
    foo: Model1 | Model2 = pydantic.Field(discriminator='target')


print(Foo(**{"foo": {"target": 't2', 'b': 123}}))
#> foo=Model2(target='t2', b=123)

Foo(**{"foo": {"target": []}})
"""
pydantic_core._pydantic_core.ValidationError: 1 validation error for Foo
foo
  Input should be a valid string [type=string_type, input_value=[], input_type=list]
"""
Foo(**{'foo': {'target': {}}})
"""
pydantic_core._pydantic_core.ValidationError: 1 validation error for Foo
foo
  Input should be a valid string [type=string_type, input_value={}, input_type=dict]
"""
Foo(**{"foo": {"target": 123}})
"""
pydantic_core._pydantic_core.ValidationError: 1 validation error for Foo
foo
    Input tag '123' found using 'target' does not match any of the expected tags: 't1', 't2' [type=union_tag_invalid, input_value={'target': 123}, input_type=dict]
"""

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug V1 Bug related to Pydantic V1.X unconfirmed Bug not yet confirmed as valid/applicable
Projects
None yet
Development

No branches or pull requests

5 participants