pydantic: Attribute error for `functools.partial`

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

Using a partialmethodor partial as a validator or root_validator creates an unhelpful AttributeError:

tests/conftest.py:14: in <module>
    class TestClass(BaseModel):
tests/conftest.py:17: in TestClass
    _custom_validate = validator("name")(validate)
pydantic/class_validators.py:93: in pydantic.class_validators.validator.dec
    ???
pydantic/class_validators.py:150: in pydantic.class_validators._prepare_validator
    ???
E   AttributeError: 'functools.partial' object has no attribute '__qualname__'

The problem is rooted at this code.

IMO an try except block with a test for partial methods would be useful here, telling the User to supply the “allow_reuse” parameter for partials.

Example Code

from functools import partial

from pydantic import validator, BaseModel
from pydantic.main import ModelMetaclass
from pydantic.utils import GetterDict

def custom_validator(additional_stuff: str, cls: ModelMetaclass, values: GetterDict):
    print(additional_stuff)
    return values

validate = partial(custom_validator, "TEXT")

class TestClass(BaseModel):
    name: str

    _custom_validate = validator("name")(validate)

Python, Pydantic & OS Version

pydantic version: 1.10.5
            pydantic compiled: True
                 install path: XXX/.venv/lib/python3.10/site-packages/pydantic
               python version: 3.10.7 (main, Nov 24 2022, 19:45:47) [GCC 12.2.0]
                     platform: Linux-5.19.0-31-generic-x86_64-with-glibc2.36
     optional deps. installed: ['typing-extensions']

Affected Components

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 15 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I personally find the responses in the links from the last two comments reasonable; it seems we should just not assume that __qualname__ definitely exists.

TBH I feel functools is broken here and we are just adding a workaround. Even a lambda gets an __qualname__

agreed. Feel free to create an issue on cpython and copy me into it, I’d be interest to see what they say.

Also, can you create a PR against main to see if this is working there?

TBH I feel functools is broken here and we are just adding a workaround. Even a lambda gets an __qualname__

Thanks @JensHeinrich for reporting this issue.

I can confirm the issue. partial() returns an instance, not a class or function.

it may fix by accessing the function in the following line. I mean replacing f_cls.__func__.__qualname__ with f_cls.__func__.func.__qualname__ in case of partial

https://github.com/pydantic/pydantic/blob/73373c3e08fe5fe23e4b05f549ea34e0da6a16b7/pydantic/_internal/_decorators.py#L204

Would you like to open a PR?