← Back to context

Comment by eqvinox

16 hours ago

> You can take a look yourself if you think some of them are wrong: https://github.com/python/typeshed/tree/main/stdlib/asyncio

Hmm. Presumably mypy and pyrefly use the same ones, but then I don't understand why pyrefly is complaining and mypy isn't:

  ERROR Argument `Future[list[BaseException | Any]]` is not assignable to parameter `future` with type `Awaitable[tuple[Any]]` in function `asyncio.events.AbstractEventLoop.run_until_complete` [bad-argument-type]
     --> xxx/xxx.py:513:33
      |
  513 |         loop.run_until_complete(tasks.gather(*x, return_exceptions=True))
      |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The definition in typeshed is this:

  def run_until_complete(self, future: _AwaitableLike[_T]) -> _T: ...

…where is it even puling "tuple[Any]" from…

(tbh this is rather insignificant compared to the noise from external packages without type annotations, or with incomplete ones… pyrefly's inferences at the existence of attributes and their types are extremely conservative…)

> Hmm. Presumably mypy and pyrefly use the same ones, but then I don't understand why pyrefly is complaining and mypy isn't:

> …where is it even puling "tuple[Any]" from…

Perhaps it's a bug in pyrefly, perhaps mypy or pyrefly is able to infer something about the types that the other isn't. I would strongly suggest checking their issues page, and if not seeing a report already report it yourself.

While there is an ongoing push to more consistently document the typing spec: https://typing.python.org/. It does not actually cover all the things you can infer from type hints, and different type hint checkers have decided to take different design choices compared to mypy and will produce different errors even in the most ideal situation.

This is one of the reasons why I am waiting for these libraries to mature a little more.

  • > it does not actually cover what rules you can check or infer from type hints

    Indeed this is the cause of maybe 30% of the warnings I'm seeing… items being added to lists or dicts in some place (or something else making it infer a container type), and pyrefly then refusing other types getting added elsewhere. The most "egregious" one I saw was:

      def something(x: list[str]) -> str:
          foo = []
          for i in x:
              foo.append(i)
          return "".join(foo)
    

    Where it complains:

      ERROR Argument `str` is not assignable to parameter `object` with type `LiteralString` in function `list.append` [bad-argument-type]
       --> test.py:4:20
      4 |         foo.append(i)
    

    Edit: now that I have posted it, this might actually be a bug in the .join type annotation… or something

    Edit: nah, it's the loop (and the LiteralString variant of .join is just the first overload listed in the type hints)… https://github.com/facebook/pyrefly/issues/1107 - this is kinda important, I don't think I can use it before this is improved :/

    • I assume in your example if you update the foo declaration to the following it solves the complaint:

          foo: list[str] = []
      

      If so this a type checking design choice:

        * What can I infer from an empty collection declaration?
        * What do I allow further down the code to update inferences further up the code?
      

      I don't know Pyrefly's philosophy here, but I assume it's guided by opinionated coding guidelines inside Meta, not what is perhaps the easiest for users to understand.

      3 replies →