Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Type alias definition not shown #224

Closed
joelberkeley-secondmind opened this issue Jun 27, 2020 · 12 comments
Closed

Type alias definition not shown #224

joelberkeley-secondmind opened this issue Jun 27, 2020 · 12 comments

Comments

@joelberkeley-secondmind
Copy link

joelberkeley-secondmind commented Jun 27, 2020

I like the way this library doesn't expand type aliases at usage site. It makes the docs more readable, conveys the meaning in the type alias names, and also works with docstrings that reference type aliases.

However, it only works if the aliases show their definition, otherwise users have to look at the source code to know what type a type alias actually refers to. I realise this may be difficult in Python, cos a type alias uses the same syntax as a variable (except where it also uses items from the typing module such as Union). In rust, for example, this would be easier cos it starts with the keyword type. Would sphinx need some kind of specific directive, akin to :param: e.g. :type: for this to be possible?

A similar problem occurs with TypeVar. Don't know if you want a separate ticket for that

@AWhetter
Copy link
Collaborator

AWhetter commented Jun 30, 2020

I don't quite understand the issue you're describing. At the moment, an attribute is documented like my_attr = ... unless it's a constant, in which case it looks like my_attr = 5. Are you saying that you have an attribute like T = typing.TypeVar('T'), that you want it to be documented like that rather than T = ...?

@joelberkeley-secondmind
Copy link
Author

joelberkeley-secondmind commented Jun 30, 2020

Yeah, and for type aliases, having

MyTypeAlias = Dict[str, float]
""" The type alias for float kwargs. """

appear like that in the docs as well as the source code, rather than

MyTypeAlias
The type alias for float kwargs.

@joelberkeley-secondmind
Copy link
Author

but as I say, I'm not sure how you'd do this without directives, because there are some aliases

Alias1 = int
Alias2 = MyCustomGenericClass[str]

where we can't assume they're type aliases

@joelberkeley-secondmind
Copy link
Author

this section of the mypy docs may be useful

@joelberkeley-secondmind
Copy link
Author

I should add that it gets more complicated when a public alias refers to a private one, like

_Foo = int
Bar = List[_Foo]

where it doesn't make sense to show List[_Foo] in the docs

@joelberkeley
Copy link

joelberkeley commented Nov 25, 2020

^^^ replying to my own message, I think the last message is not an issue. Having a private type alias as a generic parameter, as above, is to be avoided, as if the definition of Bar is to be public (which it needs to be if we're going to be able to make a Bar, and also if we put it in the docs), then it needs to be formed of public entities, which _Foo is not.

@Conchylicultor
Copy link

Conchylicultor commented Jan 7, 2022

+1 for this feature.

For example TensorFlow doc do it correctly. Here is the documentation for the type alias tfds.typing.JsonValue which show the source definition directly in the doc:

https://www.tensorflow.org/datasets/api_docs/python/tfds/typing/JsonValue

@etienneschalk
Copy link

+1 for this feature too, documenting Type Aliases can help a lot in modules that describes a bunch of types at their beginning, that are used in later functions and classes. Type Hinting is in itself a formalized way to document the code

🔎 Example of current behaviour

Example of code using both a traditional type alias (Keys), and type aliases using the new type keyword introduced in Python 3.12

# Do not use the type keyword, as values are used dynamically
# in the code too (not only the type declarations)
Keys = Literal["one", "two", "three", "four", "five", "six", "seven", "eight", "nine"]
type Mappings = dict[Literal["default", "reversed"], dict[Keys, str]]
type PuzzleInput = list[str]

Here is what the rendered autoapi doc looks like

Screenshot from 2024-02-25 10-52-30

Observation:

Hovering Keys in the code in an IDE such as VSCode would provide this tooltip:

(type alias) Keys: type[Literal['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine']]

Also, no link is provided to jump to the Keys definition:

Screenshot from 2024-02-25 10-55-35

🔥 What I would like

What would be perfect would to have, in the possible extent, the same experience as in an IDE when reading the doc:

  • being able to navigate from type to type
  • show tooltips (bonus, as navigation always fulfill this role, but tooltip can avoid a click for having a quick look at the contents of a simple type)

Details

For the recordshere are excerpts from my conf.py

extensions = [
    "sphinx.ext.coverage",
    "sphinx.ext.napoleon",
    "sphinx.ext.intersphinx",
    "sphinx.ext.autodoc",
    "autoapi.extension",
    # "sphinx.ext.autosummary",
    "nbsphinx",
    "myst_parser",
    # "sphinxemoji.sphinxemoji",
    # "sphinx_mdinclude",
    "sphinxcontrib.youtube",
    "sphinx_favicon",
]
autoapi_generate_api_docs = True
autoapi_dirs = ["../../advent_of_code"]
autoapi_type = "python"
# autoapi_keep_files = True
# autoapi_template_dir = "_autoapi_templates"
autoapi_options = [
    "members",
    "undoc-members",
    "show-inheritance",
    # "show-module-summary",  # does not look good
    "special-members",
    "imported-members",
]
autoapi_python_class_content = "class"
autoapi_member_order = "bysource"

autodoc_typehints = "signature"  # "description"
autodoc_typehints_format = "short"
# autodoc_typehints_format = "fully-qualified"
autodoc_inherit_docstrings = False
napoleon_google_docstring = False
napoleon_numpy_docstring = True
napoleon_use_param = False
napoleon_use_ivar = True
# Do not show fully qualified paths to classes and functions
add_module_names = False

# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {
    # Numpy seems broken
    "python": ("https://docs.python.org/3.12/", None),
    "numpy": ("https://numpy.org/doc/stable/", None),
    "xarray": ("https://xarray.pydata.org/en/stable/", None),
}

@joelberkeley
Copy link

note that when I wrote this, the type keyword was not available. I haven't looked at how that changes things, if at all

@AWhetter
Copy link
Collaborator

AWhetter commented Apr 2, 2024

AutoAPI isn't going to support implicit type alias definitions without contributions from someone else. Detection of implicit type aliases is too complex, and not very well defined as far as I can tell.
The value of the alias will be shown for explicit type aliases. That's assignments annotated with TypeAlias and PEP-695 type aliases.

@joelberkeley
Copy link

joelberkeley commented Apr 2, 2024

that seems like an overwhelmingly pragmatic approach, I approve (I'm OP with a different account)

@bzm3r
Copy link

bzm3r commented Sep 19, 2024

@AWhetter I'm finding that I can't get "type alias expansion" to occur if I use type Hello = str (PEP 695): https://stackoverflow.com/questions/79004521/are-type-hello-str-style-type-alias-definitions-pep-695-supported-in-any

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants