Loading PKG-INFO +1 −1 Original line number Diff line number Diff line Metadata-Version: 2.1 Name: mypy Version: 0.600 Version: 0.610 Summary: Optional static typing for Python Home-page: http://www.mypy-lang.org/ Author: Jukka Lehtosalo Loading README.md +1 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ this: $ python3 -m pip install -U mypy This should automatically installed the appropriate version of This should automatically install the appropriate version of mypy's parser, typed-ast. If for some reason it does not, you can install it manually: Loading docs/source/additional_features.rst +249 −3 Original line number Diff line number Diff line Additional features ------------------- This section discusses various features outside core mypy features. This section discusses various features that did not fit in naturally in one of the previous sections. .. _function-overloading: Function overloading ******************** Sometimes the types in a function depend on each other in ways that can't be captured with a ``Union``. For example, the ``__getitem__`` (``[]`` bracket indexing) method can take an integer and return a single item, or take a ``slice`` and return a ``Sequence`` of items. You might be tempted to annotate it like so: .. code-block:: python from typing import Sequence, TypeVar, Union T = TypeVar('T') class MyList(Sequence[T]): def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]: if isinstance(index, int): ... # Return a T here elif isinstance(index, slice): ... # Return a sequence of Ts here else: raise TypeError(...) But this is too loose, as it implies that when you pass in an ``int`` you might sometimes get out a single item and sometimes a sequence. The return type depends on the parameter type in a way that can't be expressed using a type variable. Instead, we can use `overloading <https://www.python.org/dev/peps/pep-0484/#function-method-overloading>`_ to give the same function multiple type annotations (signatures) and accurately describe the function's behavior. .. code-block:: python from typing import overload, Sequence, TypeVar, Union T = TypeVar('T') class MyList(Sequence[T]): # The @overload definitions are just for the type checker, # and overwritten by the real implementation below. @overload def __getitem__(self, index: int) -> T: pass # Don't put code here # All overloads and the implementation must be adjacent # in the source file, and overload order may matter: # when two overloads may overlap, the more specific one # should come first. @overload def __getitem__(self, index: slice) -> Sequence[T]: pass # Don't put code here # The implementation goes last, without @overload. # It may or may not have type hints; if it does, # these are checked against the overload definitions # as well as against the implementation body. def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]: # This is exactly the same as before. if isinstance(index, int): ... # Return a T here elif isinstance(index, slice): ... # Return a sequence of Ts here else: raise TypeError(...) Calls to overloaded functions are type checked against the variants, not against the implementation. A call like ``my_list[5]`` would have type ``T``, not ``Union[T, Sequence[T]]`` because it matches the first overloaded definition, and ignores the type annotations on the implementation of ``__getitem__``. The code in the body of the definition of ``__getitem__`` is checked against the annotations on the corresponding declaration. In this case the body is checked with ``index: Union[int, slice]`` and a return type ``Union[T, Sequence[T]]``. If there are no annotations on the corresponding definition, then code in the function body is not type checked. The annotations on the function body must be compatible with the types given for the overloaded variants listed above it. The type checker will verify that all the types for the overloaded variants are compatible with the types given for the implementation. In this case it checks that the parameter type ``int`` and the return type ``T`` are compatible with ``Union[int, slice]`` and ``Union[T, Sequence[T]]`` for the first variant. For the second variant it verifies that the parameter type ``slice`` and the return type ``Sequence[T]`` are compatible with ``Union[int, slice]`` and ``Union[T, Sequence[T]]``. Overloaded function variants are still ordinary Python functions and they still define a single runtime object. There is no automatic dispatch happening, and you must manually handle the different types in the implementation (usually with :func:`isinstance` checks, as shown in the example). The overload variants must be adjacent in the code. This makes code clearer, as you don't have to hunt for overload variants across the file. Overloads in stub files are exactly the same, except there is no implementation. .. note:: As generic type variables are erased at runtime when constructing instances of generic types, an overloaded function cannot have variants that only differ in a generic type argument, e.g. ``List[int]`` and ``List[str]``. .. note:: If you just need to constrain a type variable to certain types or subtypes, you can use a :ref:`value restriction <type-variable-value-restriction>`. .. _attrs_package: Loading @@ -17,6 +134,7 @@ 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+) Loading @@ -28,6 +146,7 @@ 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 Loading @@ -43,6 +162,7 @@ That enables this to work: import attr from typing import Dict @attr.s(auto_attribs=True) class A: one: int = attr.ib(8) Loading Loading @@ -175,7 +295,7 @@ Caching with mypy daemon ======================== You can also use remote caching with the :ref:`mypy daemon <mypy_daemon>`. The remote cache will significantly speed up the the first ``dmypy check`` The remote cache will significantly speed up the first ``dmypy check`` run after starting or restarting the daemon. The mypy daemon requires extra fine-grained dependency data in Loading @@ -187,7 +307,7 @@ build:: This flag adds extra information for the daemon to the cache. In order to use this extra information, you will also need to use the ``--use-fine-grained-cache`` option with ``dymypy start`` or ``--use-fine-grained-cache`` option with ``dmypy start`` or ``dmypy restart``. Example:: $ dmypy start -- --use-fine-grained-cache <options...> Loading Loading @@ -231,3 +351,129 @@ at least if your codebase is hundreds of thousands of lines or more: mypy build to create the cache data, as repeatedly updating cache data incrementally could result in drift over a long time period (due to a mypy caching issue, perhaps). .. _extended_callable: Extended Callable types *********************** As an experimental mypy extension, you can specify ``Callable`` types that support keyword arguments, optional arguments, and more. When you specify the arguments of a Callable, you can choose to supply just the type of a nameless positional argument, or an "argument specifier" representing a more complicated form of argument. This allows one to more closely emulate the full range of possibilities given by the ``def`` statement in Python. As an example, here's a complicated function definition and the corresponding ``Callable``: .. code-block:: python from typing import Callable from mypy_extensions import (Arg, DefaultArg, NamedArg, DefaultNamedArg, VarArg, KwArg) def func(__a: int, # This convention is for nameless arguments b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int) -> int: ... F = Callable[[int, # Or Arg(int) Arg(int, 'b'), DefaultArg(int, 'c'), VarArg(int), NamedArg(int, 'd'), DefaultNamedArg(int, 'e'), KwArg(int)], int] f: F = func Argument specifiers are special function calls that can specify the following aspects of an argument: - its type (the only thing that the basic format supports) - its name (if it has one) - whether it may be omitted - whether it may or must be passed using a keyword - whether it is a ``*args`` argument (representing the remaining positional arguments) - whether it is a ``**kwargs`` argument (representing the remaining keyword arguments) The following functions are available in ``mypy_extensions`` for this purpose: .. code-block:: python def Arg(type=Any, name=None): # A normal, mandatory, positional argument. # If the name is specified it may be passed as a keyword. def DefaultArg(type=Any, name=None): # An optional positional argument (i.e. with a default value). # If the name is specified it may be passed as a keyword. def NamedArg(type=Any, name=None): # A mandatory keyword-only argument. def DefaultNamedArg(type=Any, name=None): # An optional keyword-only argument (i.e. with a default value). def VarArg(type=Any): # A *args-style variadic positional argument. # A single VarArg() specifier represents all remaining # positional arguments. def KwArg(type=Any): # A **kwargs-style variadic keyword argument. # A single KwArg() specifier represents all remaining # keyword arguments. In all cases, the ``type`` argument defaults to ``Any``, and if the ``name`` argument is omitted the argument has no name (the name is required for ``NamedArg`` and ``DefaultNamedArg``). A basic ``Callable`` such as .. code-block:: python MyFunc = Callable[[int, str, int], float] is equivalent to the following: .. code-block:: python MyFunc = Callable[[Arg(int), Arg(str), Arg(int)], float] A ``Callable`` with unspecified argument types, such as .. code-block:: python MyOtherFunc = Callable[..., int] is (roughly) equivalent to .. code-block:: python MyOtherFunc = Callable[[VarArg(), KwArg()], int] .. note:: This feature is experimental. Details of the implementation may change and there may be unknown limitations. **IMPORTANT:** Each of the functions above currently just returns its ``type`` argument, so the information contained in the argument specifiers is not available at runtime. This limitation is necessary for backwards compatibility with the existing ``typing.py`` module as present in the Python 3.5+ standard library and distributed via PyPI. docs/source/basics.rstdeleted 100644 → 0 +0 −194 Original line number Diff line number Diff line Basics ====== This chapter introduces some core concepts of mypy, including function annotations, the ``typing`` module and library stubs. Read it carefully, as the rest of documentation may not make much sense otherwise. Function signatures ******************* A function without a type annotation is considered dynamically typed: .. code-block:: python def greeting(name): return 'Hello, {}'.format(name) You can declare the signature of a function using the Python 3 annotation syntax (Python 2 is discussed later in :ref:`python2`). This makes the function statically typed, and that causes type checker report type errors within the function. Here's a version of the above function that is statically typed and will be type checked: .. code-block:: python def greeting(name: str) -> str: return 'Hello, {}'.format(name) If a function does not explicitly return a value we give the return type as ``None``. Using a ``None`` result in a statically typed context results in a type check error: .. code-block:: python def p() -> None: print('hello') a = p() # Type check error: p has None return value Arguments with default values can be annotated as follows: .. code-block:: python def greeting(name: str, prefix: str = 'Mr.') -> str: return 'Hello, {} {}'.format(name, prefix) Mixing dynamic and static typing ******************************** Mixing dynamic and static typing within a single file is often useful. For example, if you are migrating existing Python code to static typing, it may be easiest to do this incrementally, such as by migrating a few functions at a time. Also, when prototyping a new feature, you may decide to first implement the relevant code using dynamic typing and only add type signatures later, when the code is more stable. .. code-block:: python def f(): 1 + 'x' # No static type error (dynamically typed) def g() -> None: 1 + 'x' # Type check error (statically typed) .. note:: The earlier stages of mypy, known as the semantic analysis, may report errors even for dynamically typed functions. However, you should not rely on this, as this may change in the future. The typing module ***************** The ``typing`` module contains many definitions that are useful in statically typed code. You typically use ``from ... import`` to import them (we'll explain ``Iterable`` later in this document): .. code-block:: python from typing import Iterable def greet_all(names: Iterable[str]) -> None: for name in names: print('Hello, {}'.format(name)) For brevity, we often omit the ``typing`` import in code examples, but you should always include it in modules that contain statically typed code. The presence or absence of the ``typing`` module does not affect whether your code is type checked; it is only required when you use one or more special features it defines. Type checking programs ********************** You can type check a program by using the ``mypy`` tool, which is basically a linter -- it checks your program for errors without actually running it:: $ mypy program.py All errors reported by mypy are essentially warnings that you are free to ignore, if you so wish. The next chapter explains how to download and install mypy: :ref:`getting-started`. More command line options are documented in :ref:`command-line`. .. note:: Depending on how mypy is configured, you may have to explicitly use the Python 3 interpreter to run mypy. The mypy tool is an ordinary mypy (and so also Python) program. For example:: $ python3 -m mypy program.py .. _library-stubs: Library stubs and the Typeshed repo *********************************** In order to type check code that uses library modules such as those included in the Python standard library, you need to have library *stubs*. A library stub defines a skeleton of the public interface of the library, including classes, variables and functions and their types, but dummy function bodies. For example, consider this code: .. code-block:: python x = chr(4) Without a library stub, the type checker would have no way of inferring the type of ``x`` and checking that the argument to ``chr`` has a valid type. Mypy incorporates the `typeshed <https://github.com/python/typeshed>`_ project, which contains library stubs for the Python builtins and the standard library. The stub for the builtins contains a definition like this for ``chr``: .. code-block:: python def chr(code: int) -> str: ... In stub files we don't care about the function bodies, so we use an ellipsis instead. That ``...`` is three literal dots! Mypy complains if it can't find a stub (or a real module) for a library module that you import. You can create a stub easily; here is an overview: * Write a stub file for the library and store it as a ``.pyi`` file in the same directory as the library module. * Alternatively, put your stubs (``.pyi`` files) in a directory reserved for stubs (e.g., ``myproject/stubs``). In this case you have to set the environment variable ``MYPYPATH`` to refer to the directory. For example:: $ export MYPYPATH=~/work/myproject/stubs Use the normal Python file name conventions for modules, e.g. ``csv.pyi`` for module ``csv``. Use a subdirectory with ``__init__.pyi`` for packages. If a directory contains both a ``.py`` and a ``.pyi`` file for the same module, the ``.pyi`` file takes precedence. This way you can easily add annotations for a module even if you don't want to modify the source code. This can be useful, for example, if you use 3rd party open source libraries in your program (and there are no stubs in typeshed yet). That's it! Now you can access the module in mypy programs and type check code that uses the library. If you write a stub for a library module, consider making it available for other programmers that use mypy by contributing it back to the typeshed repo. There is more information about creating stubs in the `mypy wiki <https://github.com/python/mypy/wiki/Creating-Stubs-For-Python-Modules>`_. The following sections explain the kinds of type annotations you can use in your programs and stub files. .. note:: You may be tempted to point ``MYPYPATH`` to the standard library or to the ``site-packages`` directory where your 3rd party packages are installed. This is almost always a bad idea -- you will likely get tons of error messages about code you didn't write and that mypy can't analyze all that well yet, and in the worst case scenario mypy may crash due to some construct in a 3rd party package that it didn't expect. docs/source/builtin_types.rst +20 −19 Original line number Diff line number Diff line Loading @@ -3,13 +3,13 @@ Built-in types These are examples of some of the most common built-in types: =================== =============================== ====================== =============================== Type Description =================== =============================== ``int`` integer of arbitrary size ====================== =============================== ``int`` integer ``float`` floating point number ``bool`` boolean value ``str`` unicode string ``str`` string (unicode) ``bytes`` 8-bit string ``object`` an arbitrary object (``object`` is the common base class) ``List[str]`` list of ``str`` objects Loading @@ -17,11 +17,12 @@ Type Description ``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 ``Sequence[bool]`` sequence of booleans ``Sequence[bool]`` sequence of booleans (read-only) ``Mapping[str, int]`` mapping from ``str`` keys to ``int`` values (read-only) ``Any`` dynamically typed value with an arbitrary type =================== =============================== ====================== =============================== The type ``Any`` and type constructors ``List``, ``Dict``, The type ``Any`` and type constructors such as ``List``, ``Dict``, ``Iterable`` and ``Sequence`` are defined in the ``typing`` module. The type ``Dict`` is a *generic* class, signified by type arguments within Loading @@ -30,7 +31,7 @@ strings and and ``Dict[Any, Any]`` is a dictionary of dynamically typed (arbitrary) values and keys. ``List`` is another generic class. ``Dict`` and ``List`` are aliases for the built-ins ``dict`` and ``list``, respectively. ``Iterable`` and ``Sequence`` are generic abstract base classes that ``Iterable``, ``Sequence``, and ``Mapping`` are generic types that correspond to Python protocols. For example, a ``str`` object or a ``List[str]`` object is valid when ``Iterable[str]`` or ``Sequence[str]`` is expected. Note that even though Loading Loading
PKG-INFO +1 −1 Original line number Diff line number Diff line Metadata-Version: 2.1 Name: mypy Version: 0.600 Version: 0.610 Summary: Optional static typing for Python Home-page: http://www.mypy-lang.org/ Author: Jukka Lehtosalo Loading
README.md +1 −1 Original line number Diff line number Diff line Loading @@ -136,7 +136,7 @@ this: $ python3 -m pip install -U mypy This should automatically installed the appropriate version of This should automatically install the appropriate version of mypy's parser, typed-ast. If for some reason it does not, you can install it manually: Loading
docs/source/additional_features.rst +249 −3 Original line number Diff line number Diff line Additional features ------------------- This section discusses various features outside core mypy features. This section discusses various features that did not fit in naturally in one of the previous sections. .. _function-overloading: Function overloading ******************** Sometimes the types in a function depend on each other in ways that can't be captured with a ``Union``. For example, the ``__getitem__`` (``[]`` bracket indexing) method can take an integer and return a single item, or take a ``slice`` and return a ``Sequence`` of items. You might be tempted to annotate it like so: .. code-block:: python from typing import Sequence, TypeVar, Union T = TypeVar('T') class MyList(Sequence[T]): def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]: if isinstance(index, int): ... # Return a T here elif isinstance(index, slice): ... # Return a sequence of Ts here else: raise TypeError(...) But this is too loose, as it implies that when you pass in an ``int`` you might sometimes get out a single item and sometimes a sequence. The return type depends on the parameter type in a way that can't be expressed using a type variable. Instead, we can use `overloading <https://www.python.org/dev/peps/pep-0484/#function-method-overloading>`_ to give the same function multiple type annotations (signatures) and accurately describe the function's behavior. .. code-block:: python from typing import overload, Sequence, TypeVar, Union T = TypeVar('T') class MyList(Sequence[T]): # The @overload definitions are just for the type checker, # and overwritten by the real implementation below. @overload def __getitem__(self, index: int) -> T: pass # Don't put code here # All overloads and the implementation must be adjacent # in the source file, and overload order may matter: # when two overloads may overlap, the more specific one # should come first. @overload def __getitem__(self, index: slice) -> Sequence[T]: pass # Don't put code here # The implementation goes last, without @overload. # It may or may not have type hints; if it does, # these are checked against the overload definitions # as well as against the implementation body. def __getitem__(self, index: Union[int, slice]) -> Union[T, Sequence[T]]: # This is exactly the same as before. if isinstance(index, int): ... # Return a T here elif isinstance(index, slice): ... # Return a sequence of Ts here else: raise TypeError(...) Calls to overloaded functions are type checked against the variants, not against the implementation. A call like ``my_list[5]`` would have type ``T``, not ``Union[T, Sequence[T]]`` because it matches the first overloaded definition, and ignores the type annotations on the implementation of ``__getitem__``. The code in the body of the definition of ``__getitem__`` is checked against the annotations on the corresponding declaration. In this case the body is checked with ``index: Union[int, slice]`` and a return type ``Union[T, Sequence[T]]``. If there are no annotations on the corresponding definition, then code in the function body is not type checked. The annotations on the function body must be compatible with the types given for the overloaded variants listed above it. The type checker will verify that all the types for the overloaded variants are compatible with the types given for the implementation. In this case it checks that the parameter type ``int`` and the return type ``T`` are compatible with ``Union[int, slice]`` and ``Union[T, Sequence[T]]`` for the first variant. For the second variant it verifies that the parameter type ``slice`` and the return type ``Sequence[T]`` are compatible with ``Union[int, slice]`` and ``Union[T, Sequence[T]]``. Overloaded function variants are still ordinary Python functions and they still define a single runtime object. There is no automatic dispatch happening, and you must manually handle the different types in the implementation (usually with :func:`isinstance` checks, as shown in the example). The overload variants must be adjacent in the code. This makes code clearer, as you don't have to hunt for overload variants across the file. Overloads in stub files are exactly the same, except there is no implementation. .. note:: As generic type variables are erased at runtime when constructing instances of generic types, an overloaded function cannot have variants that only differ in a generic type argument, e.g. ``List[int]`` and ``List[str]``. .. note:: If you just need to constrain a type variable to certain types or subtypes, you can use a :ref:`value restriction <type-variable-value-restriction>`. .. _attrs_package: Loading @@ -17,6 +134,7 @@ 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+) Loading @@ -28,6 +146,7 @@ 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 Loading @@ -43,6 +162,7 @@ That enables this to work: import attr from typing import Dict @attr.s(auto_attribs=True) class A: one: int = attr.ib(8) Loading Loading @@ -175,7 +295,7 @@ Caching with mypy daemon ======================== You can also use remote caching with the :ref:`mypy daemon <mypy_daemon>`. The remote cache will significantly speed up the the first ``dmypy check`` The remote cache will significantly speed up the first ``dmypy check`` run after starting or restarting the daemon. The mypy daemon requires extra fine-grained dependency data in Loading @@ -187,7 +307,7 @@ build:: This flag adds extra information for the daemon to the cache. In order to use this extra information, you will also need to use the ``--use-fine-grained-cache`` option with ``dymypy start`` or ``--use-fine-grained-cache`` option with ``dmypy start`` or ``dmypy restart``. Example:: $ dmypy start -- --use-fine-grained-cache <options...> Loading Loading @@ -231,3 +351,129 @@ at least if your codebase is hundreds of thousands of lines or more: mypy build to create the cache data, as repeatedly updating cache data incrementally could result in drift over a long time period (due to a mypy caching issue, perhaps). .. _extended_callable: Extended Callable types *********************** As an experimental mypy extension, you can specify ``Callable`` types that support keyword arguments, optional arguments, and more. When you specify the arguments of a Callable, you can choose to supply just the type of a nameless positional argument, or an "argument specifier" representing a more complicated form of argument. This allows one to more closely emulate the full range of possibilities given by the ``def`` statement in Python. As an example, here's a complicated function definition and the corresponding ``Callable``: .. code-block:: python from typing import Callable from mypy_extensions import (Arg, DefaultArg, NamedArg, DefaultNamedArg, VarArg, KwArg) def func(__a: int, # This convention is for nameless arguments b: int, c: int = 0, *args: int, d: int, e: int = 0, **kwargs: int) -> int: ... F = Callable[[int, # Or Arg(int) Arg(int, 'b'), DefaultArg(int, 'c'), VarArg(int), NamedArg(int, 'd'), DefaultNamedArg(int, 'e'), KwArg(int)], int] f: F = func Argument specifiers are special function calls that can specify the following aspects of an argument: - its type (the only thing that the basic format supports) - its name (if it has one) - whether it may be omitted - whether it may or must be passed using a keyword - whether it is a ``*args`` argument (representing the remaining positional arguments) - whether it is a ``**kwargs`` argument (representing the remaining keyword arguments) The following functions are available in ``mypy_extensions`` for this purpose: .. code-block:: python def Arg(type=Any, name=None): # A normal, mandatory, positional argument. # If the name is specified it may be passed as a keyword. def DefaultArg(type=Any, name=None): # An optional positional argument (i.e. with a default value). # If the name is specified it may be passed as a keyword. def NamedArg(type=Any, name=None): # A mandatory keyword-only argument. def DefaultNamedArg(type=Any, name=None): # An optional keyword-only argument (i.e. with a default value). def VarArg(type=Any): # A *args-style variadic positional argument. # A single VarArg() specifier represents all remaining # positional arguments. def KwArg(type=Any): # A **kwargs-style variadic keyword argument. # A single KwArg() specifier represents all remaining # keyword arguments. In all cases, the ``type`` argument defaults to ``Any``, and if the ``name`` argument is omitted the argument has no name (the name is required for ``NamedArg`` and ``DefaultNamedArg``). A basic ``Callable`` such as .. code-block:: python MyFunc = Callable[[int, str, int], float] is equivalent to the following: .. code-block:: python MyFunc = Callable[[Arg(int), Arg(str), Arg(int)], float] A ``Callable`` with unspecified argument types, such as .. code-block:: python MyOtherFunc = Callable[..., int] is (roughly) equivalent to .. code-block:: python MyOtherFunc = Callable[[VarArg(), KwArg()], int] .. note:: This feature is experimental. Details of the implementation may change and there may be unknown limitations. **IMPORTANT:** Each of the functions above currently just returns its ``type`` argument, so the information contained in the argument specifiers is not available at runtime. This limitation is necessary for backwards compatibility with the existing ``typing.py`` module as present in the Python 3.5+ standard library and distributed via PyPI.
docs/source/basics.rstdeleted 100644 → 0 +0 −194 Original line number Diff line number Diff line Basics ====== This chapter introduces some core concepts of mypy, including function annotations, the ``typing`` module and library stubs. Read it carefully, as the rest of documentation may not make much sense otherwise. Function signatures ******************* A function without a type annotation is considered dynamically typed: .. code-block:: python def greeting(name): return 'Hello, {}'.format(name) You can declare the signature of a function using the Python 3 annotation syntax (Python 2 is discussed later in :ref:`python2`). This makes the function statically typed, and that causes type checker report type errors within the function. Here's a version of the above function that is statically typed and will be type checked: .. code-block:: python def greeting(name: str) -> str: return 'Hello, {}'.format(name) If a function does not explicitly return a value we give the return type as ``None``. Using a ``None`` result in a statically typed context results in a type check error: .. code-block:: python def p() -> None: print('hello') a = p() # Type check error: p has None return value Arguments with default values can be annotated as follows: .. code-block:: python def greeting(name: str, prefix: str = 'Mr.') -> str: return 'Hello, {} {}'.format(name, prefix) Mixing dynamic and static typing ******************************** Mixing dynamic and static typing within a single file is often useful. For example, if you are migrating existing Python code to static typing, it may be easiest to do this incrementally, such as by migrating a few functions at a time. Also, when prototyping a new feature, you may decide to first implement the relevant code using dynamic typing and only add type signatures later, when the code is more stable. .. code-block:: python def f(): 1 + 'x' # No static type error (dynamically typed) def g() -> None: 1 + 'x' # Type check error (statically typed) .. note:: The earlier stages of mypy, known as the semantic analysis, may report errors even for dynamically typed functions. However, you should not rely on this, as this may change in the future. The typing module ***************** The ``typing`` module contains many definitions that are useful in statically typed code. You typically use ``from ... import`` to import them (we'll explain ``Iterable`` later in this document): .. code-block:: python from typing import Iterable def greet_all(names: Iterable[str]) -> None: for name in names: print('Hello, {}'.format(name)) For brevity, we often omit the ``typing`` import in code examples, but you should always include it in modules that contain statically typed code. The presence or absence of the ``typing`` module does not affect whether your code is type checked; it is only required when you use one or more special features it defines. Type checking programs ********************** You can type check a program by using the ``mypy`` tool, which is basically a linter -- it checks your program for errors without actually running it:: $ mypy program.py All errors reported by mypy are essentially warnings that you are free to ignore, if you so wish. The next chapter explains how to download and install mypy: :ref:`getting-started`. More command line options are documented in :ref:`command-line`. .. note:: Depending on how mypy is configured, you may have to explicitly use the Python 3 interpreter to run mypy. The mypy tool is an ordinary mypy (and so also Python) program. For example:: $ python3 -m mypy program.py .. _library-stubs: Library stubs and the Typeshed repo *********************************** In order to type check code that uses library modules such as those included in the Python standard library, you need to have library *stubs*. A library stub defines a skeleton of the public interface of the library, including classes, variables and functions and their types, but dummy function bodies. For example, consider this code: .. code-block:: python x = chr(4) Without a library stub, the type checker would have no way of inferring the type of ``x`` and checking that the argument to ``chr`` has a valid type. Mypy incorporates the `typeshed <https://github.com/python/typeshed>`_ project, which contains library stubs for the Python builtins and the standard library. The stub for the builtins contains a definition like this for ``chr``: .. code-block:: python def chr(code: int) -> str: ... In stub files we don't care about the function bodies, so we use an ellipsis instead. That ``...`` is three literal dots! Mypy complains if it can't find a stub (or a real module) for a library module that you import. You can create a stub easily; here is an overview: * Write a stub file for the library and store it as a ``.pyi`` file in the same directory as the library module. * Alternatively, put your stubs (``.pyi`` files) in a directory reserved for stubs (e.g., ``myproject/stubs``). In this case you have to set the environment variable ``MYPYPATH`` to refer to the directory. For example:: $ export MYPYPATH=~/work/myproject/stubs Use the normal Python file name conventions for modules, e.g. ``csv.pyi`` for module ``csv``. Use a subdirectory with ``__init__.pyi`` for packages. If a directory contains both a ``.py`` and a ``.pyi`` file for the same module, the ``.pyi`` file takes precedence. This way you can easily add annotations for a module even if you don't want to modify the source code. This can be useful, for example, if you use 3rd party open source libraries in your program (and there are no stubs in typeshed yet). That's it! Now you can access the module in mypy programs and type check code that uses the library. If you write a stub for a library module, consider making it available for other programmers that use mypy by contributing it back to the typeshed repo. There is more information about creating stubs in the `mypy wiki <https://github.com/python/mypy/wiki/Creating-Stubs-For-Python-Modules>`_. The following sections explain the kinds of type annotations you can use in your programs and stub files. .. note:: You may be tempted to point ``MYPYPATH`` to the standard library or to the ``site-packages`` directory where your 3rd party packages are installed. This is almost always a bad idea -- you will likely get tons of error messages about code you didn't write and that mypy can't analyze all that well yet, and in the worst case scenario mypy may crash due to some construct in a 3rd party package that it didn't expect.
docs/source/builtin_types.rst +20 −19 Original line number Diff line number Diff line Loading @@ -3,13 +3,13 @@ Built-in types These are examples of some of the most common built-in types: =================== =============================== ====================== =============================== Type Description =================== =============================== ``int`` integer of arbitrary size ====================== =============================== ``int`` integer ``float`` floating point number ``bool`` boolean value ``str`` unicode string ``str`` string (unicode) ``bytes`` 8-bit string ``object`` an arbitrary object (``object`` is the common base class) ``List[str]`` list of ``str`` objects Loading @@ -17,11 +17,12 @@ Type Description ``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 ``Sequence[bool]`` sequence of booleans ``Sequence[bool]`` sequence of booleans (read-only) ``Mapping[str, int]`` mapping from ``str`` keys to ``int`` values (read-only) ``Any`` dynamically typed value with an arbitrary type =================== =============================== ====================== =============================== The type ``Any`` and type constructors ``List``, ``Dict``, The type ``Any`` and type constructors such as ``List``, ``Dict``, ``Iterable`` and ``Sequence`` are defined in the ``typing`` module. The type ``Dict`` is a *generic* class, signified by type arguments within Loading @@ -30,7 +31,7 @@ strings and and ``Dict[Any, Any]`` is a dictionary of dynamically typed (arbitrary) values and keys. ``List`` is another generic class. ``Dict`` and ``List`` are aliases for the built-ins ``dict`` and ``list``, respectively. ``Iterable`` and ``Sequence`` are generic abstract base classes that ``Iterable``, ``Sequence``, and ``Mapping`` are generic types that correspond to Python protocols. For example, a ``str`` object or a ``List[str]`` object is valid when ``Iterable[str]`` or ``Sequence[str]`` is expected. Note that even though Loading