Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 58af039

Browse files
authored
Merge branch 'master' into typeguard-ocd
2 parents 43adc46 + 695ea30 commit 58af039

27 files changed

Lines changed: 323 additions & 88 deletions

.github/workflows/test.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ jobs:
102102
name: ${{ matrix.name }}
103103
env:
104104
TOX_SKIP_MISSING_INTERPRETERS: False
105+
# Rich (pip)
106+
FORCE_COLOR: 1
107+
# Tox
108+
PY_COLORS: 1
109+
# Mypy (see https://github.com/python/mypy/issues/7771)
110+
TERM: xterm-color
111+
MYPY_FORCE_COLOR: 1
112+
MYPY_FORCE_TERMINAL_WIDTH: 200
113+
# Pytest
114+
PYTEST_ADDOPTS: --color=yes
105115
steps:
106116
- uses: actions/checkout@v3
107117
- uses: actions/setup-python@v4

README.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ more examples and information.
8484
In particular, see:
8585
- [type hints cheat sheet](https://mypy.readthedocs.io/en/stable/cheat_sheet_py3.html)
8686
- [getting started](https://mypy.readthedocs.io/en/stable/getting_started.html)
87+
- [list of error codes](https://mypy.readthedocs.io/en/stable/error_code_list.html)
8788

8889
Quick start
8990
-----------
@@ -109,9 +110,13 @@ programs, even if mypy reports type errors:
109110
python3 PROGRAM
110111

111112
You can also try mypy in an [online playground](https://mypy-play.net/) (developed by
112-
Yusuke Miyazaki).
113+
Yusuke Miyazaki). If you are working with large code bases, you can run mypy in
114+
[daemon mode], that will give much faster (often sub-second) incremental updates:
115+
116+
dmypy run -- PROGRAM
113117

114118
[statically typed parts]: https://mypy.readthedocs.io/en/latest/getting_started.html#function-signatures-and-dynamic-vs-static-typing
119+
[daemon-mode]: https://mypy.readthedocs.io/en/stable/mypy_daemon.html
115120

116121

117122
Integrations
@@ -124,7 +129,7 @@ Mypy can be integrated into popular IDEs:
124129
`let g:syntastic_python_checkers=['mypy']`
125130
* Using [ALE](https://github.com/dense-analysis/ale): should be enabled by default when `mypy` is installed,
126131
or can be explicitly enabled by adding `let b:ale_linters = ['mypy']` in `~/vim/ftplugin/python.vim`
127-
* Emacs: using [Flycheck](https://github.com/flycheck/) and [Flycheck-mypy](https://github.com/lbolla/emacs-flycheck-mypy)
132+
* Emacs: using [Flycheck](https://github.com/flycheck/)
128133
* Sublime Text: [SublimeLinter-contrib-mypy](https://github.com/fredcallaway/SublimeLinter-contrib-mypy)
129134
* Atom: [linter-mypy](https://atom.io/packages/linter-mypy)
130135
* PyCharm: [mypy plugin](https://github.com/dropbox/mypy-PyCharm-plugin) (PyCharm integrates
@@ -160,14 +165,7 @@ To get started with developing mypy, see [CONTRIBUTING.md](CONTRIBUTING.md).
160165
If you need help getting started, don't hesitate to ask on [gitter](https://gitter.im/python/typing).
161166

162167

163-
Development status
164-
------------------
165-
166-
Mypy is beta software, but it has already been used in production
167-
for several years at Dropbox and in many other organizations, and
168-
it has an extensive test suite.
169-
170-
mypyc and compiled version of mypy
168+
Mypyc and compiled version of mypy
171169
----------------------------------
172170

173171
[Mypyc](https://github.com/mypyc/mypyc) uses Python type hints to compile Python

docs/source/index.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@ understand, debug, and maintain.
3939

4040
.. note::
4141

42-
Mypy is used in production by many companies and projects, but mypy is
43-
officially beta software. There will be occasional changes
42+
Although mypy is production ready, there will be occasional changes
4443
that break backward compatibility. The mypy development team tries to
45-
minimize the impact of changes to user code.
44+
minimize the impact of changes to user code. In case of a major breaking
45+
change, mypy's major version will be bumped.
4646

4747
Contents
4848
--------

mypy/config_parser.py

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,15 @@ def check_follow_imports(choice: str) -> str:
137137
return choice
138138

139139

140+
def split_commas(value: str) -> list[str]:
141+
# Uses a bit smarter technique to allow last trailing comma
142+
# and to remove last `""` item from the split.
143+
items = value.split(",")
144+
if items and items[-1] == "":
145+
items.pop(-1)
146+
return items
147+
148+
140149
# For most options, the type of the default value set in options.py is
141150
# sufficient, and we don't have to do anything here. This table
142151
# exists to specify types for values initialized to None or container
@@ -151,13 +160,13 @@ def check_follow_imports(choice: str) -> str:
151160
"junit_xml": expand_path,
152161
"follow_imports": check_follow_imports,
153162
"no_site_packages": bool,
154-
"plugins": lambda s: [p.strip() for p in s.split(",")],
155-
"always_true": lambda s: [p.strip() for p in s.split(",")],
156-
"always_false": lambda s: [p.strip() for p in s.split(",")],
157-
"enable_incomplete_feature": lambda s: [p.strip() for p in s.split(",")],
158-
"disable_error_code": lambda s: validate_codes([p.strip() for p in s.split(",")]),
159-
"enable_error_code": lambda s: validate_codes([p.strip() for p in s.split(",")]),
160-
"package_root": lambda s: [p.strip() for p in s.split(",")],
163+
"plugins": lambda s: [p.strip() for p in split_commas(s)],
164+
"always_true": lambda s: [p.strip() for p in split_commas(s)],
165+
"always_false": lambda s: [p.strip() for p in split_commas(s)],
166+
"enable_incomplete_feature": lambda s: [p.strip() for p in split_commas(s)],
167+
"disable_error_code": lambda s: validate_codes([p.strip() for p in split_commas(s)]),
168+
"enable_error_code": lambda s: validate_codes([p.strip() for p in split_commas(s)]),
169+
"package_root": lambda s: [p.strip() for p in split_commas(s)],
161170
"cache_dir": expand_path,
162171
"python_executable": expand_path,
163172
"strict": bool,

mypy/constraints.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
Type,
3030
TypeAliasType,
3131
TypedDictType,
32-
TypeList,
3332
TypeOfAny,
3433
TypeQuery,
3534
TypeType,
@@ -135,7 +134,13 @@ def infer_constraints_for_callable(
135134

136135
unpacked_type = get_proper_type(unpack_type.type)
137136
if isinstance(unpacked_type, TypeVarTupleType):
138-
constraints.append(Constraint(unpacked_type, SUPERTYPE_OF, TypeList(actual_types)))
137+
constraints.append(
138+
Constraint(
139+
unpacked_type,
140+
SUPERTYPE_OF,
141+
TupleType(actual_types, unpacked_type.tuple_fallback),
142+
)
143+
)
139144
elif isinstance(unpacked_type, TupleType):
140145
# Prefixes get converted to positional args, so technically the only case we
141146
# should have here is like Tuple[Unpack[Ts], Y1, Y2, Y3]. If this turns out
@@ -147,12 +152,13 @@ def infer_constraints_for_callable(
147152
suffix_len = len(unpacked_type.items) - 1
148153
constraints.append(
149154
Constraint(
150-
inner_unpacked_type, SUPERTYPE_OF, TypeList(actual_types[:-suffix_len])
155+
inner_unpacked_type,
156+
SUPERTYPE_OF,
157+
TupleType(actual_types[:-suffix_len], inner_unpacked_type.tuple_fallback),
151158
)
152159
)
153160
else:
154161
assert False, "mypy bug: unhandled constraint inference case"
155-
156162
else:
157163
for actual in actuals:
158164
actual_arg_type = arg_types[actual]
@@ -640,7 +646,9 @@ def visit_instance(self, template: Instance) -> list[Constraint]:
640646
if isinstance(instance_unpack, TypeVarTupleType):
641647
res.append(
642648
Constraint(
643-
instance_unpack, SUBTYPE_OF, TypeList(list(mapped_middle))
649+
instance_unpack,
650+
SUBTYPE_OF,
651+
TupleType(list(mapped_middle), instance_unpack.tuple_fallback),
644652
)
645653
)
646654
elif (
@@ -742,7 +750,9 @@ def visit_instance(self, template: Instance) -> list[Constraint]:
742750
if isinstance(template_unpack, TypeVarTupleType):
743751
res.append(
744752
Constraint(
745-
template_unpack, SUPERTYPE_OF, TypeList(list(mapped_middle))
753+
template_unpack,
754+
SUPERTYPE_OF,
755+
TupleType(list(mapped_middle), template_unpack.tuple_fallback),
746756
)
747757
)
748758
elif (

mypy/expandtype.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
Type,
2323
TypeAliasType,
2424
TypedDictType,
25-
TypeList,
2625
TypeType,
2726
TypeVarId,
2827
TypeVarLikeType,
@@ -95,7 +94,9 @@ def expand_type_by_instance(typ: Type, instance: Instance) -> Type:
9594
instance.type.type_var_tuple_prefix,
9695
instance.type.type_var_tuple_suffix,
9796
)
98-
variables = {tvars_middle[0].id: TypeList(list(args_middle))}
97+
tvar = tvars_middle[0]
98+
assert isinstance(tvar, TypeVarTupleType)
99+
variables = {tvar.id: TupleType(list(args_middle), tvar.tuple_fallback)}
99100
instance_args = args_prefix + args_suffix
100101
tvars = tvars_prefix + tvars_suffix
101102
else:
@@ -447,8 +448,6 @@ def expand_unpack_with_variables(
447448
repl = get_proper_type(variables.get(t.type.id, t))
448449
if isinstance(repl, TupleType):
449450
return repl.items
450-
if isinstance(repl, TypeList):
451-
return repl.items
452451
elif isinstance(repl, Instance) and repl.type.fullname == "builtins.tuple":
453452
return repl
454453
elif isinstance(repl, AnyType):

mypy/plugins/attrs.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from __future__ import annotations
44

55
from typing import Iterable, List, cast
6-
from typing_extensions import Final
6+
from typing_extensions import Final, Literal
77

88
import mypy.plugin # To avoid circular imports.
99
from mypy.exprtotype import TypeTranslationError, expr_to_unanalyzed_type
@@ -756,20 +756,28 @@ def _add_init(
756756
ctx: mypy.plugin.ClassDefContext,
757757
attributes: list[Attribute],
758758
adder: MethodAdder,
759-
method_name: str,
759+
method_name: Literal["__init__", "__attrs_init__"],
760760
) -> None:
761761
"""Generate an __init__ method for the attributes and add it to the class."""
762-
# Convert attributes to arguments with kw_only arguments at the end of
762+
# Convert attributes to arguments with kw_only arguments at the end of
763763
# the argument list
764764
pos_args = []
765765
kw_only_args = []
766+
sym_table = ctx.cls.info.names
766767
for attribute in attributes:
767768
if not attribute.init:
768769
continue
769770
if attribute.kw_only:
770771
kw_only_args.append(attribute.argument(ctx))
771772
else:
772773
pos_args.append(attribute.argument(ctx))
774+
775+
# If the attribute is Final, present in `__init__` and has
776+
# no default, make sure it doesn't error later.
777+
if not attribute.has_default and attribute.name in sym_table:
778+
sym_node = sym_table[attribute.name].node
779+
if isinstance(sym_node, Var) and sym_node.is_final:
780+
sym_node.final_set_in_init = True
773781
args = pos_args + kw_only_args
774782
if all(
775783
# We use getattr rather than instance checks because the variable.type

mypy/test/testconstraints.py

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from mypy.constraints import SUBTYPE_OF, SUPERTYPE_OF, Constraint, infer_constraints
66
from mypy.test.helpers import Suite
77
from mypy.test.typefixture import TypeFixture
8-
from mypy.types import Instance, TupleType, TypeList, UnpackType
8+
from mypy.types import Instance, TupleType, UnpackType
99

1010

1111
class ConstraintsSuite(Suite):
@@ -27,13 +27,19 @@ def test_basic_type_var_tuple_subtype(self) -> None:
2727
fx = self.fx
2828
assert infer_constraints(
2929
Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUBTYPE_OF
30-
) == [Constraint(type_var=fx.ts, op=SUBTYPE_OF, target=TypeList([fx.a, fx.b]))]
30+
) == [
31+
Constraint(type_var=fx.ts, op=SUBTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple))
32+
]
3133

3234
def test_basic_type_var_tuple(self) -> None:
3335
fx = self.fx
3436
assert infer_constraints(
3537
Instance(fx.gvi, [UnpackType(fx.ts)]), Instance(fx.gvi, [fx.a, fx.b]), SUPERTYPE_OF
36-
) == [Constraint(type_var=fx.ts, op=SUPERTYPE_OF, target=TypeList([fx.a, fx.b]))]
38+
) == [
39+
Constraint(
40+
type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.a, fx.b], fx.std_tuple)
41+
)
42+
]
3743

3844
def test_type_var_tuple_with_prefix_and_suffix(self) -> None:
3945
fx = self.fx
@@ -45,7 +51,9 @@ def test_type_var_tuple_with_prefix_and_suffix(self) -> None:
4551
)
4652
) == {
4753
Constraint(type_var=fx.t, op=SUPERTYPE_OF, target=fx.a),
48-
Constraint(type_var=fx.ts, op=SUPERTYPE_OF, target=TypeList([fx.b, fx.c])),
54+
Constraint(
55+
type_var=fx.ts, op=SUPERTYPE_OF, target=TupleType([fx.b, fx.c], fx.std_tuple)
56+
),
4957
Constraint(type_var=fx.s, op=SUPERTYPE_OF, target=fx.d),
5058
}
5159

mypyc/analysis/attrdefined.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def foo(self) -> int:
9191
SetMem,
9292
Unreachable,
9393
)
94-
from mypyc.ir.rtypes import RInstance, is_fixed_width_rtype
94+
from mypyc.ir.rtypes import RInstance
9595

9696
# If True, print out all always-defined attributes of native classes (to aid
9797
# debugging and testing)
@@ -424,5 +424,5 @@ def detect_undefined_bitmap(cl: ClassIR, seen: Set[ClassIR]) -> None:
424424
if len(cl.base_mro) > 1:
425425
cl.bitmap_attrs.extend(cl.base_mro[1].bitmap_attrs)
426426
for n, t in cl.attributes.items():
427-
if is_fixed_width_rtype(t) and not cl.is_always_defined(n):
427+
if t.error_overlap and not cl.is_always_defined(n):
428428
cl.bitmap_attrs.append(n)

0 commit comments

Comments
 (0)