Friday, 7 December 2018

Mypy 0.650 Released

We’ve just uploaded mypy 0.650 to the Python Package Index (PyPI). Mypy is a static type checker for Python. This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the documentation for this release on Read the Docs.

Skipping the Rest of a File Using Asserts

You can now use certain always-false, unindented top-level assertions to tell mypy to skip the rest of the file. This allows you to skip type checking based on the target platform, for example:

    import sys

    assert sys.platform != 'win32'

    # The rest of this file doesn't work on Windows.

Some other expressions exhibit similar behavior; in particular, typing.TYPE_CHECKING, variables named MYPY, and any variable whose name is passed to --always-true or --always-false. (However, True and False are not treated specially!)

Mypy Daemon Improvements

  • Exit with status 2 from dmypy on irregular errors, and with 1 only if type checking finished but generated errors (PR 5982)
  • Work towards dmypy support on Windows:
    • Add initial support for dmypy on Windows (Ethan Smith, PR 5859)
    • Create new, hidden window when starting daemon on Windows (Ethan Smith, PR 5994)
  • Add --remove/--update flags to dmypy recheck (to allow Watchman integration, for example) (PR 5840, PR 5745)
  • Fix issues with # type: ignore in dmypy (PR 5861)
  • Fix daemon dependency handling for super() (PR 5793)
  • Speed up dmypy by reducing constant overhead (PR 5907)

Stubgen Improvements

  • Update stubgen to output async def and coroutine decorators (Bryan Forbes, PR 5845)
  • Improve stub files generated by stubgenc for pybind11 modules (Wiktor Niesiobędzki, PR 5850)
  • Improve stub generation so it works better with pybind11 wrappers (Eric Chang, PR 5814)
  • Make stubgen less aggressive about walking C extension modules (PR 5900)

Plugin Improvements

The mypy plugin system is still not documented or officially supported for third-party plugin development, but it’s available for brave early adopters.

  • Add plugin for ctypes.Array (dgelessus, PR 4869)
  • Fix ctypes plugin trying to look up bytes in Python 2 (dgelessus, PR 5924)
  • Fix dataclass inherited field ordering (Jakub Stasiak, PR 5877)
  • Invalidate cache when a plugin is added, removed or changed (PR 5878, PR 5892)
  • Add plugin hook for dynamic class definition (PR 5875)
  • Add options attribute to all plugin APIs (dgelessus, PR 5890)
  • Fix plugin hooks not being called correctly for dunder methods (dgelessus, PR 5700)
  • Fix issues with plugins in daemon mode (PR 5828)

Documentation Updates

  • Document ClassVar (PR 6005, PR 5733) (Joannah Nanjekye)
  • Improve documentation of ABCs (PR 6004)
  • Document what to do if a class is not generic at runtime (PR 5833)
  • Remove the “revision history” chapter, which was not very useful (PR 6018)

Other Improvements and Notable Bugs Fixed

  • Re-order module search path to put MYPYPATH first (Ethan Smith, PR 5776)
  • Stop suggesting MYPYPATH on missing imports (Michael Lee, PR 5950)
  • Add --disallow-any-generics to --strict (Joel Croteau, PR 5685)
  • Change all TypedDicts to be subtypes of Mapping[str, object] (PR 5933)
  • Type check TypedDict as caller kwargs (PR 5925)
  • Fix crash in PEP 561 module resolution (Ethan Smith, PR 6000)
  • Fix crash when reveal_locals() encounters a class definition (PR 5920)
  • Make descriptor assignments more like normal assignments (PR 5853)
  • Fix issue with module __getattr__ (PR 5893)
  • Fixes to reports: don't crash on control characters, ensure directories exist earlier (PR 5885)
  • Preserve tabs when creating XML reports (Maarten ter Huurne, PR 5945)
  • Create missing directories for junit XML output (Evan Kepner, PR 5827)
  • Fix constraint inference for non-invariant instances (PR 5817)
  • Use actual variable name for failed enum calls (PR 5810)
  • Support None.__bool__() (Daniel Darabos, PR 5780)
  • Avoid "No such file or directory" if module ancestor doesn't exist (PR 5785)
  • Add option to raise exception on internal errors (Joel Croteau, PR 5768)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • Bryan Forbes
  • Chris Philip
  • Daniel Darabos
  • dgelessus
  • Eric Chang
  • Ethan Smith
  • Evan Kepner
  • Florian Bruhin
  • Jakub Stasiak
  • Joannah Nanjekye
  • Joel Croteau
  • Maarten ter Huurne
  • Michael Lee
  • Sebastian Rittau
  • Tomasz Walotek
  • Wiktor Niesiobędzki

Additional thanks to all contributors to typeshed:

  • Adam Simpkins
  • Andrew Svetlov
  • anentropic
  • Brandt Bucher
  • Daniel Li
  • Dave Halter
  • David Zbarsky
  • Dev Aggarwal
  • dgelessus
  • Diego Elio Pettenò
  • edgchen1
  • Ethan Smith
  • Fionn Fitzmaurice
  • Florian Bruhin
  • Gregory P. Smith
  • Grzegorz Śliwiński
  • Hannes Karppila
  • Jakub Stasiak
  • Jelle Zijlstra
  • Jerome Leclanche
  • Jared Hance
  • Joel Rosdahl
  • Joey Wilhelm
  • Keith Gray
  • Lourens Veen
  • Maarten ter Huurne
  • Marco Leogrande
  • Matt Gilson
  • MatthewPScott81
  • Maxim Kurnikov
  • Michael
  • Michael Lee
  • Michael R. Crusoe
  • Opal Symes
  • Pascal Corpet
  • Peter Pentchev
  • PRAJWAL M
  • Rebecca Chen
  • Ruud van Asseldonk
  • Sebastian Rittau
  • Semyon Proshev
  • Siva Chandra
  • Summon528
  • thautwarm
  • Utkarsh Gupta
— Jukka Lehtosalo, on behalf of the mypy team

Friday, 12 October 2018

Mypy 0.641 Released

THIS RELEASE REPLACES 0.640. The bug reported in issue 5784 has been fixed. There are no other changes.

We’ve just uploaded mypy 0.641 to the Python Package Index (PyPI). Mypy is an optional static type checker for Python. This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:
    python3 -m pip install -U mypy
You can read the documentation for this release on ReadTheDocs.

New Feature: Final Qualifiers

In this release we’re rolling out an exciting new (experimental) feature for the type system: final qualifiers.

Installation

Using this feature requires installing the latest typing_extensions package, version 3.6.6:
    python3 -m pip install -U typing_extensions

Final variables

You can declare a variable “final” using the Final qualifier, like so:
    from typing_extensions import Final
    RATE: Final = 3000
    # ...
    RATE = 300  # error: Cannot assign to final name "RATE"
This also works for local variables, class variables and instance variables. For class variables it implies that subclasses cannot override the value either. You can also use a type comment (# type: Final).
Note that “final” variables may have a mutable type, and then they can still be mutated:
    PLATFORMS: Final = ['mac', 'windows']
    PLATFORMS.append('linux')  # OK

Final methods and classes

You can also declare methods “final”, meaning they cannot be overridden by a subclass:
    from typing_extensions import final  # Note lower-case 'f'
    class Base:
       @final
       def update(self) -> None:
           ...
    class Derived(base):
        def update(self) -> None:  # error: Cannot override final attribute "update"
            ...
The @final decorator can also be used for classes, where it means they cannot be subclassed.

Note

Final qualifiers only have an effect during type checking, in type-checked code; they don’t do anything at runtime.

Documentation

The full documentation has additional details about this feature.

New Feature: Allow Omitting Return Type for __init__

It is now possible to omit the return type of an annotated __init__ method without getting an error message. For example:
    class Circuit:
        def __init__(self, voltage: float):
            self.voltage = voltage
In previous mypy versions this would elicit an error message:
    error: The return type of "__init__" must be None
This error was just annoying as the only legal return declaration for __init__ is -> None, so we’ve removed it. Note that this only works if there’s at least one annotated argument! For __init__ methods without arguments you must still add -> None, otherwise the method will be treated as untyped, and its body will not be type checked at all. Examples:
    class UntypedExample:
        # This method is not type-checked at all!
        def __init__(self):
            self.voltage = 0.0
    
    class TypedExample:
        # This is how to ensure that a 0-argument __init__ is type-checked:
        def __init__(self) -> None:
            self.voltage = 0.0

New Feature: Namespace Package Support

Python 3 supports packages without __init__.py files, better known as namespace packages. These were introduced by PEP 420 as a mechanism for splitting a single Python package across multiple directories. There are some subtleties in their semantics (e.g. a package with __init__.py file are preferred even if they occur later on sys.path), and until this release mypy did not support them. Support is now provided using the command-line flag --namespace-packages (or the correponding config file phrase namespace_packages = True). Note that the default is still off. At some point in the future the default may change to on for Python 3. (Python 2 doesn’t support namespace packages, though mypy will let you combine this flag with --py2.)

Other Flags and Options Changes

  • New flag: --allow-untyped-globals suppresses errors caused by not being able to fully infer the types of global and class variables (PR 5670)
  • Deprecated flag: --quick-and-dirty ; it will be removed in a future release (PR 5737)
  • Removed flags, all of which have been deprecated for a long time: --disallow-any, -f/--dirty-stubs, --use-python-path, -s/--silent-imports, --almost-silent, --[no-]fast-parser, --strict-boolean (for the latter, see discussion in issue 3195) (PR 5740)
  • The -2/--py2 flag’s behavior now matches --python-version (sqwishy, PR 5619)
  • New experimental flag: --fast-exit makes mypy exit faster (by skipping final GC pass) (PR 5569)

Other Improvements and Notable Bugs Fixed

  • Get rid of Optional when assigning Any in an is None branch (PR 5629)
  • Don't crash on aliases of the form C = C (PR 5632)
  • Fix meet for tuple with instance (PR 5641)
  • Add missing fine-grained dependencies when using Type[X] (PR 5607)
  • Make NamedTuple provide __new__ instead of __init__ (PR 5643)
  • Fully analyze named tuple subclasses in third pass (PR 5644)
  • Defer subclass methods if superclass has not been analyzed to fix issues with checking method overrides in import cycles (PR 5637)
  • Fix type object signature when both __new__ and __init__ present (PR 5642)
  • Fix crash related to decorated functions (PR 5654)
  • Fix “Invalid type” errors in import cycles (PR 5635)
  • Make classmethod's first argument be Type[...] and fix __init__ defined after a class method (PR 5646)
  • Allow comparisons to refine Optional types without strict-optional (PR 4523)
  • Fix untyped decorator check for class instances (Daniel Izquierdo, PR 5509)
  • Fix bug with inferring bad arguments to overloads (Michael Lee, PR 5660)
  • Add the current directory to sys.path when running stubgen (PR 5673)
  • Allow returning inferred None from functions (PR 5663)
  • Support stubs marked with py.typed in PEP-420 nested packages (Chris Philip, PR 5591)
  • Don't report "function does not return a value" in unannotated functions (PR 5683)
  • Make return type implicitly None for type checked __init__ and __init_subclass__ (Ekin Dursun, PR 5677)
  • Improve usage of outer context for inference (PR 5699)
  • Reformat and reorganize the config file docs (Michael Lee, PR 5595)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.
Thanks to all mypy contributors who contributed to this release:
  • ceh
  • Chris Philip
  • Daniel Izquierdo
  • Ekin Dursun
  • Elazar Gershuni
  • Ethan Smith
  • Jan Teske
  • Joel Croteau
  • Michael Lee
  • sqwishy
Additional thanks to all contributors to typeshed:
  • Adam Dangoor
  • Benjamin Peterson
  • Christian Haudum
  • Dmitry Shachnev
  • Emil Hessman
  • Grzegorz Śliwiński
  • Israel Tsadok
  • Jan Teske
  • Jelle Zijlstra
  • Jon Dufresne
  • kitsuyui
  • Manuel Vázquez Acosta
  • Martin DeMello
  • Matt Robinson
  • Matthew Christopher
  • Michael R. Crusoe
  • Nathaniel Manista
  • Ran Benita
  • Rebecca Chen
  • Richard Levasseur
  • Ruben Berenguel
  • Scott Colby
  • Sebastian Kreft
  • Sebastian Rittau
  • Siva Chandra
  • spdkils
  • Teddy Sudol
  • Wim L
  • Zac Hatfield-Dodds
— Guido van Rossum, on behalf of the mypy team
















Monday, 17 September 2018

Mypy 0.630 Released

We’ve just uploaded mypy 0.630 to the Python Package Index (PyPI). Mypy is an optional static type checker for Python. This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:
    python3 -m pip install -U mypy
You can read the documentation for this release on ReadTheDocs.

New Feature: Callback Protocols

You can now use protocols to specify callable types. In some situations it was hard (or even impossible) to express types of complex callbacks using the Callable[[Arg, ...], Ret] syntax. Examples include overloaded callbacks, complex generic callbacks, or just callables that don’t accept a fixed number of positional arguments. You can define a callback protocol for situations like these — it’s a protocol with only __call__ defined:
    from typing import Optional, Iterable, List
    from typing_extensions import Protocol
    
    class Combiner(Protocol):
        def __call__(self, *vals: bytes, 
                     maxlen: Optional[int] = None) -> List[bytes]: ...
    
    def batch_proc(data: Iterable[bytes],
                   cb_results: Combiner) -> bytes:
        ...        
    def good_cb(*vals: bytes,
                maxlen: Optional[int] = None) -> List[bytes]:
        ...
    batch_proc([], good_cb)  # OK
For more information see the docs.

Other Improvements and Notable Bugs Fixed

  • Support classes and type aliases in plugin hooks (PR 5379)
  • Treat IntEnum type object as iterable (Elazar Gershuni, PR 5388)
  • Improve Tuple/Sequence/Iterable type overlap checks (Ethan Smith, PR 5315)
  • Improve checks for overlapping types (Michael Lee, PR 5476)
  • Improve error message for overload overrides with swapped variants (Michael Lee, PR 5369)
  • Add support for optional converters in attrs plugin (David Euresti, PR 5411)
  • Allow calling Type[T] where T has a generic bound (Elazar Gershuni, PR 5309)
  • Support additional arguments to namedtuple() (Jelle Zijlstra, PR 5215)
  • Fix crash related to decorated functions (PR 5427)
  • Fix daemon crash related to named tuples (PR 5429)
  • Avoid infinite recursion when attempting to define recursive types (PR 5434)
  • Don't treat non-method functions whose name resembles a reverse operator (e.g. __radd__) as such (Sebastian Rittau, PR 5421)
  • Allow plugin registration in mypy.ini using module names or entry points (Chad Dombrova, PR 5358)
  • Invalidate cache when a previously missing stub is added (PR 5465)
  • Fix issues related to reverse operator methods (Michael Lee, PR 5475)

Documentation Fixes and Internal Improvements

  • Remove runtests.py in favor of pytest (Elazar Gershuni, PR 5274)
  • Improve stub testing to cover all of typeshed (Ethan Smith, PR 5051)
  • Reorganize command line documentation (Michael Lee, PR 5333)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team. Thanks to all mypy contributors who contributed to this release:
  • Alex Jurkiewicz
  • Anthony Sottile
  • Batuhan Osman Taşkaya
  • Bernát Gábor
  • Bruce Merry
  • Chad Dombrova
  • David Euresti
  • Elazar Gershuni
  • Elias Zamaria
  • Emil Hessman
  • Ethan Smith
  • Georg Molau
  • Janus Troelsen
  • Jelle Zijlstra
  • Matvey Tolstolytski
  • Michael Lee
  • Sebastian Rittau
  • William Schwartz
  • ceh
  • snarkmaster
Additional thanks to all contributors to typeshed:
  • Amol Bhave
  • Anthony Sottile
  • Brandon Lin
  • Bruce Merry
  • Chelsea Voss
  • Daniel Li
  • David Euresti
  • David Zbarsky
  • Devin Fee
  • Dmitry Shachnev
  • Dominik Gabi
  • EFanZh
  • Emil Hessman
  • Ethan Smith
  • Gary van der Merwe
  • Goldstein
  • Hynek Schlawack
  • Ilya Konstantinov
  • Jelle Zijlstra
  • Linda_pp
  • Martin DeMello
  • Matt Gilson
  • Max Murin
  • Michael Lee
  • MinJune Kim
  • Ollie Ford
  • Olmo Kramer
  • Omar Sandoval
  • Philipp Hahn
  • Ran Benita
  • Rebecca Chen
  • Sebastian Kreft
  • Sebastian Rittau
  • Siva Chandra
  • Stig Johan Berggren
  • Teddy Sudol
  • Tomasz Trębski
  • Ville Skyttä
  • Yusuke Miyazaki
  • Zac Hatfield-Dodds
  • Zsolt Dollenstein
  • justinpawela
  • stevenjackson121
  • tikki
— Ivan Levkivskyi, on behalf of the mypy team

Friday, 13 July 2018

Mypy 0.620 Released

We’ve just uploaded mypy 0.620 to the Python Package Index (PyPI). Mypy is an optional static type checker for Python. This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:
    python3 -m pip install -U mypy
You can read the documentation for this release on ReadTheDocs.

New Features

Support for data classes in Python 3.7

The recently released Python 3.7 added a new module dataclasses that allows writing simple boilerplate-free classes. Mypy now supports this new feature:
    from dataclasses import dataclass
    from typing import List
    
    @dataclass
    class FitResult:
        optimum: List[float]
        chi: float
        method: str = "TRF"
    
    FitResult([0.1, 0.2], 1.2)  # OK
    FitResult([0.1, 0.2], 1.2, "LM")  # Also OK
    FitResult(1, 2)  # Error!
Note: there are some limitations in supported features — see the docs. (Contributed by Bogdan Popa in PR 5010.)

Overloads on generic types and other overload improvements

Mypy previously rejected certain patterns involving overloaded functions, in particular defining overloads on generic types, and calling overloads on union and optional types. These (and a few others) are now supported. In addition, the error messages for overloads are now more detailed:
    from typing import List, Union, overload
    
    @overload
    def summarize(data: List[int]) -> float: ...
    @overload
    def summarize(data: List[str]) -> str: ...
    def summarize(data):
        # Implementation goes here
        ...
    
    gen_data: Union[List[int], List[str]]
    res = summarize(gen_data)  # OK, inferred type is Union[float, str]
    
    bad_data: int
    summarize(bad_data)
    # error: No overload variant of "summarize" matches argument type "int"
    # note: Possible overload variants:
    # note:     def summarize(data: List[int]) -> float
    # note:     def summarize(data: List[str]) -> str
See the updated docs for more details. (Contributed by Michael Lee.)

Incomplete and partial packages

Writing complete stubs for an existing large library may be hard and sometimes impractical. To allow gradual improvements in library stubs without generating spurious errors, two mechanisms are now supported. Adding a __getattr__ function to __init__.pyi indicates that the corresponding package (or subpackage) is incomplete, thus silencing Missing library stub errors for this package:
    # pack/__init__.pyi
    from typing import Any
    def __getattr__(arrr: str) -> Any: ...
    
    # pack/subpack/__init__.pyi
    # empty
    
    # pack/subpack/mod.pyi
    class Test: ...
    
    # main.py
    from pack import other  # OK, pack is incomplete
    other.func(1, 2)  # OK, all types in incomplete packages are Any
    
    from pack.subpack import mod  # OK
    from pack.subpack import another  # Error: missing library stub file
In addition, a PEP 561 stub package can declare itself as partial, allowing fallbacks to other sources of typing information such as inline annotations and typeshed stubs. See PEP 561 for the details. (Contributed by Ethan Smith.)

Other Improvements and Notable Bugs Fixed

  • Fix running mypy from editable install directory (Ethan Smith, PR 5381)
  • Support egg/setuptools packages for PEP 561 searching (Ethan Smith, PR 5282)
  • Refactor and reorder search path to make it compliant with PEP 561 (Ethan Smith, PR 5256)
  • Silence errors in modules in site-packages and typeshed (Ethan Smith, PR 5303)
  • Fix two option handling bugs in dmypy (PR 5172)
  • Fix a daemon crash bug (PR 5285)
  • Fix incorrect handling of attrs attributes with init=False and default (David Euresti, PR 5154)
  • Various additional overload bug fixes (PR 5236, PR 5254, PR 5224, PR 5163, PR 5166) (Michael Lee)
  • Several module __getattr__ fixes (PR 5332, PR 5306, PR 5295, PR 5292)

Internal Improvements

  • Test suite cleanups (PR 5142, PR 5271) (Elazar Gershuni)
  • Improve PEP 561 testing infrastructure (PR 5060, PR 5225, PR 5237) (Ethan Smith)
  • Support for PyCharm test debugging, and add tox environment setup (Bernát Gábor, PR 5189)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team. Thanks to all mypy contributors who contributed to this release:
  • Alex Tereshenkov
  • Bogdan Popa
  • David Euresti
  • Elazar Gershuni
  • Emil Hessman
  • Ethan Smith
  • Gábor Bernát
  • Herst
  • Jelle Zijlstra
  • Julian Ospald
  • Michael Lee
  • Nate White
  • Sebastian Rittau
Additional thanks to all contributors to typeshed:
  • Andrew Svetlov
  • Anthony Sottile
  • Bertrand Bonnefoy-Claudet
  • Cyril Jouve
  • Daniel Li
  • Ethan Smith
  • Froger David
  • George King
  • Hanaasagi
  • Ilya Konstantinov
  • Jason Fried
  • Jelle Zijlstra
  • John Reese
  • Josh Holland
  • Martin DeMello
  • Mathieu Leduc-Hamel
  • Max
  • Max R
  • Michael
  • Michael Hirsch, Ph.D
  • Michael Lee
  • NAKAMURA Yoshitaka
  • Nipunn Koorapati
  • Philipp Hahn
  • Rebecca Chen
  • Robert Collins
  • Roy Williams
  • Scott Belden
  • Sebastian Rittau
  • Sekou Diao
  • Stephen Thorne
  • Steven Karas
  • Sushain Cherivirala
  • Yusuke Miyazaki
  • mbarkhau
  • potykion
  • strager
— Ivan Levkivskyi, on behalf of the mypy team

Friday, 8 June 2018

Mypy 0.610 released

We’ve just uploaded mypy 0.610 to the Python Package Index (PyPI). Mypy is an optional static type checker for Python. This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:
    python3 -m pip install -U mypy
You can read the documentation for this release on ReadTheDocs.

New Features

Add a dmypy run command that starts/restarts the mypy daemon as needed

The 0.600 release added support for a mypy daemon (in beta) which can speed up mypy runtimes by a large factor, especially when performing incremental builds where only a few files have changed. To avoid requiring projects to write scripting around dmypy start/dmypy check/dmypy status, this release adds a dmypy run command that checks files while automatically managing the lifecycle of the daemon. A set of files (or directories) can be checked with dmypy run -- <flags> <files>. See the documentation for more details. As a simple example, the way we run dmypy on mypy itself is: dmypy run -- ``--ignore-imports=error --config-file=mypy_self_check.ini mypy/

Make async function return type more specific

The type of the object returned by calling an async function used to be Awaitable; it’s changed to Coroutine since such objects support calling send() and throw() on them (André Caron, PR 5052)

Other Improvements

  • Allow wildcards instead of configuration section names again (PR 5120)
  • Store the daemon’s socket in /tmp instead of the current directory (Ming-Yuan Jian, PR 5003)
  • Support types as converters and factory= in attrs plugin (David Euresti, PR 4917, PR 5005)
  • Use .dmypy.json instead of dmypy.json as the daemon run file (PR 5036)
  • Improve error messages for invalid tuple types (MentalMegalodon, PR 5042)
  • Make conditional expressions use Union instead of join when the result type is a Union (MentalMegalodon, PR 5041, PR 5095)
  • Add a reveal_locals() expression that displays the types of all local variables (Anton Ian Sipos, PR 3425)
  • Allow raise E when E has the type Type[Exn] (bwo, PR 4918)
  • Allow specifying multiple shadow files (Gareth T, PR 5023)
  • Relax overload checks to allow return types to be regular subtypes (Michael Lee, PR 5064)
  • Remove "builtins." from output for overloads and builtins.None (Jelle Zijlstra, PR 5073)
  • Allow __getattr__ in nested scopes (Jelle Zijlstra, PR 4958)
  • Support module-level __getattr__ outside of stubs (PEP 562) (Jelle Zijlstra, PR 4958)
  • Improve "Name already defined" error message (Sid Kapur, PR 5067)

Notable Bugs Fixed

  • Fix false positives caused by differing function parameter names in certain circumstances (Michael Lee, PR 4920)
  • Fix a number of daemon bugs (PR 4988, PR 4989, PR 4993, PR 4994, PR 5065, PR 5091)
  • Fix a crash that one of those earlier fixes caused (Nate White, PR 5126)
  • Support protocols in daemon mode (PR 4790)
  • Fix access to operators on metaclass through a type variable (Elazer Gershuni, PR 5009)
  • Fix descriptor/Union interactions (PR 5039)
  • Fix a crash bug caused by bogus symbol table nodes (PR 5094)
  • Fix crash when checking async generator return type (PR 5123)
  • Write indirect dependencies into the cache even when not in incremental mode (PR 5123)

Internal Improvements

  • Substantial test suite cleanups (Elazar Gershuni, PR 5011, PR 5041, PR 5076, PR 5075, PR 5087)
  • Use a shared incremental cache for pythoneval tests (Ethan Smith, PR 5114)
  • Fix testcmdline.py when run with pytest -n0 (PR 5113)

Documentation Improvements

  • Wide-ranging documentation improvements (PR 5043, PR 5053)
  • Reorganize the documentation into sections (Michael Lee, PR 5104)
  • Add mention of --check-untyped-defs option to docs (Tony E Lewis, PR 4996)
  • Clarify that checking Python 2 is fully supported (Mitchel Humpherys, PR 5029)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team. Thanks to all mypy contributors who contributed to this release:
  • André Caron
  • Anton Ian Sipos
  • bwo
  • Daniel Li
  • David Euresti
  • Elazar Gershuni
  • Emil Hessman
  • Ethan Smith
  • Gareth T
  • Jelle Zijlstra
  • MentalMegalodon
  • Michael Lee
  • Mikel Solabarrieta
  • Ming-Yuan Jian
  • Mitchel Humpherys
  • Nate White
  • Sid Kapur
  • Tony E Lewis
Additional thanks to all contributors to typeshed:
  • Alex Vandiver
  • Andrew Gaul
  • Andrew Svetlov
  • Daniel Li
  • Danny Weinberg
  • David Euresti
  • Dmitry Figol
  • Dominik Gabi
  • Emil Hessman
  • Ethan Smith
  • Ilya Konstantinov
  • Jakub Nabaglo
  • Jasper Spaans
  • Jelle Zijlstra
  • Katelyn Gigante
  • Martijn Pieters
  • Michael Lee
  • Omar Sandoval
  • Phillip Schanely
  • Salvo 'LtWorf' Tomaselli
  • Sebastian Rittau
  • Semyon Proshev
  • Stanislav Syekirin
  • Thomas Schaper
  • Zabolekar
  • Zac Hatfield-Dodds
— Michael J. Sullivan, on behalf of the mypy team

Wednesday, 2 May 2018

Mypy 0.600 Released

We’ve just uploaded mypy 0.600 to the Python Package Index (PyPI). Mypy is an optional static type checker for Python. This is a major release that turns on strict optional checking by default (there’s a flag to disable it for backward compatibility), introduces a new mypy daemon mode with much, much faster incremental checking, along with other new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the documentation for this release on ReadTheDocs.

New Features

Strict Optional Checking Enabled by Default

Over a year after introducing it, strict optional mode is now on by default. This means that mypy checks that you use an Optional[…] type whenever a None is a valid value (see below for how to get the old behavior):

    def greet(name: str) -> None:
        print('hi, ' + name)

    greet(None)  # Error! None not compatible with 'str'

Mypy also verifies that only valid operations are performed on None values:

    from typing import Optional

    def greet(name: Optional[str]) -> None:
        print('hi, ' + name)  # Error: Incompatible types
                              # 'str' and 'Optional[str]'

    greet(None)  # OK

Mypy recognizes common Python idioms for checking against None values:

    from typing import Optional

    def greet(name: Optional[str]) -> None:
        if name is None:
            print('hello, stranger')
        else:
            print('hi, ' + name)  # OK

    greet(None)  # OK

You can still get the old behavior, where None was a valid value for every type, by using the --no-strict-optional flag (or strict_optional = False in your config file). Strict optional checking was previously available through the --strict-optional flag, which is no longer required. Read the now significantly expanded documentation for the details, including hints about how to migrate an existing codebase to strict optional checking. We have no plans to deprecate the backward compatibility flag, however.

Mypy Daemon

This release adds support for a mypy daemon (in beta) which can speed up mypy runtimes by a large factor, especially when performing incremental builds where only a few files have changed. The mypy daemon is a server process that runs on your development machine (where you’d normally run mypy) and keeps program state in memory to avoid redundant work when running mypy repeatedly. There’s a client tool dmypy that requests type checking results from the daemon.

We’ve used the mypy daemon at Dropbox for over a month now (it’s been under development much longer), and typical incremental builds for a codebase with millions of lines complete in a few seconds. Running mypy using the daemon can be dozens of times faster than non-daemon incremental mypy runs for large codebases. The documentation explains how to use the mypy daemon.

Remote Caching

We’ve documented how to use remote caching with mypy, where you set up a Continuous Integration build to pre-generate mypy cache files for each new commit in your repository, and mypy runs “warm up” the cache by downloading a pre-generated cache file to speed up type checking. This can speed up mypy runtimes by a large factor.

We’ve used remote caching at Dropbox together with the mypy daemon for over a month now, and our users are very happy with the results. A cold mypy run (when the daemon is not already running) for a codebase with millions of lines often takes less than a minute, including the time needed to download the remote cache data (over a fast network). Without remote caching typical runtimes were several minutes. Read the documentation for details on how to set up remote caching.

Support Repeated Assignment to Local Variable '_'

Mypy now allows unrestricted assignments to the underscore variable (_) within functions, so code like this will no longer generate errors:

    from typing import Tuple

    def get_item(n: int) -> Tuple[int, str, float]: ...

    def get_length(n : int) -> int:
        length, _, _ = get_item(n)  # OK!
        assert length > 0
        return length

User-specific Config File

You can now store common mypy configuration options in a .mypy.ini file in your home directory, and it will be automatically used by mypy. This was contributed by Alejandro Avilés (PR 4939).

Notable Bugs Fixed

  • Fix crashes in coverage reports (PR 4978)
  • Fix to functional Enums (Elazar Gershuni, PR 4942)
  • Allow incompatible overriding of __slots__ (PR 4890)
  • Make an override of a ClassVar implicitly a ClassVar (Carl Meyer, PR 4718)
  • Use EnumMeta instead of Enum to mark enum classes (Elazar Gershuni, PR 4319)

Other Improvements

  • Improve performance with large config files and adjust semantics of section patterns (PR 4894)
  • Improve performance when using custom source encodings (PR 4957)
  • Reduce mypy memory usage (PR 4902, PR 4904)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • Alejandro Avilés
  • Carl Meyer
  • Elazar Gershuni
  • Emil Hessman
  • Ethan Smith
  • Jelle Zijlstra

Additional thanks to all contributors to typeshed:

  • Aaron Miller
  • Andrew Gaul
  • Charles-Axel Dein
  • Chris Gavin
  • Eddie Schoute
  • Freek Dijkstra
  • Jelle Zijlstra
  • John Reese
  • Martin DeMello
  • NODA, Kai
  • rchen152
  • Semyon Proshev
  • Siva Chandra
  • Svend Sorensen
  • Tomas Krizek
— Jukka Lehtosalo, on behalf of the mypy team

Friday, 13 April 2018

Mypy 0.590 Released

We’ve just uploaded mypy 0.590 to the Python Package Index (PyPI). This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the documentation for this release on ReadTheDocs.

New Features

PEP 561

We are releasing experimental support for PEP 561, which allows packages installed through pip (or other packaging tools, as long as packages end up on sys.path, typically in site-packages) to indicate that they contain type annotations (either inline or in stubs), and also allows packages that just provide stubs, overriding typeshed. We’re grateful to PEP 561 author Ethan Smith for the design and implementation. (Note that normally mypy doesn’t process packages installed in site-packages or elsewhere on sys.path, because realistically most packages, whether third-party or in the standard library, cause a myriad of spurious type checking errors.)

A summary of the new functionality: 1. Packages can include a marker file named py.typed to indicate that they have inline annotations or stubs next to the sources. For packages marked this way, if foo.py and foo.pyi both exist, mypy will use the annotations from foo.pyi (ignoring foo.py completely), while if only bar.py exists, mypy will type-check and use the annotations in bar.py. 2. Instead of distributing annotations or stubs as part of a package, it’s also possible to have a separately installable package that just provides stubs; e.g. for package baz, if a package named baz-stubs is installed, mypy will use the annotations from that package.

For more details read the documentation. The full specification is in PEP 561. Note that the PEP hasn’t been accepted yet, hence the labeling of mypy’s support as experimental. (The mypy implementation is considered a reference implementation which will be used to gain experience to feed back into the PEP review process. We’re expecting minimal changes to the basics as described above though.)

Incremental mode is on by default

After over a year of “burn-in” we’re finally confident enough about incremental mode to make it the default. For larger codebases this can dramatically speed up mypy runs. If for some reason you want to turn it off, you can use --no-incremental.

Flags for always true/false

New command line flags --always-true NAME and --always-false NAME can be used to treat variables named NAME als compile-time constants. This allows you to define your own flags for things like platform checks, version checks, and other environmental checks. Example:

    ON_WINDOWS = (sys.platform == 'win32')
    def foo():
        if ON_WINDOWS:
            <do it the Windows way>
        else:
            <do it the UNIX way>

By default mypy will check both branches of the if statement. When this example is checked with --always-true ON_WINDOWS only the first branch is checked; with --always-false ON_WINDOWS only the second branch is checked. Note that in all cases mypy does not consider the initial value given to the variable. (This is by design, since mypy doesn’t assume that variables remain constant over the lifetime of the program.)

Note that mypy only checks the last component of the variable name — module and class attributes whose name matches one of these will also be affected. (This is a blessing and a curse, and a reminder to use this feature sparingly and only for the most obvious cases.)

These flags may be repeated on the command line, e.g. --always-true FOO --always-true BAR --always-true BAZ assumes FOO and BAR are always true and BAZ is always false.

These flags may also be given in the config file (e.g. mypy.ini). There the syntax is

    always_true = FOO, BAR
    always_false = BAZ

The may also occur in per-module sections, in order to limit the scope of their effect.

Add a per-module follow_imports_for_stubs options

Setting this flag to true causes follow_imports to affect stub files. Example:

    [mypy-foo]
    follow_imports = skip
    follow_imports_for_stubs = true
will force skipping the import of module foo even if a stub file (foo.pyi) is found. See the documentation for a full explanation.

Notable Bugs Fixed

  • Fix error message when assigning to read-only property (PR 4863 by Michael Lee, fixes issue 4756)
  • Respect --follow-imports=silent in --warn-unused-ignores (PR 4857, fixes issue 3949)
  • Don't produce spurious “unused type ignore” messages in incremental mode (PR 4841, fixes issue 2960)
  • Fix operator access on Type[...] (PR 4823, fixes issue 4789)
  • Remove incorrect override check on overloaded methods (PR 4810 by Michael Lee, fixes issue 4565)
  • Handle NotImplemented returned from __ne__ (PR 4770 by Peter Ludemann, fixes issue 4767)
  • Options in mypy.ini should be spelled with underscores, not hyphens (PR 4754 by Emil Hessman, fixes issue 4753)

Documentation Improvements

Stubgen Improvements

  • Emit Any type annotations for unannotated arguments (PR 4774 by Matt Gilson, fixes issue 4766)
  • Fix stubgen --recursive to only generate stubs for requested submodules. (PR 4845 by Matt Gilson, fixes issue 4844)
  • Properly format Callables (PR 4650 by Evan Hubinger, fixes issue 4640)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • Emil Hessman
  • Eric Wieser
  • Ethan Smith
  • Evan Hubinger
  • Evan Krall
  • Jelle Zijlstra
  • Matt Gilson
  • Michael Lee
  • Peter Ludemann
  • Rob Day
  • Viet Hung Nguyen

Additional thanks to all contributors to typeshed:

  • Alan Du
  • Ashwini Chaudhary
  • Bryce Guinta
  • Christopher Schramm
  • Danny Weinberg
  • David Euresti
  • dgelessus
  • Eric Wieser
  • Evan Krall
  • Jelle Zijlstra
  • Josh Holland
  • João Santos
  • Leonardo Fedalto
  • Luka Sterbic
  • Łukasz Langa
  • Matt Gilson
  • matthewfranglen
  • NODA, Kai
  • Nipunn Koorapati
  • Omar Sandoval
  • Patrick Meyer
  • Russell Cloran
  • Sebastian Rittau
  • Semyon Proshev
  • Tuomas Suutari
  • z33ky
— Guido van Rossum, on behalf of the mypy team

Friday, 23 March 2018

Mypy 0.580 released

We’ve just uploaded mypy 0.580 to the Python Package Index (PyPI). This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the documentation for this release on ReadTheDocs.

New Features

  • Add support for multiple packages on the command line alongside modules (Eric Wieser, PR 4733). Now you can run mypy with several packages on the command line, for example:
    mypy --package p.a --package p.b --module c
  • Set python_version to default to sys.version_info (Ethan Smith, PR 4686). This makes the implementation match docs and makes it easier to implement PEP 561.

Notable Bugs Fixed

  • Fix issues related to indirect imports in import cycles (PR 4695)
  • Fix frozen subclass and callable issues in attrs plugin (David Euresti, PR 4755)
  • stubgenc: Generate PEP 526 style variable annotations (gclinch, PR 4716)
  • Fix XML report generation (PR 4745)

Improved Error Messages

  • Helpful error message when strict is found in configuration file, which is unsupported (gclinch, PR 4706)

Other Changes

  • Refuse to run under Python 3.5.0 or anything before Python 3.4 (PR 4721). This is caused by the fact that the version of typing module shipped with Python 3.5.0 has several bugs and incompatible/old API.

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • David Euresti
  • Eric Wieser
  • Ethan Smith
  • gclinch
  • Jelle Zijlstra

Additional thanks to all contributors to typeshed:

  • Dan Sully
  • David Euresti
  • Ethan Smith
  • Josh Holland
  • Kenny Do
  • Martin DeMello
  • Matthias Kramm
  • Miguel Gaiowski
  • Nipunn Koorapati
  • rchen152
  • Rob Day
  • Roy Williams
  • Salvo 'LtWorf' Tomaselli
  • Sebastian Rittau
  • Sergey Passichenko
  • Svyatoslav Ilinskiy
  • Takuya Akiba
  • yed podtrzitko

— Ivan Levkivskyi, on behalf of the mypy team

Friday, 2 March 2018

Mypy 0.570 Released

We’ve just uploaded mypy 0.570 to the Python Package Index (PyPI). This release includes new features, bug fixes and library stub (typeshed) updates. You can install it as follows:

    python3 -m pip install -U mypy

You can read the documentation for this release on ReadTheDocs.

We're also happy to welcome long-time mypy core dev Ivan Levkivskyi to the mypy team at Dropbox.

New Features

  • Type check class decorators (David Euresti, PR 4544)
  • Plugin for typechecking classes generated by attrs (Documentation) (David Euresti)
  • Hooks into the semantic analyzer for plugins (PR 4328, PR 4397) (David Euresti)

Notable Bugs Fixed

  • Allow calling instances of tuple subclasses that define __call__ (PR 4367)
  • Improve handling of callable() (PR 4343)
  • Fix crashes due to improper handling of type variables (PR 4384)
  • Various stubgen bugs fixed (PR 4407, PR 4467, PR 4518) (hoefling)
  • Allow subtypes to define more overloads than their supertype (Ryan Gonzalez, PR 3263)
  • Fix typing of assignment to list (e.g. [a, b] = foo()) (Elazar Gershuni, PR 4340)
  • Don’t generate --warn-return-any warnings from binary magic methods that raise NotImplementedError (Vlad Starostin, PR 4545)
  • Fix false negatives in incremental mode due to missing dependencies on parent classes (PR 4566)
  • Fix type of forward reference to a decorated class method (PR 4486)
  • Have divmod() properly dispatch to __[r]divmod__ methods (David Euresti, PR 4585)
  • Fix setup.py breakage (yed podtrzitko, PR 4570)
  • Fix platforms in setup.py (Thomas Grainger, PR 3765)
  • Make psutil an optional dependency (Dominik Miedziński, PR 4634)

Improved Error Messages

  • Give faster feedback by streaming error messages incrementally during type checking (PR 4396)
  • Add variable name to "Need type annotation for variable" error (Elliott Beach, PR 4496)
  • Report columns as 1-based, not 0-based (Elliott Beach, PR 4482)
  • Display argument name, not number, for functions called with keyword arguments (Elliott Beach, PR 4504)

Other Changes

  • Document Generator/Iterator distinction (Carl Meyer, PR 4424)
  • Consistently exit with code 2 on blocking errors (PR 4449)
  • Allow unrecognized flags beginning with x_ in mypy.ini, for use in configuring linters and other tools that work with mypy (PR 4521)
  • Refactor and clean up test discovery (Elazar Gershuni, PR 3973)
  • Remove the home-rolled myunit testing framework (Elazar Gershuni, PR 4369)
  • Test cases for enum iteration (Nick Gaya, PR 4400)

Acknowledgments

First of all, we’d like to thank our employer, Dropbox, for funding the mypy core team.

Thanks to all mypy contributors who contributed to this release:

  • a4ff7810
  • Amit D
  • Ashwini Chaudhary
  • Carl Meyer
  • David Euresti
  • Dominik Miedziński
  • Elazar Gershuni
  • Elliott Beach
  • Ethan Smith
  • Germano Gabbianelli
  • Guilherme Caminha
  • hoefling
  • Jelle Zijlstra
  • Nick Gaya
  • Ryan Gonzalez
  • Thomas Grainger
  • Vlad Starostin
  • yed podtrzitko

Additional thanks to all contributors to typeshed:

  • Alan Du
  • Alex Dehnert
  • Anthony Sottile
  • Ashwini Chaudhary
  • Asim Goheer
  • Can Berk Güder
  • Carl Meyer
  • Chad Dombrova
  • Daniel Bowman
  • Daniel Bowtell
  • Daniel Li
  • David Euresti
  • David Zbarsky
  • Elazar Gershuni
  • Elliott Beach
  • Erwin Janssen
  • Ethan Smith
  • Garrett
  • George King
  • gossrock
  • Han Song
  • Ilya Kulakov
  • James M. Allen
  • Jason Fried
  • Jelle Zijlstra
  • Karl Ramm
  • Łukasz Langa
  • Mark Amery
  • Martin DeMello
  • Marti Raudsepp
  • Matt Bogosian
  • Matthias Kramm
  • Michael Lee
  • Michel Albert
  • Nathan Henrie
  • Neil Conway
  • Nick Gaya
  • NODA, Kai
  • PeterJCLaw
  • Pradyun Gedam
  • rchen152
  • Rhys Parry
  • Rick Kilgore
  • Roy Williams
  • Salvo 'LtWorf' Tomaselli
  • Sebastian Rittau
  • Semyon Proshev
  • shahin
  • Thomas Broadley
  • Yuri Khan

--Michael J. Sullivan, on behalf of the mypy team

Monday, 5 February 2018

Dropbox releases mypy-protobuf

At Dropbox we use Google’s Protocol Buffers a lot. So much, in fact, that we sorely needed a way to generate mypy stub files (.pyi files) that match the generated .py files. And out of sheer enthusiasm we implemented the stub file generation code twice! Once in Go, once in Python. Go figure. :-)

We’ve now open-sourced both versions, so if you’re a Python shop, you can use the Python version, while if you’re a Go shop that occasionally uses Python, or you want a faster stub generator, you can use the Go version.

Ready to give it a try? Here’s the repo: https://github.com/dropbox/mypy-protobuf; instructions for both versions are in the top-level README.md. If you’re going for the Python version there’s no need to clone the repo: just pip install mypy-protobuf and pass --mypy_out=<somewhere> to your protoc invocation.