[New-bugs-announce] [issue43257] get_type_hints evaluates class variables before type hints

Josue Balandrano Coronel report at bugs.python.org
Thu Feb 18 13:53:09 EST 2021

New submission from Josue Balandrano Coronel <jbc at rmcomplexity.com>:

Using typing.get_type_hints() on classes returns the wrong value when a class variable has the same name as a type and a default value.

For instance:

    from dataclasses import dataclass
    from typing import get_type_hints

    class DataClassHints:
        str: str="asdf"

    >>> get_type_hints(DataClassHints)
    ... NameError: name 'asdf' is not defined

Looks like get_type_hints() is using "asdf" as a type.
This is more clear if we use something like datetime:

    from datetime import datetime

    class ClassHints:
        datetime: datetime=datetime.now()

    >>> get_type_hints(ClassHints)
    ... {'datetime': datetime.datetime(2021, 2, 18, 12, 40, 16, 966502)

If we do the same thing in a method get_type_hints works correctly:

    class CorrectHints:
        def __init__(self, str: str="asdf", datetime: datetime=datetime.now()):
            self.str = str
            self.datetime = datetime

    >>> ch = CorrectHints()
    >>> ch.str
    ... 'asdf'

    >>> ch.datetime
    ... datetime.datetime(2021, 2, 18, 12, 41, 46, 214844)

    >>> get_type_hints(CorrectHints.__init__)
    ... {'str': str, 'datetime': datetime.datetime}

Also functions work correctly:
    def func_type_hints(str: str="asdf", datetime: datetime=datetime.now()):
        return f"str: {str}, datetime: {datetime}"

    >>> func_type_hints()
    ... 'str: asdf, datetime: 2021-02-18 12:44:21.102933'

    >>> get_type_hints(func_type_hints)
    ... {'str': str, 'datetime': datetime.datetime}

It looks like get_type_hints is evaluating the default value in a class variable before the type hint.
Here's another way to replicate this issue to make it clearer:

    class EvalOrderHints:
        datetime = datetime.now()
        datetime: datetime

    >>> get_type_hints(EvalOrderHints)
    ... {'datetime': datetime.datetime(2021, 2, 18, 12, 47, 56, 608261)}

    >>> EvalOrderHints().datetime
    ... datetime.datetime(2021, 2, 18, 12, 47, 56, 608261)

messages: 387266
nosy: xirdneh
priority: normal
severity: normal
status: open
title: get_type_hints evaluates class variables before type hints
type: behavior
versions: Python 3.8, Python 3.9

Python tracker <report at bugs.python.org>

More information about the New-bugs-announce mailing list