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

Type error on initialization of classes derived from RootModel #8745

Closed
1 task done
WarpedPixel opened this issue Feb 6, 2024 · 3 comments
Closed
1 task done

Type error on initialization of classes derived from RootModel #8745

WarpedPixel opened this issue Feb 6, 2024 · 3 comments
Labels
bug V2 Bug related to Pydantic V2

Comments

@WarpedPixel
Copy link

Initial Checks

  • I confirm that I'm using Pydantic V2

Description

RootModel classes should be able to take one argument of the root model type and initialize it that way. From the docs: "The root value can be passed to the model init or model_validate via the first and only argument."
Attempting to initialize a FancyID in the example with a simple string reports "expected 0 positional arguments".

Note that the code works in all cases, however the type system (Pylance in this case) does not understand it correctly. Moreover, workarounds like the one in HackyID below, or only initializing FancyID with model_validate() also work.

In the example SimpleID and HackyID work and report nothing wrong, and FancyID also works but reports "Expected 0 positional arguments Pylance(reportGeneralTypeIssues)".

Example Code

from pydantic import RootModel

SimpleID = RootModel[str]

class FancyID(RootModel[str]):
    def __str__(self) -> str:
        return self.root

class HackyID(RootModel[str]):
    def __init__(self, root: str):
        super().__init__(root=root)

    def __str__(self) -> str:
        return self.root

# from https://docs.pydantic.dev/2.5/concepts/models/#rootmodel-and-custom-root-types
# "The root value can be passed to the model __init__ or model_validate via the first and only argument."
foo = SimpleID('foo')
bar = FancyID('bar')    # Expected 0 positional arguments Pylance(reportGeneralTypeIssues)
hack = HackyID('hack')

print(foo)
print(bar)
print(hack)
assert str(bar) == 'bar'  # works just fine
assert str(hack) == 'hack'

bar = FancyID.model_validate('bar') # no type errors

Python, Pydantic & OS Version

pydantic version: 2.5.3
        pydantic-core version: 2.14.6
          pydantic-core build: profile=release pgo=false
                 install path: /Users/xxx/Library/Caches/pypoetry/virtualenvs/companion-mgXvcyvA-py3.11/lib/python3.11/site-packages/pydantic
               python version: 3.11.4 (main, Jun 20 2023, 16:59:59) [Clang 14.0.3 (clang-1403.0.22.14.1)]
                     platform: macOS-13.6.1-x86_64-i386-64bit
             related packages: typing_extensions-4.9.0 pydantic-extra-types-2.2.0 fastapi-0.108.0 pydantic-settings-2.1.0 email-validator-2.1.0.post1
@WarpedPixel WarpedPixel added bug V2 Bug related to Pydantic V2 pending Awaiting a response / confirmation labels Feb 6, 2024
@sydney-runkle
Copy link
Member

@WarpedPixel,

Thanks for reporting this. Looks like we fixed this issue for the mypy case here: #7677.

@Viicos, any idea what we might be able to do here for a fix? I know you did some work recently with the dataclass_transform logic that might be relevant. Not sure if this is easily fixable, though.

@sydney-runkle sydney-runkle removed the pending Awaiting a response / confirmation label Feb 6, 2024
@Viicos
Copy link
Contributor

Viicos commented Feb 6, 2024

@WarpedPixel you are still on 2.5.x, where a positional argument to a RootModel was not allowed. #7677 fixed for mypy but for pyright as well. This is a MRE for pyright, showing it is working fine.

Updating to 2.6 should solve the issue.

@WarpedPixel
Copy link
Author

You are correct of course. Just verified with 2.6.1 and it works as expected.

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

3 participants