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

Recursion errors for self-referencing generic models #1345

Closed
umvarma opened this issue Mar 27, 2020 · 4 comments
Closed

Recursion errors for self-referencing generic models #1345

umvarma opened this issue Mar 27, 2020 · 4 comments
Labels

Comments

@umvarma
Copy link

umvarma commented Mar 27, 2020

Question

Output of python -c "import pydantic.utils; print(pydantic.utils.version_info())":

pydantic version: 1.4
            pydantic compiled: False
                 install path: F:\Software\Miniconda3\Lib\site-packages\pydantic
               python version: 3.7.6 | packaged by conda-forge | (default, Jan  7 2020, 21:48:41) [MSC v.1916 64 bit (AMD64)]
                     platform: Windows-10-10.0.18362-SP0
     optional deps. installed: []

Issue

I wrote a generic model named Tree as shown in the following snippet.

from __future__ import annotations
from pydantic import BaseModel, Schema
from typing import List, Generic, TypeVar
from pydantic.generics import GenericModel

T = TypeVar('T')

class Node(GenericModel, Generic[T]):
    value: T = Schema(..., description = 'Node value')
    children: List[Node[T]] = Schema([], description = 'Node children')
        
Node.update_forward_refs()

class Tree(GenericModel, Generic[T]):
    nodes: List[Node[T]] = Schema([], description = 'Top level nodes')

I get the error "maximum recursion depth exceeded while calling a Python object" when I try to use it. Any suggestions on how I can fix this would be greatly appreciated.

If I modify the Node.children type from List[Node[T]] to List[Node], then the error disappers.

from __future__ import annotations
from pydantic import BaseModel, Schema
from typing import List, Generic, TypeVar
from pydantic.generics import GenericModel

T = TypeVar('T')

class Node(GenericModel, Generic[T]):
    value: T = Schema(..., description = 'Node value')
    children: List[Node] = Schema([], description = 'Node children')
        
Node.update_forward_refs()

class Tree(GenericModel, Generic[T]):
    nodes: List[Node[T]] = Schema([], description = 'Top level nodes')

The problem in this case is that, it accepts any Node type as the children as shown in the following code.

n1 = Node[str](value = "j")
n2 = Node[int](value = 2)
n0 = Node[int](value = 0, children = [n1, n2])
Tree[int](nodes = [n0]).dict()

I want it to support only Node[int] as children, and I want it throw a validation error in the above case.

@samuelcolvin
Copy link
Member

I don't know of any easy way to fix this. @dmontagu any idea?

@d-tw
Copy link

d-tw commented Aug 26, 2020

I have also encountered this issue - @umvarma did you find a workaround?

@StefanUlbrich
Copy link

I ran into the same error. Any news on this?

@samuelcolvin
Copy link
Member

Thanks for using pydantic. 🙏

As part of a migration to using discussions and cleanup old issues, I'm closing all open issues with the "question" label. 💭 🆘 🚁

I hope you've now found an answer to your question. If you haven't, feel free to start a 👉 question discussion.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants