A static type analyzer for Python code

CI PyPI - Wheel

pytype - ?

Pytype checks and infers types for your Python code - without requiring type annotations. Pytype can:

  • Lint plain Python code, flagging common mistakes such as misspelled attribute names, incorrect function calls, and much more, even across file boundaries.
  • Enforce user-provided type annotations. While annotations are optional for pytype, it will check and apply them where present.
  • Generate type annotations in standalone files ("pyi files"), which can be merged back into the Python source with a provided merge-pyi tool.

Pytype is a static analyzer; it does not execute the code it runs on.

Thousands of projects at Google rely on pytype to keep their Python code well-typed and error-free.

For more information, check out the user guide, FAQ, or supported features.

How is pytype different from other type checkers?

  1. Pytype uses inference instead of gradual typing. This means it will infer types on code even when the code has no type hints on it. So it can detect issues with code like this, which other type checkers would miss:

    def f():
        return "PyCon"
    def g():
        return f() + 2019
    
    # pytype: line 4, in g: unsupported operand type(s) for +: 'str'
    # and 'int' [unsupported-operands]
  2. Pytype is lenient instead of strict. That means it allows all operations that succeed at runtime and don't contradict annotations. For instance, this code will pass as safe in pytype, but fail in other type checkers, which assign types to variables as soon as they are initialized:

    from typing import List
    def get_list() -> List[str]:
        lst = ["PyCon"]
        lst.append(2019)
        return [str(x) for x in lst]
    
    # mypy: line 4: error: Argument 1 to "append" of "list" has
    # incompatible type "int"; expected "str"

Also see the corresponding FAQ entry.

Quickstart

To quickly get started with type-checking a file or directory, run the following, replacing file_or_directory with your input:

pip install pytype
pytype file_or_directory

To set up pytype on an entire package, add the following to a setup.cfg file in the directory immediately above the package, replacing package_name with the package name:

[pytype]
inputs = package_name

Now you can run the no-argument command pytype to type-check the package. It's also easy to add pytype to your automated testing; see this example of a GitHub project that runs pytype on Travis.

Finally, pytype generates files of inferred type information, located by default in .pytype/pyi. You can use this information to type-annotate the corresponding source file:

merge-pyi -i <filepath>.py .pytype/pyi/<filename>.pyi

Requirements

You need a Python 3.6-3.8 interpreter to run pytype, as well as an interpreter in $PATH for the Python version of the code you're analyzing (supported: 2.7, 3.5-3.8).

Platform support:

  • Pytype is currently developed and tested on Linux*, which is the main supported platform.
  • Installation on MacOSX requires OSX 10.7 or higher and Xcode v8 or higher.
  • Windows is currently not supported unless you use WSL.

* Note: On Alpine Linux, installing may fail due to issues with upstream dependencies. See the details of this issue for a possible fix.

Installing

Pytype can be installed via pip. Note that the installation requires wheel and setuptools. (If you're working in a virtualenv, these two packages should already be present.)

pip install pytype

Or from the source code on GitHub.

git clone --recurse-submodules https://github.com/google/pytype.git
cd pytype
pip install .

Instead of using --recurse-submodules, you could also have run

git submodule init
git submodule update

in the pytype directory. To edit the code and have your edits tracked live, replace the pip install command with:

pip install -e .

Installing on WSL

Follow the steps above, but make sure you have the correct libraries first:

sudo apt install build-essential python3-dev libpython3-dev

Usage

usage: pytype [options] input [input ...]

positional arguments:
  input                 file or directory to process

Common options:

  • -V, --python-version: Python version (major.minor) of the target code. Defaults to the version that pytype is running under.
  • -o, --output: The directory into which all pytype output goes, including generated .pyi files. Defaults to .pytype.
  • -d, --disable. Comma or space separated list of error names to ignore. Detailed explanations of pytype's error names are in this doc. Defaults to empty.

For a full list of options, run pytype --help.

In addition to the above, you can direct pytype to use a custom typeshed installation instead of its own bundled copy by setting $TYPESHED_HOME.

Config File

For convenience, you can save your pytype configuration in a file. The config file is an INI-style file with a [pytype] section; if an explicit config file is not supplied, pytype will look for a [pytype] section in the first setup.cfg file found by walking upwards from the current working directory.

Start off by generating a sample config file:

$ pytype --generate-config pytype.cfg

Now customize the file based on your local setup, keeping only the sections you need. Directories may be relative to the location of the config file, which is useful if you want to check in the config file as part of your project.

For example, suppose you have the following directory structure and want to analyze package ~/repo1/foo, which depends on package ~/repo2/bar:

~/
├── repo1
│   └── foo
│       ├── __init__.py
│       └── file_to_check.py
└── repo2
    └── bar
        ├── __init__.py
        └── dependency.py

Here is the filled-in config file, which instructs pytype to type-check ~/repo1/foo as Python 3.6 code, look for packages in ~/repo1 and ~/repo2, and ignore attribute errors. Notice that the path to a package does not include the package itself.

$ cat ~/repo1/pytype.cfg

# NOTE: All relative paths are relative to the location of this file.

[pytype]

# Space-separated list of files or directories to process.
inputs =
    foo

# Python version (major.minor) of the target code.
python_version = 3.6

# Paths to source code directories, separated by ':'.
pythonpath =
    .:
    ~/repo2

# Comma or space separated list of error names to ignore.
disable =
    attribute-error

We could've discovered that ~/repo2 needed to be added to the pythonpath by running pytype's broken dependency checker:

$ pytype --config=~/repo1/pytype.cfg ~/repo1/foo/*.py --unresolved

Unresolved dependencies:
  bar.dependency

Subtools

Pytype ships with a few scripts in addition to pytype itself:

  • annotate-ast, an in-progress type annotator for ASTs.
  • merge-pyi, for merging type information from a .pyi file into a Python file.
  • pytd-tool, a parser for .pyi files.
  • pytype-single, a debugging tool for pytype developers, which analyzes a single Python file assuming that .pyi files have already been generated for all of its dependencies.
  • pyxref, a cross references generator.

2021 Roadmap

  • Python 3.9 support
  • Better performance on large files
  • Support for numerical libraries

License

Apache 2.0

Disclaimer

This is not an official Google product.

Comments
  • Python 3 support?

    Python 3 support?

    I'm attempting to use pytype and it appears it doesn't support Python 3( complains about no StringIO module). Any plans to support Python 3? or, perhaps add some documentation about which version of Python are supported.

  • xref crashes with AttributeError: 'LateAnnotation' object has no attribute 'Bindings'

    xref crashes with AttributeError: 'LateAnnotation' object has no attribute 'Bindings'

    Clone https://github.com/kamahen/pykythe.git I don't think you need to install other the other pre-reqs to regenerate this bug; just run:

    make pytype
    

    You should see these lines in the output:

    pykythe/ast_cooked.py pytype_output/imports/pykythe.ast_cooked.imports /tmp/ast_cooked.xref.json
    Pytype error: AttributeError: 'LateAnnotation' object has no attribute 'Bindings'
    
  • Generating pyis in the right order is cumbersome

    Generating pyis in the right order is cumbersome

    I just see this kind of declaration being generated:

      def to_dataframe(self, ...) -> Any: ...
      def to_file(self, path, ...) -> Any: ...
      def to_view(self, view_name) -> Any: ...
    

    I..e. with optional args it just generates '...' and with positional args it just outputs the arg name, and the return types are just Any. This seems to be so generic as to not be useful at all. What am I missing here?

    I'm just running this like:

    pytype foo.py -o foo.pyi
    
  • Pytype fails on MacOSX(Mojave-10.14.9) when inferring types.

    Pytype fails on MacOSX(Mojave-10.14.9) when inferring types.

    Hello,

    I am trying to execute Pytype in a project as below.

    pytype --pythonpath=./$PROJECT_DIRECTORY --no-report-errors $PROJECT_DIRECTORY

    What I need is to run Pytype over a project (first step) and then use AST annotator to get type information of variables in a file. When I run above command it gives me the following error.

    [2/154] infer pymc3.backends.HDF5
    FAILED: /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/HDF5.pyi 
    /Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/bin/python -m pytype.single --imports_info /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/imports/pymc3.backends.HDF5.imports --module-name pymc3.backends.HDF5 -V 3.7 -o /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/HDF5.pyi --no-report-errors --nofail --quick /Users/user_name/Documents/Research_Topic_2/PytypeTest/pymc3-master/pymc3/backends/HDF5.py
    ERROR:pytype.imports_map_loader Invalid imports_map entries (checking from root dir: /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype)
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/HDF5.pyi' (mapped from 'pymc3/backends/HDF5')
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/NDArray.pyi' (mapped from 'pymc3/backends/NDArray')
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/SQLite.pyi' (mapped from 'pymc3/backends/SQLite')
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/Text.pyi' (mapped from 'pymc3/backends/Text')
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/__init__.pyi' (mapped from 'pymc3/backends/__init__')
    ERROR:pytype.imports_map_loader   file does not exist: '/Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/base.pyi' (mapped from 'pymc3/backends/base')
    Traceback (most recent call last):
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
        "__main__", mod_spec)
      File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
        exec(code, run_globals)
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/single.py", line 103, in <module>
        sys.exit(main() or 0)
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/single.py", line 66, in main
        options = config.Options(sys.argv[1:])
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/config.py", line 54, in __init__
        Postprocessor(names, options, self).process()
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/config.py", line 392, in process
        node.processor(value)
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/config.py", line 550, in _store_imports_map
        imports_map, self.output_options.output)
      File "/Users/user_name/Documents/Research_Topic_2/VMS/pytestenv/lib/python3.7/site-packages/pytype/imports_map_loader.py", line 90, in build_imports_map
        raise ValueError(msg)
    ValueError: Invalid imports_map: /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/imports/pymc3.backends.HDF5.imports
    Bad entries:
      pymc3/backends/HDF5 -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/HDF5.pyi
      pymc3/backends/NDArray -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/NDArray.pyi
      pymc3/backends/SQLite -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/SQLite.pyi
      pymc3/backends/Text -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/Text.pyi
      pymc3/backends/__init__ -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/__init__.pyi
      pymc3/backends/base -> /Users/user_name/Documents/Research_Topic_2/PytypeTest/.pytype/pyi/pymc3/backends/base.pyi
    

    Steps to reproduce

    1. Clone https://github.com/pymc-devs/pymc3
    2. Run pytype --pythonpath=./$PROJECT_DIRECTORY --no-report-errors $PROJECT_DIRECTORY (Pytype version = 2020.08.17, OS version = macOS Mojave-10.14.9)

    Questions

    1. Do you have any idea on the above error?
    2. Suppose that, I want to run Pytype without failing. I observed two options (--nofail and --return-success) in the configuration file . When I try to run pytype with these two options, pytype does not identify the options. It says pytype: error: unrecognized arguments: --nofail. What could be the reason for these errors and what options should I use to run Pytype without failing?

    The command that I tried is pytype --pythonpath=$PROJECT_DIRECTORY --no-report-errors --nofail $PROJECT_DIRECTORY Thank you in advance.

  • pytype chokes on python 3 testtools

    pytype chokes on python 3 testtools

    pytype seems to choke on testtools:

    $ cat testtools-bug.py
    #!/usr/bin/python3
    import testtools
    $ pytype -V3.5 testtools-bug.py
    CRITICAL Cannot parse input files:
    invalid syntax (_compat2x.py, line 16)
    

    It seems that pytype isn't understanding that importing compat2x is wrapped in a try: block in testtools/compat.py to determine whether it should import the python 2 or 3 version:

    try:
        from testtools import _compat2x as _compat
    except SyntaxError:
        from testtools import _compat3x as _compat
    
  • No such file or directory: 'ninja'

    No such file or directory: 'ninja'

    Running pytype on a Python scripts gives me the following error message.

    Computing dependencies
    Analyzing 1 sources with 2 local dependencies
    Traceback (most recent call last):
      File "/usr/lib/python3.8/runpy.py", line 193, in _run_module_as_main
        return _run_code(code, main_globals, None,
      File "/usr/lib/python3.8/runpy.py", line 86, in _run_code
        exec(code, run_globals)
      File "/workdir/user/chdu/side_projects/dbay/.venv/lib/python3.8/site-packages/pytype/__main__.py", line 10, in <module>
        sys.exit(main())
      File "/workdir/user/chdu/side_projects/dbay/.venv/lib/python3.8/site-packages/pytype/tools/analyze_project/main.py", line 97, in main
        return runner.run()
      File "/workdir/user/chdu/side_projects/dbay/.venv/lib/python3.8/site-packages/pytype/tools/analyze_project/pytype_runner.py", line 355, in run
        ret = self.build()
      File "/workdir/user/chdu/side_projects/dbay/.venv/lib/python3.8/site-packages/pytype/tools/analyze_project/pytype_runner.py", line 346, in build
        return subprocess.call(command)
      File "/usr/lib/python3.8/subprocess.py", line 340, in call
        with Popen(*popenargs, **kwargs) as p:
      File "/usr/lib/python3.8/subprocess.py", line 854, in __init__
        self._execute_child(args, executable, preexec_fn, close_fds,
      File "/usr/lib/python3.8/subprocess.py", line 1702, in _execute_child
        raise child_exception_type(errno_num, err_msg, err_filename)
    FileNotFoundError: [Errno 2] No such file or directory: 'ninja'
    
  • Question: merge two `pyi` files

    Question: merge two `pyi` files

    Hello, found existing of merge_pyi tool for merging pyi types into py files.

    Use case:

    I want to merge two pyi files. Purpose is generating stubs for code i.e. via mypy.stubgen and next apply some clarifications for types from external file. Add doc strings, clarify return parameters manually and so on.

    My use case is support stub package for some external lib. And when API is changed during release just regenerate stubs, but save all previously collected type knowledge. In this case we can automate entire process of generating and testing stubs correctness (i.e. via mypy.stubtest).

    Question:

    Are there any tools for merging exactly pyi files? Or there is only one way is parse pyi manually and manipulating parse tree from script?

    Thanks in advance!

  • Dict[slice, ...] is not valid

    Dict[slice, ...] is not valid

    I have a function like this:

    def foo(a):
        return a[:10].lower()
    

    The generated stub is:

    def foo(a: bytes or str or unicode or Dict[slice, bytearray or bytes or str or unicode or List[?, ...] or Tuple[?, ...]]) -> bytearray or bytes or str or unicode
    

    Now, it's cute that it figures out that if the argument were a dict with slice keys and string values it might work, but in fact slice does not implement hash() so Dict[slice, ...] is nonsense.

    I'm also unclear on why it thinks that the value could be a List or Tuple, since neither of those has a lower() method.

  • fix: simplifiy pybind11 usage

    fix: simplifiy pybind11 usage

    This is a suggestion for using pybind11 via submodule. pyproject.toml is more elegant, but does require Pip 10+. I can switch to that if requested. Follow up on #714. I don't know all the details of building from scratch (It wants bison 3), but this should be close, I think. CC @rwgk .

    I did not include ParallelCompile, but that might also be useful, I think.

  • Support Python 3.8

    Support Python 3.8

    Invoking pytype under Python 3.8 fails with the following error:

    Python versions > 3.7 are not yet supported.
    

    Is there an ETA for Python 3.8 support?

  • Support for dataclasses

    Support for dataclasses

    Currently, when using python 3.7 dataclass, pytype will fail to recognize constructor arguments. Here's a proof of concept code snippet:

    from dataclasses import dataclass
    
    
    @dataclass
    class DataClass:
        first: int
        second: int
    
    
    data_class = DataClass(1, 2)
    

    It gives an error of

    File "type_check.py", line 11, in <module>: Function DataClass.__init__ expects 1 arg(s), got 3 [wrong-arg-count]
      Expected: (self)
      Actually passed: (self, _, _)
    
  • A curious failure of type narrowing (bad-return-type)

    A curious failure of type narrowing (bad-return-type)

    Description

    This code doesn't make a lot of sense, because it was simplified from a larger program. It runs successfully and prints 'x' two times, and mypy doesn't complain about it. However, pytype seems to fail to narrow the type of 'OPTIONAL' to str in the OPTIONAL is not None branch.

    Example Code

    OPTIONAL: str | None = 'foo'
    
    def foo(val):
        if val == val + 'y':
            return None
        return val
    
    class MyClass:
        def bar(self) -> str:
            return 'x'
    
        def baz(self) -> str:
            if OPTIONAL is not None:
                return OPTIONAL
            return 'x'
    
    objects: list[MyClass] = []
    
    for val in ['a', 'b']:
        x = foo('x')
        if x is not None:
            objects.append(MyClass())
    
    for o in objects:
        if o.bar() == foo('x'):
            print(o.baz())
    

    Expected Behavior

    pytype reports no errors.

    Actual Behavior

    $ pytype-single repr.py
    File "repr.py", line 14, in baz: bad option 'None' in return type [bad-return-type]
               Expected: str
      Actually returned: Optional[str]
    Called from (traceback):
      line 26, in current file
    
    For more details, see https://google.github.io/pytype/errors.html#bad-return-type
    

    Software Versions

    Python 3.10.8 pytype 2022.12.15

  • Python 3.10 collections.Counter.total not supported

    Python 3.10 collections.Counter.total not supported

    https://docs.python.org/3/library/collections.html?highlight=counter#collections.Counter.total

    Example

    from collections import Counter
    
    c = Counter()
    print(c.total())
    

    This error is reported.

     No attribute 'total' on Counter[nothing] [attribute-error]
    
  • Inferred type info is lost when constructing tuple

    Inferred type info is lost when constructing tuple

    I'm not sure the title of this issue is very good. I had some trouble deciding what to call it. But hopefully this small example will make the issue more clear:

    from typing import Optional, Dict, Tuple, Union, Any
    
    def foo(d: Dict[Union[str, Tuple[str, str]], Any],
            opt_k: Optional[str],
            k: str):
        reveal_type(opt_k)  # reveals Optional[str]
    
        if opt_k is None:
            d[k] = object()
            reveal_type(opt_k)  # reveals None
            return
    
        reveal_type(opt_k)  # reveals str
        reveal_type((opt_k, k))  # reveals Tuple[Optional[str], str] (too broad)
        d[(opt_k, k)] = object()  # container-types-mismatch (false positive)
    

    Here is the output from pytype:

    File "/home/dominickpastore/test.py", line 6, in foo: Optional[str] [reveal-type]
    File "/home/dominickpastore/test.py", line 9, in foo: None [reveal-type]
    File "/home/dominickpastore/test.py", line 11, in foo: str [reveal-type]
    File "/home/dominickpastore/test.py", line 12, in foo: Tuple[Optional[str], str] [reveal-type]
    File "/home/dominickpastore/test.py", line 13, in foo: New container type for d does not match type annotation [container-type-mismatch]
      Container: Dict[_K, _V]
      Allowed contained types (from annotation Dict[Union[str, Tuple[str, str]], Any]):
        _K: Union[Tuple[str, str], str]
      New contained types:
        _K: Tuple[Optional[str], str]
    

    As we can see, it's correctly inferring that opt_k must not be None after the if block. Yet, if we make a tuple out of it, it seems to forget that it knows that. And if we try to use that tuple as a key in the dictionary, we get a false positive.

    It seems to be a bit more complex than that, though. If we were to try to .append the tuple to a list instead, like this, the tuple's type is still revealed as Tuple[Optional[str], str], but there's no false positive:

    from typing import Optional, List, Tuple, Union
      
    def foo(l: List[Union[str, Tuple[str, str]]],
            opt_k: Optional[str],
            k: str):
        reveal_type(opt_k)  # reveals Optional[str]
        if opt_k is None:
            l.append(k)
            reveal_type(opt_k)  # reveals None
            return
        reveal_type(opt_k)  # reveals str
        reveal_type((opt_k, k))  # reveals Tuple[Optional[str], str] (too broad)
        l.append((opt_k, k))  # No false positive
    
  • pytype is not py.typed

    pytype is not py.typed

    Running mypy on a script that uses pytype results in the following:

    tests/pytype_test.py:22: error: Skipping analyzing "pytype": module is installed, but missing library stubs or py.typed marker  [import]
    tests/pytype_test.py:23: error: Skipping analyzing "pytype.imports": module is installed, but missing library stubs or py.typed marker  [import]
    tests/pytype_test.py:23: note: See https://mypy.readthedocs.io/en/stable/running_mypy.html#missing-imports
    

    https://github.com/python/typeshed/blob/main/tests/pytype_test.py

  • Errors with `map`

    Errors with `map`

    When trying to use the map class in a type stub, I get the following errors:

    1. pytype.pytd.visitors.SymbolLookupError: Couldn't find map in some.module This can be worked around by importing map from builtins: from builtins import map
    NotImplementedError: Can't convert <class 'pytype.pytd.pytd.Function'>: Function(name='builtins.map', signatures=(Signature(params=(Parameter(name='function', type=AnythingType(), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, 
    mutated_type=None),), starargs=Parameter(name='sequences', type=GenericType(base_type=ClassType(builtins.tuple), parameters=(GenericType(base_type=ClassType(typing.Iterable), parameters=(NothingType(),)),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=True, mutated_type=None), starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(NothingType(),)), exceptions=(), template=()), Signature(params=(Parameter(name='__func', type=CallableType(base_type=ClassType(typing.Callable), parameters=(TypeParameter(name='_T', constraints=(), 
    bound=None, scope='builtins.map'), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=None, starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map')))), Signature(params=(Parameter(name='__func', type=CallableType(base_type=ClassType(typing.Callable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter2', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=None, starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map')))), Signature(params=(Parameter(name='__func', type=CallableType(base_type=ClassType(typing.Callable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter2', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter3', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=None, starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map')))), Signature(params=(Parameter(name='__func', type=CallableType(base_type=ClassType(typing.Callable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter2', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter3', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter4', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=None, starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map')))), Signature(params=(Parameter(name='__func', type=CallableType(base_type=ClassType(typing.Callable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_T5', constraints=(), bound=None, scope='builtins.map'), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), 
    Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter2', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T2', constraints=(), 
    bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter3', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map'),)), 
    kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter4', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter5', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(TypeParameter(name='_T5', constraints=(), bound=None, scope='builtins.map'),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=None, starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T2', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T3', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T4', constraints=(), bound=None, scope='builtins.map')), TemplateItem(type_param=TypeParameter(name='_T5', constraints=(), bound=None, scope='builtins.map')))), Signature(params=(Parameter(name='__func', type=GenericType(base_type=ClassType(typing.Callable), parameters=(AnythingType(), TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'))), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter1', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 
    'regular'>, optional=False, mutated_type=None), Parameter(name='__iter2', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter3', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter4', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None), Parameter(name='__iter5', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 'regular'>, 
    optional=False, mutated_type=None), Parameter(name='__iter6', type=GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=False, mutated_type=None)), starargs=Parameter(name='iterables', type=GenericType(base_type=ClassType(builtins.tuple), parameters=(GenericType(base_type=ClassType(typing.Iterable), parameters=(AnythingType(),)),)), kind=<ParameterKind.REGULAR: 'regular'>, optional=True, mutated_type=None), starstarargs=None, return_type=GenericType(base_type=ClassType(typing.Iterator), parameters=(TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map'),)), exceptions=(), template=(TemplateItem(type_param=TypeParameter(name='_S', constraints=(), bound=None, scope='builtins.map')),))), kind=<MethodKind.METHOD: 'method'>, flags=<MethodFlag.NONE: 1>)
    
  • No attribute 'readinto' on BinaryIO

    No attribute 'readinto' on BinaryIO

    Pytype shows attribute-error for io.BufferedIOBase methods (readinto, read1, etc):

    buffer = bytearray(4096)
    with open("anyfile", "rb") as file:
        print(file.__class__)  # <class '_io.BufferedReader'>
        reveal_type(file)  # BinaryIO [reveal-type]
        file.readinto(buffer)  # No attribute 'readinto' on BinaryIO [attribute-error]
    

    For comparision: no error in MyPy and main.py:4: note: Revealed type is "io.BufferedReader*"

Static type checker for Python
Static type checker for Python

Static type checker for Python Speed Pyright is a fast type checker meant for large Python source bases. It can run in a “watch” mode and performs fas

Jan 7, 2023
Robocop is a tool that performs static code analysis of Robot Framework code.
Robocop is a tool that performs static code analysis of Robot Framework code.

Robocop Introduction Documentation Values Requirements Installation Usage Example Robotidy FAQ Watch our talk from RoboCon 2021 about Robocop and Robo

Dec 29, 2022
CodeAnalysis - Static Code Analysis: a code comprehensive analysis platform
CodeAnalysis - Static Code Analysis: a code comprehensive analysis platform

TCA, Tencent Cloud Code Analysis English | 简体中文 What is TCA Tencent Cloud Code A

Jan 7, 2023
A simple stopwatch for measuring code performance with static typing.

A simple stopwatch for measuring code performance. This is a fork from python-stopwatch, which adds static typing and a few other things.

Feb 18, 2022
Collection of library stubs for Python, with static types

typeshed About Typeshed contains external type annotations for the Python standard library and Python builtins, as well as third party packages as con

Jan 2, 2023
Optional static typing for Python 3 and 2 (PEP 484)

Mypy: Optional Static Typing for Python Got a question? Join us on Gitter! We don't have a mailing list; but we are always happy to answer questions o

Jan 5, 2023
A static analysis tool for Python

pyanalyze Pyanalyze is a tool for programmatically detecting common mistakes in Python code, such as references to undefined variables and some catego

Jan 7, 2023
TidyPy is a tool that encapsulates a number of other static analysis tools and makes it easy to configure, execute, and review their results.

TidyPy Contents Overview Features Usage Docker Configuration Ignoring Issues Included Tools Included Reporters Included Integrations Extending TidyPy

Nov 27, 2022
Pymwp is a tool for automatically performing static analysis on programs written in C

pymwp: MWP analysis in Python pymwp is a tool for automatically performing static analysis on programs written in C, inspired by "A Flow Calculus of m

Dec 2, 2022
Inspects Python source files and provides information about type and location of classes, methods etc

prospector About Prospector is a tool to analyse Python code and output information about errors, potential problems, convention violations and comple

Dec 31, 2022
Performant type-checking for python.
Performant type-checking for python.

Pyre is a performant type checker for Python compliant with PEP 484. Pyre can analyze codebases with millions of lines of code incrementally – providi

Jan 7, 2023
Unbearably fast O(1) runtime type-checking in pure Python.
Unbearably fast O(1) runtime type-checking in pure Python.

Look for the bare necessities, the simple bare necessities. Forget about your worries and your strife. — The Jungle Book.

Dec 29, 2022
Data parsing and validation using Python type hints

pydantic Data validation and settings management using Python type hinting. Fast and extensible, pydantic plays nicely with your linters/IDE/brain. De

Jan 5, 2023
Run-time type checker for Python

This library provides run-time type checking for functions defined with PEP 484 argument (and return) type annotations. Four principal ways to do type

Dec 19, 2022
Turn your Python and Javascript code into DOT flowcharts
Turn your Python and Javascript code into DOT flowcharts

Notes from 2017 This is an older project which I am no longer working on. It was built before ES6 existed and before Python 3 had much usage. While it

Jan 9, 2023
Find dead Python code

Vulture - Find dead code Vulture finds unused code in Python programs. This is useful for cleaning up and finding errors in large code bases. If you r

Jan 3, 2023
Code audit tool for python.

Pylama Code audit tool for Python and JavaScript. Pylama wraps these tools: pycodestyle (formerly pep8) © 2012-2013, Florent Xicluna; pydocstyle (form

Dec 29, 2022
The uncompromising Python code formatter
The uncompromising Python code formatter

The Uncompromising Code Formatter “Any color you like.” Black is the uncompromising Python code formatter. By using it, you agree to cede control over

Dec 28, 2022
Print a directory tree structure in your Python code.

directory-structure Print a directory tree structure in your Python code. Download You can simply: pip install directory-structure Or you can also: Cl

Dec 19, 2022