Skip to content
Commits on Source (3)
Metadata-Version: 1.1
Name: mypy
Version: 0.560
Version: 0.570
Summary: Optional static typing for Python
Home-page: http://www.mypy-lang.org/
Author: Jukka Lehtosalo
......@@ -17,12 +17,11 @@ Description: Mypy -- Optional Static Typing for Python
features such as type inference, gradual typing, generics and union
types.
Platform: POSIX
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
......
......@@ -14,7 +14,7 @@ sure you've found a bug please search our issue trackers for a
duplicate before filing a new issue:
- [mypy tracker](https://github.com/python/mypy/issues)
for mypy isues
for mypy issues
- [typeshed tracker](https://github.com/python/typeshed/issues)
for issues with specific modules
- [typing tracker](https://github.com/python/typing/issues)
......
mypy (0.570-1) unstable; urgency=medium
* New upstream version.
* Added manual page for dmypy
-- Michael R. Crusoe <michael.crusoe@gmail.com> Sat, 10 Mar 2018 08:55:23 -0800
mypy (0.560-1) unstable; urgency=medium
* Team upload.
......
......@@ -16,7 +16,7 @@ Build-Depends: debhelper (>= 10),
python3-sphinx-rtd-theme,
python3-typed-ast (>= 1.1.0),
python3-psutil (>= 5.4.0)
Standards-Version: 4.1.2
Standards-Version: 4.1.3
Vcs-Browser: https://anonscm.debian.org/cgit/debian-med/mypy.git
Vcs-Git: https://anonscm.debian.org/git/debian-med/mypy.git
Homepage: http://www.mypy-lang.org/
......
......@@ -5,6 +5,6 @@ Subject: specify python3 for typeshed test
@@ -1,4 +1,4 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
"""Test runner for typeshed.
r"""Test runner for typeshed.
Depends on mypy and pytype being installed.
......@@ -18,6 +18,9 @@ override_dh_auto_build:
PYTHONPATH=$(PPATH) help2man scripts/mypy --no-info \
--version-string="${DEB_VERSION_UPSTREAM}" \
--name 'Optional Static Typing for Python' > debian/mypy.1
PYTHONPATH=$(PPATH) help2man scripts/dmypy --no-info \
--version-string="${DEB_VERSION_UPSTREAM}" \
--name 'Client for mypy daemon mode' > debian/dmypy.1
PYTHONPATH=$(PPATH) help2man 'python${PY3V} scripts/stubgen' --no-info \
--no-discard-stderr --version-string="${DEB_VERSION_UPSTREAM}" \
--name 'Generate draft stubs for Python modules.' > \
......
......@@ -7,3 +7,79 @@ including the following:
- inheritance between generic classes
- compatibility and subtyping of generic types, including covariance of generic types
- ``super()``
.. _attrs_package:
The attrs package
*****************
`attrs <https://www.attrs.org/en/stable>`_ is a package that lets you define
classes without writing boilerplate code. Mypy can detect uses of the
package and will generate the necessary method definitions for decorated
classes using the type annotations it finds.
Type annotations can be added as follows:
.. code-block:: python
import attr
@attr.s
class A:
one: int = attr.ib() # Variable annotation (Python 3.6+)
two = attr.ib() # type: int # Type comment
three = attr.ib(type=int) # type= argument
If you're using ``auto_attribs=True`` you must use variable annotations.
.. code-block:: python
import attr
@attr.s(auto_attribs=True)
class A:
one: int
two: int = 7
three: int = attr.ib(8)
Typeshed has a couple of "white lie" annotations to make type checking
easier. ``attr.ib`` and ``attr.Factory`` actually return objects, but the
annotation says these return the types that they expect to be assigned to.
That enables this to work:
.. code-block:: python
import attr
from typing import Dict
@attr.s(auto_attribs=True)
class A:
one: int = attr.ib(8)
two: Dict[str, str] = attr.Factory(dict)
bad: str = attr.ib(16) # Error: can't assign int to str
Caveats/Known Issues
====================
* The detection of attr classes and attributes works by function name only.
This means that if you have your own helper functions that, for example,
``return attr.ib()`` mypy will not see them.
* All boolean arguments that mypy cares about must be literal ``True`` or ``False``.
e.g the following will not work:
.. code-block:: python
import attr
YES = True
@attr.s(init=YES)
class A:
...
* Currently, ``converter`` only supports named functions. If mypy finds something else it
will complain about not understanding the argument and the type annotation in
``__init__`` will be replaced by ``Any``.
* `Validator decorators <http://www.attrs.org/en/stable/examples.html#decorator>`_
and `default decorators <http://www.attrs.org/en/stable/examples.html#defaults>`_
are not type-checked against the attribute they are setting/validating.
* Method definitions added by mypy currently overwrite any existing method
definitions.
......@@ -13,7 +13,7 @@ Type Description
``bytes`` 8-bit string
``object`` an arbitrary object (``object`` is the common base class)
``List[str]`` list of ``str`` objects
``Tuple[int, int]`` tuple of two ``int``s (``Tuple[()]`` is the empty tuple)
``Tuple[int, int]`` tuple of two ``int`` objects (``Tuple[()]`` is the empty tuple)
``Tuple[int, ...]`` tuple of an arbitrary number of ``int`` objects
``Dict[str, int]`` dictionary from ``str`` keys to ``int`` values
``Iterable[int]`` iterable object containing ints
......
......@@ -292,22 +292,11 @@ Here are some more useful flags:
- ``--ignore-missing-imports`` suppresses error messages about imports
that cannot be resolved (see :ref:`follow-imports` for some examples).
- ``--strict-optional`` enables experimental strict checking of ``Optional[...]``
types and ``None`` values. Without this option, mypy doesn't generally check the
use of ``None`` values -- they are valid everywhere. See :ref:`strict_optional` for
more about this feature.
- ``--strict-optional-whitelist`` attempts to suppress strict Optional-related
errors in non-whitelisted files. Takes an arbitrary number of globs as the
whitelist. This option is intended to be used to incrementally roll out
``--strict-optional`` to a large codebase that already has mypy annotations.
However, this flag comes with some significant caveats. It does not suppress
all errors caused by turning on ``--strict-optional``, only most of them, so
there may still be a bit of upfront work to be done before it can be used in
CI. It will also suppress some errors that would be caught in a
non-strict-Optional run. Therefore, when using this flag, you should also
re-check your code without ``--strict-optional`` to ensure new type errors
are not introduced.
- ``--strict-optional`` enables strict checking of ``Optional[...]``
types and ``None`` values. Without this option, mypy doesn't
generally check the use of ``None`` values -- they are valid
everywhere. See :ref:`strict_optional` for more about this feature.
This flag will become the default in the near future.
- ``--disallow-untyped-defs`` reports an error whenever it encounters
a function definition without type annotations.
......@@ -342,17 +331,19 @@ Here are some more useful flags:
.. _incremental:
- ``--incremental`` is an experimental option that enables a module
cache. When enabled, mypy caches results from previous runs
to speed up type checking. Incremental mode can help when most parts
of your program haven't changed since the previous mypy run. A
companion flag is ``--cache-dir DIR``, which specifies where the
cache files are written. By default this is ``.mypy_cache`` in the
current directory. While the cache is only read in incremental
mode, it is written even in non-incremental mode, in order to "warm"
the cache. To disable writing the cache, use
``--cache-dir=/dev/null`` (UNIX) or ``--cache-dir=nul`` (Windows).
Cache files belonging to a different mypy version are ignored.
- ``--incremental`` enables a module cache, using results from
previous runs to speed up type checking. Incremental mode can help
when most parts of your program haven't changed since the previous
mypy run.
- ``--cache-dir DIR`` is a companion flag to ``-incremental``, which
specifies where the cache files are written. By default this is
``.mypy_cache`` in the current directory. While the cache is only
read in incremental mode, it is written even in non-incremental
mode, in order to "warm" the cache. To disable writing the cache,
use ``--cache-dir=/dev/null`` (UNIX) or ``--cache-dir=nul``
(Windows). Cache files belonging to a different mypy version are
ignored.
.. _quick-mode:
......
......@@ -74,9 +74,6 @@ The following global flags may only be set in the global section
- ``warn_redundant_casts`` (Boolean, default False) warns about
casting an expression to its inferred type.
- ``warn_unused_ignores`` (Boolean, default False) warns about
unneeded ``# type: ignore`` comments.
- ``warn_unused_configs`` (Boolean, default False) warns about
per-module sections in the config file that didn't match any
files processed in the current run.
......@@ -203,6 +200,9 @@ overridden by the pattern sections matching the module name.
returning a value with type ``Any`` from a function declared with a
non- ``Any`` return type.
- ``warn_unused_ignores`` (Boolean, default False) warns about
unneeded ``# type: ignore`` comments.
- ``strict_boolean`` (Boolean, default False) makes using non-boolean
expressions in conditions an error.
......
......@@ -167,16 +167,6 @@ features will be supported in a restricted form (for example, runtime
modification is only supported for classes or methods registered as
dynamic or 'patchable').
How is mypy different from PyPy?
********************************
*This answer relates to PyPy as a Python implementation. See also the answer related to RPython below.*
Mypy and PyPy are orthogonal. Mypy does static type checking, i.e. it
is basically a linter, but static typing has no runtime effect,
whereas the PyPy is an Python implementation. You can use PyPy to run
mypy programs.
How is mypy different from Cython?
**********************************
......
......@@ -307,7 +307,7 @@ Variance of generic types
There are three main kinds of generic types with respect to subtype
relations between them: invariant, covariant, and contravariant.
Assuming that we have a pair of types types ``A`` and ``B`` and ``B`` is
Assuming that we have a pair of types ``A`` and ``B``, and ``B`` is
a subtype of ``A``, these are defined as follows:
* A generic class ``MyCovGen[T, ...]`` is called covariant in type variable
......
......@@ -432,13 +432,14 @@ idiomatic.
.. _strict_optional:
Experimental strict optional type and None checking
Strict optional type and None checking
***************************************************
Currently, ``None`` is a valid value for each type, similar to
``null`` or ``NULL`` in many languages. However, you can use the
experimental ``--strict-optional`` command line option to tell mypy
that types should not include ``None``
``--strict-optional`` command line option
(which will become the default in the near future)
to tell mypy that types should not include ``None``
by default. The ``Optional`` type modifier is then used to define
a type variant that includes ``None``, such as ``Optional[int]``:
......@@ -478,10 +479,6 @@ recognizes ``is None`` checks:
Mypy will infer the type of ``x`` to be ``int`` in the else block due to the
check against ``None`` in the if condition.
.. note::
``--strict-optional`` is experimental and still has known issues.
.. _noreturn:
The NoReturn type
......@@ -987,6 +984,11 @@ annotated the first example as the following:
for i in range(n):
yield i * i
This is slightly different from using ``Iterable[int]`` or ``Iterator[int]``,
since generators have ``close()``, ``send()``, and ``throw()`` methods that
generic iterables don't. If you will call these methods on the returned
generator, use the ``Generator`` type instead of ``Iterable`` or ``Iterator``.
.. _async-and-await:
Typing async/await
......
......@@ -3,6 +3,11 @@ Revision history
List of major changes:
- March 2018
* Publish ``mypy`` version 0.570 on PyPI.
* Add support for :ref:`attrs_package`.
- December 2017
* Publish ``mypy`` version 0.560 on PyPI.
......
......@@ -2,7 +2,7 @@
from setuptools import setup
version = '0.3.0'
version = '0.4.0-dev'
description = 'Experimental type system extensions for programs checked with the mypy typechecker.'
long_description = '''
Mypy Extensions
......@@ -17,7 +17,6 @@ classifiers = [
'Environment :: Console',
'Intended Audience :: Developers',
'License :: OSI Approved :: MIT License',
'Operating System :: POSIX',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
......@@ -37,7 +36,6 @@ setup(
author_email='jukka.lehtosalo@iki.fi',
url='http://www.mypy-lang.org/',
license='MIT License',
platforms=['POSIX'],
py_modules=['mypy_extensions'],
classifiers=classifiers,
install_requires=[
......
Metadata-Version: 1.1
Name: mypy
Version: 0.560
Version: 0.570
Summary: Optional static typing for Python
Home-page: http://www.mypy-lang.org/
Author: Jukka Lehtosalo
......@@ -17,12 +17,11 @@ Description: Mypy -- Optional Static Typing for Python
features such as type inference, gradual typing, generics and union
types.
Platform: POSIX
Platform: UNKNOWN
Classifier: Development Status :: 3 - Alpha
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: POSIX
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
......
......@@ -63,6 +63,9 @@ mypy/exprtotype.py
mypy/fastparse.py
mypy/fastparse2.py
mypy/fixup.py
mypy/fscache.py
mypy/fswatcher.py
mypy/gclogger.py
mypy/git.py
mypy/indirection.py
mypy/infer.py
......@@ -79,9 +82,11 @@ mypy/parse.py
mypy/plugin.py
mypy/report.py
mypy/sametypes.py
mypy/scope.py
mypy/semanal.py
mypy/semanal_pass1.py
mypy/semanal_pass3.py
mypy/semanal_shared.py
mypy/sharedparse.py
mypy/solve.py
mypy/stats.py
......@@ -106,8 +111,8 @@ mypy.egg-info/dependency_links.txt
mypy.egg-info/entry_points.txt
mypy.egg-info/requires.txt
mypy.egg-info/top_level.txt
mypy/myunit/__init__.py
mypy/myunit/__main__.py
mypy/plugins/__init__.py
mypy/plugins/attrs.py
mypy/server/__init__.py
mypy/server/astdiff.py
mypy/server/astmerge.py
......@@ -128,8 +133,10 @@ mypy/test/testcmdline.py
mypy/test/testdeps.py
mypy/test/testdiff.py
mypy/test/testdmypy.py
mypy/test/testerrorstream.py
mypy/test/testextensions.py
mypy/test/testfinegrained.py
mypy/test/testfinegrainedcache.py
mypy/test/testgraph.py
mypy/test/testinfer.py
mypy/test/testmerge.py
......@@ -215,6 +222,7 @@ test-data/stdlib-samples/3.2/test/subprocessdata/sigchild_ignore.py
test-data/unit/README.md
test-data/unit/check-abstract.test
test-data/unit/check-async-await.test
test-data/unit/check-attr.test
test-data/unit/check-basic.test
test-data/unit/check-bound.test
test-data/unit/check-callable.test
......@@ -224,6 +232,7 @@ test-data/unit/check-classvar.test
test-data/unit/check-columns.test
test-data/unit/check-custom-plugin.test
test-data/unit/check-default-plugin.test
test-data/unit/check-dmypy-fine-grained.test
test-data/unit/check-dynamic-typing.test
test-data/unit/check-enum.test
test-data/unit/check-expressions.test
......@@ -274,6 +283,7 @@ test-data/unit/deps-statements.test
test-data/unit/deps-types.test
test-data/unit/deps.test
test-data/unit/diff.test
test-data/unit/errorstream.test
test-data/unit/fine-grained-blockers.test
test-data/unit/fine-grained-cycles.test
test-data/unit/fine-grained-modules.test
......@@ -307,11 +317,13 @@ test-data/unit/fixtures/__new__.pyi
test-data/unit/fixtures/alias.pyi
test-data/unit/fixtures/args.pyi
test-data/unit/fixtures/async_await.pyi
test-data/unit/fixtures/attr.pyi
test-data/unit/fixtures/bool.pyi
test-data/unit/fixtures/callable.pyi
test-data/unit/fixtures/classmethod.pyi
test-data/unit/fixtures/complex.pyi
test-data/unit/fixtures/dict.pyi
test-data/unit/fixtures/divmod.pyi
test-data/unit/fixtures/exception.pyi
test-data/unit/fixtures/f_string.pyi
test-data/unit/fixtures/fine_grained.pyi
......@@ -325,6 +337,7 @@ test-data/unit/fixtures/list.pyi
test-data/unit/fixtures/module.pyi
test-data/unit/fixtures/module_all.pyi
test-data/unit/fixtures/module_all_python2.pyi
test-data/unit/fixtures/notimplemented.pyi
test-data/unit/fixtures/ops.pyi
test-data/unit/fixtures/primitives.pyi
test-data/unit/fixtures/property.pyi
......@@ -340,6 +353,7 @@ test-data/unit/fixtures/typing-full.pyi
test-data/unit/fixtures/union.pyi
test-data/unit/lib-stub/__builtin__.pyi
test-data/unit/lib-stub/abc.pyi
test-data/unit/lib-stub/attr.pyi
test-data/unit/lib-stub/blocker.pyi
test-data/unit/lib-stub/blocker2.pyi
test-data/unit/lib-stub/broken.pyi
......@@ -399,7 +413,6 @@ typeshed/stdlib/2/collections.pyi
typeshed/stdlib/2/commands.pyi
typeshed/stdlib/2/compileall.pyi
typeshed/stdlib/2/cookielib.pyi
typeshed/stdlib/2/datetime.pyi
typeshed/stdlib/2/decimal.pyi
typeshed/stdlib/2/dummy_thread.pyi
typeshed/stdlib/2/exceptions.pyi
......@@ -466,7 +479,6 @@ typeshed/stdlib/2/sys.pyi
typeshed/stdlib/2/tempfile.pyi
typeshed/stdlib/2/textwrap.pyi
typeshed/stdlib/2/thread.pyi
typeshed/stdlib/2/time.pyi
typeshed/stdlib/2/toaiff.pyi
typeshed/stdlib/2/tokenize.pyi
typeshed/stdlib/2/types.pyi
......@@ -533,6 +545,7 @@ typeshed/stdlib/2and3/contextlib.pyi
typeshed/stdlib/2and3/copy.pyi
typeshed/stdlib/2and3/crypt.pyi
typeshed/stdlib/2and3/csv.pyi
typeshed/stdlib/2and3/datetime.pyi
typeshed/stdlib/2and3/difflib.pyi
typeshed/stdlib/2and3/dis.pyi
typeshed/stdlib/2and3/doctest.pyi
......@@ -578,6 +591,7 @@ typeshed/stdlib/2and3/site.pyi
typeshed/stdlib/2and3/smtpd.pyi
typeshed/stdlib/2and3/sndhdr.pyi
typeshed/stdlib/2and3/socket.pyi
typeshed/stdlib/2and3/sre_compile.pyi
typeshed/stdlib/2and3/stringprep.pyi
typeshed/stdlib/2and3/struct.pyi
typeshed/stdlib/2and3/sunau.pyi
......@@ -589,6 +603,7 @@ typeshed/stdlib/2and3/tarfile.pyi
typeshed/stdlib/2and3/telnetlib.pyi
typeshed/stdlib/2and3/termios.pyi
typeshed/stdlib/2and3/threading.pyi
typeshed/stdlib/2and3/time.pyi
typeshed/stdlib/2and3/timeit.pyi
typeshed/stdlib/2and3/token.pyi
typeshed/stdlib/2and3/trace.pyi
......@@ -695,7 +710,6 @@ typeshed/stdlib/3/atexit.pyi
typeshed/stdlib/3/builtins.pyi
typeshed/stdlib/3/compileall.pyi
typeshed/stdlib/3/configparser.pyi
typeshed/stdlib/3/datetime.pyi
typeshed/stdlib/3/decimal.pyi
typeshed/stdlib/3/fcntl.pyi
typeshed/stdlib/3/fnmatch.pyi
......@@ -744,11 +758,11 @@ typeshed/stdlib/3/symbol.pyi
typeshed/stdlib/3/sys.pyi
typeshed/stdlib/3/tempfile.pyi
typeshed/stdlib/3/textwrap.pyi
typeshed/stdlib/3/time.pyi
typeshed/stdlib/3/tokenize.pyi
typeshed/stdlib/3/types.pyi
typeshed/stdlib/3/typing.pyi
typeshed/stdlib/3.3/ipaddress.pyi
typeshed/stdlib/3.3/lzma.pyi
typeshed/stdlib/3.4/_stat.pyi
typeshed/stdlib/3.4/_tracemalloc.pyi
typeshed/stdlib/3.4/enum.pyi
......@@ -777,6 +791,9 @@ typeshed/stdlib/3/concurrent/futures/_base.pyi
typeshed/stdlib/3/concurrent/futures/process.pyi
typeshed/stdlib/3/concurrent/futures/thread.pyi
typeshed/stdlib/3/curses/__init__.pyi
typeshed/stdlib/3/curses/ascii.pyi
typeshed/stdlib/3/curses/panel.pyi
typeshed/stdlib/3/curses/textpad.pyi
typeshed/stdlib/3/email/__init__.pyi
typeshed/stdlib/3/email/charset.pyi
typeshed/stdlib/3/email/contentmanager.pyi
......@@ -823,6 +840,7 @@ typeshed/stdlib/3/multiprocessing/context.pyi
typeshed/stdlib/3/multiprocessing/managers.pyi
typeshed/stdlib/3/multiprocessing/pool.pyi
typeshed/stdlib/3/multiprocessing/process.pyi
typeshed/stdlib/3/multiprocessing/queues.pyi
typeshed/stdlib/3/multiprocessing/synchronize.pyi
typeshed/stdlib/3/os/__init__.pyi
typeshed/stdlib/3/os/path.pyi
......@@ -861,12 +879,6 @@ typeshed/third_party/2/cryptography/hazmat/primitives/serialization.pyi
typeshed/third_party/2/cryptography/hazmat/primitives/asymmetric/__init__.pyi
typeshed/third_party/2/cryptography/hazmat/primitives/asymmetric/dsa.pyi
typeshed/third_party/2/cryptography/hazmat/primitives/asymmetric/rsa.pyi
typeshed/third_party/2/dateutil/__init__.pyi
typeshed/third_party/2/dateutil/parser.pyi
typeshed/third_party/2/dateutil/relativedelta.pyi
typeshed/third_party/2/dateutil/tz/__init__.pyi
typeshed/third_party/2/dateutil/tz/_common.pyi
typeshed/third_party/2/dateutil/tz/tz.pyi
typeshed/third_party/2/fb303/FacebookService.pyi
typeshed/third_party/2/fb303/__init__.pyi
typeshed/third_party/2/google/__init__.pyi
......@@ -922,6 +934,7 @@ typeshed/third_party/2/tornado/httputil.pyi
typeshed/third_party/2/tornado/ioloop.pyi
typeshed/third_party/2/tornado/locks.pyi
typeshed/third_party/2/tornado/netutil.pyi
typeshed/third_party/2/tornado/process.pyi
typeshed/third_party/2/tornado/tcpserver.pyi
typeshed/third_party/2/tornado/testing.pyi
typeshed/third_party/2/tornado/util.pyi
......@@ -1029,6 +1042,11 @@ typeshed/third_party/2and3/Crypto/Util/number.pyi
typeshed/third_party/2and3/Crypto/Util/randpool.pyi
typeshed/third_party/2and3/Crypto/Util/strxor.pyi
typeshed/third_party/2and3/atomicwrites/__init__.pyi
typeshed/third_party/2and3/attr/__init__.pyi
typeshed/third_party/2and3/attr/converters.pyi
typeshed/third_party/2and3/attr/exceptions.pyi
typeshed/third_party/2and3/attr/filters.pyi
typeshed/third_party/2and3/attr/validators.pyi
typeshed/third_party/2and3/backports/__init__.pyi
typeshed/third_party/2and3/backports/ssl_match_hostname.pyi
typeshed/third_party/2and3/boto/__init__.pyi
......@@ -1073,6 +1091,12 @@ typeshed/third_party/2and3/click/parser.pyi
typeshed/third_party/2and3/click/termui.pyi
typeshed/third_party/2and3/click/types.pyi
typeshed/third_party/2and3/click/utils.pyi
typeshed/third_party/2and3/dateutil/__init__.pyi
typeshed/third_party/2and3/dateutil/parser.pyi
typeshed/third_party/2and3/dateutil/relativedelta.pyi
typeshed/third_party/2and3/dateutil/tz/__init__.pyi
typeshed/third_party/2and3/dateutil/tz/_common.pyi
typeshed/third_party/2and3/dateutil/tz/tz.pyi
typeshed/third_party/2and3/jinja2/__init__.pyi
typeshed/third_party/2and3/jinja2/_compat.pyi
typeshed/third_party/2and3/jinja2/_stringdefs.pyi
......@@ -1167,14 +1191,6 @@ typeshed/third_party/2and3/requests/packages/urllib3/util/retry.pyi
typeshed/third_party/2and3/requests/packages/urllib3/util/ssl_.pyi
typeshed/third_party/2and3/requests/packages/urllib3/util/timeout.pyi
typeshed/third_party/2and3/requests/packages/urllib3/util/url.pyi
typeshed/third_party/2and3/thrift/Thrift.pyi
typeshed/third_party/2and3/thrift/__init__.pyi
typeshed/third_party/2and3/thrift/protocol/TBinaryProtocol.pyi
typeshed/third_party/2and3/thrift/protocol/TProtocol.pyi
typeshed/third_party/2and3/thrift/protocol/__init__.pyi
typeshed/third_party/2and3/thrift/transport/TSocket.pyi
typeshed/third_party/2and3/thrift/transport/TTransport.pyi
typeshed/third_party/2and3/thrift/transport/__init__.pyi
typeshed/third_party/2and3/yaml/__init__.pyi
typeshed/third_party/2and3/yaml/composer.pyi
typeshed/third_party/2and3/yaml/constructor.pyi
......@@ -1194,12 +1210,6 @@ typeshed/third_party/2and3/yaml/tokens.pyi
typeshed/third_party/3/enum.pyi
typeshed/third_party/3/itsdangerous.pyi
typeshed/third_party/3/pkg_resources.pyi
typeshed/third_party/3/dateutil/__init__.pyi
typeshed/third_party/3/dateutil/parser.pyi
typeshed/third_party/3/dateutil/relativedelta.pyi
typeshed/third_party/3/dateutil/tz/__init__.pyi
typeshed/third_party/3/dateutil/tz/_common.pyi
typeshed/third_party/3/dateutil/tz/tz.pyi
typeshed/third_party/3/docutils/__init__.pyi
typeshed/third_party/3/docutils/examples.pyi
typeshed/third_party/3/docutils/nodes.pyi
......
typed-ast<1.2.0,>=1.1.0
psutil<5.5.0,>=5.4.0
[:python_version < "3.5"]
typing>=3.5.3
[dmypy]
[dmypy:sys_platform != "win32"]
psutil<5.5.0,>=5.4.0
......@@ -52,6 +52,14 @@ from mypy.types import Type
from mypy.version import __version__
from mypy.plugin import Plugin, DefaultPlugin, ChainedPlugin
from mypy.defaults import PYTHON3_VERSION_MIN
from mypy.server.deps import get_dependencies
# Switch to True to produce debug output related to fine-grained incremental
# mode only that is useful during development. This produces only a subset of
# output compared to --verbose output. We use a global flag to enable this so
# that it's easy to enable this when running tests.
DEBUG_FINE_GRAINED = False
PYTHON_EXTENSIONS = ['.pyi', '.py']
......@@ -80,7 +88,7 @@ class BuildResult:
self.graph = graph
self.files = manager.modules
self.types = manager.all_types # Non-empty for tests only or if dumping deps
self.errors = manager.errors.messages()
self.errors = [] # type: List[str] # Filled in by build if desired
class BuildSource:
......@@ -133,6 +141,7 @@ def build(sources: List[BuildSource],
alt_lib_path: Optional[str] = None,
bin_dir: Optional[str] = None,
saved_cache: Optional[SavedCache] = None,
flush_errors: Optional[Callable[[List[str], bool], None]] = None,
) -> BuildResult:
"""Analyze a program.
......@@ -142,6 +151,11 @@ def build(sources: List[BuildSource],
Return BuildResult if successful or only non-blocking errors were found;
otherwise raise CompileError.
If a flush_errors callback is provided, all error messages will be
passed to it and the errors and messages fields of BuildResult and
CompileError (respectively) will be empty. Otherwise those fields will
report any error messages.
Args:
sources: list of sources to build
options: build options
......@@ -150,7 +164,40 @@ def build(sources: List[BuildSource],
bin_dir: directory containing the mypy script, used for finding data
directories; if omitted, use '.' as the data directory
saved_cache: optional dict with saved cache state for dmypy (read-write!)
flush_errors: optional function to flush errors after a file is processed
"""
# If we were not given a flush_errors, we use one that will populate those
# fields for callers that want the traditional API.
messages = []
def default_flush_errors(new_messages: List[str], is_serious: bool) -> None:
messages.extend(new_messages)
flush_errors = flush_errors or default_flush_errors
try:
result = _build(sources, options, alt_lib_path, bin_dir, saved_cache, flush_errors)
result.errors = messages
return result
except CompileError as e:
# CompileErrors raised from an errors object carry all of the
# messages that have not been reported out by error streaming.
# Patch it up to contain either none or all none of the messages,
# depending on whether we are flushing errors.
serious = not e.use_stdout
flush_errors(e.messages, serious)
e.messages = messages
raise
def _build(sources: List[BuildSource],
options: Options,
alt_lib_path: Optional[str],
bin_dir: Optional[str],
saved_cache: Optional[SavedCache],
flush_errors: Callable[[List[str], bool], None],
) -> BuildResult:
# This seems the most reasonable place to tune garbage collection.
gc.set_threshold(50000)
......@@ -212,7 +259,8 @@ def build(sources: List[BuildSource],
version_id=__version__,
plugin=plugin,
errors=errors,
saved_cache=saved_cache)
saved_cache=saved_cache,
flush_errors=flush_errors)
try:
graph = dispatch(sources, manager)
......@@ -352,6 +400,7 @@ CacheMeta = NamedTuple('CacheMeta',
('child_modules', List[str]), # all submodules of the given module
('options', Optional[Dict[str, object]]), # build options
('dep_prios', List[int]),
('dep_lines', List[int]),
('interface_hash', str), # hash representing the public interface
('version_id', str), # mypy version for cache invalidation
('ignore_all', bool), # if errors were ignored
......@@ -377,6 +426,7 @@ def cache_meta_from_dict(meta: Dict[str, Any], data_json: str) -> CacheMeta:
meta.get('child_modules', []),
meta.get('options'),
meta.get('dep_prios', []),
meta.get('dep_lines', []),
meta.get('interface_hash', ''),
meta.get('version_id', sentinel),
meta.get('ignore_all', True),
......@@ -518,6 +568,7 @@ class BuildManager:
version_id: The current mypy version (based on commit id when possible)
plugin: Active mypy plugin(s)
errors: Used for reporting all errors
flush_errors: A function for processing errors after each SCC
saved_cache: Dict with saved cache state for dmypy and fine-grained incremental mode
(read-write!)
stats: Dict with various instrumentation numbers
......@@ -532,6 +583,7 @@ class BuildManager:
version_id: str,
plugin: Plugin,
errors: Errors,
flush_errors: Callable[[List[str], bool], None],
saved_cache: Optional[SavedCache] = None,
) -> None:
self.start_time = time.time()
......@@ -555,6 +607,7 @@ class BuildManager:
self.stale_modules = set() # type: Set[str]
self.rechecked_modules = set() # type: Set[str]
self.plugin = plugin
self.flush_errors = flush_errors
self.saved_cache = saved_cache if saved_cache is not None else {} # type: SavedCache
self.stats = {} # type: Dict[str, Any] # Values are ints or floats
......@@ -688,6 +741,17 @@ class BuildManager:
print(file=sys.stderr)
sys.stderr.flush()
def log_fine_grained(self, *message: str) -> None:
if self.options.verbosity >= 1:
self.log('fine-grained:', *message)
elif DEBUG_FINE_GRAINED:
# Output log in a simplified format that is quick to browse.
if message:
print(*message, file=sys.stderr)
else:
print(file=sys.stderr)
sys.stderr.flush()
def trace(self, *message: str) -> None:
if self.options.verbosity >= 2:
print('TRACE:', *message, file=sys.stderr)
......@@ -996,7 +1060,8 @@ def find_cache_meta(id: str, path: str, manager: BuildManager) -> Optional[Cache
# Ignore cache if generated by an older mypy version.
if ((m.version_id != manager.version_id and not manager.options.skip_version_check)
or m.options is None
or len(m.dependencies) != len(m.dep_prios)):
or len(m.dependencies) != len(m.dep_prios)
or len(m.dependencies) != len(m.dep_lines)):
manager.log('Metadata abandoned for {}: new attributes are missing'.format(id))
return None
......@@ -1084,6 +1149,17 @@ def validate_meta(meta: Optional[CacheMeta], id: str, path: Optional[str],
if not stat.S_ISREG(st.st_mode):
manager.log('Metadata abandoned for {}: file {} does not exist'.format(id, path))
return None
# When we are using a fine-grained cache, we want our initial
# build() to load all of the cache information and then do a
# fine-grained incremental update to catch anything that has
# changed since the cache was generated. We *don't* want to do a
# coarse-grained incremental rebuild, so we accept the cache
# metadata even if it doesn't match the source file.
if manager.options.use_fine_grained_cache:
manager.log('Using potentially stale metadata for {}'.format(id))
return meta
size = st.st_size
if size != meta.size:
manager.log('Metadata abandoned for {}: file {} has different size'.format(id, path))
......@@ -1113,6 +1189,7 @@ def validate_meta(meta: Optional[CacheMeta], id: str, path: Optional[str],
'options': (manager.options.clone_for_module(id)
.select_options_affecting_cache()),
'dep_prios': meta.dep_prios,
'dep_lines': meta.dep_lines,
'interface_hash': meta.interface_hash,
'version_id': manager.version_id,
'ignore_all': meta.ignore_all,
......@@ -1140,8 +1217,9 @@ def compute_hash(text: str) -> str:
def write_cache(id: str, path: str, tree: MypyFile,
serialized_fine_grained_deps: Dict[str, List[str]],
dependencies: List[str], suppressed: List[str],
child_modules: List[str], dep_prios: List[int],
child_modules: List[str], dep_prios: List[int], dep_lines: List[int],
old_interface_hash: str, source_hash: str,
ignore_all: bool, manager: BuildManager) -> Tuple[str, Optional[CacheMeta]]:
"""Write cache files for a module.
......@@ -1156,8 +1234,12 @@ def write_cache(id: str, path: str, tree: MypyFile,
tree: the fully checked module data
dependencies: module IDs on which this module depends
suppressed: module IDs which were suppressed as dependencies
child_modules: module IDs which are this package's direct submodules
dep_prios: priorities (parallel array to dependencies)
dep_lines: import line locations (parallel array to dependencies)
old_interface_hash: the hash from the previous version of the data cache file
source_hash: the hash of the source code
ignore_all: the ignore_all flag for this module
manager: the build manager (for pyversion, log/trace)
Returns:
......@@ -1175,7 +1257,9 @@ def write_cache(id: str, path: str, tree: MypyFile,
assert os.path.dirname(meta_json) == parent
# Serialize data and analyze interface
data = tree.serialize()
data = {'tree': tree.serialize(),
'fine_grained_deps': serialized_fine_grained_deps,
}
if manager.options.debug_cache:
data_str = json.dumps(data, indent=2, sort_keys=True)
else:
......@@ -1236,6 +1320,7 @@ def write_cache(id: str, path: str, tree: MypyFile,
'child_modules': child_modules,
'options': options.select_options_affecting_cache(),
'dep_prios': dep_prios,
'dep_lines': dep_lines,
'interface_hash': interface_hash,
'version_id': manager.version_id,
'ignore_all': ignore_all,
......@@ -1440,7 +1525,7 @@ class State:
data = None # type: Optional[str]
tree = None # type: Optional[MypyFile]
is_from_saved_cache = False # True if the tree came from the in-memory cache
dependencies = None # type: List[str]
dependencies = None # type: List[str] # Modules directly imported by the module
suppressed = None # type: List[str] # Suppressed/missing dependencies
priorities = None # type: Dict[str, int]
......@@ -1477,6 +1562,8 @@ class State:
# Whether the module has an error or any of its dependencies have one.
transitive_error = False
fine_grained_deps = None # type: Dict[str, Set[str]]
# Type checker used for checking this file. Use type_checker() for
# access and to construct this on demand.
_type_checker = None # type: Optional[TypeChecker]
......@@ -1505,6 +1592,7 @@ class State:
self.id = id or '__main__'
self.options = manager.options.clone_for_module(self.id)
self._type_checker = None
self.fine_grained_deps = {}
if not path and source is None:
assert id is not None
file_id = id
......@@ -1580,8 +1668,10 @@ class State:
assert len(self.meta.dependencies) == len(self.meta.dep_prios)
self.priorities = {id: pri
for id, pri in zip(self.meta.dependencies, self.meta.dep_prios)}
assert len(self.meta.dependencies) == len(self.meta.dep_lines)
self.dep_line_map = {id: line
for id, line in zip(self.meta.dependencies, self.meta.dep_lines)}
self.child_modules = set(self.meta.child_modules)
self.dep_line_map = {}
else:
# Parse the file (and then some) to get the dependencies.
self.parse_file()
......@@ -1688,7 +1778,9 @@ class State:
with open(self.meta.data_json) as f:
data = json.load(f)
# TODO: Assert data file wasn't changed.
self.tree = MypyFile.deserialize(data)
self.tree = MypyFile.deserialize(data['tree'])
self.fine_grained_deps = {k: set(v) for k, v in data['fine_grained_deps'].items()}
self.manager.modules[self.id] = self.tree
self.manager.add_stats(fresh_trees=1)
......@@ -1850,14 +1942,14 @@ class State:
def semantic_analysis(self) -> None:
assert self.tree is not None, "Internal error: method must be called on parsed file only"
patches = [] # type: List[Callable[[], None]]
patches = [] # type: List[Tuple[int, Callable[[], None]]]
with self.wrap_context():
self.manager.semantic_analyzer.visit_file(self.tree, self.xpath, self.options, patches)
self.patches = patches
def semantic_analysis_pass_three(self) -> None:
assert self.tree is not None, "Internal error: method must be called on parsed file only"
patches = [] # type: List[Callable[[], None]]
patches = [] # type: List[Tuple[int, Callable[[], None]]]
with self.wrap_context():
self.manager.semantic_analyzer_pass3.visit_file(self.tree, self.xpath,
self.options, patches)
......@@ -1866,7 +1958,8 @@ class State:
self.patches = patches + self.patches
def semantic_analysis_apply_patches(self) -> None:
for patch_func in self.patches:
patches_by_priority = sorted(self.patches, key=lambda x: x[0])
for priority, patch_func in patches_by_priority:
patch_func()
def type_check_first_pass(self) -> None:
......@@ -1930,6 +2023,19 @@ class State:
elif dep not in self.suppressed and dep in self.manager.missing_modules:
self.suppressed.append(dep)
def compute_fine_grained_deps(self) -> None:
assert self.tree is not None
if '/typeshed/' in self.xpath or self.xpath.startswith('typeshed/'):
# We don't track changes to typeshed -- the assumption is that they are only changed
# as part of mypy updates, which will invalidate everything anyway.
#
# TODO: Not a reliable test, as we could have a package named typeshed.
# TODO: Consider relaxing this -- maybe allow some typeshed changes to be tracked.
return
self.fine_grained_deps = get_dependencies(target=self.tree,
type_map=self.type_map(),
python_version=self.options.python_version)
def valid_references(self) -> Set[str]:
assert self.ancestors is not None
valid_refs = set(self.dependencies + self.suppressed + self.ancestors)
......@@ -1954,10 +2060,12 @@ class State:
self.mark_interface_stale(on_errors=True)
return
dep_prios = self.dependency_priorities()
dep_lines = self.dependency_lines()
new_interface_hash, self.meta = write_cache(
self.id, self.path, self.tree,
{k: list(v) for k, v in self.fine_grained_deps.items()},
list(self.dependencies), list(self.suppressed), list(self.child_modules),
dep_prios, self.interface_hash, self.source_hash, self.ignore_all,
dep_prios, dep_lines, self.interface_hash, self.source_hash, self.ignore_all,
self.manager)
if new_interface_hash == self.interface_hash:
self.manager.log("Cached module {} has same interface".format(self.id))
......@@ -1969,6 +2077,13 @@ class State:
def dependency_priorities(self) -> List[int]:
return [self.priorities.get(dep, PRI_HIGH) for dep in self.dependencies]
def dependency_lines(self) -> List[int]:
return [self.dep_line_map.get(dep, 1) for dep in self.dependencies]
def generate_unused_ignore_notes(self) -> None:
if self.options.warn_unused_ignores:
self.manager.errors.generate_unused_ignore_notes(self.xpath)
def dispatch(sources: List[BuildSource], manager: BuildManager) -> Graph:
set_orig = set(manager.saved_cache)
......@@ -1995,9 +2110,6 @@ def dispatch(sources: List[BuildSource], manager: BuildManager) -> Graph:
dump_graph(graph)
return graph
process_graph(graph, manager)
if manager.options.warn_unused_ignores:
# TODO: This could also be a per-module option.
manager.errors.generate_unused_ignore_notes()
updated = preserve_cache(graph)
set_updated = set(updated)
manager.saved_cache.clear()
......@@ -2268,7 +2380,9 @@ def process_graph(graph: Graph, manager: BuildManager) -> None:
scc_str = " ".join(scc)
if fresh:
if not maybe_reuse_in_memory_tree(graph, scc, manager):
if maybe_reuse_in_memory_tree(graph, scc, manager):
manager.add_stats(sccs_kept=1, nodes_kept=len(scc))
else:
manager.trace("Queuing %s SCC (%s)" % (fresh_msg, scc_str))
fresh_scc_queue.append(scc)
else:
......@@ -2298,6 +2412,14 @@ def process_graph(graph: Graph, manager: BuildManager) -> None:
manager.log("Processing SCC of size %d (%s) as %s" % (size, scc_str, fresh_msg))
process_stale_scc(graph, scc, manager)
# If we are running in fine-grained incremental mode with caching,
# we always process fresh SCCs so that we have all of the symbol
# tables and fine-grained dependencies available.
if manager.options.use_fine_grained_cache:
for prev_scc in fresh_scc_queue:
process_fresh_scc(graph, prev_scc, manager)
fresh_scc_queue = []
sccs_left = len(fresh_scc_queue)
nodes_left = sum(len(scc) for scc in fresh_scc_queue)
manager.add_stats(sccs_left=sccs_left, nodes_left=nodes_left)
......@@ -2484,6 +2606,10 @@ def process_stale_scc(graph: Graph, scc: List[str], manager: BuildManager) -> No
graph[id].transitive_error = True
for id in stale:
graph[id].finish_passes()
if manager.options.cache_fine_grained or manager.options.fine_grained_incremental:
graph[id].compute_fine_grained_deps()
graph[id].generate_unused_ignore_notes()
manager.flush_errors(manager.errors.file_messages(graph[id].xpath), False)
graph[id].write_cache()
graph[id].mark_as_rechecked()
......
This diff is collapsed.