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

[tracker] Improvement of autodoc_type_aliases #11687

Open
2 tasks
picnixz opened this issue Sep 20, 2023 · 0 comments
Open
2 tasks

[tracker] Improvement of autodoc_type_aliases #11687

picnixz opened this issue Sep 20, 2023 · 0 comments
Labels

Comments

@picnixz
Copy link
Member

picnixz commented Sep 20, 2023

This is a follow-up of my #11652 (comment) concerning autodoc_type_aliases and its usage.

Currently, autodoc_type_aliases is a mapping of type aliases that maps a type name to the full-qualified object name. It is typically useful when forward references arising from from __future__ import annotations are present.

In 7.2.x, later reverted in 7.2.6, we tried to import modules with TYPE_CHECKING set to True, but this introduced multiple issues, in addition to not being entirely in line with PEP 484, which says:

For such situations the typing module defines a constant, TYPE_CHECKING, that is considered True during type checking (or other static analysis) but False at runtime

In particular, Sphinx, which is not a static analysis tool, should not set TYPE_CHECKING explicitly to True since unexpected behaviours may occur (as we could see in #11652 and #11662).

When Sphinx does not find a reference to some type in a file, it will complain; using autodoc_type_aliases is a way to solve it. However, there are many cases which fall in the following situations:

  • It is a typing.* or collections.abc.* type, e.g.:

    from __future__ import annotations
    from typing import TYPE_CHECKING
    
    if TYPE_CHECKING:
        from collections.abc import Sequence
    
    def foo(n) -> Sequence[int]:
        return list(range(n))
  • It is the "same" nominal types being type-checked but this is only specific for the module itself, namely:

    # a/user.py
    class User: 
        pass
    # b/user.py
    class User: 
        pass
    # handle_user_a.py
    from __future__ import annotations
    from typing import TYPE_CHECKING
    
    if TYPE_CHECKING:
        from a.user import User
    
    def handle(user: User) -> None: ...
    # handle_user_b.py
    from __future__ import annotations
    from typing import TYPE_CHECKING
    
    if TYPE_CHECKING:
        from b.user import User
    
    def handle(user: User) -> None: ...

    In this case, we cannot really use autodoc_type_aliases = {'User': ...} since we need a.user.User and b.user.User at the same time.

As such, I suggest the following:

  • Sphinx should provide "built-in" sets of aliases, namely one set containing all aliases with typing.* and another one for collections.abc.* ones. More precisely, we could write something like:

    # conf.py
    autodoc_type_aliases_presets = ['typing']
    # or: autodoc_type_aliases_presets = ['typing', 'collections.abc']
    # or: autodoc_type_aliases_presets = ['collections.abc']
  • In addition, we should be able to specify the "scope" of the alias. For instance, we could write:

    # conf.py
    autodoc_type_aliases = {
      'User': ('common.user.User', {
          'handle_user_a': 'a.user.User',
          'handle_user_b': 'b.user.User'
      })
    } 

    This means: "when you document module handle_user_a (resp. handle_user_b), map User to a.user.User (resp. b.user.User). For the other modules, use common.user.User. We could also assume that

    # conf.py
    autodoc_type_aliases = {
      'User': {
          'handle_user_a': 'a.user.User',
          'handle_user_b': 'b.user.User'
      }
    } 

    means "do not user aliases for other modules", or we could use 'User': ({...},) (or 'User': (None, {...})). For now, the syntax is still subject to change.

    Technically speaking, we could even be more specific about its scope and allow an event handler instead which would only change the type alias that was deduced (however, I don't have a clear idea on how to incorporate such event mechanism in the current flow).

Tasks

  • Update the autodoc_type_aliases syntax.
  • Implement presets for typing and collections.abc modules.
@picnixz picnixz changed the title Improvement of autodoc_type_aliases [tracker] Improvement of autodoc_type_aliases Sep 21, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant