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

Variable length tuple field cannot be defined #495

Closed
bofm opened this issue Apr 29, 2019 · 2 comments

Comments

Projects
None yet
2 participants
@bofm
Copy link

commented Apr 29, 2019

Bug

For bugs/questions:

  • OS: MacOS 10.14.2
  • Python version: 3.7.2
  • Pydantic version: 0.24

According to Python typing docs

To specify a variable-length tuple of homogeneous type, use literal ellipsis, e.g. Tuple[int, ...]. A plain Tuple is equivalent to Tuple[Any, ...], and in turn to tuple.

Specifying a variable length tuple like this

from typing import Tuple
from pydantic.dataclasses import dataclass

@dataclass(frozen=True)
class User1:
    name: str
    friends: Tuple[str, ...] = tuple()

causes Pydantic to fail:

Traceback (most recent call last):
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/validators.py", line 373, in find_validators
    if issubclass(type_, val_type):
TypeError: issubclass() arg 1 must be a class

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "x.py", line 4, in <module>
    @dataclass(frozen=True)
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/dataclasses.py", line 122, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, config)
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/dataclasses.py", line 85, in _process_class
    cls.__name__, __config__=config, __module__=_cls.__module__, __validators__=validators, **fields
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/main.py", line 574, in create_model
    return type(model_name, (__base__,), namespace)  # type: ignore
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/main.py", line 197, in __new__
    config=config,
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 137, in infer
    schema=schema,
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 106, in __init__
    self.prepare()
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 171, in prepare
    self._populate_sub_fields()
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 202, in _populate_sub_fields
    self._create_sub_type(t, f'{self.name}_{i}') for i, t in enumerate(self.type_.__args__)  # type: ignore
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 202, in <listcomp>
    self._create_sub_type(t, f'{self.name}_{i}') for i, t in enumerate(self.type_.__args__)  # type: ignore
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 232, in _create_sub_type
    model_config=self.model_config,
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 106, in __init__
    self.prepare()
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 172, in prepare
    self._populate_validators()
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/fields.py", line 250, in _populate_validators
    else find_validators(self.type_, self.model_config.arbitrary_types_allowed)
  File "/Users/x/.pyenv/versions/3.7.2/lib/python3.7/site-packages/pydantic/validators.py", line 376, in find_validators
    raise RuntimeError(f'error checking inheritance of {type_!r} (type: {display_as_type(type_)})') from e
RuntimeError: error checking inheritance of Ellipsis (type: ellipsis)

And If we omit the ellipsis Pydantic does not allow us to set the field value to an empty tuple (which is actually correct).

from typing import Tuple
from pydantic.dataclasses import dataclass

@dataclass(frozen=True)
class User2:
    name: str
    friends: Tuple[str] = tuple()

user2 = User2(name='Jimmy', friends=())
print(user2)
pydantic.error_wrappers.ValidationError: 1 validation error
friends
  wrong tuple length 0, expected 1 (type=value_error.tuple.length; actual_length=0; expected_length=1)

@bofm bofm changed the title Variable length typing.Tuple field cannot be defined Variable length tuple field cannot be defined Apr 29, 2019

@samuelcolvin

This comment has been minimized.

Copy link
Owner

commented Apr 29, 2019

yes, it's not implemented. PR welcome.

@samuelcolvin

This comment has been minimized.

Copy link
Owner

commented Apr 29, 2019

you can use Sequence[str] as a work around.

pilosus added a commit to pilosus/pydantic that referenced this issue May 7, 2019

@pilosus pilosus referenced this issue May 7, 2019

Merged

Tuple ellipsis #512

4 of 4 tasks complete

pilosus added a commit to pilosus/pydantic that referenced this issue May 9, 2019

pilosus added a commit to pilosus/pydantic that referenced this issue May 9, 2019

pilosus added a commit to pilosus/pydantic that referenced this issue May 9, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.