Skip to content

[conflict] Fix #1855: Multiassign from Union #2154

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 54 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
7e043d0
handle union, add test
elazarg Sep 18, 2016
9a50d73
kill blank
elazarg Sep 18, 2016
5c4d86e
more tests
elazarg Sep 18, 2016
60cfbbb
handle binding
elazarg Sep 19, 2016
5e9e0f2
try to minimize visual difference
elazarg Sep 19, 2016
71f8475
(cont.)
elazarg Sep 19, 2016
42b6e73
add tests
elazarg Sep 21, 2016
0560bd8
no binder yet
elazarg Sep 23, 2016
7683ee2
Sync typeshed
Sep 23, 2016
8f0316f
Docs: Replace "if False" trick with "if TYPE_CHECKING". (#2181)
davidfstr Sep 25, 2016
fde83d5
Add column number support (#2163)
bavardage Sep 25, 2016
2fbf387
Fix #2070 - bytes formatting incorrect in python 3 (#2168)
buckbaskin Sep 26, 2016
da3a516
Support rebinding on multiassignment from union
elazarg Sep 27, 2016
ab60317
Merge remote-tracking branch 'upstream/master' into multiassign_union
elazarg Sep 27, 2016
6bb5519
more tests
elazarg Sep 27, 2016
0d2c594
Bare `Tuple` should mean `Tuple[Any, ...]`. (#2185)
gvanrossum Sep 27, 2016
2c73db5
Add --recursive and --ignore-errors flags to stubgen (#2183)
rtpg Sep 27, 2016
d2c6e8b
Fix lint
Sep 27, 2016
5c03ac9
Make runtests.py output less verbose
Sep 27, 2016
c3e1b35
Small module name translation fix for fast parser (#2187)
ddfisher Sep 27, 2016
87f7d90
Fix overzealous new submodule check (#2189)
Michael0x2a Sep 28, 2016
c752b42
Sync typeshed
Sep 28, 2016
5f0d02c
Implement PEP 526 Variable Annotations Syntax (#2131)
ilevkivskyi Sep 28, 2016
bec9454
Fix a fixup bug for nested class references.
Sep 28, 2016
a9fac0b
Add gitter chat room
gvanrossum Sep 29, 2016
ea23ac0
Rename --suppress-error-context to --hide-error-context (#2192)
gvanrossum Sep 29, 2016
4a34623
Add gitter badge for the new chat room (#2202)
gvanrossum Sep 30, 2016
2db6a11
Don't crash in fast parser on complex numbers in Python 2 mode
Oct 1, 2016
6151d20
Add more precise types to fastparse{,2}.py (#2204)
elazarg Oct 1, 2016
4a457fc
Tighter types for binder, checker and checkexpr (#2205)
elazarg Oct 1, 2016
c8a9b52
Tighten types for semanal (#2207)
elazarg Oct 2, 2016
af0b24a
Tighten types for parse.py and some more (#2208)
elazarg Oct 2, 2016
d5c5c02
Make Expression and Statement separable (#2209)
elazarg Oct 3, 2016
640921b
Make Expression, Statement true subclasses of Node. See #1783.
Oct 3, 2016
20aea69
Add mypy.ini. Fix strict none errors in the test subpackage. (#2200)
gvanrossum Oct 3, 2016
a3b6546
Sync typeshed
Oct 3, 2016
91a2275
Document support for Python 3.6 features.
Oct 3, 2016
bc4a390
Document --show-column-numbers and --scripts-are-modules
Oct 3, 2016
2e6cb95
Shorten "inherently stale" log message if all nodes in scc are stale
Oct 3, 2016
d6a7069
Fix lint error
Oct 3, 2016
eb16d1d
Remove weird implementation of --show_traceback and --pdb. (#2216)
gvanrossum Oct 4, 2016
dd71ddc
RIP weak mode. (#2217)
gvanrossum Oct 4, 2016
38651c4
handle union, add test
elazarg Sep 18, 2016
9000099
kill blank
elazarg Sep 18, 2016
f20f3d6
more tests
elazarg Sep 18, 2016
61be4e9
handle binding
elazarg Sep 19, 2016
9830cb4
try to minimize visual difference
elazarg Sep 19, 2016
59dc8b7
(cont.)
elazarg Sep 19, 2016
7f304e4
add tests
elazarg Sep 21, 2016
ff1ca80
no binder yet
elazarg Sep 23, 2016
168087e
Support rebinding on multiassignment from union
elazarg Sep 27, 2016
3f198cf
more tests
elazarg Sep 27, 2016
4fa059f
Rebase
elazarg Oct 5, 2016
ab35a4c
Merge
elazarg Oct 5, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ install:
- python setup.py install

script:
- python runtests.py -v
- python runtests.py
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,16 @@ Mypy: Optional Static Typing for Python
=======================================

[![Build Status](https://travis-ci.org/python/mypy.svg)](https://travis-ci.org/python/mypy)
[![Chat at https://gitter.im/python/mypy](https://badges.gitter.im/python/mypy.svg)](https://gitter.im/python/mypy?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)


Got a question? File an issue!
------------------------------

We don't have a mailing list; but we are always happy to answer questions
filed as issues in our trackers:
We don't have a mailing list; but we are always happy to answer
questions on [gitter chat](https://gitter.im/python/mypy) or filed as
issues in our trackers:

- [mypy tracker](https://github.com/python/mypy/issues)
for mypy isues
- [typeshed tracker](https://github.com/python/typeshed/issues)
Expand All @@ -17,7 +20,6 @@ filed as issues in our trackers:
for discussion of new type system features (PEP 484 changes) and
runtime bugs in the typing module


What is mypy?
-------------

Expand Down
38 changes: 28 additions & 10 deletions docs/source/command_line.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,24 @@ summary of command line flags can always be printed using the ``-h``
flag (or its long form ``--help``)::

$ mypy -h
usage: mypy [-h] [-v] [-V] [--python-version x.y] [--platform PLATFORM]
[-2] [-s] [--almost-silent] [--disallow-untyped-calls]
usage: mypy [-h] [-v] [-V] [--python-version x.y] [--platform PLATFORM] [-2]
[-s] [--almost-silent] [--disallow-untyped-calls]
[--disallow-untyped-defs] [--check-untyped-defs]
[--disallow-subclassing-any] [--warn-incomplete-stub]
[--warn-redundant-casts] [--warn-unused-ignores]
[--suppress-error-context] [--fast-parser] [-i]
[--cache-dir DIR] [--strict-optional]
[--hide-error-context] [--fast-parser] [-i] [--cache-dir DIR]
[--strict-optional]
[--strict-optional-whitelist [GLOB [GLOB ...]]] [--pdb]
[--show-traceback] [--stats] [--inferstats]
[--custom-typing MODULE] [--scripts-are-modules]
[--config-file CONFIG_FILE] [--linecount-report DIR]
[--linecoverage-report DIR] [--old-html-report DIR]
[--memory-xml-report DIR] [--xml-report DIR]
[--xslt-html-report DIR] [--xslt-txt-report DIR]
[--html-report DIR] [--txt-report DIR] [-m MODULE]
[-c PROGRAM_TEXT] [-p PACKAGE]
[--config-file CONFIG_FILE] [--show-column-numbers]
[--linecount-report DIR] [--linecoverage-report DIR]
[--old-html-report DIR] [--memory-xml-report DIR]
[--xml-report DIR] [--xslt-html-report DIR]
[--xslt-txt-report DIR] [--html-report DIR] [--txt-report DIR]
[-m MODULE] [-c PROGRAM_TEXT] [-p PACKAGE]
[files [files ...]]

(etc., too long to show everything here)

Specifying files and directories to be checked
Expand Down Expand Up @@ -306,6 +307,23 @@ Here are some more useful flags:
default to using whatever operating system you are currently using. See
:ref:`version_and_platform_checks` for more about this feature.

- ``--show-column-numbers`` will add column offsets to error messages,
for example, the following indicates an error in line 12, column 9
(note that column offsets are 0-based):

.. code-block:: python

main.py:12:9: error: Unsupported operand types for / ("int" and "str")

- ``--scripts-are-modules`` will give command line arguments that
appear to be scripts (i.e. files whose name does not end in ``.py``)
a module name derived from the script name rather than the fixed
name ``__main__``. This allows checking more than one script in a
single mypy invocation. (The default ``__main__`` is technically
more correct, but if you have many scripts that import a large
package, the behavior enabled by this flag is often more
convenient.)

.. _config-file-flag:

- ``--config-file CONFIG_FILE`` causes configuration settings to be
Expand Down
13 changes: 5 additions & 8 deletions docs/source/common_issues.rst
Original file line number Diff line number Diff line change
Expand Up @@ -260,17 +260,16 @@ imports to a module and those imports cause cycles that didn't exist
before. If those cycles become a problem when running your program,
there's a trick: if the import is only needed for type annotations in
forward references (string literals) or comments, you can write the
imports inside ``if False:`` so that they are not executed at runtime.
The reason this works is that mypy (currently) does not analyze
unreachable code like this. Example:
imports inside ``if TYPE_CHECKING:`` so that they are not executed at runtime.
Example:

File ``foo.py``:

.. code-block:: python

from typing import List
from typing import List, TYPE_CHECKING

if False:
if TYPE_CHECKING:
import bar

def listify(arg: 'bar.BarClass') -> 'List[bar.BarClass]':
Expand All @@ -289,7 +288,5 @@ File ``bar.py``:

.. note::

It is possible that in the future, mypy will change its dead code
analysis and this trick will stop working. We will then offer an
alternative, e.g. a constant defined by the ``typing`` module that
The ``TYPE_CHECKING`` constant defined by the ``typing`` module
is ``False`` at runtime but ``True`` while type checking.
2 changes: 1 addition & 1 deletion docs/source/config_file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ The following global flags may only be set in the global section
- ``cache_dir`` (string, default ``.mypy_cache``) stores module cache
info in the given folder in incremental mode.

- ``suppress_error_context`` (Boolean, default False) suppresses
- ``hide_error_context`` (Boolean, default False) hides
context notes before errors.


Expand Down
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Mypy is a static type checker for Python.
additional_features
command_line
config_file
python36
faq
cheat_sheet
revision_history
Expand Down
64 changes: 64 additions & 0 deletions docs/source/python36.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.. python36:

New features in Python 3.6
==========================

Python 3.6 will be `released
<https://www.python.org/dev/peps/pep-0494>`_ in December 2016. The
`first beta <https://www.python.org/downloads/release/python-360b1/>`_
came out in September and adds some exciting features. Here's the
support matrix for these in mypy (to be updated with each new mypy
release). The intention is to support all of these by the time Python
3.6 is released.

Syntax for variable annotations (`PEP 526 <https://www.python.org/dev/peps/pep-0526>`_)
---------------------------------------------------------------------------------------

Python 3.6 feature: variables (in global, class or local scope) can
now have type annotations using either of the two forms:

.. code-block:: python

foo: Optional[int]
bar: List[str] = []

Mypy fully supports this syntax, interpreting them as equivalent to

.. code-block:: python

foo = None # type: Optional[int]
bar = [] # type: List[str]

Literal string formatting (`PEP 498 <https://www.python.org/dev/peps/pep-0498>`_)
---------------------------------------------------------------------------------

Python 3.6 feature: string literals of the form
``f"text {expression} text"`` evaluate ``expression`` using the
current evaluation context (locals and globals).

Mypy does not yet support this.

Underscores in numeric literals (`PEP 515 <https://www.python.org/dev/peps/pep-0515>`_)
---------------------------------------------------------------------------------------

Python 3.6 feature: numeric literals can contain underscores,
e.g. ``1_000_000``.

Mypy does not yet support this.

Asynchronous generators (`PEP 525 <https://www.python.org/dev/peps/pep-0525>`_)
-------------------------------------------------------------------------------

Python 3.6 feature: coroutines defined with ``async def`` (PEP 492)
can now also be generators, i.e. contain ``yield`` expressions.

Mypy does not yet support this.

Asynchronous comprehensions (`PEP 530 <https://www.python.org/dev/peps/pep-0530>`_)
-----------------------------------------------------------------------------------

Python 3.6 feature: coroutines defined with ``async def`` (PEP 492)
can now also contain list, set and dict comprehensions that use
``async for`` syntax.

Mypy does not yet support this.
5 changes: 5 additions & 0 deletions mypy.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[mypy]
show_none_errors = False

[mypy-mypy/test/*]
show_none_errors = True
39 changes: 25 additions & 14 deletions mypy/binder.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
from typing import (Any, Dict, List, Set, Iterator)
from typing import (Any, Dict, List, Set, Iterator, Optional, DefaultDict, Tuple, Union)
from contextlib import contextmanager
from collections import defaultdict

from mypy.types import Type, AnyType, PartialType
from mypy.nodes import (Node, Var)
from mypy.nodes import (Node, Expression, Var, RefExpr, SymbolTableNode)

from mypy.subtypes import is_subtype
from mypy.join import join_simple
Expand Down Expand Up @@ -37,6 +38,7 @@ class A:
reveal_type(lst[0].a) # str
```
"""
type_assignments = None # type: Optional[DefaultDict[Expression, List[Tuple[Type, Type]]]]

def __init__(self) -> None:
# The set of frames currently used. These map
Expand Down Expand Up @@ -96,16 +98,16 @@ def _get(self, key: Key, index: int=-1) -> Type:
return self.frames[i][key]
return None

def push(self, expr: Node, typ: Type) -> None:
if not expr.literal:
def push(self, node: Node, typ: Type) -> None:
if not node.literal:
return
key = expr.literal_hash
key = node.literal_hash
if key not in self.declarations:
self.declarations[key] = self.get_declaration(expr)
self.declarations[key] = self.get_declaration(node)
self._add_dependencies(key)
self._push(key, typ)

def get(self, expr: Node) -> Type:
def get(self, expr: Union[Expression, Var]) -> Type:
return self._get(expr.literal_hash)

def cleanse(self, expr: Node) -> None:
Expand Down Expand Up @@ -165,19 +167,29 @@ def pop_frame(self, fall_through: int = 0) -> Frame:

return result

def get_declaration(self, expr: Any) -> Type:
if hasattr(expr, 'node') and isinstance(expr.node, Var):
type = expr.node.type
def get_declaration(self, node: Node) -> Type:
if isinstance(node, (RefExpr, SymbolTableNode)) and isinstance(node.node, Var):
type = node.node.type
if isinstance(type, PartialType):
return None
return type
else:
return None

def assign_type(self, expr: Node,
@contextmanager
def accumulate_type_assignments(self) -> Iterator[DefaultDict[Expression,
List[Tuple[Type, Type]]]]:
self.type_assignments = defaultdict(list)
yield self.type_assignments
self.type_assignments = None

def assign_type(self, expr: Expression,
type: Type,
declared_type: Type,
restrict_any: bool = False) -> None:
if self.type_assignments is not None:
self.type_assignments[expr].append((type, declared_type))
return
if not expr.literal:
return
self.invalidate_dependencies(expr)
Expand All @@ -197,7 +209,6 @@ def assign_type(self, expr: Node,

# If x is Any and y is int, after x = y we do not infer that x is int.
# This could be changed.
# Eric: I'm changing it in weak typing mode, since Any is so common.

if (isinstance(self.most_recent_enclosing_type(expr, type), AnyType)
and not restrict_any):
Expand All @@ -212,7 +223,7 @@ def assign_type(self, expr: Node,
# just copy this variable into a single stored frame.
self.allow_jump(i)

def invalidate_dependencies(self, expr: Node) -> None:
def invalidate_dependencies(self, expr: Expression) -> None:
"""Invalidate knowledge of types that include expr, but not expr itself.

For example, when expr is foo.bar, invalidate foo.bar.baz.
Expand All @@ -223,7 +234,7 @@ def invalidate_dependencies(self, expr: Node) -> None:
for dep in self.dependencies.get(expr.literal_hash, set()):
self._cleanse_key(dep)

def most_recent_enclosing_type(self, expr: Node, type: Type) -> Type:
def most_recent_enclosing_type(self, expr: Expression, type: Type) -> Type:
if isinstance(type, AnyType):
return self.get_declaration(expr)
key = expr.literal_hash
Expand Down
Loading