Hi,
since version 2.13 (i think concretely since #717) it is very easy to break bool arguments. The reason for this is non-type things inside the field metadata, e.g. by using CliSuppress or StrictBool. The following script breaks:
import pydantic_settings
from pydantic_settings import BaseSettings, CliApp, CliSuppress
class Settings(BaseSettings):
field: CliSuppress[bool]
def parse_args():
print(f'{pydantic_settings.VERSION=}')
settings = CliApp.run(Settings)
print(f'{settings=}')
return settings
def main() -> None:
parse_args()
if __name__ == '__main__':
main()
$ python test_suppress.py
pydantic_settings.VERSION='2.13.0'
Traceback (most recent call last):
File "/home/georg/Documents/denkweit/git/pydantic-settings/test_suppress.py", line 21, in <module>
main()
File "/home/georg/Documents/denkweit/git/pydantic-settings/test_suppress.py", line 17, in main
parse_args()
File "/home/georg/Documents/denkweit/git/pydantic-settings/test_suppress.py", line 11, in parse_args
settings = CliApp.run(Settings)
^^^^^^^^^^^^^^^^^^^^
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/main.py", line 733, in run
sources, init_kwargs = model_cls._settings_init_sources(**model_init_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/main.py", line 424, in _settings_init_sources
cli_settings = CliSettingsSource[Any](
^^^^^^^^^^^^^^^^^^^^^^^
File "/home/georg/.local/share/uv/python/cpython-3.11.10-linux-x86_64-gnu/lib/python3.11/typing.py", line 1289, in __call__
result = self.__origin__(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/sources/providers/cli.py", line 415, in __init__
self._connect_root_parser(
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/sources/providers/cli.py", line 906, in _connect_root_parser
self._add_parser_args(
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/sources/providers/cli.py", line 1046, in _add_parser_args
self._convert_bool_flag(arg.kwargs, field_info, model_default)
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/sources/providers/cli.py", line 1088, in _convert_bool_flag
meta_bool_flags = [
^
File "/home/georg/Documents/denkweit/git/pydantic-settings/pydantic_settings/sources/providers/cli.py", line 1089, in <listcomp>
meta for meta in field_info.metadata if issubclass(meta, _CliImplicitFlag | _CliExplicitFlag)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: issubclass() arg 1 must be a class
Here is the link to the erroring line:
|
meta for meta in field_info.metadata if issubclass(meta, _CliImplicitFlag | _CliExplicitFlag) |
Which raises the above exception, because
CliSuppress, which is a literal string (
"==SUPPRESS==") is inside
field_info.metadata and which cannot be passed as 1st argument to
issubclass
Hi,
since version 2.13 (i think concretely since #717) it is very easy to break
boolarguments. The reason for this is non-type things inside the field metadata, e.g. by usingCliSuppressorStrictBool. The following script breaks:Here is the link to the erroring line:
pydantic-settings/pydantic_settings/sources/providers/cli.py
Line 1089 in 198e71c
Which raises the above exception, because
CliSuppress, which is a literal string ("==SUPPRESS==") is insidefield_info.metadataand which cannot be passed as 1st argument toissubclass