bug: Class init parameter name disappears from attribute docstring using `separate_signature`
Description of the bug
When calling a method on an input argument to a class __init__ while having separate_signature: true, the parameter name disappears from the rendered instance attribute docstring, leaving only the attribute name and the method called on the input argument.
To Reproduce
python -m venv .venv
. .venv/bin/activate
pip install mkdocstrings-python
python
# mkdocs.yml
site_name: test-site
plugins:
- mkdocstrings:
default_handler: python
handlers:
python:
options:
separate_signature: true
<!-- test.md -->
::: test
# test.py
class SomeClass:
"""This is a class that does something."""
def __init__(self, some_float: float) -> None:
self.as_hex = some_float.hex()
"""The hex value of the input float."""
Expected behavior
I expect the rendered docstring for the as_hex instance attribute to say as_hex = some_float.hex().
Actual behavior
With separate_signature: true, the some_float part disappears, and what is rendered is only as_hex = hex().
Environment information
python -m mkdocstrings_handlers.python.debug # | xclip -selection clipboard
- System: Linux-6.8.0-49-generic-x86_64-with-glibc2.39
- Python: cpython 3.13.1 (/home/stefan/test-mkdocstrings/.venv/bin/python)
- Environment variables:
-
Installed packages:
-
mkdocsv1.6.1 -
mkdocstringsv0.27.0 -
mkdocstrings-pythonv1.12.2 -
griffev1.5.1
-
Thanks for the report @connesy.
This behavior is configurable with this setting: https://mkdocstrings.github.io/python/usage/configuration/signatures/#annotations_path.
Note though that we already have one special case, for enumeration values: Class.ENUM_VALUE.value will not be shortened to value (which wouldn't be cross-reference'able) but to ENUM_VALUE.value. We could consider doing the same thing for other kinds of objects. I suppose some_float here is a float? Not sure how hard it would be.
Or maybe attribute values should never be shortened! Or configured with a different setting than annotations_path.
I suppose some_float here is a float?
Yes, there's a reproducible example in the details of my issue.
This behavior is configurable with this setting: https://mkdocstrings.github.io/python/usage/configuration/signatures/#annotations_path.
I would think this would be a different setting (if it existed) thanannotations_path, since this is not about the type annotation of the argument, but the actual value of the instance attribute.
Or maybe attribute values should never be shortened!
I would not expect attribute values to be shortened (more than what is in the source document). If my __init__ had from pathlib import Path and takes a some_path: pathlib.Path() parameter instead, and set e.g. self.resolved_path = some_path.resolve(), then I would expect the type annotation to show Path and the attribute value to be some_path.resolve(), not resolve().
Yeah, I agree that would be more sensible. And that would even allow us to get rid of the special casing for enum values.
I guess it could follow the value of annotations_path, but only shorten objects paths, not method and attribute paths.
import module.submodule
class SomeClass:
def __init__(self, value: module.submodule.SomeType):
self.parsed_value = module.submodule.module_instance.method(value)
In this case, the type annotation will be shortened (or not) based on annotations_path, but so could parsed_value, e.g. module_instance.method(value) for brief and module.submodule.module_instance.method(value) for full.
So basically removing all parts that are modules. I can imagine a few edge cases where users would still want to show the module parts because otherwise the rest would be ambiguous (several different modules providing a function with the same name for example). The safest bet here is to render what's in the source. Any other "smart" shortening would feel a bit arbitrary IMO.
I'll review existing docs to see how this setting is used, and how it affects attributes rendering, and whether we can easily change it without breaking use-cases.