tox-dev / sphinx-autodoc-typehints

Type hints support for the Sphinx autodoc extension
MIT License
562 stars 106 forks source link

Using Type Aliases #132

Open yasserfarouk opened 4 years ago

yasserfarouk commented 4 years ago

I have a type alias defined using NewType:

OutcomeUtilityMapping = NewType(
    "OutcomeUtilityMapping",
    Union[
        Callable[[Union["Outcome", int, str, float]], "UtilityValue"],
        Mapping[Union[Sequence, Mapping, int, str, float], "UtilityValue"],
    ],
)

Now one of my parameters uses this type:

mapping: OutcomeUtilityMapping

the problem is that the type gets unrolled to something like

mapping (NewType()(OutcomeUtilityMapping, Union[Callable[[Union[ForwardRef, int, str, float]], ForwardRef], Mapping[Union[Sequence, Mapping, int, str, float], ForwardRef]]))

which is unhelpful.

A tip for handling this is to rely on the new annotations using:

from __future__ import annotations
import typing
typing.get_type_hints = lambda obj, *unused: obj

in conf.py but this fails for autodoc-typehints with an error: AttributeError: '_SpecialForm' object has no attribute 'items'

I know that this should have been resolved in #64 but it seems that I am still having the same issue.

agronholm commented 4 years ago

What is it that you expect the output to be then?

arabello commented 4 years ago

Hi, related question: is there a way to reduce the verbosity of NewType output?

For example: Image instead of NewType()(Image, ndarray)

agronholm commented 4 years ago

Hi, related question: is there a way to reduce the verbosity of NewType output?

For example: Image instead of NewType()(Image, ndarray)

What would tell your users that it's a subtype of ndarray then?

agronholm commented 4 years ago

@yasserfarouk by the way, you're using NewType incorrectly. The second argument should be an actual class, not an annotation. If you want to make a type alias, just do:

OutcomeUtilityMapping = Union[
    Callable[[Union["Outcome", int, str, float]], "UtilityValue"],
    Mapping[Union[Sequence, Mapping, int, str, float], "UtilityValue"],
]

The reason behind this is that OutcomeUtilityMapping is now a function that will pass the arguments to its second argument which is the Union here, and that won't work. Mypy will give you an error like Argument 2 to NewType(...) must be subclassable (...) when you try something like this.

krassowski commented 4 years ago

@yasserfarouk you might be interested in this workaround: https://github.com/pandas-dev/pandas/issues/33025#issuecomment-699636759

aaugustin commented 3 years ago

For example: Image instead of NewType()(Image, ndarray)

I would expect sphinx_autodoc_typehints to render this source:

:obj:`full.path.to.Image`

which would then link to the documentation of the Image type.

With from __future__ import annotations, sphinx.ext.autodoc manages to extract required info, but I'm not sure how exactly.

0x0L commented 3 years ago

See https://github.com/0x0L/typehints-test

When the sphinx_autodoc_typehints extension is added both the alias and the link are lost

gaborbernat commented 2 years ago

I don't we can support type aliases in form of simple assignments, as we don't know if something is an alias or not, that information is lost at runtime. The path forward will be those projects to switch to using to explicit type alias via https://www.python.org/dev/peps/pep-0613/ and that would be handled well.

antonagestam commented 1 year ago

@gaborbernat Is support for TypeAlias tracked somewhere else?

gaborbernat commented 1 year ago

I don't think so, but PR welcome to add support for it.

LecrisUT commented 1 day ago

Could this issue be re-opened and tracked as a PEP613 support? #284 is not an ideal workaround because it requires too much manual tracking, and on the other hand, sphinx already supports the PEP613. There are still benefits of having the support here: