Thursday, 25 August 2016

Mypy 0.4.4 Released

I just uploaded version 0.4.4 of mypy-lang to PyPI! This release adds several new features, bug fixes and library stub updates.

Run this to upgrade to the new release using pip:

    python3 -m pip install -U mypy-lang

Experimental async and await Support

Mypy can now type check code using async and await (PEP 492). Here is an example from the documentation (this requires --fast-parser):

    import asyncio

    async def format_string(tag: str, count: int) -> str:
        return 'T-minus {} ({})'.format(count, tag)

    async def countdown_1(tag: str, count: int) -> str:
        while count > 0:
            my_str = await format_string(tag, count)  # has type 'str'
            print(my_str)
            await asyncio.sleep(0.1)
            count -= 1
        return "Blastoff!"

    loop = asyncio.get_event_loop()
    loop.run_until_complete(countdown_1("Millennium Falcon", 5))
    loop.close()

NewType

You can use NewType (see documentation) to define a special lightweight variant of an existing type. Mypy considers it to be a separate type, but there’s only minimal runtime overhead, as it doesn’t define a new class. We can create a new type called UserId, instances of which are actually int objects at runtime, but which is treated like a subclass of int by mypy:

    from typing import NewType

    UserId = NewType('UserId', int)

    def name_by_id(user_id: UserId) -> str:
        ...

    name_by_id(42)          # Type check error -- UserId expected
    name_by_id(UserId(42))  # OK
    print(UserId(42))       # 42 (the runtime representation is just int)

Additional Changes

Here is list of other notable changes in this release:

  • Support checks for sys.version_info and sys.platform, which are especially useful for stubs (see documentation)
  • Add the --platform command line option to explicitly set the target platform, instead of defaulting to the current platform
  • Support *expr within list, tuple and set expressions, and **expr within dict expressions (requires --fast-parser)
  • Incremental type checking is now more robust (--incremental)
  • Strict optional checking is also more robust (--strict-optional)
  • Many bugs fixed (especially crashes)
  • Lots of typeshed improvements
  • Documentation updates
  • Warn about unused type ignores on imports with --warn-unused-ignores
  • Add --suppress-error-context flag to suppress notes about class/function (this cleaner output mode may become the default in the future)
  • Less output by default on internal error (use --tb to show traceback)
  • Removed the need for -f /--dirty-stubs during mypy development
  • Started transitioning to using pytest for the mypy test suite (PR #1944)

Acknowledgements

Thanks to all mypy contributors who contributed to this release:
  • Daniel F Moisset
  • Fabian Heredia Montiel
  • Roy Williams
  • Ryan Gonzalez
  • Shrey Desai
  • Valérian Rousset
Additional thanks to typeshed contributors:
  • Alvaro Caceres
  • Antoine Catton
  • Daniel Horn
  • Daniël van Eeden
  • David Euresti
  • Elazar Gershuni
  • Emanuel Barry
  • Fu Yong Quah
  • Jakub Stasiak
  • Matthias Kramm
  • Max Wittek
  • Michael R. Crusoe
  • Nicholas Bishop
  • Tom Manderson
  • Tomasz Elendt
  • Tyler O'Meara
  • Wojciech Kaczmarek
  • Alvaro Caceres
  • jchien14
  • jdelic
  • John K Lai
  • kosaka
  • peterdotran
  • speezepearson
  • Tony Grue
  • wreed4

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

5 comments:

  1. Hi. I use MyPy at work, and I'd like to use something analogous to `NewType` for a current project, but I don't understand the semantics behind `NewType` as described in this post.

    In your example, we create `UserID = NewType("UserID", int)`. If `UserID` is truly a fresh type, then we have no way to manipulate it. It seems we have just the one introduction form `UserID(int)`, which will do, but no corresponding elimination forms. How are values of type `UserId` supposed to be used?

    ReplyDelete
    Replies
    1. For questions, please use the tracker at https://github.com/python/mypy

      Delete
  2. I love NewType! Used it for a medium-sized system at work and it was a great help in catching logical errors (eg, email addresses are simply strings, but by creating a constructor function that returns an "email" after the appropriate string checks, I can use the email string throughout the system without needing additional validation checks. Thanks much, and looking forward future additions!

    ReplyDelete