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

Empty tuple type #2318

Closed
gpkc opened this issue Feb 4, 2021 · 3 comments · Fixed by #2319
Closed

Empty tuple type #2318

gpkc opened this issue Feb 4, 2021 · 3 comments · Fixed by #2319
Labels
bug V1 Bug related to Pydantic V1.X

Comments

@gpkc
Copy link

gpkc commented Feb 4, 2021

Bug

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

             pydantic version: 1.7.3
            pydantic compiled: True
                 install path: /home/guilherme/PycharmProjects/bulk-uploader/venv/lib/python3.8/site-packages/pydantic
               python version: 3.8.5 (default, Jul 28 2020, 12:59:40)  [GCC 9.3.0]
                     platform: Linux-5.4.0-65-generic-x86_64-with-glibc2.29
     optional deps. installed: ['typing-extensions']

from pydantic import BaseModel

class Example(BaseModel):
    example: Tuple[()]

Will result in:

Traceback (most recent call last):
  File "pydantic/validators.py", line 615, in pydantic.validators.find_validators
TypeError: issubclass() arg 1 must be a class

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "...", line 12, in <module>
    class Example(BaseModel):
  File "pydantic/main.py", line 262, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 315, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 284, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 356, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 458, in pydantic.fields.ModelField._type_analysis
  File "pydantic/fields.py", line 516, in pydantic.fields.ModelField._create_sub_type
  File "pydantic/fields.py", line 284, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 362, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 538, in pydantic.fields.ModelField.populate_validators
  File "pydantic/validators.py", line 624, in find_validators
RuntimeError: error checking inheritance of () (type: tuple)
@gpkc gpkc added the bug V1 Bug related to Pydantic V1.X label Feb 4, 2021
@mpkocher
Copy link

mpkocher commented Feb 5, 2021

This looks like you might be mixing up types and instances by using example: Tuple[()] For example, List[dict()] doesn't really make sense from a type standpoint. The "empty" tuple might be better addressed by using a default_factory. This makes it consistent with other defaults, such as dict or set.

You can specify a variable length tuple with a single type as example: Tuple[int, ...]. It's possible to use Tuple[Any, ...] for a heterogeneous tuple, however, this isn't particularly useful from a type standpoint.

Here's an explicit example:

from typing import Tuple
from pydantic import BaseModel, Field

class T(BaseModel):
    example: Tuple[int, ...] = Field(default_factory=tuple)

def demo() -> int:

    a = T()
    b = T(example=(1,2))

    for x in (a, b):
        print(x)

    return 0


demo()

@PrettyWood
Copy link
Member

@mpkocher the syntax may not be the one you expected but it's the one chosen in PEP 484

Tuple, used by listing the element types, for example Tuple[int, int, str]. The empty tuple can be typed as Tuple[()]. Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, for example Tuple[int, ...]. (The ... here are part of the syntax, a literal ellipsis.)

So if you want to enforce in pydantic an empty tuple, you don't want to set Tuple[Any, ...] but really Tuple[()].
@gpkc I opened a small PR to support this syntax. Thanks for reporting!

@mpkocher
Copy link

mpkocher commented Feb 5, 2021

@PrettyWood Thanks for clarifying.

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
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants