Skip to content

resolve_types doesn't resolve types in our methods #733

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

Closed
hynek opened this issue Dec 13, 2020 · 10 comments
Closed

resolve_types doesn't resolve types in our methods #733

hynek opened this issue Dec 13, 2020 · 10 comments
Labels
Typing Typing/stub/Mypy/PyRight related bugs.

Comments

@hynek
Copy link
Member

hynek commented Dec 13, 2020

While working on #716 I noticed an inconsistency: the type annotations of our methods (notably __attrs__) aren't resolved. It's especially jarring, if a type was passed via the type= parameter because then some are resolved and some aren't.

I think we should fix this, what do y'all (especially @ambv & @euresti) think?

@hynek hynek added the Typing Typing/stub/Mypy/PyRight related bugs. label Dec 13, 2020
@euresti
Copy link
Contributor

euresti commented Dec 13, 2020

I guess you're suggesting adding to attr.resolve_types? That should be possible.

@hynek
Copy link
Member Author

hynek commented Dec 13, 2020

Yes, and (mainly) asking if it makes sense or whether I'm missing something.

@euresti
Copy link
Contributor

euresti commented Dec 13, 2020

Actually now that I think about it more. I don't think we need to do this. This is what type.get_type_hints is for. And it's what PEP 563 says to use.

Oh. Now I see you mention __attrs__ specifically. Though I can't seem to find this method in the codebase. What did you mean?

@hynek
Copy link
Member Author

hynek commented Dec 13, 2020

Eh I meant __init__ – sorry!

@euresti
Copy link
Contributor

euresti commented Dec 13, 2020

Does typing.get_type_hints(A.__init__) work for this purpose?

@hynek
Copy link
Member Author

hynek commented Dec 14, 2020

I think it should, but looks like we're breaking something. :( This is from my attempt to fix test_annotations for Python 3.10:

__________________________________________________________ TestAnnotations.test_typing_annotations ___________________________________________________________

self = <tests.test_annotations.TestAnnotations object at 0x10d52f520>

    def test_typing_annotations(self):
        """
        Sets the `Attribute.type` attr from typing annotations.
        """

        @attr.s
        class C:
            x: typing.List[int] = attr.ib()
            y = attr.ib(type=typing.Optional[str])

        attr.resolve_types(C)

        assert typing.List[int] is attr.fields(C).x.type
        assert typing.Optional[str] is attr.fields(C).y.type
>       assert typing.get_type_hints(C.__init__) == {
            "x": typing.List[int],
            "y": typing.Optional[str],
            "return": type(None),
        }

tests/test_annotations.py:74:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
../../.asdf/installs/python/3.10-dev/Python.framework/Versions/3.10/lib/python3.10/typing.py:1491: in get_type_hints
    value = _eval_type(value, globalns, localns)
../../.asdf/installs/python/3.10-dev/Python.framework/Versions/3.10/lib/python3.10/typing.py:279: in _eval_type
    return t._evaluate(globalns, localns, recursive_guard)
../../.asdf/installs/python/3.10-dev/Python.framework/Versions/3.10/lib/python3.10/typing.py:557: in _evaluate
    eval(self.__forward_code__, globalns, localns),
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

>   ???
E   NameError: name 'typing' is not defined

<string>:1: NameError
================================================================== short test summary info ===================================================================
FAILED tests/test_annotations.py::TestAnnotations::test_typing_annotations - NameError: name 'typing' is not defined

How bad did I screw up? 😬

@euresti
Copy link
Contributor

euresti commented Dec 14, 2020

Oh right. I remember seeing this problem before.
When you do typing.get_type_hints(C) get_type_hints will look in the entire module automatically.
https://github.com/python/cpython/blob/master/Lib/typing.py#L1454

But when you pass in a method it doesn't do that. So you have to specify the globalns yourself.

        assert typing.get_type_hints(C.__init__, globalns=sys.modules[C.__module__].__dict__) == {
            "x": typing.List[int],
            "y": typing.Optional[str],
            "return": type(None),
        }

or more succintly:

        assert typing.get_type_hints(C.__init__, globalns=globals()) == {
            "x": typing.List[int],
            "y": typing.Optional[str],
            "return": type(None),
        }

@euresti
Copy link
Contributor

euresti commented Dec 14, 2020

Ah ha!. This is #593

@hynek
Copy link
Member Author

hynek commented Dec 14, 2020

That was my big fear. 😭

@hynek
Copy link
Member Author

hynek commented Dec 21, 2020

Closing now, guess we'll have to tackle #593. 😬

@hynek hynek closed this as completed Dec 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Typing Typing/stub/Mypy/PyRight related bugs.
Projects
None yet
Development

No branches or pull requests

2 participants