Skip to content
Commits on Source (6)
Mypy is licensed under the terms of the MIT license, reproduced below.
Mypy (and mypyc) are licensed under the terms of the MIT license, reproduced below.
= = = = =
The MIT License
Copyright (c) 2015-2016 Jukka Lehtosalo and contributors
Copyright (c) 2015-2019 Jukka Lehtosalo and contributors
Permission is hereby granted, free of charge, to any person obtaining a
copy of this software and associated documentation files (the "Software"),
......@@ -26,8 +26,10 @@ DEALINGS IN THE SOFTWARE.
= = = = =
Portions of mypy are licensed under different licenses. The files
under stdlib-samples are licensed under the PSF 2 License, reproduced below.
Portions of mypy and mypyc are licensed under different licenses. The
files under stdlib-samples as well as the files
mypyc/lib-rt/pythonsupport.h and mypyc/lib-rt/getargs.c are licensed
under the PSF 2 License, reproduced below.
= = = = =
......@@ -223,5 +225,3 @@ FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
= = = = =
\ No newline at end of file
Metadata-Version: 2.1
Name: mypy
Version: 0.720
Version: 0.730
Summary: Optional static typing for Python
Home-page: http://www.mypy-lang.org/
Author: Jukka Lehtosalo
......@@ -26,4 +26,5 @@ Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Topic :: Software Development
Requires-Python: >=3.5
Provides-Extra: dmypy
......@@ -265,9 +265,10 @@ Compiled version of mypy
------------------------
We have built an compiled version of mypy using the [mypyc
compiler](https://github.com/mypyc/mypyc) for mypy-annotated Python
code. It is approximately 4 times faster than interpreted mypy and is
available (and the default) for 64-bit Windows, macOS, and Linux.
compiler](https://github.com/python/mypy/tree/master/mypyc) for
mypy-annotated Python code. It is approximately 4 times faster than
interpreted mypy and is available (and the default) for 64-bit
Windows, macOS, and Linux.
To install an interpreted mypy instead, use:
......
mypy (0.730-1) UNRELEASED; urgency=medium
* New upstream version
-- Michael R. Crusoe <michael.crusoe@gmail.com> Fri, 27 Sep 2019 13:18:42 +0200
mypy (0.720-3) unstable; urgency=medium
* debhelper-compat 12
......
From 4c8e430e92ab290aca6f2147785dcadb26e7c809 Mon Sep 17 00:00:00 2001
From: Michael Lee <michael.lee.0x2a@gmail.com>
Date: Mon, 29 Jul 2019 09:31:16 -0700
Subject: [PATCH] Fix XML attribute order in tests
Our tests recently started breaking -- it turns out this was because
LXML 4.4.0 was released this Saturday, and LXML apparently respects now
respects the insertion order of dicts/keyword arguments when setting
XML attributes.
See the changelog for more details: https://github.com/lxml/lxml/blob/master/CHANGES.txt
I didn't feel like tweaking a bunch of tests, so decided to fix this
in a relatively lazy way: I just went through every place we instantiated
an "Element" or "SubElement" object in report.py and manually sorted the
attributes.
The only exception was the precision info in stats.py -- I discovered to
my mild surprise that the order of those stats apparently has semantic
meaning (the higher the number, the less "precise" that line is?), so
decided it might be more useful to preserve that ordering.
And for good measure, I pinned the LXML test requirement to 4.4.0 so
we won't need to remember to keep attributes sorted or whatever when
adding new tests in the future.
---
mypy/report.py | 22 +++++++++++-----------
test-data/unit/check-reports.test | 2 +-
test-requirements.txt | 2 +-
3 files changed, 13 insertions(+), 13 deletions(-)
--- mypy.orig/mypy/report.py
+++ mypy/mypy/report.py
@@ -445,10 +445,11 @@
status = visitor.line_map.get(lineno, stats.TYPE_EMPTY)
file_info.counts[status] += 1
etree.SubElement(root, 'line',
- number=str(lineno),
- precision=stats.precision_names[status],
+ any_info=self._get_any_info_for_line(visitor, lineno),
content=line_text.rstrip('\n').translate(self.control_fixer),
- any_info=self._get_any_info_for_line(visitor, lineno))
+ number=str(lineno),
+ precision=stats.precision_names[status]
+ )
# Assumes a layout similar to what XmlReporter uses.
xslt_path = os.path.relpath('mypy-html.xslt', path)
transform_pi = etree.ProcessingInstruction('xml-stylesheet',
@@ -483,9 +484,9 @@
for file_info in output_files:
etree.SubElement(root, 'file',
file_info.attrib(),
- total=str(file_info.total()),
+ module=file_info.module,
name=file_info.name,
- module=file_info.module)
+ total=str(file_info.total()))
xslt_path = os.path.relpath('mypy-html.xslt', '.')
transform_pi = etree.ProcessingInstruction('xml-stylesheet',
'type="text/xsl" href="%s"' % pathname2url(xslt_path))
@@ -517,8 +518,8 @@
def as_xml(self) -> Any:
package_element = etree.Element('package',
- name=self.name,
- complexity='1.0')
+ complexity='1.0',
+ name=self.name)
package_element.attrib['branch-rate'] = '0'
package_element.attrib['line-rate'] = get_line_rate(self.covered_lines, self.total_lines)
classes_element = etree.SubElement(package_element, 'classes')
@@ -559,8 +560,8 @@
class_name = os.path.basename(path)
file_info = FileInfo(path, tree._fullname)
class_element = etree.Element('class',
- filename=path,
complexity='1.0',
+ filename=path,
name=class_name)
etree.SubElement(class_element, 'methods')
lines_element = etree.SubElement(class_element, 'lines')
@@ -582,10 +583,10 @@
branch = True
file_info.counts[status] += 1
line_element = etree.SubElement(lines_element, 'line',
- number=str(lineno),
- precision=stats.precision_names[status],
+ branch=str(branch).lower(),
hits=str(hits),
- branch=str(branch).lower())
+ number=str(lineno),
+ precision=stats.precision_names[status])
if branch:
line_element.attrib['condition-coverage'] = '50% (1/2)'
class_element.attrib['branch-rate'] = '0'
Author: Michael R. Crusoe <michael.crusoe@gmail.com>
Subject: Don't include mypyc for now
There is no documentation for how to use it.
It describes itself as being for "prototyping and testing"
"Mypyc is not (yet) an end-user product."
https://github.com/python/mypy/blob/master/mypyc/doc/dev-intro.md
So it doesn't sound ready for general release yet
--- mypy.orig/setup.py
+++ mypy/setup.py
@@ -181,7 +181,6 @@
'mypyc', 'mypyc.test',
],
package_data={'mypy': package_data},
- scripts=['scripts/mypyc'],
entry_points={'console_scripts': ['mypy=mypy.__main__:console_entry',
'stubgen=mypy.stubgen:main',
'dmypy=mypy.dmypy.client:console_entry',
Author: Michael R. Crusoe <michael.crusoe@gmail.com>
Description: Add file from upstream missing from their sdist
--- /dev/null
+++ mypy/misc/proper_plugin.py
@@ -0,0 +1,131 @@
+from mypy.plugin import Plugin, FunctionContext
+from mypy.types import (
+ Type, Instance, CallableType, UnionType, get_proper_type, ProperType,
+ get_proper_types, TupleType, NoneTyp, AnyType
+)
+from mypy.nodes import TypeInfo
+from mypy.subtypes import is_proper_subtype
+
+from typing_extensions import Type as typing_Type
+from typing import Optional, Callable
+
+
+class ProperTypePlugin(Plugin):
+ """
+ A plugin to ensure that every type is expanded before doing any special-casing.
+
+ This solves the problem that we have hundreds of call sites like:
+
+ if isinstance(typ, UnionType):
+ ... # special-case union
+
+ But after introducing a new type TypeAliasType (and removing immediate expansion)
+ all these became dangerous because typ may be e.g. an alias to union.
+ """
+ def get_function_hook(self, fullname: str
+ ) -> Optional[Callable[[FunctionContext], Type]]:
+ if fullname == 'builtins.isinstance':
+ return isinstance_proper_hook
+ if fullname == 'mypy.types.get_proper_type':
+ return proper_type_hook
+ if fullname == 'mypy.types.get_proper_types':
+ return proper_types_hook
+ return None
+
+
+def isinstance_proper_hook(ctx: FunctionContext) -> Type:
+ right = get_proper_type(ctx.arg_types[1][0])
+ for arg in ctx.arg_types[0]:
+ if (is_improper_type(arg) or
+ isinstance(get_proper_type(arg), AnyType) and is_dangerous_target(right)):
+ if is_special_target(right):
+ return ctx.default_return_type
+ ctx.api.fail('Never apply isinstance() to unexpanded types;'
+ ' use mypy.types.get_proper_type() first', ctx.context)
+ return ctx.default_return_type
+
+
+def is_special_target(right: ProperType) -> bool:
+ """Whitelist some special cases for use in isinstance() with improper types."""
+ if isinstance(right, CallableType) and right.is_type_obj():
+ if right.type_object().fullname() == 'builtins.tuple':
+ # Used with Union[Type, Tuple[Type, ...]].
+ return True
+ if right.type_object().fullname() in ('mypy.types.Type',
+ 'mypy.types.ProperType',
+ 'mypy.types.TypeAliasType'):
+ # Special case: things like assert isinstance(typ, ProperType) are always OK.
+ return True
+ if right.type_object().fullname() in ('mypy.types.UnboundType',
+ 'mypy.types.TypeVarType',
+ 'mypy.types.RawExpressionType',
+ 'mypy.types.EllipsisType',
+ 'mypy.types.StarType',
+ 'mypy.types.TypeList',
+ 'mypy.types.CallableArgument',
+ 'mypy.types.PartialType',
+ 'mypy.types.ErasedType'):
+ # Special case: these are not valid targets for a type alias and thus safe.
+ # TODO: introduce a SyntheticType base to simplify this?
+ return True
+ elif isinstance(right, TupleType):
+ return all(is_special_target(t) for t in get_proper_types(right.items))
+ return False
+
+
+def is_improper_type(typ: Type) -> bool:
+ """Is this a type that is not a subtype of ProperType?"""
+ typ = get_proper_type(typ)
+ if isinstance(typ, Instance):
+ info = typ.type
+ return info.has_base('mypy.types.Type') and not info.has_base('mypy.types.ProperType')
+ if isinstance(typ, UnionType):
+ return any(is_improper_type(t) for t in typ.items)
+ return False
+
+
+def is_dangerous_target(typ: ProperType) -> bool:
+ """Is this a dangerous target (right argument) for an isinstance() check?"""
+ if isinstance(typ, TupleType):
+ return any(is_dangerous_target(get_proper_type(t)) for t in typ.items)
+ if isinstance(typ, CallableType) and typ.is_type_obj():
+ return typ.type_object().has_base('mypy.types.Type')
+ return False
+
+
+def proper_type_hook(ctx: FunctionContext) -> Type:
+ """Check if this get_proper_type() call is not redundant."""
+ arg_types = ctx.arg_types[0]
+ if arg_types:
+ arg_type = get_proper_type(arg_types[0])
+ proper_type = get_proper_type_instance(ctx)
+ if is_proper_subtype(arg_type, UnionType.make_union([NoneTyp(), proper_type])):
+ # Minimize amount of spurious errors from overload machinery.
+ # TODO: call the hook on the overload as a whole?
+ if isinstance(arg_type, (UnionType, Instance)):
+ ctx.api.fail('Redundant call to get_proper_type()', ctx.context)
+ return ctx.default_return_type
+
+
+def proper_types_hook(ctx: FunctionContext) -> Type:
+ """Check if this get_proper_types() call is not redundant."""
+ arg_types = ctx.arg_types[0]
+ if arg_types:
+ arg_type = arg_types[0]
+ proper_type = get_proper_type_instance(ctx)
+ item_type = UnionType.make_union([NoneTyp(), proper_type])
+ ok_type = ctx.api.named_generic_type('typing.Iterable', [item_type])
+ if is_proper_subtype(arg_type, ok_type):
+ ctx.api.fail('Redundant call to get_proper_types()', ctx.context)
+ return ctx.default_return_type
+
+
+def get_proper_type_instance(ctx: FunctionContext) -> Instance:
+ types = ctx.api.modules['mypy.types'] # type: ignore
+ proper_type_info = types.names['ProperType']
+ assert isinstance(proper_type_info.node, TypeInfo)
+ return Instance(proper_type_info.node, [])
+
+
+def plugin(version: str) -> typing_Type[ProperTypePlugin]:
+ return ProperTypePlugin
fix-xml-reports
ignore_mypyc
proper_plugin
......@@ -429,8 +429,8 @@ of the above sections.
``--no-implicit-reexport``
By default, imported values to a module are treated as exported and mypy allows
other modules to import them. This flag changes the behavior to not re-export unless
the item is imported using from-as. Note this is always treated as enabled for
stub files. For example:
the item is imported using from-as or is included in ``__all__``. Note this is
always treated as enabled for stub files. For example:
.. code-block:: python
......@@ -438,6 +438,9 @@ of the above sections.
from foo import bar
# This will re-export it as bar and allow other modules to import it
from foo import bar as bar
# This will also re-export bar
from foo import bar
__all__ = ['bar']
``--strict-equality``
......@@ -494,12 +497,27 @@ in error messages.
main.py:3: error: Unsupported operand types for + ("int" and "str")
``--show-column-numbers``
This flag will add column offsets to error messages,
for example, the following indicates an error in line 12, column 9
This flag will add column offsets to error messages.
For example, the following indicates an error in line 12, column 9
(note that column offsets are 0-based)::
main.py:12:9: error: Unsupported operand types for / ("int" and "str")
``--show-error-codes``
This flag will add an error code ``[<code>]`` to error messages. The error
code is shown after each error message::
prog.py:1: error: "str" has no attribute "trim" [attr-defined]
See :ref:`error-codes` for more information.
``--no-color-output``
This flag will disable color output in error messages, enabled by default.
``--no-error-summary``
This flag will disable error summary. By default mypy shows a summary line
including total number of errors, number of files with errors, and number
of files checked.
.. _incremental:
......@@ -530,6 +548,9 @@ beyond what incremental mode can offer, try running mypy in
change this folder. This flag can also be useful for controlling
cache use when using :ref:`remote caching <remote-cache>`.
This setting will override the ``MYPY_CACHE_DIR`` environment
variable if it is set.
Mypy will also always write to the cache even when incremental
mode is disabled so it can "warm up" the cache. To disable
writing to the cache, use ``--cache-dir=/dev/null`` (UNIX)
......@@ -659,18 +680,6 @@ Miscellaneous
have many scripts that import a large package, the behavior enabled
by this flag is often more convenient.)
``--no-new-semantic-analyzer``
This flag disables the improved implementation of
the *semantic analyzer* (the part of mypy that binds Python
names to definitions). The old and the new semantic analyzers
mostly behave identically. The new semantic analyzer is better at
handling import cycles and forward references to definitions. It
also fixes inconsistencies between the daemon and non-daemon modes,
and it detects additional error conditions.
Likely, the old semantic analyzer will be removed in the next
release.
.. _PEP 420: https://www.python.org/dev/peps/pep-0420/
.. _PEP 561: https://www.python.org/dev/peps/pep-0561/
......
......@@ -124,6 +124,14 @@ error:
The second line is now fine, since the ignore comment causes the name
``frobnicate`` to get an implicit ``Any`` type.
.. note::
You can use the form ``# type: ignore[<code>]`` to only ignore
specific errors on the line. This way you are less likely to
silence unexpected errors that are not safe to ignore, and this
will also document what the purpose of the comment is. See
:ref:`error-codes` for more information.
.. note::
The ``# type: ignore`` comment will only assign the implicit ``Any``
......
......@@ -21,6 +21,10 @@ Most flags correspond closely to :ref:`command-line flags
<command-line>` but there are some differences in flag names and some
flags may take a different value based on the module being processed.
Some flags support user home directory and environment variable expansion.
To refer to the user home directory, use ``~`` at the beginning of the path.
To expand environment variables use ``$VARNAME`` or ``${VARNAME}``.
Config file format
******************
......@@ -306,8 +310,8 @@ Miscellaneous strictness flags
``implicit_reexport`` (bool, default True)
By default, imported values to a module are treated as exported and mypy allows
other modules to import them. When false, mypy will not re-export unless
the item is imported using from-as. Note that mypy treats stub files as if this
is always disabled. For example:
the item is imported using from-as or is included in ``__all__``. Note that mypy
treats stub files as if this is always disabled. For example:
.. code-block:: python
......@@ -315,6 +319,9 @@ Miscellaneous strictness flags
from foo import bar
# This will re-export it as bar and allow other modules to import it
from foo import bar as bar
# This will also re-export bar
from foo import bar
__all__ = ['bar']
``strict_equality`` (bool, default False)
Prohibit equality checks, identity checks, and container checks between
......@@ -355,7 +362,8 @@ a list of import discovery options that may be used
``python_executable`` (string)
Specifies the path to the Python executable to inspect to collect
a list of available :ref:`PEP 561 packages <installed-packages>`. Defaults to
a list of available :ref:`PEP 561 packages <installed-packages>`. User
home directory and environment variables will be expanded. Defaults to
the executable used to run mypy.
``no_silence_site_packages`` (bool, default False)
......@@ -366,13 +374,15 @@ a list of import discovery options that may be used
``mypy_path`` (string)
Specifies the paths to use, after trying the paths from ``MYPYPATH`` environment
variable. Useful if you'd like to keep stubs in your repo, along with the config file.
Multiple paths are always separated with a ``:`` or ``,`` regardless of the platform.
User home directory and environment variables will be expanded.
``files`` (string)
A comma-separated list of paths which should be checked by mypy if none are given on the command
line. Supports recursive file globbing using
[the glob library](https://docs.python.org/3/library/glob.html), where `*` (e.g. `*.py`) matches
files in the current directory and `**/` (e.g. `**/*.py`) matches files in any directories below
the current one.
the current one. User home directory and environment variables will be expanded.
Platform configuration
......@@ -405,6 +415,10 @@ section of the command line docs.
``cache_dir`` (string, default ``.mypy_cache``)
Specifies the location where mypy stores incremental cache info.
User home directory and environment variables will be expanded.
This setting will be overridden by the ``MYPY_CACHE_DIR`` environment
variable.
Note that the cache is only read when incremental mode is enabled
but is always written to, unless the value is set to ``/dev/nul``
(UNIX) or ``nul`` (Windows).
......@@ -427,6 +441,15 @@ section of the command line docs.
``show_column_numbers`` (bool, default False)
Shows column numbers in error messages.
``show_error_codes`` (bool, default False)
Shows error codes in error messages. See :ref:`error-codes` for more information.
``color_output`` (bool, default True)
Shows error messages with color enabled.
``error_summary`` (bool, default True)
Shows a short summary line after error messages.
Advanced options
----------------
......@@ -445,7 +468,8 @@ section of the command line docs.
``custom_typeshed_dir`` (string)
Specifies an alternative directory to look for stubs instead of the
default ``typeshed`` directory.
default ``typeshed`` directory. User home directory and environment
variables will be expanded.
``warn_incomplete_stub`` (bool, default False)
Warns about missing type annotations in typeshed. This is only relevant
......
.. _error-code-list:
Error codes enabled by default
==============================
This section documents various errors codes that mypy can generate
with default options. See :ref:`error-codes` for general documentation
about error codes. :ref:`error-codes-optional` documents additional
error codes that you can enable.
Check that attribute exists [attr-defined]
------------------------------------------
Mypy checks that an attribute is defined in the target class or module
when using the dot operator. This applies to both getting and setting
an attribute. New attributes are defined by assignments in the class
body, or assignments to ``self.x`` in methods. These assignments don't
generate ``attr-defined`` errors.
Example:
.. code-block:: python
class Resource:
def __init__(self, name: str) -> None:
self.name = name
r = Resouce('x')
print(r.name) # OK
print(r.id) # Error: "Resource" has no attribute "id" [attr-defined]
r.id = 5 # Error: "Resource" has no attribute "id" [attr-defined]
This error code is also generated if an imported name is not defined
in the module in a ``from ... import`` statement (as long as the
target module can be found):
.. code-block:: python
# Error: Module 'os' has no attribute 'non_existent' [attr-defined]
from os import non_existent
A reference to a missing attribute is given the ``Any`` type. In the
above example, the type of ``non_existent`` will be ``Any``, which can
be important if you silence the error.
Check that attribute exists in each union item [union-attr]
-----------------------------------------------------------
If you access the attribute of a value with a union type, mypy checks
that the attribute is defined for *every* type in that
union. Otherwise the operation can fail at runtime. This also applies
to optional types.
Example:
.. code-block:: python
from typing import Union
class Cat:
def sleep(self) -> None: ...
def miaow(self) -> None: ...
class Dog:
def sleep(self) -> None: ...
def follow_me(self) -> None: ...
def func(animal: Union[Cat, Dog]) -> None:
# OK: 'sleep' is defined for both Cat and Dog
animal.sleep()
# Error: Item "Cat" of "Union[Cat, Dog]" has no attribute "follow_me" [union-attr]
animal.follow_me()
You can often work around these errors by using ``assert isinstance(obj, ClassName)``
or ``assert obj is not None`` to tell mypy that you know that the type is more specific
than what mypy thinks.
Check that name is defined [name-defined]
-----------------------------------------
Mypy expects that all references to names have a corresponding
definition in an active scope, such as an assignment, function
definition or an import. This can catch missing definitions, missing
imports, and typos.
This example accidentally calls ``sort()`` instead of ``sorted()``:
.. code-block:: python
x = sort([3, 2, 4]) # Error: Name 'sort' is not defined [name-defined]
Check arguments in calls [call-arg]
-----------------------------------
Mypy expects that the number and names of arguments match the called function.
Note that argument type checks have a separate error code ``arg-type``.
Example:
.. code-block:: python
from typing import Sequence
def greet(name: str) -> None:
print('hello', name)
greet('jack') # OK
greet('jill', 'jack') # Error: Too many arguments for "greet" [call-arg]
Check argument types [arg-type]
-------------------------------
Mypy checks that argument types in a call match the declared argument
types in the signature of the called function (if one exists).
Example:
.. code-block:: python
from typing import List, Optional
def first(x: List[int]) -> Optional[int]:
return x[0] if x else 0
t = (5, 4)
# Error: Argument 1 to "first" has incompatible type "Tuple[int, int]";
# expected "List[int]" [arg-type]
print(first(t))
Check calls to overloaded functions [call-overload]
---------------------------------------------------
When you call an overloaded function, mypy checks that at least one of
the signatures of the overload items match the argument types in the
call.
Example:
.. code-block:: python
from typing import overload, Optional
@overload
def inc_maybe(x: None) -> None: ...
@overload
def inc_maybe(x: int) -> int: ...
def inc_maybe(x: Optional[int]) -> Optional[int]:
if x is None:
return None
else:
return x + 1
inc_maybe(None) # OK
inc_maybe(5) # OK
# Error: No overload variant of "inc_maybe" matches argument type "float" [call-overload]
inc_maybe(1.2)
Check validity of types [valid-type]
------------------------------------
Mypy checks that each type annotation and any expression that
represents a type is a valid type. Examples of valid types include
classes, union types, callable types, type aliases, and literal types.
Examples of invalid types include bare integer literals, functions,
variables, and modules.
This example incorrectly uses the function ``log`` as a type:
.. code-block:: python
from typing import List
def log(x: object) -> None:
print('log:', repr(x))
# Error: Function "t.log" is not valid as a type [valid-type]
def log_all(objs: List[object], f: log) -> None:
for x in objs:
f(x)
You can use ``Callable`` as the type for callable objects:
.. code-block:: python
from typing import List, Callable
# OK
def log_all(objs: List[object], f: Callable[[object], None]) -> None:
for x in objs:
f(x)
Require annotation if variable type is unclear [var-annotated]
--------------------------------------------------------------
In some cases mypy can't infer the type of a variable without an
explicit annotation. Mypy treats this as an error. This typically
happens when you initialize a variable with an empty collection or
``None``. If mypy can't infer the collection item type, mypy replaces
any parts of the type it couldn't infer with ``Any`` and generates an
error.
Example with an error:
.. code-block:: python
class Bundle:
def __init__(self) -> None:
# Error: Need type annotation for 'items'
# (hint: "items: List[<type>] = ...") [var-annotated]
self.items = []
reveal_type(Bundle().items) # list[Any]
To address this, we add an explicit annotation:
.. code-block:: python
from typing import List
class Bundle:
def __init__(self) -> None:
self.items: List[str] = [] # OK
reveal_type(Bundle().items) # list[str]
Check validity of overrides [override]
--------------------------------------
Mypy checks that an overridden method or attribute is compatible with
the base class. A method in a subclass must accept all arguments
that the base class method accepts, and the return type must conform
to the return type in the base class (Liskov substitution principle).
Argument types can be more general is a subclass (i.e., they can vary
contravariantly). The return type can be narrowed in a subclass
(i.e., it can vary covariantly). It's okay to define additional
arguments in a subclass method, as long all extra arguments have default
values or can be left out (``*args``, for example).
Example:
.. code-block:: python
from typing import Optional, Union
class Base:
def method(self,
arg: int) -> Optional[int]:
...
class Derived(Base):
def method(self,
arg: Union[int, str]) -> int: # OK
...
class DerivedBad(Base):
# Error: Argument 1 of "method" is incompatible with "Base" [override]
def method(self,
arg: bool) -> int:
...
Check that function returns a value [return]
--------------------------------------------
If a function has a non-``None`` return type, mypy expects that the
function always explicitly returns a value (or raises an exception).
The function should not fall off the end of the function, since this
is often a bug.
Example:
.. code-block:: python
# Error: Missing return statement [return]
def show(x: int) -> int:
print(x)
# Error: Missing return statement [return]
def pred1(x: int) -> int:
if x > 0:
return x - 1
# OK
def pred2(x: int) -> int:
if x > 0:
return x - 1
else:
raise ValueError('not defined for zero')
Check that return value is compatible [return-value]
----------------------------------------------------
Mypy checks that the returned value is compatible with the type
signature of the function.
Example:
.. code-block:: python
def func(x: int) -> str:
# Error: Incompatible return value type (got "int", expected "str") [return-value]
return x + 1
Check types in assignment statement [assignment]
------------------------------------------------
Mypy checks that the assigned expression is compatible with the
assignment target (or targets).
Example:
.. code-block:: python
class Resource:
def __init__(self, name: str) -> None:
self.name = name
r = Resource('A')
r.name = 'B' # OK
# Error: Incompatible types in assignment (expression has type "int",
# variable has type "str") [assignment]
r.name = 5
Check type variable values [type-var]
-------------------------------------
Mypy checks that value of a type variable is compatible with a value
restriction or the upper bound type.
Example:
.. code-block:: python
from typing import TypeVar
T1 = TypeVar('T1', int, float)
def add(x: T1, y: T1) -> T1:
return x + y
add(4, 5.5) # OK
# Error: Value of type variable "T1" of "add" cannot be "str" [type-var]
add('x', 'y')
Check uses of various operators [operator]
------------------------------------------
Mypy checks that operands support a binary or unary operation, such as
``+`` or ``~``. Indexing operations are so common that they have their
own error code ``index`` (see below).
Example:
.. code-block:: python
# Error: Unsupported operand types for + ("int" and "str") [operator]
1 + 'x'
Check indexing operations [index]
---------------------------------
Mypy checks that the indexed value in indexing operation such as
``x[y]`` supports indexing, and that the index expression has a valid
type.
Example:
.. code-block:: python
a = {'x': 1, 'y': 2}
a['x'] # OK
# Error: Invalid index type "int" for "Dict[str, int]"; expected type "str" [index]
print(a[1])
# Error: Invalid index type "bytes" for "Dict[str, int]"; expected type "str" [index]
a[b'x'] = 4
Check list items [list-item]
----------------------------
When constructing a list using ``[item, ...]``, mypy checks that each item
is compatible with the list type that is inferred from the surrounding
context.
Example:
.. code-block:: python
from typing import List
# Error: List item 0 has incompatible type "int"; expected "str" [list-item]
a: List[str] = [0]
Check dict items [dict-item]
----------------------------
When constructing a dictionary using ``{key: value, ...}`` or ``dict(key=value, ...)``,
mypy checks that each key and value is compatible with the dictionary type that is
inferred from the surrounding context.
Example:
.. code-block:: python
from typing import Dict
# Error: Dict entry 0 has incompatible type "str": "str"; expected "str": "int" [dict-item]
d: Dict[str, int] = {'key': 'value'}
Check TypedDict items [typeddict-item]
--------------------------------------
When constructing a TypedDict object, mypy checks that each key and value is compatible
with the TypedDict type that is inferred from the surrounding context.
Example:
.. code-block:: python
from typing_extensions import TypedDict
class Point(TypedDict):
x: int
y: int
# Error: Incompatible types (expression has type "float",
# TypedDict item "x" has type "int") [typeddict-item]
p: Point = {'x': 1.2, 'y': 4}
Check that type of target is known [has-type]
---------------------------------------------
Mypy sometimes generates an error when it hasn't inferred any type for
a variable being referenced. This can happen for references to
variables that are initialized later in the source file, and for
references across modules that form an import cycle. When this
happens, the reference gets an implicit ``Any`` type.
In this example the definitions of ``x`` and ``y`` are circular:
.. code-block:: python
class Problem:
def set_x(self) -> None:
# Error: Cannot determine type of 'y' [has-type]
self.x = self.y
def set_y(self) -> None:
self.y = self.x
To work around this error, you can add an explicit type annotation to
the target variable or attribute. Sometimes you can also reorganize
the code so that the definition of the variable is placed earlier than
the reference to the variable in a source file. Untangling cyclic
imports may also help.
We add an explicit annotation to the ``y`` attribute to work around
the issue:
.. code-block:: python
class Problem:
def set_x(self) -> None:
self.x = self.y # OK
def set_y(self) -> None:
self.y: int = self.x # Added annotation here
Check that import target can be found [import]
----------------------------------------------
Mypy generates an error if it can't find the source code or a stub file
for an imported module.
Example:
.. code-block:: python
# Error: Cannot find module named 'acme' [import]
import acme
See :ref:`ignore-missing-imports` for how to work around these errors.
Check that each name is defined once [no-redef]
-----------------------------------------------
Mypy may generate an error if you have multiple definitions for a name
in the same namespace. The reason is that this is often an error, as
the second definition may overwrite the first one. Also, mypy often
can't be able to determine whether references point to the first or
the second definition, which would compromise type checking.
If you silence this error, all references to the defined name refer to
the *first* definition.
Example:
.. code-block:: python
class A:
def __init__(self, x: int) -> None: ...
class A: # Error: Name 'A' already defined on line 1 [no-redef]
def __init__(self, x: str) -> None: ...
# Error: Argument 1 to "A" has incompatible type "str"; expected "int"
# (the first definition wins!)
A('x')
Check that called function returns a value [func-returns-value]
---------------------------------------------------------------
Mypy reports an error if you call a function with a ``None``
return type and don't ignore the return value, as this is
usually (but not always) a programming error.
In this example, the ``if f()`` check is always false since ``f``
returns ``None``:
.. code-block:: python
def f() -> None:
...
# OK: we don't do anything with the return value
f()
# Error: "f" does not return a value [func-returns-value]
if f():
print("not false")
Check instantiation of abstract classes [abstract]
--------------------------------------------------
Mypy generates an error if you try to instantiate an abstract base
class (ABC). An abtract base class is a class with at least one
abstract method or attribute. (See also `Python
abc module documentation <https://docs.python.org/3/library/abc.html>`_.)
Sometimes a class is made accidentally abstract, often due to an
unimplemented abstract method. In a case like this you need to provide
an implementation for the method to make the class concrete
(non-abstract).
Example:
.. code-block:: python
from abc import ABCMeta, abstractmethod
class Persistent(metaclass=ABCMeta):
@abstractmethod
def save(self) -> None: ...
class Thing(Persistent):
def __init__(self) -> None:
...
... # No "save" method
# Error: Cannot instantiate abstract class 'Thing' with abstract attribute 'save' [abstract]
t = Thing()
Check the target of NewType [valid-newtype]
-------------------------------------------
The target of a ``NewType`` definition must be a class type. It can't
be a union type, ``Any``, or various other special types.
You can also get this error if the target has been imported from a
module whose source mypy cannot find, since any such definitions are
treated by mypy as values with ``Any`` types. Example:
.. code-block:: python
from typing import NewType
# The source for "acme" is not available for mypy
from acme import Entity # type: ignore
# Error: Argument 2 to NewType(...) must be subclassable (got "Any") [valid-newtype]
UserEntity = NewType('UserEntity', Entity)
To work around the issue, you can either give mypy access to the sources
for ``acme`` or create a stub file for the module. See :ref:`ignore-missing-imports`
for more information.
Report syntax errors [syntax]
-----------------------------
If the code being checked is not syntactically valid, mypy issues a
syntax error. Most, but not all, syntax errors are *blocking errors*:
they can't be ignored with a ``# type: ignore`` comment.
Miscellaneous checks [misc]
---------------------------
Mypy performs numerous other, less commonly failing checks that don't
have specific error codes. These use the ``misc`` error code. Other
than being used for multiple unrelated errors, the ``misc`` error code
is not special. For example, you can ignore all errors in this
category by using ``# type: ignore[misc]`` comment. Since these errors
are not expected to be common, it's unlikely that you'll see two
*different* errors with the ``misc`` code on a single line -- though
this can certainly happen once in a while.
.. note::
Future mypy versions will likely add new error codes for some errors
that currently use the ``misc`` error code.
.. _error-codes-optional:
Error codes for optional checks
===============================
This section documents various errors codes that mypy generates only
if you enable certain options. See :ref:`error-codes` for general
documentation about error codes. :ref:`error-code-list` documents
error codes that are enabled by default.
.. note::
The examples in this section use :ref:`inline configuration
<inline-config>` to specify mypy options. You can also set the same
options by using a :ref:`configuration file <config-file>` or
:ref:`command-line options <command-line>`.
Check that type arguments exist [type-arg]
------------------------------------------
If you use ``--disallow-any-generics``, mypy requires that each generic
type has values for each type argument. For example, the types ``List`` or
``dict`` would be rejected. You should instead use types like ``List[int]`` or
``Dict[str, int]``. Any omitted generic type arguments get implicit ``Any``
values. The type ``List`` is equivalent to ``List[Any]``, and so on.
Example:
.. code-block:: python
# mypy: disallow-any-generics
from typing import List
# Error: Missing type parameters for generic type "List" [type-arg]
def remove_dups(items: List) -> List:
...
Check that every function has an annotation [no-untyped-def]
------------------------------------------------------------
If you use ``--disallow-untyped-defs``, mypy requires that all functions
have annotations (either a Python 3 annotation or a type comment).
Example:
.. code-block:: python
# mypy: disallow-untyped-defs
def inc(x): # Error: Function is missing a type annotation [no-untyped-def]
return x + 1
def inc_ok(x: int) -> int: # OK
return x + 1
class Counter:
# Error: Function is missing a type annotation [no-untyped-def]
def __init__(self):
self.value = 0
class CounterOk:
# OK: An explicit "-> None" is needed if "__init__" takes no arguments
def __init__(self) -> None:
self.value = 0
Check that cast is not redundant [redundant-cast]
-------------------------------------------------
If you use ``--warn-redundant-casts``, mypy will generate an error if the source
type of a cast is the same as the target type.
Example:
.. code-block:: python
# mypy: warn-redundant-casts
from typing import cast
Count = int
def example(x: Count) -> int:
# Error: Redundant cast to "int" [redundant-cast]
return cast(int, x)
Check that comparisons are overlapping [comparison-overlap]
-----------------------------------------------------------
If you use ``--strict-equality``, mypy will generate an error if it
thinks that a comparison operation is always true or false. These are
often bugs. Sometimes mypy is too picky and the comparison can
actually be useful. Instead of disabling strict equality checking
everywhere, you can use ``# type: ignore[comparison-overlap]`` to
ignore the issue on a particular line only.
Example:
.. code-block:: python
# mypy: strict-equality
def is_magic(x: bytes) -> bool:
# Error: Non-overlapping equality check (left operand type: "bytes",
# right operand type: "str") [comparison-overlap]
return x == 'magic'
We can fix the error by changing the string literal to a bytes
literal:
.. code-block:: python
# mypy: strict-equality
def is_magic(x: bytes) -> bool:
return x == b'magic' # OK
Check that no untyped functions are called [no-untyped-call]
------------------------------------------------------------
If you use ``--disallow-untyped-calls``, mypy generates an error when you
call an unannotated function in an annotated function.
Example:
.. code-block:: python
# mypy: disallow-untyped-calls
def do_it() -> None:
# Error: Call to untyped function "bad" in typed context [no-untyped-call]
bad()
def bad():
...
Check that function does not return Any value [no-any-return]
-------------------------------------------------------------
If you use ``--warn-return-any``, mypy generates an error if you return a
value with an ``Any`` type in a function that is annotated to return a
non-``Any`` value.
Example:
.. code-block:: python
# mypy: warn-return-any
def fields(s):
return s.split(',')
def first_field(x: str) -> str:
# Error: Returning Any from function declared to return "str" [no-any-return]
return fields(x)[0]
Check that types have no Any components due to missing imports [no-any-unimported]
----------------------------------------------------------------------------------
If you use ``--disallow-any-unimported``, mypy generates an error if a component of
a type becomes ``Any`` because mypy couldn't resolve an import. These "stealth"
``Any`` types can be surprising and accidentally cause imprecise type checking.
In this example, we assume that mypy can't find the module ``animals``, which means
that ``Cat`` falls back to ``Any`` in a type annotation:
.. code-block:: python
# mypy: disallow-any-unimported
from animals import Cat # type: ignore
# Error: Argument 1 to "feed" becomes "Any" due to an unfollowed import [no-any-unimported]
def feed(cat: Cat) -> None:
...
.. _error-codes:
Error codes
===========
Mypy can optionally display an error code such as ``[attr-defined]``
after each error message. Error codes serve two purposes:
1. It's possible to silence specific error codes on a line using ``#
type: ignore[code]``. This way you won't accidentally ignore other,
potentially more serious errors.
2. The error code can be used to find documentation about the error.
The next two topics (:ref:`error-code-list` and
:ref:`error-codes-optional`) document the various error codes
mypy can report.
Most error codes are shared between multiple related error messages.
Error codes may change in future mypy releases.
Displaying error codes
----------------------
Error codes are not displayed by default. Use ``--show-error-codes``
to display error codes. Error codes are shown inside square brackets:
.. code-block:: text
$ mypy --show-error-codes prog.py
prog.py:1: error: "str" has no attribute "trim" [attr-defined]
Silencing errors based on error codes
-------------------------------------
You can use a special comment ``# type: ignore[code, ...]`` to only
ignore errors with a specific error code (or codes) on a particular
line. This can be used even if you have not configured mypy to show
error codes. Currently it's only possible to disable arbitrary error
codes on individual lines using this comment.
.. note::
There are command-line flags and config file settings for enabling
certain optional error codes, such as ``--disallow-untype-defs``,
which enables the ``no-untyped-def`` error code.
This example shows how to ignore an error about an imported name mypy
thinks is undefined:
.. code-block:: python
# 'foo' is defined in 'foolib', even though mypy can't see the
# definition.
from foolib import foo # type: ignore[attr-defined]
......@@ -5,7 +5,7 @@ Final names, methods and classes
This section introduces these related features:
1. *Final names* are variables or attributes that should not reassigned after
1. *Final names* are variables or attributes that should not be reassigned after
initialization. They are useful for declaring constants.
2. *Final methods* should not be overridden in a subclass.
3. *Final classes* should not be subclassed.
......
......@@ -158,7 +158,7 @@ Arguments with default values can be annotated like so:
# 'args' has type 'Tuple[int, ...]' (a tuple of ints)
# 'kwargs' has type 'Dict[str, float]' (a dict of strs to floats)
for arg in args:
print(name)
print(arg)
for key, value in kwargs:
print(key, value)
......
......@@ -66,6 +66,9 @@ Mypy is a static type checker for Python 3 and Python 2.7.
common_issues
supported_python_features
error_codes
error_code_list
error_code_list2
python36
additional_features
faq
......
......@@ -42,9 +42,10 @@ Making PEP 561 compatible packages
PEP 561 notes three main ways to distribute type information. The first is a
package that has only inline type annotations in the code itself. The second is
a package that ships stub files with type information alongside the runtime
code. The third method, also known as a "stub only package" is a package that
ships type information for a package separately as stub files.
a package that ships :ref:`stub files <stub-files>` with type information
alongside the runtime code. The third method, also known as a "stub only
package" is a package that ships type information for a package separately as
stub files.
If you would like to publish a library package to a package repository (e.g.
PyPI) for either internal or external use in type checking, packages that
......@@ -105,8 +106,9 @@ the setup.py might look like:
packages=["package_b"]
)
In this example, both ``lib.py`` and ``lib.pyi`` exist. At runtime, the Python
interpreter will use ``lib.py``, but mypy will use ``lib.pyi`` instead.
In this example, both ``lib.py`` and the ``lib.pyi`` stub file exist. At
runtime, the Python interpreter will use ``lib.py``, but mypy will use
``lib.pyi`` instead.
If the package is stub-only (not imported at runtime), the package should have
a prefix of the runtime package name and a suffix of ``-stubs``.
......
......@@ -254,8 +254,8 @@ be used in ``with`` and ``async with`` statements.
Simple user-defined protocols
*****************************
You can define your own protocol class by inheriting the special
``typing_extensions.Protocol`` class:
You can define your own protocol class by inheriting the special ``Protocol``
class:
.. code-block:: python
......@@ -284,10 +284,9 @@ similarly compatible with the protocol, as they support ``close()``.
.. note::
The ``Protocol`` base class is currently provided in the ``typing_extensions``
package. Once structural subtyping is mature and
`PEP 544 <https://www.python.org/dev/peps/pep-0544/>`_ has been accepted,
``Protocol`` will be included in the ``typing`` module.
The ``Protocol`` base class is provided in the ``typing_extensions``
package for Python 2.7 and 3.4-3.7. Starting with Python 3.8, ``Protocol``
is included in the ``typing`` module.
Defining subprotocols and subclassing protocols
***********************************************
......@@ -319,8 +318,8 @@ and merged using multiple inheritance. Example:
Note that inheriting from an existing protocol does not automatically
turn the subclass into a protocol -- it just creates a regular
(non-protocol) class or ABC that implements the given protocol (or
protocols). The ``typing_extensions.Protocol`` base class must always
be explicitly present if you are defining a protocol:
protocols). The ``Protocol`` base class must always be explicitly
present if you are defining a protocol:
.. code-block:: python
......@@ -383,14 +382,14 @@ Using ``isinstance()`` with protocols
*************************************
You can use a protocol class with ``isinstance()`` if you decorate it
with the ``typing_extensions.runtime`` class decorator. The decorator
adds support for basic runtime structural checks:
with the ``@runtime_checkable`` class decorator. The decorator adds
support for basic runtime structural checks:
.. code-block:: python
from typing_extensions import Protocol, runtime
from typing_extensions import Protocol, runtime_checkable
@runtime
@runtime_checkable
class Portable(Protocol):
handles: int
......
......@@ -23,9 +23,9 @@ For example, consider this source file:
class Window:
parent = dynamic()
def __init__(self, width, hight):
def __init__(self, width, height):
self.width = width
self.hight = hight
self.height = height
def create_empty() -> Window:
return Window(0, 0)
......@@ -47,7 +47,7 @@ Stubgen can generate this stub file based on the above file:
def create_empty() -> Window: ...
Stubgen generates *draft* stubs. The auto-generated stub files often
require some some manual updates, and most types will default to ``Any``.
require some manual updates, and most types will default to ``Any``.
The stubs will be much more useful if you add more precise type annotations,
at least for the most commonly used functionality.
......