Skip to content

Traceback analysing asyncio "item = yield from queue.get()" #836

Closed

Description

@gjcarneiro

Analysing:

import asyncio

@asyncio.coroutine
def test(self):
    queue = asyncio.Queue(16384)
    sample = yield from queue.get()

Result:

  File "/home/gjc/projects/mollytest/env/lib/python3.4/site-packages/mypy/checker.py", line 1693, in visit_yield_from_expr
    if result_instance.type.fullname() == "asyncio.futures.Future":
AttributeError: 'AnyType' object has no attribute 'type'

Activity

  1. rockneurotiko commented on Aug 20, 2015

    @rockneurotiko
    Contributor

    That's probably because queue.get() should return a Future[T] or Future[Any], not Any.

  2. JukkaL commented on Aug 20, 2015

    @JukkaL
    Collaborator

    Thanks for reporting this! I was able to reproduce the issue.

  3. vitawasalreadytaken commented on Aug 21, 2015

    @vitawasalreadytaken
    Contributor

    I'm not familiar with mypy internals but I stepped through the analysis of this in pdb and found a couple of things:

    1. The function is dynamically typed (there's a flag in TypeChecker.dynamic_funcs) so local variables apparently default to type Any. Fix: def test_get(self) -> None:
    2. My Queue.get stub indeed has an incorrect return type as pointed out by @rockneurotiko. Fix: def get(self) -> Future[T]: ... in queues.pyi.
    3. Mypy does not infer that queue is of type asyncio.Queue from this line: queue = asyncio.Queue(16384) (it is just Any). No idea why, but this fixes it: queue = asyncio.Queue(16384) # type: asyncio.Queue.

    Only after all three fixes are applied the attribute error goes away.

    I'm submitting a PR with fixed Queue stubs (Queue.put also needs to return Future instead of None). By the way, analyzing

    @asyncio.coroutine
    def test_put(self) -> None:
        queue = asyncio.Queue(16384)
        yield from queue.put(123)

    does tell me that I need a type annotation for queue, unlike the get test which fails with the above AttributeError.

    q.py: note: In function "test_put":
    q.py:11: error: Need type annotation for variable
    q.py:12: error: Iterable function return type expected for "yield from"
    

    Again, it works if I explicitly add # type: asyncio.Queue. This baffles me because I expected mypy to detect the type automatically.

  4. nierob commented on Sep 10, 2015

    @nierob

    I think the problem is more generic:

    import asyncio
    import typing
    
    @asyncio.coroutine
    def foo(a):
       b = yield from a
       return b

    gives me:

    Traceback (most recent call last):
      File "/usr/local/bin/mypy", line 169, in <module>
        main()
      File "/usr/local/bin/mypy", line 34, in main
        type_check_only(path, module, bin_dir, options)
      File "/usr/local/bin/mypy", line 78, in type_check_only
        python_path=options.python_path)
      File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 164, in build
        result = manager.process(UnprocessedFile(info, program_text))
      File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 341, in process
        next.process()
      File "/usr/local/lib/python3.4/dist-packages/mypy/build.py", line 814, in process
        self.type_checker().visit_file(self.tree, self.tree.path)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 349, in visit_file
        self.accept(d)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 356, in accept
        typ = node.accept(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 363, in accept
        return visitor.visit_decorator(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 1661, in visit_decorator
        e.func.accept(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 332, in accept
        return visitor.visit_func_def(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 445, in visit_func_def
        self.check_func_item(defn, name=defn.name())
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 477, in check_func_item
        self.check_func_def(defn, typ, name)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 545, in check_func_def
        self.accept_in_frame(item.body)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 369, in accept_in_frame
        answer = self.accept(node, type_context)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 356, in accept
        typ = node.accept(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 504, in accept
        return visitor.visit_block(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 934, in visit_block
        self.accept(s)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 356, in accept
        typ = node.accept(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 543, in accept
        return visitor.visit_assignment_stmt(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 943, in visit_assignment_stmt
        self.check_assignment(s.lvalues[-1], s.rvalue, s.type == None)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 971, in check_assignment
        self.infer_variable_type(inferred, lvalue, self.accept(rvalue),
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 356, in accept
        typ = node.accept(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/nodes.py", line 947, in accept
        return visitor.visit_yield_from_expr(self)
      File "/usr/local/lib/python3.4/dist-packages/mypy/checker.py", line 1708, in visit_yield_from_expr
        if result_instance.type.fullname() == "asyncio.futures.Future":
    AttributeError: 'AnyType' object has no attribute 'type'
    
  5. added a commit that references this issue on Sep 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugmypy got something wrong

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions