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

Compatibility issues when converting stdlib data classes to pydantic data classes #3566

Closed
3 tasks done
souloss opened this issue Dec 23, 2021 · 7 comments
Closed
3 tasks done
Labels
bug V1 Bug related to Pydantic V1.X

Comments

@souloss
Copy link

souloss commented Dec 23, 2021

Checks

  • I added a descriptive title to this issue
  • I have searched (google, github) for similar issues and couldn't find anything
  • I have read and followed the docs and still think this is a bug

Bug

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

(.venv) [root@localhost py]# python -c "import pydantic.utils; print(pydantic.utils.version_info())"
             pydantic version: 1.8.2
            pydantic compiled: False
                 install path: /root/py/.venv/lib/python3.10/site-packages/pydantic
               python version: 3.10.1 (main, Dec  9 2021, 08:55:38) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
                     platform: Linux-4.4.0-19041-Microsoft-x86_64-with-glibc2.17
     optional deps. installed: ['dotenv', 'email-validator', 'typing-extensions']
(.venv) [root@localhost  py]# 
from dataclasses import dataclass
from typing import List
from dataclasses import field
import pydantic

@dataclass
class A:
    b: int = 0
    c: List[int] = field(default_factory=list)

pydantic.dataclasses.dataclass(A)
...

output:

(.venv) [root@localhost  py]# python3 test/utils/test_pydanic_bug.py 
Traceback (most recent call last):
  File "/root/py/test/utils/test_pydanic_bug.py", line 15, in <module>
    pydantic.dataclasses.dataclass(A)
  File "/root/py/.venv/lib/python3.10/site-packages/pydantic/dataclasses.py", line 257, in dataclass
    return wrap(_cls)
  File "/root/py/.venv/lib/python3.10/site-packages/pydantic/dataclasses.py", line 252, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, config)
  File "/root/py/.venv/lib/python3.10/site-packages/pydantic/dataclasses.py", line 160, in _process_class
    cls: Type['Dataclass'] = dataclasses.dataclass(  # type: ignore
  File "/usr/local/python3.10/lib/python3.10/dataclasses.py", line 1185, in dataclass
    return wrap(cls)
  File "/usr/local/python3.10/lib/python3.10/dataclasses.py", line 1176, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash,
  File "/usr/local/python3.10/lib/python3.10/dataclasses.py", line 1025, in _process_class
    _init_fn(all_init_fields,
  File "/usr/local/python3.10/lib/python3.10/dataclasses.py", line 546, in _init_fn
    raise TypeError(f'non-default argument {f.name!r} '
TypeError: non-default argument 'c' follows default argument

because The stdlib dataclass passes def _process_class(cls, init, repr, eq, order, unsafe_hash, frozen,match_args, kw_only, slots): After processing the ordinary class once, some field class attributes will be deleted, and they will be set to _FIELDS. this process cannot be repeated.

@souloss souloss added the bug V1 Bug related to Pydantic V1.X label Dec 23, 2021
@samuelcolvin
Copy link
Member

Would this be fixed by #2557?

@souloss
Copy link
Author

souloss commented Dec 23, 2021

It is a pity that I just cloned the code of PrettyWood and the test result failed.

@souloss
Copy link
Author

souloss commented Dec 23, 2021

But this seems to be just a small problem, very easy.

@PrettyWood
Copy link
Member

Hi @witchc
The code you shared works well with #2557. In which way does it not solve your issue?

@souloss
Copy link
Author

souloss commented Dec 23, 2021

@PrettyWood
Maybe there is a problem with my test method?
My test steps are as follows:

[root@localhost ~]# git clone https://github.com/PrettyWood/pydantic.git
Cloning into 'pydantic'...
remote: Enumerating objects: 10878, done.
remote: Counting objects: 100% (217/217), done.
remote: Compressing objects: 100% (119/119), done.
remote: Total 10878 (delta 135), reused 158 (delta 96), pack-reused 10661
Receiving objects: 100% (10878/10878), 4.33 MiB | 2.44 MiB/s, done.
Resolving deltas: 100% (8224/8224), done.
Checking connectivity... done.
[root@localhost ~]# cd pydantic/
[root@localhost pydantic]# python3 -m venv .venv
[root@localhost pydantic]# source .venv/bin/activate
(.venv) [root@localhost pydantic]# pip3 install -r requirements.txt 
Ignoring dataclasses: markers 'python_version < "3.7"' don't match your environment
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple
Collecting Cython==0.29.25 (from -r requirements.txt (line 3))
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/a6/e0/74dfae7ef24e036538269061aa7d82132c1de84cfb31278927996c09033e/Cython-0.29.25-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl (2.0MB)
    100% |████████████████████████████████| 2.0MB 705kB/s 
Collecting devtools==0.8.0 (from -r requirements.txt (line 4))
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/54/11/32e995d0978b8898fbdb35179186b0155355db2fdd20f7058761b27006e2/devtools-0.8.0-py3-none-any.whl
Collecting email-validator==1.1.3 (from -r requirements.txt (line 5))
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/9e/e4/e01e92092fdac940f10fa4c8ac3481bf70fc74023a76f5c72020c9445e68/email_validator-1.1.3-py2.py3-none-any.whl
Collecting typing-extensions==4.0.1 (from -r requirements.txt (line 7))
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/05/e4/baf0031e39cf545f0c9edd5b1a2ea12609b7fcba2d58e118b11753d68cf0/typing_extensions-4.0.1-py3-none-any.whl
Collecting python-dotenv==0.19.2 (from -r requirements.txt (line 8))
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/0e/f1/0317f4b2c5284075a2154fe95539b43c0acecbcb86fe80fcb2645803edd9/python_dotenv-0.19.2-py2.py3-none-any.whl
Collecting executing<1.0.0,>=0.8.0 (from devtools==0.8.0->-r requirements.txt (line 4))
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/ba/64/59e024b685666514cb20ffc2463a8b062df8e6c36efc5199cb422b728b78/executing-0.8.2-py2.py3-none-any.whl
Collecting asttokens<3.0.0,>=2.0.0 (from devtools==0.8.0->-r requirements.txt (line 4))
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/16/d5/b0ad240c22bba2f4591693b0ca43aae94fbd77fb1e2b107d54fff1462b6f/asttokens-2.0.5-py2.py3-none-any.whl
Collecting dnspython>=1.15.0 (from email-validator==1.1.3->-r requirements.txt (line 5))
  Downloading https://pypi.tuna.tsinghua.edu.cn/packages/f5/2d/ae9e172b4e5e72fa4b3cfc2517f38b602cc9ba31355f9669c502b4e9c458/dnspython-2.1.0-py3-none-any.whl (241kB)
    100% |████████████████████████████████| 245kB 354kB/s 
Collecting idna>=2.0.0 (from email-validator==1.1.3->-r requirements.txt (line 5))
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/04/a2/d918dcd22354d8958fe113e1a3630137e0fc8b44859ade3063982eacd2a4/idna-3.3-py3-none-any.whl
Collecting six (from asttokens<3.0.0,>=2.0.0->devtools==0.8.0->-r requirements.txt (line 4))
  Using cached https://pypi.tuna.tsinghua.edu.cn/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl
Installing collected packages: Cython, executing, six, asttokens, devtools, dnspython, idna, email-validator, typing-extensions, python-dotenv
Successfully installed Cython-0.29.25 asttokens-2.0.5 devtools-0.8.0 dnspython-2.1.0 email-validator-1.1.3 executing-0.8.2 idna-3.3 python-dotenv-0.19.2 six-1.16.0 typing-extensions-4.0.1
You are using pip version 19.0.3, however version 21.3.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(.venv) [root@localhost pydantic]# cat <<EOF > tests/
check_tag.py                       test_abc.py                        test_color.py                      test_edge_cases.py                 test_json.py                       test_parse.py                      test_types.py
conftest.py                        test_aliases.py                    test_construction.py               test_errors.py                     test_main.py                       test_private_attributes.py         test_typing.py
__init__.py                        test_annotated.py                  test_create_model.py               test_fastapi.sh                    test_model_signature.py            test_schema.py                     test_utils.py
mypy/                              test_annotated_types.py            test_dataclasses.py                test_forward_ref.py                test_networks_ipaddress.py         test_settings.py                   test_validators_dataclass.py
requirements-linting.txt           test_assert_in_validators.py       test_datetime_parse.py             test_generics.py                   test_networks.py                   test_tools.py                      test_validators.py
requirements-testing.txt           test_callable.py                   test_decorator.py                  test_hypothesis_plugin.py          test_orm_mode.py                   test_types_payment_card_number.py  test_version.py
(.venv) [root@localhost pydantic]# cat <<EOF > tests/test_dataclass.py
> from dataclasses import dataclass
> from typing import List
> from dataclasses import field
> import pydantic
> 
> @dataclass
> class A:
>     b: int = 0
>     c: List[int] = field(default_factory=list)
> 
> pydantic.dataclasses.dataclass(A)
> EOF
(.venv) [root@localhost pydantic]# export PYTHONPATH=$(pwd)
(.venv) [root@localhost pydantic]# python3 tests/test_dataclass.py 
Traceback (most recent call last):
  File "tests/test_dataclass.py", line 11, in <module>
    pydantic.dataclasses.dataclass(A)
  File "/root/pydantic/pydantic/dataclasses.py", line 256, in dataclass
    return wrap(_cls)
  File "/root/pydantic/pydantic/dataclasses.py", line 251, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen, config)
  File "/root/pydantic/pydantic/dataclasses.py", line 160, in _process_class
    _cls, init=init, repr=repr, eq=eq, order=order, unsafe_hash=unsafe_hash, frozen=frozen
  File "/usr/local/python3/lib/python3.7/dataclasses.py", line 991, in dataclass
    return wrap(_cls)
  File "/usr/local/python3/lib/python3.7/dataclasses.py", line 983, in wrap
    return _process_class(cls, init, repr, eq, order, unsafe_hash, frozen)
  File "/usr/local/python3/lib/python3.7/dataclasses.py", line 904, in _process_class
    else 'self',
  File "/usr/local/python3/lib/python3.7/dataclasses.py", line 490, in _init_fn
    raise TypeError(f'non-default argument {f.name!r} '
TypeError: non-default argument 'c' follows default argument
(.venv) [root@localhost pydantic]# 

@souloss
Copy link
Author

souloss commented Dec 23, 2021

@PrettyWood
Sorry, I made a low-level mistake and didn't switch branches.

@souloss
Copy link
Author

souloss commented Dec 23, 2021

@PrettyWood
It does work well with the code on the correct branch, great.
I will close this issue.

@souloss souloss closed this as completed Dec 23, 2021
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

No branches or pull requests

3 participants