diff --git a/.chronus/changes/python-docstring-duplicate-fix-2026-7-16-22-38-0.md b/.chronus/changes/python-docstring-duplicate-fix-2026-7-16-22-38-0.md new file mode 100644 index 00000000000..b25638ff083 --- /dev/null +++ b/.chronus/changes/python-docstring-duplicate-fix-2026-7-16-22-38-0.md @@ -0,0 +1,8 @@ +--- +# Change versionKind to one of: internal, fix, dependencies, feature, deprecation, breaking +changeKind: fix +packages: + - "@typespec/http-client-python" +--- + +[Python] Fix duplicate `:keyword:`/`:paramtype:` lines in generated DPG model docstrings that duplicated the existing `:ivar:`/`:vartype:` entries diff --git a/packages/http-client-python/generator/pygen/codegen/serializers/model_serializer.py b/packages/http-client-python/generator/pygen/codegen/serializers/model_serializer.py index 15e82108a89..be35a23b89e 100644 --- a/packages/http-client-python/generator/pygen/codegen/serializers/model_serializer.py +++ b/packages/http-client-python/generator/pygen/codegen/serializers/model_serializer.py @@ -122,15 +122,6 @@ def input_documentation_string(prop: Property) -> list[str]: # building the param line of the property doc return _documentation_string(prop, "keyword", "paramtype") - def keyword_documentation_string(self, model: ModelType) -> list[str]: - # building the ``:keyword:``/``:paramtype:`` lines for the keyword-only - # arguments of the generated ``__init__`` overload so that the docstring - # keeps a 1:1 correlation with the keyword-only arguments in the signature. - retval: list[str] = [] - for prop in sorted(self._init_line_parameters(model), key=lambda x: x.optional): - retval.extend(self.input_documentation_string(prop)) - return retval - @staticmethod def variable_documentation_string(prop: Property) -> list[str]: return _documentation_string(prop, "ivar", "vartype") @@ -428,6 +419,16 @@ def declare_model(self, model: ModelType) -> str: basename += f", discriminator='{model.discriminator_value}'" return f"class {model.name}({basename}):{self.class_pylint_disable(model)}" + def class_pylint_disable(self, model: ModelType) -> str: + retval = super().class_pylint_disable(model) + # DPG models render an empty ``@overload def __init__(self, *, ...)`` body, so the + # guideline checker validates the keyword-only arguments against the *class* docstring. + # We only document those arguments as instance variables (``:ivar:``) to avoid a redundant + # ``:keyword:`` entry per property, so silence the keyword/keyword-only correlation check. + if self._init_line_parameters(model): + retval = add_to_pylint_disable(retval, "docstring-keyword-should-match-keyword-only") + return retval + @staticmethod def get_properties_to_declare(model: ModelType) -> list[Property]: if model.parents: diff --git a/packages/http-client-python/generator/pygen/codegen/templates/model_dpg.py.jinja2 b/packages/http-client-python/generator/pygen/codegen/templates/model_dpg.py.jinja2 index 6a2b533ae55..8bcbbf4af41 100644 --- a/packages/http-client-python/generator/pygen/codegen/templates/model_dpg.py.jinja2 +++ b/packages/http-client-python/generator/pygen/codegen/templates/model_dpg.py.jinja2 @@ -16,11 +16,6 @@ {% endfor %} {% endfor %} {% endif %} - {% if serializer.need_init(model) %} - {% for line in serializer.keyword_documentation_string(model) %} - {{ macros.wrap_model_string(line, '\n ') -}} - {% endfor %} - {% endif %} """ {% if model.is_polymorphic %}