Skip to content
Commits on Source (11)
Metadata-Version: 2.1
Name: mypy
Version: 0.650
Version: 0.660
Summary: Optional static typing for Python
Home-page: http://www.mypy-lang.org/
Author: Jukka Lehtosalo
......
mypy (0.660-1) unstable; urgency=medium
* New upstream version
* Standards-Version: 4.3.0, no changes needed
* Ignore changes to ./*egg-info via debian/source/options
* Run the provided tests during build and as an autopkgtest
* python3-mypy-extensions is now from a separate source package
* Support the nocheck and/or nodoc Build Profiles
-- Michael R. Crusoe <michael.crusoe@gmail.com> Sat, 19 Jan 2019 06:41:40 -0800
mypy (0.650-1) unstable; urgency=medium
* New upstream version
......
extensions/mypy_extensions.egg-info/
.mypy_cache/
.pytest_cache/
......@@ -10,14 +10,16 @@ Build-Depends: debhelper (>= 11),
help2man,
python3-all,
python3-lxml,
python3-pytest,
python3-pytest-cov,
python3-pytest-xdist <!nocheck>,
python3-pytest-cov <!nocheck>,
python3-setuptools,
python3-sphinx,
python3-sphinx-rtd-theme,
python3-sphinx <!nodoc>,
python3-sphinx-rtd-theme <!nodoc>,
python3-typed-ast (>= 1.1.0),
python3-psutil (>= 5.4.0)
Standards-Version: 4.2.1
python3-psutil (>= 5.4.0),
python3-mypy-extensions,
python3-virtualenv <!nocheck>
Standards-Version: 4.3.0
Vcs-Browser: https://salsa.debian.org/med-team/mypy
Vcs-Git: https://salsa.debian.org/med-team/mypy.git
Homepage: http://www.mypy-lang.org/
......@@ -43,6 +45,7 @@ Section: doc
Depends: ${misc:Depends},
${sphinxdoc:Depends}
Built-Using: ${sphinxdoc:Built-Using}
Build-Profiles: <!nodoc>
Description: documentation for mypy
Add type annotations to your Python programs, and use mypy to type check them.
Mypy is essentially a Python linter on steroids, and it can catch many
......
Author: Michael R. Crusoe <michael.crusoe@gmail.com>
Description: match the published version on PyPI
--- mypy.orig/extensions/setup.py
+++ mypy/extensions/setup.py
@@ -2,7 +2,7 @@
from setuptools import setup
-version = '0.5.0-dev'
+version = '0.4.1'
description = 'Experimental type system extensions for programs checked with the mypy typechecker.'
long_description = '''
Mypy Extensions
adjust-test-py-path
adjust-mypy-extensions-version
......@@ -2,26 +2,21 @@
SHELL=bash # needed for the <(echo …) process subsitution temporary file
# tricks with help2man
export DH_VERBOSE=1
export PYBUILD_DISABLE=test
export PYBUILD_DESTDIR_python3=debian/python3-mypy
PPATH=$(CURDIR):$(CURDIR)/extensions
export PYBUILD_NAME=mypy
PPATH=$(CURDIR)
PY3V=$(shell py3versions -dv)
include /usr/share/dpkg/pkg-info.mk
ifeq (,$(filter nodoc,$(DEB_BUILD_PROFILES)))
WITH += ,sphinxdoc
endif
%:
PYBUILD_NAME=mypy_extensions \
PYBUILD_DIR=$(CURDIR)/extensions/ \
dh $@ --with python3,sphinxdoc --buildsystem=pybuild
PYBUILD_NAME=mypy \
PYBUILD_DIR=$(CURDIR) \
dh $@ --with python3,sphinxdoc --buildsystem=pybuild
dh $@ --with python3$(WITH) --buildsystem=pybuild
override_dh_auto_build:
PYBUILD_NAME=mypy_extensions \
PYBUILD_DIR=$(CURDIR)/extensions/ \
dh_auto_build
PYBUILD_NAME=mypy \
PYBUILD_DIR=$(CURDIR) \
dh_auto_build
ifeq (,$(filter nodoc,$(DEB_BUILD_PROFILES)))
PYTHONPATH=$(PPATH) help2man 'python3 -m mypy' --no-info \
--version-string="${DEB_VERSION_UPSTREAM}" \
--name 'Optional Static Typing for Python' > debian/mypy.1
......@@ -74,17 +69,26 @@ override_dh_auto_build:
--include <(echo -e "[NAME]\nstubgen \- Generate draft stubs for Python modules.") \
> debian/stubgen.1
PYTHONPATH=$(CURDIR) $(MAKE) -C docs html
endif
override_dh_auto_clean:
rm -f debian/*.1
dh_auto_clean
ifeq (,$(filter nodoc,$(DEB_BUILD_PROFILES)))
$(MAKE) -C docs clean
endif
override_dh_auto_install:
PYBUILD_NAME=mypy_extensions \
PYBUILD_DIR=$(CURDIR)/extensions/ \
dh_auto_install
PYBUILD_NAME=mypy \
PYBUILD_DIR=$(CURDIR) \
dh_auto_install
dh_movefiles --package=mypy --sourcedir=debian/python3-mypy usr/bin
override_dh_auto_test:
ifeq (,$(filter nocheck,$(DEB_BUILD_PROFILES)))
PYBUILD_SYSTEM=custom \
PYBUILD_TEST_ARGS="{interpreter} -m mypy \
--config-file {dir}/mypy_self_check.ini -p mypy" dh_auto_test
dh_auto_install
PATH=$$PATH:$(CURDIR)/debian/mypy/usr/bin/ pytest-3 -n auto \
-o testpaths=mypy/test -o python_files=test*.py \
-o python_classes= -o python_functions=
endif
extend-diff-ignore="^[^/]+.egg-info/"
Tests: run-unit-test
Depends: mypy, python3-pytest-xdist, python3-virtualenv
Test-Command: mypy --help
Depends: mypy
#!/bin/bash
set -e
pkg=mypy
START=$(pwd)
if [ "$AUTOPKGTEST_TMP" = "" ] ; then
AUTOPKGTEST_TMP=$(mktemp -d /tmp/${pkg}-test.XXXXXX)
trap "rm -rf $AUTOPKGTEST_TMP" 0 INT QUIT ABRT PIPE TERM
fi
cd "$AUTOPKGTEST_TMP"
MYPY_TEST_PREFIX=${START} pytest-3 -n auto -o testpaths=mypy/test \
-o python_files=test*.py -o python_classes= -o python_functions= \
--pyarg mypy
cp -r /usr/lib/python3/dist-packages/mypy ./
/usr/bin/mypy --config-file ${START}/mypy_self_check.ini mypy
......@@ -95,7 +95,7 @@ do **not** work:
attribute: int
@dataclass_wrapper
class DynamicallyDecoarted:
class DynamicallyDecorated:
"""
Mypy doesn't recognize this as a dataclass because it is decorated by a
function returning `dataclass` rather than by `dataclass` itself.
......@@ -103,7 +103,7 @@ do **not** work:
attribute: int
AliasDecorated(attribute=1) # error: Unexpected keyword argument
DynamicallyDecoarted(attribute=1) # error: Unexpected keyword argument
DynamicallyDecorated(attribute=1) # error: Unexpected keyword argument
.. _attrs_package:
......
......@@ -46,9 +46,12 @@ Built-in types
# Use Optional[] for values that could be None
x = some_function() # type: Optional[str]
# Mypy understands a value can't be None in an if-statement
if x is not None:
print x
print x.upper()
# If a value can never be None due to some invariants, use an assert
assert x is not None
print x.upper()
Functions
*********
......
......@@ -72,9 +72,12 @@ Built-in types
# Use Optional[] for values that could be None
x: Optional[str] = some_function()
# Mypy understands a value can't be None in an if-statement
if x is not None:
print(x)
print(x.upper())
# If a value can never be None due to some invariants, use an assert
assert x is not None
print(x.upper())
Functions
*********
......
......@@ -451,23 +451,6 @@ beyond what incremental mode can offer, try running mypy in
By default, mypy will ignore cache data generated by a different
version of mypy. This flag disables that behavior.
.. _quick-mode:
``--quick-and-dirty``
This flag enables a **deprecated**, unsafe variant of incremental mode.
Quick mode is faster than regular incremental mode because it only
re-checks modules that were modified since their cache file was
last written: regular incremental mode also re-checks all modules
that depend on one or more modules that were re-checked.
Quick mode is unsafe because it may miss problems caused by a change
in a dependency. Quick mode updates the cache, but regular incremental
mode ignores cache files written by quick mode.
We recommend that you try using the :ref:`mypy_daemon` before
attempting to use this feature.
Quick mode is deprecated and will soon be removed.
.. _advanced-flags:
Advanced flags
......
......@@ -370,9 +370,6 @@ section of the command line docs.
different version of mypy. (By default, mypy will perform a version
check and regenerate the cache if it was written by older versions of mypy.)
``quick_and_dirty`` (bool, default False)
Enables :ref:`quick mode <quick-mode>`. **Deprecated.**
Configuring error messages
--------------------------
......
......@@ -40,13 +40,190 @@ A trivial example of using the api is the following
Extending mypy using plugins
****************************
Python is a highly dynamic language and has extensive metaprogramming
capabilities. Many popular libraries use these to create APIs that may
be more flexible and/or natural for humans, but are hard to express using
static types. Extending the PEP 484 type system to accommodate all existing
dynamic patterns is impractical and often just impossible.
Mypy supports a plugin system that lets you customize the way mypy type checks
code. This can be useful if you want to extend mypy so it can type check code
that uses a library that is difficult to express using just PEP 484 types, for
example.
that uses a library that is difficult to express using just PEP 484 types.
The plugin system is focused on improving mypy's understanding
of *semantics* of third party frameworks. There is currently no way to define
new first class kinds of types.
.. note::
The plugin system is experimental and prone to change. If you want to write
a mypy plugin, we recommend you start by contacting the mypy core developers
on `gitter <https://gitter.im/python/typing>`_. In particular, there are
no guarantees about backwards compatibility. Backwards incompatible changes
may be made without a deprecation period.
Configuring mypy to use plugins
*******************************
Plugins are Python files that can be specified in a mypy
:ref:`config file <config-file>` using one of the two formats: relative or
absolute path to the plugin to the plugin file, or a module name (if the plugin
is installed using ``pip install`` in the same virtual environment where mypy
is running). The two formats can be mixed, for example:
.. code-block:: ini
[mypy]
plugins = /one/plugin.py, other.plugin
Mypy will try to import the plugins and will look for an entry point function
named ``plugin``. If the plugin entry point function has a different name, it
can be specified after colon:
.. code-block:: ini
[mypy]
plugins = custom_plugin:custom_entry_point
In following sections we describe basics of the plugin system with
some examples. For more technical details please read docstrings in
`mypy/plugin.py <https://github.com/python/mypy/blob/master/mypy/plugin.py>`_
in mypy source code. Also you can find good examples in the bundled plugins
located in `mypy/plugins <https://github.com/python/mypy/tree/master/mypy/plugins>`_.
High-level overview
*******************
Every entry point function should accept a single string argument
that is a full mypy version and return a subclass of ``mypy.plugins.Plugin``:
.. code-block:: python
from mypy.plugin import Plugin
class CustomPlugin(Plugin):
def get_type_analyze_hook(self, fullname: str):
# see explanation below
...
def plugin(version: str):
# ignore version argument if the plugin works with all mypy versions.
return CustomPlugin
During different phases of analyzing the code (first in semantic analysis,
and then in type checking) mypy calls plugin methods such as
``get_type_analyze_hook()`` on user plugins. This particular method for example
can return a callback that mypy will use to analyze unbound types with given
full name. See full plugin hook methods list :ref:`below <plugin_hooks>`.
Mypy maintains a list of plugins it gets from the config file plus the default
(built-in) plugin that is always enabled. Mypy calls a method once for each
plugin in the list until one of the methods returns a non-``None`` value.
This callback will be then used to customize the corresponding aspect of
analyzing/checking the current abstract syntax tree node.
The callback returned by the ``get_xxx`` method will be given a detailed
current context and an API to create new nodes, new types, emit error messages
etc., and the result will be used for further processing.
Plugin developers should ensure that their plugins work well in incremental and
daemon modes. In particular, plugins should not hold global state due to caching
of plugin hook results.
.. _plugin_hooks:
Current list of plugin hooks
****************************
**get_type_analyze_hook()** customizes behaviour of the type analyzer.
For example, PEP 484 doesn't support defining variadic generic types:
.. code-block:: python
from lib import Vector
a: Vector[int, int]
b: Vector[int, int, int]
When analyzing this code, mypy will call ``get_type_analyze_hook("lib.Vector")``,
so the plugin can return some valid type for each variable.
**get_function_hook()** is used to adjust the return type of a function call.
This is a good choice if the return type of some function depends on *values*
of some arguments that can't be expressed using literal types (for example
a function may return an ``int`` for positive arguments and a ``float`` for
negative arguments). This hook will be also called for instantiation of classes.
For example:
.. code-block:: python
from contextlib import contextmanager
from typing import TypeVar, Callable
T = TypeVar('T')
@contextmanager # built-in plugin can infer a precise type here
def stopwatch(timer: Callable[[], T]) -> Iterator[T]:
...
yield timer()
**get_method_hook()** is the same as ``get_function_hook()`` but for methods
instead of module level functions.
**get_method_signature_hook()** is used to adjust the signature of a method.
This includes special Python methods except ``__init__()`` and ``__new__()``.
For example in this code:
.. code-block:: python
from ctypes import Array, c_int
x: Array[c_int]
x[0] = 42
mypy will call ``get_method_signature_hook("ctypes.Array.__setitem__")``
so that the plugin can mimic the ``ctypes`` auto-convert behavior.
**get_attribute_hook** can be used to give more precise type of an instance
attribute. Note however, that this method is only called for variables that
already exist in the class symbol table. If you want to add some generated
variables/methods to the symbol table you can use one of the three hooks
below.
**get_class_decorator_hook()** can be used to update class definition for
given class decorators. For example, you can add some attributes to the class
to match runtime behaviour:
.. code-block:: python
from lib import customize
@customize
class UserDefined:
pass
var = UserDefined
var.customized # mypy can understand this using a plugin
**get_metaclass_hook()** is similar to above, but for metaclasses.
**get_base_class_hook()** is similar to above, but for base classes.
**get_dynamic_class_hook()** can be used to allow dynamic class definitions
in mypy. This plugin hook is called for every assignment to a simple name
where right hand side is a function call:
.. code-block:: python
from lib import dynamic_class
X = dynamic_class('X', [])
*Warning:* The plugin system is extremely experimental and prone to change. If you want
to contribute a plugin to mypy, we recommend you start by contacting the mypy
core developers either on `gitter <https://gitter.im/python/typing>`_ or on mypy's
`issue tracker <https://github.com/python/mypy/issues>`_.
For such definition, mypy will call ``get_dynamic_class_hook("lib.dynamic_class")``.
The plugin should create the corresponding ``mypy.nodes.TypeInfo`` object, and
place it into a relevant symbol table. (Instances of this class represent
classes in mypy and hold essential information such as qualified name,
method resolution order, etc.)
**get_customize_class_mro_hook()** can be used to modify class MRO (for example
insert some entries there) before the class body is analyzed.
.. _final_attrs:
Final names, methods and classes
================================
......
......@@ -39,6 +39,7 @@ Mypy is a static type checker for Python 3 and Python 2.7.
stubs
generics
more_types
literal_types
final_attrs
metaclasses
......
.. _literal_types:
Literal types
=============
.. note::
Literal is an officially supported feature, but is highly experimental
and should be considered to be in alpha stage. It is very likely that future
releases of mypy will modify the behavior of literal types, either by adding
new features or by tuning or removing problematic ones.
Literal types let you indicate that an expression is equal to some specific
primitive value. For example, if we annotate a variable with type ``Literal["foo"]``,
mypy will understand that variable is not only of type ``str``, but is also
equal to specifically the string ``"foo"``.
This feature is primarily useful when annotating functions that behave
differently based on the exact value the caller provides. For example,
suppose we have a function ``fetch_data(...)`` that returns ``bytes`` if the
first argument is ``True``, and ``str`` if it's ``False``. We can construct a
precise type signature for this function using ``Literal[...]`` and overloads:
.. code-block:: python
from typing import overload, Union
from typing_extensions import Literal
# The first two overloads use Literal[...] so we can
# have precise return types:
@overload
def fetch_data(raw: Literal[True]) -> bytes: ...
@overload
def fetch_data(raw: Literal[False]) -> str: ...
# The last overload is a fallback in case the caller
# provides a regular bool:
@overload
def fetch_data(raw: bool) -> Union[bytes, str]: ...
def fetch_data(raw: bool) -> Union[bytes, str]:
# Implementation is omitted
...
reveal_type(fetch_data(True)) # Revealed type is 'bytes'
reveal_type(fetch_data(False)) # Revealed type is 'str'
# Variables declared without annotations will continue to have an
# inferred type of 'bool'.
variable = True
reveal_type(fetch_data(variable)) # Revealed type is 'Union[bytes, str]'
Parameterizing Literals
***********************
Literal types may contain one or more literal bools, ints, strs, and bytes.
However, literal types **cannot** contain arbitrary expressions:
types like ``Literal[my_string.trim()]``, ``Literal[x > 3]``, or ``Literal[3j + 4]``
are all illegal.
Literals containing two or more values are equivalent to the union of those values.
So, ``Literal[-3, b"foo", True]`` is equivalent to
``Union[Literal[-3], Literal[b"foo"], Literal[True]]``. This makes writing
more complex types involving literals a little more convenient.
Literal types may also contain ``None``. Mypy will treat ``Literal[None]`` as being
equivalent to just ``None``. This means that ``Literal[4, None]``,
``Union[Literal[4], None]``, and ``Optional[Literal[4]]`` are all equivalent.
Literals may also contain aliases to other literal types. For example, the
following program is legal:
.. code-block:: python
PrimaryColors = Literal["red", "blue", "yellow"]
SecondaryColors = Literal["purple", "green", "orange"]
AllowedColors = Literal[PrimaryColors, SecondaryColors]
def paint(color: AllowedColors) -> None: ...
paint("red") # Type checks!
paint("turquoise") # Does not type check
Literals may not contain any other kind of type or expression. This means doing
``Literal[my_instance]``, ``Literal[Any]``, ``Literal[3.14]``, or
``Literal[{"foo": 2, "bar": 5}]`` are all illegal.
Future versions of mypy may relax some of these restrictions. For example, we
plan on adding support for using enum values inside ``Literal[...]`` in an upcoming release.
Declaring literal variables
***************************
You must explicitly add an annotation to a variable to declare that it has
a literal type:
.. code-block:: python
a: Literal[19] = 19
reveal_type(a) # Revealed type is 'Literal[19]'
In order to preserve backwards-compatibility, variables without this annotation
are **not** assumed to be literals:
.. code-block:: python
b = 19
reveal_type(b) # Revealed type is 'int'
If you find repeating the value of the variable in the type hint to be tedious,
you can instead change the variable to be :ref:`Final <final_attrs>`:
.. code-block:: python
from typing_extensions import Final, Literal
def expects_literal(x: Literal[19]) -> None: pass
c: Final = 19
reveal_type(c) # Revealed type is 'int'
expects_literal(c) # ...but this type checks!
If you do not provide an explicit type in the Final, the type of ``c`` becomes
context-sensitive: mypy will basically try "substituting" the original assigned
value whenever it's used before performing type checking. So, mypy will type-check
the above program almost as if it were written like so:
.. code-block:: python
from typing_extensions import Final, Literal
def expects_literal(x: Literal[19]) -> None: pass
reveal_type(19)
expects_literal(19)
This is why ``expects_literal(19)`` type-checks despite the fact that ``reveal_type(c)``
reports ``int``.
So while changing a variable to be Final is not quite the same thing as adding
an explicit ``Literal[...]`` annotation, it often leads to the same effect in practice.
Limitations
***********
Mypy will not understand expressions that use variables of type ``Literal[..]``
on a deep level. For example, if you have a variable ``a`` of type ``Literal[3]``
and another variable ``b`` of type ``Literal[5]``, mypy will infer that
``a + b`` has type ``int``, **not** type ``Literal[8]``.
The basic rule is that literal types are treated as just regular subtypes of
whatever type the parameter has. For example, ``Literal[3]`` is treated as a
subtype of ``int`` and so will inherit all of ``int``'s methods directly. This
means that ``Literal[3].__add__`` accepts the same arguments and has the same
return type as ``int.__add__``.