Monday, 10 July 2017

Mypy 0.520 Released

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

    python3 -m pip install --upgrade mypy

We are always happy to answer questions on Gitter — note that we’ve moved to a new channel, python/typing.

Major New Features

Fine-grained Control of Any Types

Mypy now has a --disallow-any option that gives you more fine-grained control over Any types in your code. In particular, it lets you disallow the following kinds of Any:

  • explicit disallows explicit Any in type positions such as type annotations and generic type parameters
  • expr disallows all expressions in the module that have type Any
  • unimported disallows Any types that come from unfollowed imports (they usually appear with --follow-imports=skip or --ignore-missing-imports)
  • generics disallows usage of generic types that do not specify explicit type parameters. For example, List (without type parameters) is disallowed but using List[int] (or even List[Any]) is allowed.
  • decorated disallows functions that have Any in their signature after decorator transformation

You can use the option from command-line as --disallow-any=expr,explicit or from config file as disallow_any = generics,expr.

To learn more about the --disallow-any option, read the documentation.

This was implemented by Svyatoslav Ilinskiy.

__setattr__ Support

Mypy now understands __setattr__. If a class defines it, mypy allows assignments to arbitrary attributes. Example:

    class A:
        ...
        # This will allow assignment to any A.x, if x is the same type as value.
        def __setattr__(self, name: str, value: int) -> None:
            ...
    a.foo = 42  # Works
    a.bar = 'Ex-parrot'  # Fails type checking

This was contributed by Ethan Smith (PR 3451).

Hash-based Incremental Cache

Previously the incremental cache (enabled by the -i option) detected changes in source files based on the file modification time and file size. This made it hard to share incremental cache files between systems, since modification times generally aren’t consistent across multiple repository checkouts. Now mypy requires a change to the md5 hash of a file to consider it changed. This makes it possible to “warm up” the incremental cache by downloading it from a central repository, which can speed up mypy runs significantly. Providing an implementation of such a repository is out of scope for mypy, though.

This was implemented by Max Moroz and Guido (PR 3437 and some others).

NamedTuple Methods

It is now possible to add methods to NamedTuples defined using the Python 3.6 class-based syntax:
    class Point(NamedTuple):
        x: float
        y: float

        def translate(self, dx: float, dx: float) -> 'Point':
            return Point(x=self.x + dx, y=self.y + dy)

    p = Point(1, 2).translate(Point(4, 5))
    print(p)

Note that runtime support for this feature requires typing 3.6.1.

This was contributed by Jelle Zijlstra (PR 3081).

Improved Error Messages

Various error messages generated by mypy have been improved. Here is a summary of what’s changed:

  • Use distinct formatting for regular types and type object types; previously they looked sometimes confusingly identical (Elazar Gershuni, PR 3374)
  • Display the union type and offending union item when reporting a missing attribute for a union type (Amir Rachum, PR 3402)
  • Include line number of previous definition when there is a redefinition error (Max Moroz, PR 3424)
  • Suggest a type annotation if the type of a returned variable is incompatible with the declared return type (Jesse Lord, PR 3428)
  • Improve error message for invalid package names passed to mypy (chernrick, PR 3447)
  • Fix several error messages that didn't display types correctly (Svyatoslav Ilinskiy, PR 3638)
  • Revamp TypedDict-related error messages (Jukka Lehtosalo)

More New Features

  • Experimental support for enabling strict optional checking on a per file basis (David Fisher, PR 3206)
  • Support simple aliases to modules (Carl Meyer, PR 3435)
  • Support six.with_metaclass (Guido, PR 3364)
  • Allow any subtype of typing.Mapping[str, Any] to be passed in as **kwargs (Roy Williams, PR 3604)
  • Add flag --no-implicit-optional to avoid interpreting arguments with a default of None as Optional — this may become the default behavior in the future (David Fisher, PR 3248)
  • Allow NewType that subclasses another NewType (Carl Meyer, PR 3465)
  • Infer better return types for certain common special signatures such as open (if the mode is a string literal), contextlib.contextmanager and ** with a literal exponent (Jukka Lehtosalo, PR 3299)
  • Add --include-private flag to stubgen to include private members (Chad Dombrova, PR 3367)
  • Add flag --any-exprs-report to generate report about Any expressions (Svyatoslav Ilinskiy, PR 3492)
  • Allow tuple indexing using non-literal expressions (David Fisher, PR 3514)
  • Normalize Type[Union[...]] internally to Union[Type[...], ...] (Max Moroz, PR 3209)
  • Improve handling of compile-time relational operators (Ryan Gonzalez, PR 3158)
  • Add --no-incremental flag to disable incremental mode (David Fisher, PR 3570)
  • Improve type inference of unconditional if statements without else block (Michael Lee, PR 3567)
  • Document the --shadow-file option (David Fisher, PR 3615)
  • Display unreachable code as Any in HTML coverage reports (Svyatoslav Ilinskiy, PR 3616)
  • Add --skip-version-check flag to ignore the mypy version when validating incremental cache metadata (Guido, PR 3641)
  • Add a very experimental (and still undocumented) plugin system for extending mypy (PR 3534 and Jukka Lehtosalo, PR 3517)
  • Many improvements to TypedDict and new documentation [this is still not an officially supported feature] (Jukka Lehtosalo, Max Moroz and Ivan Levkivskyi)

Notable Bugs Fixed

  • Make change of platform invalidate the cache (Guido, PR 3663)
  • Fix imported generic type aliases (Ivan Levkivskyi, PR 3524)
  • Fix Optional[...] type aliases (Ivan Levkivskyi, PR 3524)
  • Reject redefinition of type aliases (Ivan Levkivskyi, PR 3524)
  • Fix None slice bounds with --strict-optional (Dominik Miedziński, PR 3445)
  • Fix crashes related to referring to a type before the definition has been processed (Ivan Levkiskyi, PR 3322 and PR 3560)
  • Fix crash when displaying the location of a method definition (Dominik Miedziński, PR 3375)
  • Treat non-inplace augmented assignment as a simple assignment (Max Moroz, PR 3110)
  • Fixes to quick mode (Ivan Levkivskyi, PR 3304 and PR 3356)
  • Don't warn about returning Any if an Any return value is explicitly allowed (Ivan Levkivskyi, PR 3473)
  • Fix type of f-string with only {…} such as f'{x}' (lincolnq, PR 3390)
  • Make Type[X] compatible with the metaclass of X (Elazar Gershuni, PR 3346)
  • Support accessing modules imported in class bodies within methods (Carl Meyer, PR 3450)
  • Fix crash when serializing a type-ignored property setter (Jelle Zijlstra, PR 3493)
  • Fix spurious "cycle in function expansion" errors (Guido, PR 3504)
  • Fix to union type used in condition (David Fisher, PR 3510)
  • Fix crashes on lambda generators (Ivan Levkivskyi, PR 3523)
  • Fix accessing qualified import in incremental mode (Michael Lee, PR 3548)
  • Fix overload resolution for metaclass (Elazar Gershuni, PR 3511)
  • Allow instances of a class to access inner class definitions on that class (Roy Williams, PR 3636)
  • Fix to type checking calls to classmethods with self types (Elazar Gershuni, PR 3633)
  • Don't crash if isinstance() called with too few arguments (Jukka Lehtosalo, PR 3652)
  • Reject isinstance() with NewType (Jukka Lehtosalo, PR 3654)
  • Fix crash during deserialization of callable types (Jukka Lehtosalo, PR 3660)

Other Changes

  • Require version 1.0.4 of the typed-ast dependency to run mypy
  • Release version 0.3.0 of mypy_extensions
  • Publish a new mypy roadmap
  • The majority of the mypy implementation is now type checked using strict optional checking (Ivan Levkiskyi)

Acknowledgments

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

Thanks to all mypy contributors who contributed to this release:

  • Abhas Bhattacharya
  • Amir Rachum
  • Carl Meyer
  • Chad Dombrova
  • chernrick
  • Dominik Miedziński
  • Elazar Gershuni
  • Ethan Smith
  • fdeliege
  • Ivan Levkivskyi
  • Jelle Zijlstra
  • Jesse Lord
  • lincolnq
  • Max Moroz
  • Michael Lee
  • Nathaniel Smith
  • Patrick Williams
  • Roy Williams
  • Ryan Gonzalez
  • Svyatoslav Ilinskiy
  • Thomas Grainger

Additional thanks to all contributors to typeshed:

  • Alex Grönholm
  • Alex Khomchenko
  • amstree
  • Antoine Reversat
  • Ashwini Chaudhary
  • Ask Solem
  • Atul Varma
  • Benjamin Starling
  • Carl Meyer
  • Cooper Lees
  • Daniel Li
  • David Euresti
  • DmitriyS
  • Doug Freed
  • Eklavya Sharma
  • Elliot Marsden
  • elmar bucher
  • Emily Morehouse
  • Ethan Smith
  • George Caley
  • Harmen
  • Ivan Levkivskyi
  • James Elford
  • Jan Hermann
  • Jason Fried
  • Jelle Zijlstra
  • Joe Bateson
  • John Reese
  • khyox
  • li-dan
  • Luka Sterbic
  • Lukasz Langa
  • macheins
  • Mahmoud Afaneh
  • Matthew Page
  • Matthias Kramm
  • Matěj Cepl
  • Max Moroz
  • Max Rozentsveyg
  • Michael Lee
  • Miguel Gaiowski
  • mistermocha
  • mpage
  • Nathan Henrie
  • Peter Vilim
  • pkordas
  • Ray Kraesig
  • rchen152
  • Rhys Parry
  • Roy Williams
  • Ryan Jarvis
  • Sebastian Meßmer
  • Semyon Proshev
  • Sergey Passichenko
  • Suren Nihalani
  • Svyatoslav Ilinskiy
  • Teemu R
  • Thomas Grainger
  • Yusuke Miyazaki

— Jukka (on behalf of the rest of the mypy team: Guido, David and Greg)