Conversation
dbaa702 to
1a10995
Compare
…_schema_extra` When running with `python -OO`, docstrings are stripped (`__doc__` is `None`), causing CLI help descriptions to disappear. This adds a fallback to `json_schema_extra['description']` from model_config, matching pydantic's behavior for JSON schema generation. Fixes #827 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1a10995 to
d4c4e3d
Compare
aytekinar
reviewed
Apr 15, 2026
aytekinar
left a comment
There was a problem hiding this comment.
How about this type of fix, @hramezani?
Follow-up: #827 (comment)
Comment on lines
+100
to
+107
| if model_cls.__doc__ is not None: | ||
| return dedent(model_cls.__doc__) | ||
| config: Any = {} | ||
| if is_model_class(model_cls): | ||
| config = model_cls.model_config | ||
| elif is_pydantic_dataclass(model_cls): | ||
| config = getattr(model_cls, '__pydantic_config__', None) or {} | ||
| json_schema_extra = config.get('json_schema_extra') |
There was a problem hiding this comment.
Suggested change
| if model_cls.__doc__ is not None: | |
| return dedent(model_cls.__doc__) | |
| config: Any = {} | |
| if is_model_class(model_cls): | |
| config = model_cls.model_config | |
| elif is_pydantic_dataclass(model_cls): | |
| config = getattr(model_cls, '__pydantic_config__', None) or {} | |
| json_schema_extra = config.get('json_schema_extra') | |
| config: Any = {} | |
| if is_model_class(model_cls): | |
| config = model_cls.model_config | |
| elif is_pydantic_dataclass(model_cls): | |
| config = getattr(model_cls, '__pydantic_config__', {}) | |
| json_schema_extra = config.get('json_schema_extra', model_cls.__doc__) | |
| if isinstance(json_schema_extra, str): | |
| return dedent(json_schema_extra) |
There was a problem hiding this comment.
I think this would be a better / more symmetric fix when the current functionality of pydantic is considered.
aytekinar
reviewed
Apr 15, 2026
Comment on lines
+3498
to
+3504
| def test_get_model_description_docstring_takes_precedence(): | ||
| class MyModel(BaseModel): | ||
| """Docstring wins.""" | ||
|
|
||
| model_config = ConfigDict(json_schema_extra={'description': 'Schema description.'}) | ||
|
|
||
| assert _get_model_description(MyModel) == 'Docstring wins.' |
There was a problem hiding this comment.
Suggested change
| def test_get_model_description_docstring_takes_precedence(): | |
| class MyModel(BaseModel): | |
| """Docstring wins.""" | |
| model_config = ConfigDict(json_schema_extra={'description': 'Schema description.'}) | |
| assert _get_model_description(MyModel) == 'Docstring wins.' | |
| def test_get_model_description_schema_takes_precedence(): | |
| class MyModel(BaseModel): | |
| """Docstring description.""" | |
| model_config = ConfigDict(json_schema_extra={'description': 'Schema wins.'}) | |
| assert _get_model_description(MyModel) == 'Schema wins.' |
aytekinar
reviewed
Apr 15, 2026
Comment on lines
+3568
to
+3596
| def test_cli_docstring_takes_precedence_over_json_schema_extra(capsys, monkeypatch): | ||
| """When __doc__ is available, it should be used instead of json_schema_extra description.""" | ||
|
|
||
| class Settings(BaseSettings, cli_prog_name='example.py'): | ||
| """Docstring description.""" | ||
|
|
||
| model_config = SettingsConfigDict( | ||
| cli_parse_args=True, | ||
| json_schema_extra={'description': 'JSON schema description.'}, | ||
| ) | ||
| my_var: str = 'default' | ||
|
|
||
| with monkeypatch.context() as m: | ||
| m.setattr(sys, 'argv', ['example.py', '--help']) | ||
|
|
||
| with pytest.raises(SystemExit): | ||
| Settings() | ||
|
|
||
| assert ( | ||
| capsys.readouterr().out | ||
| == f"""usage: example.py [-h] [--my_var str] | ||
|
|
||
| Docstring description. | ||
|
|
||
| {ARGPARSE_OPTIONS_TEXT}: | ||
| -h, --help show this help message and exit | ||
| --my_var str (default: default) | ||
| """ | ||
| ) |
There was a problem hiding this comment.
Suggested change
| def test_cli_docstring_takes_precedence_over_json_schema_extra(capsys, monkeypatch): | |
| """When __doc__ is available, it should be used instead of json_schema_extra description.""" | |
| class Settings(BaseSettings, cli_prog_name='example.py'): | |
| """Docstring description.""" | |
| model_config = SettingsConfigDict( | |
| cli_parse_args=True, | |
| json_schema_extra={'description': 'JSON schema description.'}, | |
| ) | |
| my_var: str = 'default' | |
| with monkeypatch.context() as m: | |
| m.setattr(sys, 'argv', ['example.py', '--help']) | |
| with pytest.raises(SystemExit): | |
| Settings() | |
| assert ( | |
| capsys.readouterr().out | |
| == f"""usage: example.py [-h] [--my_var str] | |
| Docstring description. | |
| {ARGPARSE_OPTIONS_TEXT}: | |
| -h, --help show this help message and exit | |
| --my_var str (default: default) | |
| """ | |
| ) | |
| def test_cli_json_schema_extra_takes_precedence_over_docstring(capsys, monkeypatch): | |
| """Even when __doc__ is available, json_schema_extra description should be used, instead.""" | |
| class Settings(BaseSettings, cli_prog_name='example.py'): | |
| """Docstring description.""" | |
| model_config = SettingsConfigDict( | |
| cli_parse_args=True, | |
| json_schema_extra={'description': 'JSON schema description.'}, | |
| ) | |
| my_var: str = 'default' | |
| with monkeypatch.context() as m: | |
| m.setattr(sys, 'argv', ['example.py', '--help']) | |
| with pytest.raises(SystemExit): | |
| Settings() | |
| assert ( | |
| capsys.readouterr().out | |
| == f"""usage: example.py [-h] [--my_var str] | |
| JSON schema description. | |
| {ARGPARSE_OPTIONS_TEXT}: | |
| -h, --help show this help message and exit | |
| --my_var str (default: default) | |
| """ | |
| ) |
…ydantic Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add tests for callable json_schema_extra on dataclass and dict without description key falling back to docstring. Remove unreachable else branch. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
python -OO, docstrings are stripped (__doc__isNone), causing CLI help descriptions to disappear entirely_get_model_description()helper that falls back tojson_schema_extra['description']frommodel_configwhen__doc__isNone__doc__was used: root parser, subcommand description, subcommand help withcli_use_class_docs_for_groups, and model group descriptionFixes #827
Test plan
_get_model_descriptioncovering: docstring present, no doc/no extra, dict fallback, docstring precedence, callablejson_schema_extra, pydantic dataclass, BaseSettingscli_use_class_docs_for_groupsfallback, subcommand fallback🤖 Generated with Claude Code