GithubHelp home page GithubHelp logo

facebook / pyre-check Goto Github PK

View Code? Open in Web Editor NEW
6.7K 112.0 425.0 115.36 MB

Performant type-checking for python.

Home Page: https://pyre-check.org/

License: MIT License

Makefile 0.01% OCaml 62.65% C 4.68% Python 32.60% Shell 0.03% TypeScript 0.02%
python typechecker type-check static-analysis ocaml code-quality abstract-interpretation security program-analysis taint-analysis

pyre-check's Issues

Not installing on macOS Sierra

macOS Sierra 10.12.6
using python's installed with brew:

❯ pip3 install pyre-check
Collecting pyre-check
  Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check

❯ pip3.6 install pyre-check
Collecting pyre-check
  Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check

❯ pip2 install pyre-check
Collecting pyre-check
  Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

❯ ll $(which pip3)
lrwxr-xr-x  1 leigh.schrandt  admin    31B Apr 22 00:29 /usr/local/bin/pip3 -> ../Cellar/python/3.6.5/bin/pip3

❯ ll $(which pip2)
lrwxr-xr-x  1 leigh.schrandt  admin    36B Apr 23 15:47 /usr/local/bin/pip2 -> ../Cellar/python@2/2.7.14_3/bin/pip2

similar to #5

No documentation for .pyre_configuration

The documentation shows pyre init generates a .pyre_configuration, but there is no information on how to set the values, or what configs exist.

For example, I don't know how to exclude a particular directory, and by default pyre recursively checks a virtualenv in my project root, spitting out a ton of errors in standard libraries. For example

venv/lib/python3.6/site-packages/pip/_internal/configuration.py:212:12 Undefined name [18]: Global name `pip` is undefined.

Configuration Options

My company already has a largely type checked code base and requires all new modules to type-check,
so we'd like to require pyre-strict on all new modules/existing code
There is some legacy code that doesn't type-check and it would be nice to be able to configure that on a per-file basis.

Is there a way to do this currently and if not would this be something appropriate for this project?

Is there any chance of type-checking Python 2 code?

PEP 484 defines an optional syntax for supporting type annotations for Python 2 code, and PEP 526 also refers to support for Python 2 by way of stub files.

Is there any chance that Pyre will support type-checking Python 2-compatible code?

If not, it would be good to more explicitly document the supported versions of Python on the web site or in the documentation.

Fails basic typing.List[x] check

src/foo.py:

#!/usr/bin/env python3
from typing import List

def f(s: str) -> List[int]:
    return [ch for ch in s]

assert f("foo") == ["f", "o", "o"]

The code should fail typechecking, since f returns a List[str] but is annotated as returning List[int].

Output from pyre and mypy respectively:

$ pyre check
    No type errors found
$ mypy src
src/foo.py:4: error: List comprehension has incompatible type List[str]; expected List[int]

Incremental mode not detecting changes

Hi,

I am trying out pyre, but the incremental mode does not seem to be detecting changes after the first run.

Here is the sample file I am using

# my_lib/sample.py

class Foo:
    def __init__(self) -> None:
        self.prop_ = "bar"


class Bar:
    def __init__(self, foo: Foo) -> None:
        self.prop = "hello " + foo.prop

When I run pyre the first time, I get the error as expected, but even if I update the file, the server seems to using the old state of the file.

$ pyre
 ƛ Server not running at `.`. Starting...
 ƛ Server initializing...
 ƛ Found 1 type error!
my_lib/sample.py:8:31 Undefined attribute [16]: `Foo` has no attribute `prop`.
$ sed -i -e 's/foo\.prop/foo.prop_/' my_lib/sample.py 
$ pyre
 ƛ Waiting for server...
 ƛ Found 1 type error!
my_lib/sample.py:8:31 Undefined attribute [16]: `Foo` has no attribute `prop`.
$ pyre check
 ƛ No type errors found

Restarting the server or using check works, but I could not find a way to use the incremental mode yet.

Any idea?

Thanks.

Environment

$ cat .pyre_configuration
{
  "binary": "/home/daniel/.asdf/installs/python/3.6.2/bin/pyre.bin",
  "source_directories": [
    "."
  ],
  "typeshed": "/home/daniel/.asdf/installs/python/3.6.2/lib/pyre_check/typeshed/stdlib/"
}
$ uname -r
4.16.8-1-ARCH
$ sysctl fs.inotify
fs.inotify.max_queued_events = 16384
fs.inotify.max_user_instances = 128
fs.inotify.max_user_watches = 100000
$ lsof | grep inotify | wc -l
1468

Variable annotation with None doesn't warn

❯ pyre check
 ƛ Found 1 type error!
test.py:5:4 Incompatible return type [7]: Expected `str` but got `None`.
❯ cat test.py
a: int = None


def foobar() -> str:
    return None

Why is a:int = None valid?

Not installing on windows

(venv) C:\progr\py3\pyre>pip3 install pyre-check
Collecting pyre-check
  Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check

Add document that supports 3.6+ only at the moment?

Just so interested as the news pop up, I tried to install pyre-check immediately , but on the first run, it shows up a weird error on syntax error and after a while searching, I found out this only supports 3.6+ at the moment - when my version is 3.5.
Maybe should add one line or two on README that pyre only support 3.6+ for now? That would definitely helpful for newcomers.

Btw, I'm installing Python 3.6 to test it out,
Thanks for the great tool!

How to check an extensionless python file?

My project has an executable script that has no extension, it just has #!/usr/bin/env python3 at the top.
Currently pyre provides no way to check it. It would be great if it could do one of:

  • autodetect python scripts with a shebang and check them
  • allow hand-specifying a filename to check on the cli instead of / as well as a source directory
  • some other solution I have yet to think of.

No type err when expected!

This code clearly has a type error (and fails at runtime: TypeError: unsupported operand type(s) for ** or pow(): 'str' and 'str'):

def foo(x : int) -> str:
    return str(x ** x)

x = foo('hi')

running pyre check, however, returns No type errors found ... Not sure how to find my pyre version ... I just installed it via pip 10.0.1 with Python 3.6.5. I get the same error when x isn't used within foo, which was the original code (which, of course, doesn't actually fail because x isn't used) that I was trying with pyre:

def foo(x : int) -> str:
    return 'hi'

x = foo('hi')

Invalid result on a simple program

Here's a program that throws a type error when there is not one (AFAICS?):

import boto3


def bug() -> str:
    boto3
    return "bananas"

Throws:

$ pyre restart
 ƛ No server running
 ƛ Server not running at `.`. Starting...
 ƛ Server initializing...
 ƛ No servers running
 ƛ Found 1 type error!
bug.py:5:4 Undefined name [18]: Global name `boto3` is undefined.

boto3 is clearly not undefined.

Unable to run pyre after pip install

I pip installed pyre onto a virtual environment my Ubuntu 16.04 machine and attempting to run the pyre command is immediately met with a syntax error. Error message below

Traceback (most recent call last):
  File "/home/emilior/Desktop/showdown/dev_work/env/bin/pyre", line 7, in <module>
    from pyre_check.pyre import main
  File "/home/emilior/Desktop/showdown/dev_work/env/lib/python3.5/site-packages/pyre_check/__init__.py", line 22, in <module>
    from . import buck
  File "/home/emilior/Desktop/showdown/dev_work/env/lib/python3.5/site-packages/pyre_check/buck.py", line 11, in <module>
    from . import log
  File "/home/emilior/Desktop/showdown/dev_work/env/lib/python3.5/site-packages/pyre_check/log.py", line 64
    _terminate: bool = False

Pyre vs mypy

Hi, this tool looks promising but I am puzzled to see no references or comparisons to https://github.com/python/mypy. Could you share your reasons for developing a new typechecker instead of contributing to mypy?

How to indicate [this type] or None

It is very common for functions to return a type or None. In typescript you can say string | null and the checker will warn you where you forgot to defend against potential null instances. How do you indicate that something may be a type or None ?

Type definition repository

Are there any plans for a type definition repository, like http://definitelytyped.org/ for TypeScript? This would likely improve community adoption dramatically.

Currently the documentation says that stubs can be added via a *.pyi file in the same folder as the source. A different mechanism may be needed for handling libraries (e.g. for TypeScript you can add a library with npm install --save leaflet and then import the types with npm install --save @types/leaflet).

"Undefined name" on using `six`, which is in typeshed

Trying to run Pyre on Zulip, I get the following errors (among many others):

zthumbor/loaders/helpers.py:64:11 Undefined name [18]: Global name `six` is undefined.
zthumbor/loaders/helpers.py:64:20 Undefined name [18]: Global name `six` is undefined.
zthumbor/loaders/helpers.py:70:11 Undefined name [18]: Global name `six` is undefined.
zthumbor/loaders/helpers.py:70:20 Undefined name [18]: Global name `six` is undefined.

This puzzles me because six is in typeshed -- which Pyre is supposed to refer to, right? In fact, here's the relevant import line:

from six.moves.urllib.parse import urlparse, parse_qs

and indeed that module, and those names within it, are there in typeshed.

I don't have any good ideas for what's going wrong in this instance. If there isn't an obvious (to you as the Pyre developers) thing that this could be, I can try refining out a minimal repro case.

Leftover tail processes

After running and killing pyre a few times it appears I'm left with processes tailing server.stdout. Is this expected?

Ians-MacBook-Air:pymuscle iandanforth$ pyre
 ƛ Server not running at `.`. Starting...
 ƛ Server initializing...
 ƛ Found 1 type error!
foo.py:2:4 Incompatible return type [7]: Expected `int` but got `float`.
Ians-MacBook-Air:pymuscle iandanforth$ pyre stop
 ƛ No servers running
 ƛ No server running
Ians-MacBook-Air:pymuscle iandanforth$ pyre kill
 ƛ No server running
Ians-MacBook-Air:pymuscle iandanforth$ ps aux | grep pyre
iandanforth      78480   0.0  0.0  4267744    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78460   0.0  0.0  4276960    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78439   0.0  0.0  4268768    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78389   0.0  0.0  4276960    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78348   0.0  0.0  4267744    416   ??  S    12:27PM   0:00.01 tail -f ./.pyre/server/server.stdout
iandanforth      80211   0.0  0.0  4267752    672 s000  R+   12:37PM   0:00.01 grep pyre
iandanforth      80145   0.0  0.0  4275936    452 s000  S    12:37PM   0:00.01 tail -f ./.pyre/server/server.stdout
iandanforth      79700   0.0  0.0  4267744    452   ??  S    12:35PM   0:00.01 tail -f ./.pyre/server/server.stdout
iandanforth      79053   0.0  0.0  4268768    416   ??  S    12:31PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78988   0.0  0.0  4275936    416   ??  S    12:30PM   0:00.01 tail -f ./.pyre/server/server.stdout
iandanforth      78624   0.0  0.0  4267744    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78585   0.0  0.0  4276960    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78567   0.0  0.0  4268768    416   ??  S    12:28PM   0:00.01 tail -f ./.pyre/server/server.stdout
iandanforth      78549   0.0  0.0  4277984    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78531   0.0  0.0  4267744    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout
iandanforth      78510   0.0  0.0  4267744    416   ??  S    12:28PM   0:00.00 tail -f ./.pyre/server/server.stdout

strict mode: Spurious 'Too many arguments' errors

python: 3.5.2, 3.6.5
pyre: 0.0.7 (from pip list)
typeshed: python/typeshed@226f055

Note: I'm not sure whether this is an expected consequence of # pyre-strict, though it doesn't seem to match any of the documented differences from strict mode.

Given:

# pyre-strict

import pathlib
from typing import NamedTuple

# Also reproduces with class style syntax under Python 3.6
Complex = NamedTuple('Complex', (
    ('real', float),
    ('imaginary', float),
))

pathlib.Path('.')

Complex(4, 2)

Then pyre emits:

$ pyre --typeshed /path/to/typeshed/ check
 ƛ Found 2 type errors!
args.py:12:0 Too many arguments [19]: Call `pathlib.Path.__init__` expects 1 positional argument, 2 were provided.
args.py:14:0 Too many arguments [19]: Call `args.Complex.__init__` expects 1 positional argument, 3 were provided.

I'm guessing that this happens because neither pathlib.Path nor the generated NamedTuple class define an __init__ method, meaning that pyre finds the definition on object.

False positive error on `return` in generator

If you use return in a generator, an incorrect TypeError is generated:

$ cat srcdir/genreturn.py 
from typing import Iterable

def gen(x: int) -> Iterable[int]:
    for i in range(x):
        if i > 10:
            return
        else:
            yield i
$ pyre --source-directory srcdir/ check
 ƛ Setting up a .pyre_configuration file may reduce overhead.
 ƛ Found 1 type error!
srcdir/genreturn.py:6:12 Incompatible return type [7]: Expected `Iterable[int]` but got `None`.
$ python --version
Python 3.7.0b4
$ pip freeze | grep pyre  # related minor bug: "pyre --version" throws a TypeError
pyre-check==0.0.5

Add documentation for configuration

I looked through the website and in the repo, but I didn't find a list of configuration options for the .pyre_configuration directory. The getting started guide mentions setting some config settings after running pyre init, but I can't see to find anything other than that.

Global name is undefined.

I just tried out Pyre on a work-in-progress library, and I'm getting a "global name is undefined" error. The global name in question is the top-level namespace of the library. I installed the library into my virtual environment with pip install -e and am running Python 3.6.5.

bob@localhost:~/code/play/foo|⇒  git clone [email protected]:madedotcom/photon-pump.git
Cloning into 'photon-pump'...
</snip>

bob@localhost:~/code/play/foo|⇒  pip install -r photon-pump/requirements.txt 
Collecting aiodns>=1.1.1 (from -r photon-pump/requirements.txt (line 1))
</snip>

bob@localhost:~/code/play/foo|⇒  pip install -r photon-pump/requirements-test.txt 
Collecting aioresponses (from -r photon-pump/requirements-test.txt (line 1))
</snip>

bob@localhost:~/code/play/foo|⇒  cd photon-pump 
bob@localhost:~/code/play/foo/photon-pump|master 
⇒  pip install -e .
Obtaining file:///home/bob/code/play/foo/photon-pump
</snip>
Installing collected packages: photon-pump
  Running setup.py develop for photon-pump
Successfully installed photon-pump

bob@localhost:~/code/play/foo/photon-pump|master 
⇒  pip install pyre-check
Collecting pyre-check
  Using cached https://files.pythonhosted.org/packages/e4/96/72a7048e5f340678c6eb48163b7bdc49926cdac2dff8bb5d935563e50b7f/pyre_check-0.0.5-py3-none-manylinux1_x86_64.whl
Installing collected packages: pyre-check
Successfully installed pyre-check-0.0.5


bob@localhost:~/code/play/foo/photon-pump|master 
⇒  pyre --source-directory photonpump check
 ƛ Setting up a .pyre_configuration file may reduce overhead.
 ƛ Found 35 type errors!
photonpump/conversations.py:93:35 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:94:47 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:95:37 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:97:20 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:99:37 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:107:16 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:290:64 Incompatible parameter type [6]: Expected `Credential` but got `None`.
photonpump/conversations.py:292:18 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:292:35 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:300:14 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:308:15 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:309:34 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:347:64 Incompatible parameter type [6]: Expected `Credential` but got `None`.
photonpump/conversations.py:349:18 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:349:36 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:607:15 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:612:16 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:654:25 Incompatible parameter type [6]: Expected `UUID` but got `None`.
photonpump/conversations.py:673:14 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:691:15 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:692:34 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:698:12 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:701:17 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:704:28 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:707:28 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:709:16 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:716:12 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:738:25 Incompatible parameter type [6]: Expected `UUID` but got `None`.
photonpump/conversations.py:746:14 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:751:15 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:752:34 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:789:15 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/conversations.py:794:16 Undefined name [18]: Global name `photonpump` is undefined.
photonpump/messages.py:231:56 Incompatible parameter type [6]: Expected `typing.Optional[bytes]` but got `bytearray`.
photonpump/messages.py:278:8 Incompatible return type [7]: Expected `EventRecord` but got `typing.Union[Event, EventRecord]`.
bob@localhost:~/code/play/foo/photon-pump|master⚡ 

Pyre Server crashing instantly

Hi,

I installed the pyre-check package using pip install, and tried starting it in a directory. The first time I started it worked fine, but after closing vscode the server shut down. I tried rebooting it it and kept getting this error:

 ƛ Server not running at `.`. Starting...
 ƛ Client exited with error code -5:

I removed all the init files in the directory, tried doing a new pyre init and keep getting the same error as soon as I try starting the server.

This is on a mac, Python 3.6, with the latest osx and visual studio code insider edition.

'unknown' return type from `dateutil.parser.parse`

python: 3.5.2, 3.6.5
pyre: 0.0.7 (from pip list)
typeshed: python/typeshed@226f055

I would expect the following file to be free from errors:

# pyre-strict

import datetime
import dateutil.parser

def expect_datetime(dt: datetime.datetime) -> None:
    print(dt)

expect_datetime(dateutil.parser.parse('2018-01-01'))

Yet pyre reports an issue stemming from the return type of dateutil.parser.parse (which is stubbed in the typeshed and should return a datetime.datetime):

$ pyre --typeshed /path/to/typeshed/ --search-path /path/to/typeshed/third_party/ check
 ƛ Found 1 type error!
dt.py:9:16 Incompatible parameter type [6]: Expected `datetime.datetime` but got `unknown`.

"Undefined name" message about a name that isn't there in code

Running Pyre on a Django app (namely Zulip), I get a lot of error messages like this:

zerver/apps.py:12:4 Undefined name [18]: Global name `django` is undefined.
zerver/apps.py:21:11 Undefined name [18]: Global name `django` is undefined.
zerver/apps.py:22:12 Undefined name [18]: Global name `django` is undefined.

OK, I see in #27 that this is a funny way of saying Pyre can't find the module django. But this message is completely baffling -- most of all, because the name django doesn't appear on any of those lines!

Instead, the lines are

    cache.clear()
...
        if settings.POST_MIGRATION_CACHE_FLUSHING:
            post_migrate.connect(flush_cache, sender=self)

The real issue, I'm guessing, is that cache and settings and post_migrate are all imported from various submodules of django.

The way mypy :P would handle this is to give an error on the actual import. If for some reason you want to only give an error if the import is actually used (but if it isn't used, wouldn't it be better to just remove the import?), it could be on the line where it's used... but the message should mention an identifier that's actually on the line it refers to.

Not installing in arch linux

$ python3.6 --version
Python 3.6.5

$ uname -a
Linux lahg 4.16.13-1-ARCH #1 SMP PREEMPT Thu May 31 23:29:29 UTC 2018 x86_64 GNU/Linux

$ python3.6 -m pip install pyre-check --user
Collecting pyre-check
Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check

$ pip3.6 install pyre-check --user
Collecting pyre-check
Could not find a version that satisfies the requirement pyre-check (from versions: )
No matching distribution found for pyre-check

Similar to #11

Specializing subclass type params to `None` errors spuriously

When trying to typecheck mypy under pyre, I got a ton of type errors having to do with some of our visitors. I reduced it down to:

from typing import TypeVar, Generic

T = TypeVar('T')
class NodeVisitor(Generic[T]):
    def visit_foo(self) -> T:
        pass

class NodeVisitor(Generic[T]):
    def visit_foo(self) -> T:
        pass

# Works
class Bar(NodeVisitor[int]):
    def visit_foo(self) -> int:
        return 10

# Inconsistent override [15]: `visit_foo` overloads method defined in `foo.NodeVisitor` inconsistently.
class Foo(NodeVisitor[None]):
    def visit_foo(self) -> None:
        pass

Specializing the type parameter to int works, but specializing it to None fails.

AnalysisTypeOrder.Cyclic error raised when subclass is named "Any" in file "types.py"

So this is a really weird issue. This strange error seems to only be raised if...

  1. There's a class called Any
  2. This class is not a top level class; i.e., it has to be descended from some other class, but it doesn't matter what the name of its parent is.
  3. The class is in a file with the name types.py

If any of those things are not true, the error doesn't happen.

Here's a complete test example:

vagrant@precise64:~$ python3.6 -m venv pyretest
vagrant@precise64:~$ cd pyretest/
vagrant@precise64:~/pyretest$ . bin/activate
(pyretest) vagrant@precise64:~/pyretest$ pip install pyre-check
... snip ...
Successfully installed pyre-check-0.0.7
(pyretest) vagrant@precise64:~/pyretest$ mkdir test
(pyretest) vagrant@precise64:~/pyretest$ cd test
(pyretest) vagrant@precise64:~/pyretest/test$ touch __init__.py
(pyretest) vagrant@precise64:~/pyretest/test$ vim types.py
(pyretest) vagrant@precise64:~/pyretest/test$ cat types.py
class Foo:
    pass

class Any(Foo):
    pass

(pyretest) vagrant@precise64:~/pyretest/test$ pyre check
 ƛ Order is cyclic:
Edges:

... snip ...

Trace: `_ast.Delete` -> `_ast.stmt` -> `_ast.AST` -> `typing.Any` -> `types.Foo` -> `typing.Any`
Uncaught exception:

  AnalysisTypeOrder.Cyclic

Raised at file "format.ml" (inlined), line 242, characters 35-52
Called from file "format.ml", line 469, characters 8-33
Called from file "format.ml", line 484, characters 6-24
 ƛ Client exited with error code 1:

If the name of the file is something other than types.py, no error:

(pyretest) vagrant@precise64:~/pyretest/test$ mv types.py foo.py
(pyretest) vagrant@precise64:~/pyretest/test$ pyre check
 ƛ No type errors found

If the name of the class is something other than "Any", no error:

(pyretest) vagrant@precise64:~/pyretest/test$ mv foo.py types.py
(pyretest) vagrant@precise64:~/pyretest/test$ vim types.py
(pyretest) vagrant@precise64:~/pyretest/test$ cat types.py
class Foo:
    pass

class _Any(Foo):
    pass

(pyretest) vagrant@precise64:~/pyretest/test$ pyre check
 ƛ No type errors found

Or if the class Any is a top-level class (i.e., not a subclass), no error:

(pyretest) vagrant@precise64:~/pyretest/test$ vim types.py
(pyretest) vagrant@precise64:~/pyretest/test$ cat types.py
class Foo:
    pass

class Any:
    pass

(pyretest) vagrant@precise64:~/pyretest/test$ pyre check
 ƛ No type errors found

VSCode pyre-check not linting, but CLI works fine

I have installed pyre-check in my pyenv virtualenv VSCode project.

Pyre is able to catch an error if I run it through the CLI, but the VSCode extension does not seem to be catching anything. There is no output in any of the problem/bug prompts either.

Here is an image describing the issue. VSCode doesn't show anything, but the CLI catches the error.
vscode no errors

{
  "binary": "/Users/christophepouliot/.pyenv/versions/spotify-discow-sync/bin/pyre.bin",
  "source_directories": [
    "."
  ],
  "typeshed": "/Users/christophepouliot/.pyenv/versions/3.6.2/envs/spotify-discow-sync/lib/pyre_check/typeshed/stdlib/"
}

If I do pyre restart in the CLI the VSCode linting will catch the error, but then if I change it to return a string it still lints it as an error. If I pyre restart again it still shows an error (although I am returning a string and not an int, which is correct). If I close/reopen VSCode at this point the linting error goes away. Changing it back to returning an int shows no error again until I pyre restart, and then this all starts again.

I added a .watchmanconfig but that did not help (Is this needed? I dont see it mentioned)

VSCode 1.23.1
Python 3.6.2 with pyenv virtualenv
VSCode Python version set to /Users/christophepouliot/.pyenv/versions/spotify-discow-sync/bin/python

Importing a library like 'gevent' resulting in global name is undefined

Hey there, this is likely similar to my previous question-- sorry if it's annoying! :-)

I use gevent in my project, and when running pyre check I get the following error:

 ƛ Found 1 type error!
mud/game.py:150:12 Undefined name [18]: Global name `gevent` is undefined.

I'm using a virtual environment, so I'm not sure if that should be specified as a location to look up libraries.. or if external libraries are supported. If there is a code comment I can add to hint "stop looking in this direction" that might also be helpful.

Thanks for making pyre-check!

Should check nested functions

python: 3.5.2, 3.6.5
pyre: 0.0.7 (from pip list)

Given a file thing.py:

def outer() -> str:
    def inner(x: int, y: str) -> str:
        return x
    return inner(42, None)

outer()

# Copy of 'inner' to prove that it errors at the top level
def outer_inner(x: int, y: str) -> str:
    return x

outer_inner(42, None)

I'd expect to get errors from the bad types in the nested inner function. For reference, here's what mypy (0.600) outputs:

$ mypy thing.py 
thing.py:3: error: Incompatible return value type (got "int", expected "str")
thing.py:4: error: Argument 2 to "inner" has incompatible type "None"; expected "str"
thing.py:10: error: Incompatible return value type (got "int", expected "str")
thing.py:12: error: Argument 2 to "outer_inner" has incompatible type "None"; expected "str"

Yet while pyre does not find errors in the top level equivalent function outer_inner, it doesn't emit any errors about the nested function:

$ pyre check
 ƛ Found 1 type error!
thing.py:2:4 Incompatible return type [7]: Expected `str` but got `int`.

Support PEP 561?

It seems like pyre doesn't currently support PEP 561. In short, when looking for type annotations for imported packages, it should include packages in standard package locations that have a py.typed marker file (with some additional complications). mypy currently implements the PEP.

Thanks!

Method of executing pyre on a folder with exclusions?

I've got a base folder for my project, and I create the virtual env within it. I would like to scan the entire folder, but exclude the venv folder I've created.

I wasn't able to see any suggestions in the pyre --help list that matched what I was looking for.

Would it be expected to run pyre on each of the subfolders?

`List[Any]` is not compatible with `Sequence[str]`

A variable of type List[Any] should be compatible with an argument of type Sequence[str], because List is a subtype of Sequence and Any is a subtype of anything, but pyre rejects it:

$ cat srcdir/seqany.py 
from typing import Any, List, Sequence

def f1(lst: Sequence[str]) -> None:
    pass

def f2() -> None:
    lst: List[Any] = []
    f1(lst)
$ pyre --source-directory srcdir/ --verbose check
...
srcdir/seqany.py:8:7 Incompatible parameter type [6]: Expected `Sequence[str]` but got `List[typing.Any]`.

Missing documentation on error 18/21

When running the checking, if an external library is imported and has no type definition, it throws the following error:

Undefined name [18]: Global name `...` is undefined.

However, the docs only cover errors 14/15 and 16.

It would be useful to know what to do in this case, especially when it's a custom library with no type definitions, or how to configure pyre to silence the error.

Use of `find` does not work on macOS

In pyre-check/scripts/filesystem.py, the systemfind utility is run via the subprocess module:

find is passed the -regextype argument, but the BSD find utility included with macOS does not understand this argument. The result is a slightly cryptic error:

$ pyre
 ƛ Shared source directory is stale, updating...find: -regextype: unknown primary or operator
 ƛ pyre was unable to locate a source directory. Ensure that your project is built and re-run pyre.

I haven't thoroughly tested, but it looks like the -regextype argument can be removed for the regex used here. The -xtype argument gives a similar error, but I believe it can be changed to type since the behavior is the same for -type f.

Making those two changes resolves the issue for me.

VSCode + Virtualenv

Environment

OS: OSX 10.13.2
Python: 3.6.4 (in pipenv managed virtual environment)
VSCode: 1.23.1

Error

After installing the extension I get the following error in the 'Output' window within VSCode

[Error - 11:58:11] Starting client failed
Launching server using command pyre failed.

Running pyre within the virtual env completes successfully and detects the sample type error.

None is subtype of everything?

Why does basic type check?

import random
import string


def gen(allowed_chars: string, length: int) -> str:
    ''.join([random.choice(allowed_chars) for _ in range(1, length)])


def basic(length: int) -> str:
    gen(string.ascii_letters + string.digits, length)
❯ pyre check
 ƛ Found 1 type error!
source/lib/random_string.py:6:4 Incompatible return type [7]: Expected `str` but got `None`.

I tried strict mode on the module to no effect (unsurprisingly since its about Any, not None).

Equivalent to mypy's `reveal_type`

Does pyre have an equivalent to mypy's reveal_type(expr), which when checked displays the type of expr? If not, this is a feature request and if so a documentation one :)

cannot find module installed by pipenv

❯ cat Pipfile
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"

[dev-packages]
isort = "*"
yapf = "*"
pre-commit = "*"
pytest = "*"
pylama = "*"
codecov = "*"
coverage = "*"
pytest-cov = "*"
"boto3" = "*"
rope = "*"

[requires]
python_version = "3.6"
❯ pyre check
 ƛ Found 1 type error!
source/lib/step_functions_client.py:14:0 Undefined import [21]: Could not find a module corresponding to import `boto3`.

Noisy logs in Emacs shell window

When I run Pyre in an Emacs shell or compilation window the output starts with a bunch of gobbledygook:

�[?7l�[0G�[K�[1A�[?25l ƛ�[0m Waiting for server...�[0G�[K ƛ�[0m Finding external sources in `/Users/guido/src/mypy`...�[0G�[K ƛ�[0m Finding external sources in `/Users/guido/v36/lib/pyre_check/typeshed/stdlib`...�[0G�[K ƛ�[0m Parsing 1303 stubs and external sources...�[0G�[K ƛ�[0m Parsing 116 sources in `/Users/guido/src/mypy/mypy`...�[0G�[K ƛ�[0m Unable to parse 1 paths�[0G�[K ƛ�[0m Building type environment...�[0G�[K ƛ�[0m Adding environment information to shared memory...�[0G�[K ƛ�[0m Inferring protocol implementations...�[0G�[K ƛ�[0m Checking...�[0G�[K ƛ�[0m Processed 115 of 115 sources�[0G�[K�[31m ƛ�[0m Found 571 type errors!
�[?7h�[?25h�[?7hmypy/applytype.py:21:15 Incompatible parameter type [6]: Expected `typing.Sized` but got `Optional[List[mypy.types.TypeVarDef]]`.
``
Is there a way to disable this, or can you make it more Emacs-friendly? (Most utilities that do this these days somehow use a convention that Emacs shell mode understands, like ending each status line with `\r`, but Pyre seems to be using its own convention.)

The best I've been able to do is `pyre --noninteractive` but that just switches to a more traditional logging format; it feels there should be a flag to just silence it.

pyre not detecting changes in VSCode

The following code produces some type mismatches (see comments inside the list comprehension at the end).

from typing import Iterable, Tuple, List
import time


class Record(object):

    def __init__(
        self,
        parents: List[int] = [],
        tags: List[str] = [],
        owners: List[str] = [],
    ):
        self.parents = parents
        self.tags = tags
        self.owners = owners


def _insert(*records: Iterable[Record],
            name='records') -> Tuple[str, List[str]]:

    query = 'foo'

    values = [[
        r.parents,   # Error: [Pyre] Undefined attribute [16]: `Iterable[typing.Any]` has no attribute `parents`.
        r.tags,   # Error: [Pyre] Undefined attribute [16]: `Iterable[typing.Any]` has no attribute `tags`.
        r.owners,  # Error: [Pyre] Undefined attribute [16]: `Iterable[typing.Any]` has no attribute `owners`.
    ] for r in records]

    return query, values

I fiddled with this for a while, but I couldn't find a solution. Is this a bug, or am I doing it the wrong way?

Confusing behaviour when running `pyre` without a command

pyre: 0.0.7 (from pip list)

While the documentation does note that pyre can be run either as a server or as a one-off check, pyre's behaviour when a user misunderstands this leads to further confusion for the user rather than

Specifically, consider the following:

$ python3 -m venv venv
$ . venv/bin/activate
$ pip install pyre-check python-dateutil
$ cat thing.py
import dateutil.parser
$ pyre
 ƛ Server not running at `.`. Starting...
 ƛ Server initializing...
 ƛ Found 1 type error!
thing.py:1:0 Undefined import [21]: Could not find a module corresponding to import `dateutil.parser`.

(Consider that the user might have more than just the one type error at this point, and that they therefore might not have actually seen the lines about starting a server)

At this point the user might realise (after reviewing the docs for third party stubs, or finding #43 (comment) etc.) that they need to add --search-path to enable the third party stubs:

$ pyre --search-path=path/to/typeshed/third-party
thing.py:1:0 Undefined import [21]: Could not find a module corresponding to import `dateutil.parser`.

This output is quite confusing. The user believes that they have corrected for the lack of search-path, yet are still seeing errors.

It would have been useful on the second run, which appears to only check with the running server for its results and not alter the search-path to have errored about the search-path being specified but unused.

An ideal error might be something like this:

$ pyre --search-path=path/to/typeshed/third-party
Pyre server is already running with a different search path.
To change the search path in use, run

    pyre --search-path=path/to/typeshed/third-party restart

$

This would help the user better understand their interactions with pyre as a client-server program as well as provide a solution to their immediate problem.

I'm assuming that the client is able to detect what search path is being used by the server and thus only emit this message when the search path is different. That would allow tooling to specify the (unchanged) search path on the command line. There is still a potential for some confusion from users around this, I'd be in favour of always erroring about unusable parameters if there's no way to check their current values.

I'd be in favour of something like this applying to all the command line options that experience a similar behaviour (i.e: are currently accepted but might not actually be used).

Supporting Python <3.6

[root@c7-linpe-build ~]# pip3 install pyre-check
Collecting pyre-check
Downloading https://files.pythonhosted.org/packages/e4/96/72a7048e5f340678c6eb48163b7bdc49926cdac2dff8bb5d935563e50b7f/pyre_check-0.0.5-py3-none-manylinux1_x86_64.whl (7.7MB)
100% |████████████████████████████████| 7.7MB 3.5MB/s
Installing collected packages: pyre-check
Successfully installed pyre-check-0.0.5

[root@c7-linpe-build ~]# pyre
Traceback (most recent call last):
File "/usr/bin/pyre", line 7, in
from pyre_check.pyre import main
File "/usr/lib/python3.4/site-packages/pyre_check/init.py", line 151
**normals,
^
SyntaxError: invalid syntax

[root@c7-linpe-build ~]# rpm -qi python34
Name : python34
Version : 3.4.8
Release : 1.el7

[root@c7-linpe-build ~]# cat /etc/redhat-release
CentOS Linux release 7.5.1804 (Core)

Generics not typechecked

The following code passes typechecking:

# pyre-strict
from typing import TypeVar

T = TypeVar('T')
def coerce(x: T) -> int:
    1 + 'foo'
    return x

In general it seems that functions with types involving generics are not typechecked.

For comparison, mypy produces the following errors:

poly.py:6: error: Unsupported operand types for + ("int" and "str")
poly.py:7: error: Incompatible return value type (got "T", expected "int")

Undefined attribute for top-level numpy functions

Following #27, I added the site-packages folder in my conda env to the "search_path" in my .pyre-configuration. This seems to have resolved my package lookup issues, but now pyre is unable to find top-level functions in numpy:

"Undefined attribute [16]: Module numpy has no attribute zeros."

The relevant code looks like:

import numpy
...
a = np.zeros(b)

(failure points to the last line)

Python 3.6.5 :: Anaconda, Inc.
Ubuntu 16.04.4 LTS
Pyre version 0.0.6

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.