jaraco / inflect

Correctly generate plurals, ordinals, indefinite articles; convert numbers to words
https://pypi.org/project/inflect
MIT License
957 stars 107 forks source link

Failed to import: `Field` default cannot be set in `Annotated` for 'num_Annotated[str, FieldInfo(min_length=1, extra={})]' #169

Closed cuihaoleo closed 1 year ago

cuihaoleo commented 2 years ago

Error message:

Traceback (most recent call last):
  File "/data/cuih7/[REDACTED]", line 7, in <module>
    import inflect
  File "/data/cuih7/miniconda3/envs/nlp20220817/lib/python3.10/site-packages/inflect/__init__.py", line 2046, in <module>
    class engine:
  File "/data/cuih7/miniconda3/envs/nlp20220817/lib/python3.10/site-packages/inflect/__init__.py", line 3781, in engine
    def number_to_words(  # noqa: C901
  File "pydantic/decorator.py", line 36, in pydantic.decorator.validate_arguments.validate
    import sys
  File "pydantic/decorator.py", line 126, in pydantic.decorator.ValidatedFunction.__init__
    try:
  File "pydantic/decorator.py", line 259, in pydantic.decorator.ValidatedFunction.create_model
    return fun
  File "pydantic/main.py", line 972, in pydantic.main.create_model
  File "pydantic/main.py", line 204, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 488, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 419, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 534, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 633, in pydantic.fields.ModelField._type_analysis
  File "pydantic/fields.py", line 776, in pydantic.fields.ModelField._create_sub_type
  File "pydantic/fields.py", line 451, in pydantic.fields.ModelField._get_field_info
ValueError: `Field` default cannot be set in `Annotated` for 'num_Annotated[str, FieldInfo(min_length=1, extra={})]'

I'm using the library from conda-forge. Downgrading from 6.0.0-pyhd8ed1ab_0 to 5.6.2-pyhd8ed1ab_0 fixes the issue.

jaraco commented 1 year ago

For me, tests are passing, so there must be something unique to your environment that's incompatible. Perhaps you have an older, incompatible version of pydantic, which was introduced in version 6.

akpeker commented 1 year ago

Had the same issue. I installed the latest version of inflect (6.0.0). After receiving an error about pydantic "Field", I figured my pydantic version was old (0.18) and didn't have Field yet, so upgraded to latest pydantic (1.9.0 on conda). But this time I started getting the above error. I found this on pydantic site: pydantic issues: 3991, which implies that this is expected behavior on pydantic side, so needs to be fixed on inflect side. Hope this contributes a bit to the solution.

jaraco commented 1 year ago

What I don't understand is why don't I encounter the error and why doesn't the error occur in the CI tests?

 ~ $ pip-run inflect -- -c 'import inflect'; echo done
Collecting inflect
  Using cached inflect-6.0.1-py3-none-any.whl (34 kB)
Collecting pydantic
  Using cached pydantic-1.10.2-cp310-cp310-macosx_11_0_arm64.whl (2.6 MB)
Collecting typing-extensions>=4.1.0
  Using cached typing_extensions-4.4.0-py3-none-any.whl (26 kB)
Installing collected packages: typing-extensions, pydantic, inflect
Successfully installed inflect-6.0.1 pydantic-1.10.2 typing-extensions-4.4.0
done

It's difficult for me to fix if I can't replicate the error. It's obviously not strictly a pydantic issue. There's another factor.

Oh. That's interesting - pinning to pydantic 1.9, I can replicate the error:

 ~ $ pip-run inflect 'pydantic==1.9' -- -c 'import inflect'; echo done
Collecting inflect
  Using cached inflect-6.0.1-py3-none-any.whl (34 kB)
Collecting pydantic==1.9
  Downloading pydantic-1.9.0-cp310-cp310-macosx_11_0_arm64.whl (2.4 MB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 2.4/2.4 MB 19.7 MB/s eta 0:00:00
Collecting typing-extensions>=3.7.4.3
  Using cached typing_extensions-4.4.0-py3-none-any.whl (26 kB)
Installing collected packages: typing-extensions, pydantic, inflect
Successfully installed inflect-6.0.1 pydantic-1.9.0 typing-extensions-4.4.0
Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-run-rtp61g6y/inflect/__init__.py", line 2054, in <module>
    class engine:
  File "/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-run-rtp61g6y/inflect/__init__.py", line 3791, in engine
    def number_to_words(  # noqa: C901
  File "pydantic/decorator.py", line 36, in pydantic.decorator.validate_arguments.validate
  File "pydantic/decorator.py", line 126, in pydantic.decorator.ValidatedFunction.__init__
  File "pydantic/decorator.py", line 259, in pydantic.decorator.ValidatedFunction.create_model
  File "pydantic/main.py", line 972, in pydantic.main.create_model
  File "pydantic/main.py", line 204, in pydantic.main.ModelMetaclass.__new__
  File "pydantic/fields.py", line 488, in pydantic.fields.ModelField.infer
  File "pydantic/fields.py", line 419, in pydantic.fields.ModelField.__init__
  File "pydantic/fields.py", line 534, in pydantic.fields.ModelField.prepare
  File "pydantic/fields.py", line 633, in pydantic.fields.ModelField._type_analysis
  File "pydantic/fields.py", line 776, in pydantic.fields.ModelField._create_sub_type
  File "pydantic/fields.py", line 451, in pydantic.fields.ModelField._get_field_info
ValueError: `Field` default cannot be set in `Annotated` for 'num_Annotated[str, FieldInfo(min_length=1, extra={})]'
done

I also can get tests in CI to fail with pydantic 1.9.

Maybe the solution is simply to apply a minimum bound on pydantic to 1.10.

jaraco commented 1 year ago

In fact, tests pass on pydantic 1.9.1.

akpeker commented 1 year ago

Thanks, I think the issue is mostly clarified. Either need to update pydanticto above 1.9 (maybe below 1.9 works too?) or downgrade inflect to e.g. 5.6. I use conda and unfortunately it let's me update only to pydantic 1.9, but let's me downgrade inflect to 5.3, and everything seems to work fine then. Good enough for me.

cuihaoleo commented 1 year ago

Looks like a pydantic bug introduced in 1.9. Fixed in 1.9.1.

Fix in-place modification of FieldInfo that caused problems with PEP 593 type aliases, https://github.com/pydantic/pydantic/pull/4067 by @adriangb

I guess things are clear. Thanks for the tests! Feel free to close this issue.

jaraco commented 1 year ago

I confirmed that commit makes the difference:

``` inflect main $ .tox/py310/bin/pip install --force-reinstall git+https://github.com/pydantic/pydantic@a45276d6b1c0dd7c10d46767bb19954401b3b04a; tox -e p y310 -- -p no:cov -q -x Collecting git+https://github.com/pydantic/pydantic@a45276d6b1c0dd7c10d46767bb19954401b3b04a Cloning https://github.com/pydantic/pydantic (to revision a45276d6b1c0dd7c10d46767bb19954401b3b04a) to /private/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-req-build-07ivxgkq Running command git clone --filter=blob:none --quiet https://github.com/pydantic/pydantic /private/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-req-build-07ivxgkq Running command git rev-parse -q --verify 'sha^a45276d6b1c0dd7c10d46767bb19954401b3b04a' Running command git fetch -q https://github.com/pydantic/pydantic a45276d6b1c0dd7c10d46767bb19954401b3b04a Running command git checkout -q a45276d6b1c0dd7c10d46767bb19954401b3b04a Resolved https://github.com/pydantic/pydantic to commit a45276d6b1c0dd7c10d46767bb19954401b3b04a Preparing metadata (setup.py) ... done Collecting typing-extensions>=3.7.4.3 Using cached typing_extensions-4.4.0-py3-none-any.whl (26 kB) Building wheels for collected packages: pydantic Building wheel for pydantic (setup.py) ... done Created wheel for pydantic: filename=pydantic-1.9.0-py3-none-any.whl size=139929 sha256=9f9d4aee4662ff3e730f9cb9827ced7b01ebe04cd50b222caf5f85d771e50207 Stored in directory: /Users/jaraco/Library/Caches/pip/wheels/3e/55/d6/cf84f4e7ff0c95c42fc8bc92c9ce2642428fa87dab7571ea70 Successfully built pydantic Installing collected packages: typing-extensions, pydantic Attempting uninstall: typing-extensions Found existing installation: typing_extensions 4.4.0 Uninstalling typing_extensions-4.4.0: Successfully uninstalled typing_extensions-4.4.0 Attempting uninstall: pydantic Found existing installation: pydantic 1.9.0 Uninstalling pydantic-1.9.0: Successfully uninstalled pydantic-1.9.0 Successfully installed pydantic-1.9.0 typing-extensions-4.4.0 [notice] A new release of pip available: 22.2.2 -> 22.3 [notice] To update, run: /Users/jaraco/code/jaraco/inflect/.tox/py310/bin/python -m pip install --upgrade pip py310 develop-inst-noop: /Users/jaraco/code/jaraco/inflect py310 installed: attrs==22.1.0,black==22.10.0,build==0.8.0,click==8.1.3,coverage==6.5.0,docutils==0.19,filelock==3.8.0,flake8==4.0.1,-e git+gh://jaraco/inflect@a6294eecb489a6cf9df425459a3294139a0d4e65#egg=inflect,iniconfig==1.1.1,jaraco.context==4.1.2,jaraco.functools==3.5.2,mccabe==0.6.1,more-itertools==9.0.0,mypy==0.982,mypy-extensions==0.4.3,packaging==21.3,pathspec==0.10.1,pep517==0.13.0,platformdirs==2.5.2,pluggy==1.0.0,py==1.11.0,pycodestyle==2.8.0,pydantic @ git+https://github.com/pydantic/pydantic@a45276d6b1c0dd7c10d46767bb19954401b3b04a,pyflakes==2.4.0,Pygments==2.13.0,pyparsing==3.0.9,pytest==7.1.3,pytest-black==0.3.12,pytest-checkdocs==2.9.0,pytest-cov==4.0.0,pytest-enabler==1.3.0,pytest-flake8==1.1.1,pytest-mypy==0.10.0,toml==0.10.2,tomli==2.0.1,typing_extensions==4.4.0 py310 run-test-pre: PYTHONHASHSEED='10422945' py310 run-test: commands[0] | pytest -p no:cov -q -x ======================================================================== ERRORS ======================================================================== _________________________________________________________ ERROR collecting inflect/__init__.py _________________________________________________________ inflect/__init__.py:2054: in class engine: inflect/__init__.py:3791: in engine def number_to_words( # noqa: C901 .tox/py310/lib/python3.10/site-packages/pydantic/decorator.py:36: in validate vd = ValidatedFunction(_func, config) .tox/py310/lib/python3.10/site-packages/pydantic/decorator.py:126: in __init__ self.create_model(fields, takes_args, takes_kwargs, config) .tox/py310/lib/python3.10/site-packages/pydantic/decorator.py:259: in create_model self.model = create_model(to_camel(self.raw_function.__name__), __base__=DecoratorBaseModel, **fields) .tox/py310/lib/python3.10/site-packages/pydantic/main.py:980: in create_model return type(__model_name, __base__, namespace, **__cls_kwargs__) .tox/py310/lib/python3.10/site-packages/pydantic/main.py:205: in __new__ fields[ann_name] = ModelField.infer( .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:489: in infer return cls( .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:420: in __init__ self.prepare() .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:535: in prepare self._type_analysis() .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:636: in _type_analysis self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_] .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:636: in self.sub_fields = [self._create_sub_type(t, f'{self.name}_{display_as_type(t)}') for t in types_] .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:779: in _create_sub_type field_info, _ = self._get_field_info(name, type_, None, self.model_config) .tox/py310/lib/python3.10/site-packages/pydantic/fields.py:452: in _get_field_info raise ValueError(f'`Field` default cannot be set in `Annotated` for {field_name!r}') E ValueError: `Field` default cannot be set in `Annotated` for 'num_Annotated[str, FieldInfo(min_length=1, extra={})]' =============================================================== short test summary info ================================================================ ERROR inflect/__init__.py - ValueError: `Field` default cannot be set in `Annotated` for 'num_Annotated[str, FieldInfo(min_length=1, extra={})]' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! stopping after 1 failures !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 1 error in 0.21s ERROR: InvocationError for command /Users/jaraco/code/jaraco/inflect/.tox/py310/bin/pytest -p no:cov -q -x (exited with code 1) _______________________________________________________________________ summary ________________________________________________________________________ ERROR: py310: commands failed inflect main $ .tox/py310/bin/pip install --force-reinstall git+https://github.com/pydantic/pydantic@e5540296cc1690e3807d99c46f8a99b908735d38; tox -e p y310 -- -p no:cov -q -x Collecting git+https://github.com/pydantic/pydantic@e5540296cc1690e3807d99c46f8a99b908735d38 Cloning https://github.com/pydantic/pydantic (to revision e5540296cc1690e3807d99c46f8a99b908735d38) to /private/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-req-build-569f2bbj Running command git clone --filter=blob:none --quiet https://github.com/pydantic/pydantic /private/var/folders/sx/n5gkrgfx6zd91ymxr2sr9wvw00n8zm/T/pip-req-build-569f2bbj Running command git rev-parse -q --verify 'sha^e5540296cc1690e3807d99c46f8a99b908735d38' Running command git fetch -q https://github.com/pydantic/pydantic e5540296cc1690e3807d99c46f8a99b908735d38 Running command git checkout -q e5540296cc1690e3807d99c46f8a99b908735d38 Resolved https://github.com/pydantic/pydantic to commit e5540296cc1690e3807d99c46f8a99b908735d38 Preparing metadata (setup.py) ... done Collecting typing-extensions>=3.7.4.3 Using cached typing_extensions-4.4.0-py3-none-any.whl (26 kB) Building wheels for collected packages: pydantic Building wheel for pydantic (setup.py) ... done Created wheel for pydantic: filename=pydantic-1.9.0-py3-none-any.whl size=139944 sha256=4b8c6a217bad2367c333a5b0147eac34b1a4ff8bb9399715829fc89790e63795 Stored in directory: /Users/jaraco/Library/Caches/pip/wheels/9d/70/6e/8906dc603ac2db7393ae25b53bfda091239d687fa3f2677d41 Successfully built pydantic Installing collected packages: typing-extensions, pydantic Attempting uninstall: typing-extensions Found existing installation: typing_extensions 4.4.0 Uninstalling typing_extensions-4.4.0: Successfully uninstalled typing_extensions-4.4.0 Attempting uninstall: pydantic Found existing installation: pydantic 1.9.0 Uninstalling pydantic-1.9.0: Successfully uninstalled pydantic-1.9.0 Successfully installed pydantic-1.9.0 typing-extensions-4.4.0 [notice] A new release of pip available: 22.2.2 -> 22.3 [notice] To update, run: /Users/jaraco/code/jaraco/inflect/.tox/py310/bin/python -m pip install --upgrade pip py310 develop-inst-noop: /Users/jaraco/code/jaraco/inflect py310 installed: attrs==22.1.0,black==22.10.0,build==0.8.0,click==8.1.3,coverage==6.5.0,docutils==0.19,filelock==3.8.0,flake8==4.0.1,-e git+gh://jaraco/inflect@a6294eecb489a6cf9df425459a3294139a0d4e65#egg=inflect,iniconfig==1.1.1,jaraco.context==4.1.2,jaraco.functools==3.5.2,mccabe==0.6.1,more-itertools==9.0.0,mypy==0.982,mypy-extensions==0.4.3,packaging==21.3,pathspec==0.10.1,pep517==0.13.0,platformdirs==2.5.2,pluggy==1.0.0,py==1.11.0,pycodestyle==2.8.0,pydantic @ git+https://github.com/pydantic/pydantic@e5540296cc1690e3807d99c46f8a99b908735d38,pyflakes==2.4.0,Pygments==2.13.0,pyparsing==3.0.9,pytest==7.1.3,pytest-black==0.3.12,pytest-checkdocs==2.9.0,pytest-cov==4.0.0,pytest-enabler==1.3.0,pytest-flake8==1.1.1,pytest-mypy==0.10.0,toml==0.10.2,tomli==2.0.1,typing_extensions==4.4.0 py310 run-test-pre: PYTHONHASHSEED='3612521669' py310 run-test: commands[0] | pytest -p no:cov -q -x ...ss.ss......ss..ss..ss..ss..ss..ss..ss..ss..........ss.........ss..ss.....ss..ss......................................ss. [100%] ========================================================================= mypy ========================================================================= Success: no issues found in 16 source files 91 passed, 32 skipped in 5.29s _______________________________________________________________________ summary ________________________________________________________________________ py310: commands succeeded congratulations :) ```

Thanks everyone for the patience and understanding.