Skip to content

Commit e0a863c

Browse files
Merge branch 'master' into NarrowingTypeLen
2 parents eabc21c + 204c7da commit e0a863c

File tree

112 files changed

+2206
-534
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+2206
-534
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mypyc/doc/_build
1010
*.iml
1111
/out/
1212
.venv*/
13+
venv/
1314
.mypy_cache/
1415
.incremental_checker_cache.json
1516
.cache
@@ -44,6 +45,8 @@ htmlcov
4445
bin/
4546
lib/
4647
include/
48+
.python-version
49+
pyvenv.cfg
4750

4851
.tox
4952
pip-wheel-metadata

docs/source/command_line.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ Config file
9797

9898
This flag makes mypy read configuration settings from the given file.
9999

100-
By default settings are read from ``mypy.ini``, ``.mypy.ini``, or ``setup.cfg``
100+
By default settings are read from ``mypy.ini``, ``.mypy.ini``, ``pyproject.toml``, or ``setup.cfg``
101101
in the current directory. Settings override mypy's built-in defaults and
102102
command line flags can override settings.
103103

docs/source/config_file.rst

Lines changed: 82 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ The mypy configuration file
44
===========================
55

66
Mypy supports reading configuration settings from a file. By default
7-
it uses the file ``mypy.ini`` with a fallback to ``.mypy.ini``, then ``setup.cfg`` in
8-
the current directory, then ``$XDG_CONFIG_HOME/mypy/config``, then
7+
it uses the file ``mypy.ini`` with a fallback to ``.mypy.ini``, then ``pyproject.toml``,
8+
then ``setup.cfg`` in the current directory, then ``$XDG_CONFIG_HOME/mypy/config``, then
99
``~/.config/mypy/config``, and finally ``.mypy.ini`` in the user home directory
1010
if none of them are found; the :option:`--config-file <mypy --config-file>` command-line flag can be used
1111
to read a different file instead (see :ref:`config-file-flag`).
@@ -35,7 +35,7 @@ section names in square brackets and flag settings of the form
3535
`NAME = VALUE`. Comments start with ``#`` characters.
3636

3737
- A section named ``[mypy]`` must be present. This specifies
38-
the global flags. The ``setup.cfg`` file is an exception to this.
38+
the global flags.
3939

4040
- Additional sections named ``[mypy-PATTERN1,PATTERN2,...]`` may be
4141
present, where ``PATTERN1``, ``PATTERN2``, etc., are comma-separated
@@ -885,5 +885,84 @@ These options may only be set in the global section (``[mypy]``).
885885

886886
Controls how much debug output will be generated. Higher numbers are more verbose.
887887

888+
889+
Using a pyproject.toml file
890+
***************************
891+
892+
Instead of using a ``mypy.ini`` file, a ``pyproject.toml`` file (as specified by
893+
`PEP 518`_) may be used instead. A few notes on doing so:
894+
895+
* The ``[mypy]`` section should have ``tool.`` prepended to its name:
896+
897+
* I.e., ``[mypy]`` would become ``[tool.mypy]``
898+
899+
* The module specific sections should be moved into ``[[tool.mypy.overrides]]`` sections:
900+
901+
* For example, ``[mypy-packagename]`` would become:
902+
903+
.. code-block:: toml
904+
905+
[[tool.mypy.overrides]]
906+
module = 'packagename'
907+
...
908+
909+
* Multi-module specific sections can be moved into a single ``[[tools.mypy.overrides]]`` section with a
910+
module property set to an array of modules:
911+
912+
* For example, ``[mypy-packagename,packagename2]`` would become:
913+
914+
.. code-block:: toml
915+
916+
[[tool.mypy.overrides]]
917+
module = [
918+
'packagename',
919+
'packagename2'
920+
]
921+
...
922+
923+
* The following care should be given to values in the ``pyproject.toml`` files as compared to ``ini`` files:
924+
925+
* Strings must be wrapped in double quotes, or single quotes if the string contains special characters
926+
927+
* Boolean values should be all lower case
928+
929+
Please see the `TOML Documentation`_ for more details and information on
930+
what is allowed in a ``toml`` file. See `PEP 518`_ for more information on the layout
931+
and structure of the ``pyproject.toml`` file.
932+
933+
Example ``pyproject.toml``
934+
**************************
935+
936+
Here is an example of a ``pyproject.toml`` file. To use this config file, place it at the root
937+
of your repo (or append it to the end of an existing ``pyproject.toml`` file) and run mypy.
938+
939+
.. code-block:: toml
940+
941+
# mypy global options:
942+
943+
[tool.mypy]
944+
python_version = "2.7"
945+
warn_return_any = true
946+
warn_unused_configs = true
947+
948+
# mypy per-module options:
949+
950+
[[tool.mypy.overrides]]
951+
module = "mycode.foo.*"
952+
disallow_untyped_defs = true
953+
954+
[[tool.mypy.overrides]]
955+
module = "mycode.bar"
956+
warn_return_any = false
957+
958+
[[tool.mypy.overrides]]
959+
module = [
960+
"somelibrary",
961+
"some_other_library"
962+
]
963+
ignore_missing_imports = true
964+
888965
.. _lxml: https://pypi.org/project/lxml/
889966
.. _SQLite: https://www.sqlite.org/
967+
.. _PEP 518: https://www.python.org/dev/peps/pep-0518/
968+
.. _TOML Documentation: https://toml.io/

docs/source/error_code_list.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -421,6 +421,10 @@ Check TypedDict items [typeddict-item]
421421
When constructing a ``TypedDict`` object, mypy checks that each key and value is compatible
422422
with the ``TypedDict`` type that is inferred from the surrounding context.
423423

424+
When getting a ``TypedDict`` item, mypy checks that the key
425+
exists. When assigning to a ``TypedDict``, mypy checks that both the
426+
key and the value are valid.
427+
424428
Example:
425429

426430
.. code-block:: python

docs/source/kinds_of_types.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ will complain about the possible ``None`` value. You can use
329329
330330
When initializing a variable as ``None``, ``None`` is usually an
331331
empty place-holder value, and the actual value has a different type.
332-
This is why you need to annotate an attribute in a cases like the class
332+
This is why you need to annotate an attribute in cases like the class
333333
``Resource`` above:
334334

335335
.. code-block:: python

docs/source/running_mypy.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,3 +520,17 @@ For example, if you have multiple projects that happen to be
520520
using the same set of work-in-progress stubs, it could be
521521
convenient to just have your ``MYPYPATH`` point to a single
522522
directory containing the stubs.
523+
524+
Directories specific to Python 2 (@python2)
525+
*******************************************
526+
527+
When type checking in Python 2 mode, mypy also looks for files under
528+
the ``@python2`` subdirectory of each ``MYPYPATH`` and ``mypy_path``
529+
entry, if the subdirectory exists. Files under the subdirectory take
530+
precedence over the parent directory. This can be used to provide
531+
separate Python 2 versions of stubs.
532+
533+
.. note::
534+
535+
This does not need to be used (and cannot be used) with
536+
:ref:`PEP 561 compliant stub packages <installed-packages>`.

mypy/checker.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3961,9 +3961,10 @@ def find_type_equals_check(self, node: ComparisonExpr, expr_indices: List[int]
39613961
) -> Tuple[TypeMap, TypeMap]:
39623962
"""Narrow types based on any checks of the type ``type(x) == T``
39633963
3964-
:param node: The node that might contain the comparison
3965-
3966-
:param expr_indices: The list of indices of expressions in ``node`` that are being compared
3964+
Args:
3965+
node: The node that might contain the comparison
3966+
expr_indices: The list of indices of expressions in ``node`` that are being
3967+
compared
39673968
"""
39683969
type_map = self.type_map
39693970

mypy/checkexpr.py

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@
7777
int,
7878
int,
7979
CallableType,
80+
Optional[Type],
8081
Context,
8182
Context,
8283
MessageBuilder],
@@ -1011,7 +1012,7 @@ def check_callable_call(self,
10111012
arg_names, formal_to_actual, context, self.msg)
10121013

10131014
self.check_argument_types(arg_types, arg_kinds, args, callee, formal_to_actual, context,
1014-
messages=arg_messages)
1015+
messages=arg_messages, object_type=object_type)
10151016

10161017
if (callee.is_type_obj() and (len(arg_types) == 1)
10171018
and is_equivalent(callee.ret_type, self.named_type('builtins.type'))):
@@ -1452,10 +1453,13 @@ def check_argument_types(self,
14521453
formal_to_actual: List[List[int]],
14531454
context: Context,
14541455
messages: Optional[MessageBuilder] = None,
1455-
check_arg: Optional[ArgChecker] = None) -> None:
1456+
check_arg: Optional[ArgChecker] = None,
1457+
object_type: Optional[Type] = None) -> None:
14561458
"""Check argument types against a callable type.
14571459
14581460
Report errors if the argument types are not compatible.
1461+
1462+
The check_call docstring describes some of the arguments.
14591463
"""
14601464
messages = messages or self.msg
14611465
check_arg = check_arg or self.check_arg
@@ -1480,7 +1484,7 @@ def check_argument_types(self,
14801484
callee.arg_names[i], callee.arg_kinds[i])
14811485
check_arg(expanded_actual, actual_type, arg_kinds[actual],
14821486
callee.arg_types[i],
1483-
actual + 1, i + 1, callee, args[actual], context, messages)
1487+
actual + 1, i + 1, callee, object_type, args[actual], context, messages)
14841488

14851489
def check_arg(self,
14861490
caller_type: Type,
@@ -1490,6 +1494,7 @@ def check_arg(self,
14901494
n: int,
14911495
m: int,
14921496
callee: CallableType,
1497+
object_type: Optional[Type],
14931498
context: Context,
14941499
outer_context: Context,
14951500
messages: MessageBuilder) -> None:
@@ -1515,6 +1520,7 @@ def check_arg(self,
15151520
callee,
15161521
original_caller_type,
15171522
caller_kind,
1523+
object_type=object_type,
15181524
context=context,
15191525
outer_context=outer_context)
15201526
messages.incompatible_argument_note(original_caller_type, callee_type, context,
@@ -1978,6 +1984,7 @@ def check_arg(caller_type: Type,
19781984
n: int,
19791985
m: int,
19801986
callee: CallableType,
1987+
object_type: Optional[Type],
19811988
context: Context,
19821989
outer_context: Context,
19831990
messages: MessageBuilder) -> None:
@@ -2439,7 +2446,7 @@ def check_method_call(self,
24392446

24402447
return self.check_call(method_type, args, arg_kinds,
24412448
context, arg_messages=local_errors,
2442-
callable_name=callable_name, object_type=object_type)
2449+
callable_name=callable_name, object_type=base_type)
24432450

24442451
def check_op_reversible(self,
24452452
op_name: str,
@@ -2903,9 +2910,11 @@ def visit_index_with_type(self, left_type: Type, e: IndexExpr,
29032910

29042911
if isinstance(left_type, UnionType):
29052912
original_type = original_type or left_type
2913+
# Don't combine literal types, since we may need them for type narrowing.
29062914
return make_simplified_union([self.visit_index_with_type(typ, e,
29072915
original_type)
2908-
for typ in left_type.relevant_items()])
2916+
for typ in left_type.relevant_items()],
2917+
contract_literals=False)
29092918
elif isinstance(left_type, TupleType) and self.chk.in_checked_function():
29102919
# Special case for tuples. They return a more specific type when
29112920
# indexed by an integer literal.

0 commit comments

Comments
 (0)