Hacker News new | ask | show | jobs
by ipsum2 3142 days ago
For any dropboxers (or others), how does this compare with pytype? https://github.com/google/pytype.
3 comments

(I worked on an early version of PyAnnotate.)

The main difference is that pytype is a static analyzer (i.e. it inspects the code and tries to figure out what types various things are), whereas PyAnnotate is a profiler hook, so you have to run your code and it observes types as your code runs.

Both have their pros and cons. While static analysis (in my personal opinion) would be ideal because you don't have to run your code, and in theory it can be much more complete, it's also much harder (often impossible) in Python. The runtime analysis of PyAnnotate has a lot of downsides (it doesn't give you types for code that it didn't observe run and it can't know if it has seen all the particular types for a parameter or return). The upside is that it was quick to implement something useful and it gets you quickly to pretty descent type annotations for your main code paths. Which is nice, because in a large untyped codebase it effectively lays down a rough draft of type annotations, making it a lot easier to fix up and fill in edge cases by hand.

There was a thing called PySonar by Yin Wang. It's sort of gone now but you can still find copies around the net.
(work for Google and uses pytype daily)

Pytype is similar to mypy that it can do type checking with proper annotations. In addition to use annotations, pytype can also do inference based on static analysis.

I don't have much experience with mypy but the last time I used it, it cannot infer from `return x == y` that the function returns a bool. Pytype can correctly infer many simple forms of function argument types and return type, and even some more complex form.

From reading the project, PyAnnotate completely rely on runtime profiling info to _help_ you get to the first round of annotations. We also have similar project that gathers types from runtime and help people to annotate the code. The type information gathered this way has its limitations (PyAnnotate project called this out as well, that you should only use it on legacy code but not on newly written code).

To give an example: if PyAnnotate observe a function below to accept a list of ints and returns an int, it may conclude that the type of this function is `Callable[[List[int]], int]`

``` def foo(xs): ret = 0 for x in xs: ret += x return ret ```

But it can actually work on any iterable (because of the for-in loop), and the item in `xs` is number (because the `__iadd__` call on integer 0). With static analysis, the correct inferred type might be `Callable[[Iterable[Union[int, float]]], Union[int, float]]`

It's not possible to infer that the result `return x == y` is a bool, because python has rich comparisons (e.g. if x an y are numpy arrays you'll get an array of the same shape (after broadcasting) back). So either pytype uses additional information, or it's sometimes just wrong.
Technically true, since you'll need to check the return type of `__eq__()`. But the following code doesn't trigger any error using `mypy test.py --check-untyped-defs`.

  def foo():
    x = 1
    return x == 2


  def bar(x: bool):
    print(x)


  def baz(x: int):
    print(x)


  if __name__ == '__main__':
    bar(foo())
    baz(foo())
I think another good example of "observed types are not necessarily the intended types" is a Text parameter (unicode in python2, str in python3). The actual intent might be Iterable[Text].
Well at first glance, much better documentation :)

I just tried pytype and it basically did nothing but spit out some errors about imports not found. I didn't have time to try to investigate further and the documentation seems to be almost non-existent. Surprising with 1780 commits to the project.