This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author xirdneh
Recipients xirdneh
Date 2021-02-18.18:53:09
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1613674389.7.0.662545627223.issue43257@roundup.psfhosted.org>
In-reply-to
Content
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

    @dataclass
    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)
History
Date User Action Args
2021-02-18 18:53:09xirdnehsetrecipients: + xirdneh
2021-02-18 18:53:09xirdnehsetmessageid: <1613674389.7.0.662545627223.issue43257@roundup.psfhosted.org>
2021-02-18 18:53:09xirdnehlinkissue43257 messages
2021-02-18 18:53:09xirdnehcreate