Skip to content

Commit 5718dff

Browse files
authored
No longer support checking Python 2 (#13135)
Linking #12237
1 parent c0851f0 commit 5718dff

Some content is hidden

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

42 files changed

+42
-3716
lines changed

mypy/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,11 @@ def set_strict_flags() -> None:
955955
# The python_version is either the default, which can be overridden via a config file,
956956
# or stored in special_opts and is passed via the command line.
957957
options.python_version = special_opts.python_version or options.python_version
958+
if options.python_version < (3,):
959+
parser.error(
960+
"Mypy no longer supports checking Python 2 code. "
961+
"Consider pinning to mypy<0.980 if you need to check Python 2 code."
962+
)
958963
try:
959964
infer_python_executable(options, special_opts)
960965
except PythonExecutableInferenceError as e:

mypy/test/helpers.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -286,16 +286,15 @@ def num_skipped_suffix_lines(a1: List[str], a2: List[str]) -> int:
286286

287287

288288
def testfile_pyversion(path: str) -> Tuple[int, int]:
289-
if path.endswith('python2.test'):
290-
return defaults.PYTHON2_VERSION
291-
elif path.endswith('python310.test'):
289+
if path.endswith('python310.test'):
292290
return 3, 10
293291
else:
294292
return defaults.PYTHON3_VERSION
295293

296294

297295
def testcase_pyversion(path: str, testcase_name: str) -> Tuple[int, int]:
298296
if testcase_name.endswith('python2'):
297+
raise ValueError(testcase_name)
299298
return defaults.PYTHON2_VERSION
300299
else:
301300
return testfile_pyversion(path)

mypy/test/testdeps.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from typing import List, Tuple, Dict, Optional, Set
77
from typing_extensions import DefaultDict
88

9-
from mypy import build, defaults
9+
from mypy import build
1010
from mypy.modulefinder import BuildSource
1111
from mypy.errors import CompileError
1212
from mypy.nodes import MypyFile, Expression
@@ -29,8 +29,6 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
2929
src = '\n'.join(testcase.input)
3030
dump_all = '# __dump_all__' in src
3131
options = parse_options(src, testcase, incremental_step=1)
32-
if testcase.name.endswith('python2'):
33-
options.python_version = defaults.PYTHON2_VERSION
3432
options.use_builtins_fixtures = True
3533
options.show_traceback = True
3634
options.cache_dir = os.devnull

mypy/test/testparse.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,7 @@ def test_parser(testcase: DataDrivenTestCase) -> None:
3131
"""
3232
options = Options()
3333

34-
if testcase.file.endswith('python2.test'):
35-
options.python_version = defaults.PYTHON2_VERSION
36-
elif testcase.file.endswith('python310.test'):
34+
if testcase.file.endswith('python310.test'):
3735
options.python_version = (3, 10)
3836
else:
3937
options.python_version = defaults.PYTHON3_VERSION

mypy/test/testpythoneval.py

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,12 @@
1818
import sys
1919
from tempfile import TemporaryDirectory
2020

21-
import pytest
22-
2321
from typing import List
2422

2523
from mypy.defaults import PYTHON3_VERSION
2624
from mypy.test.config import test_temp_dir
2725
from mypy.test.data import DataDrivenTestCase, DataSuite
2826
from mypy.test.helpers import assert_string_arrays_equal, split_lines
29-
from mypy.util import try_find_python2_interpreter
3027
from mypy import api
3128

3229
# Path to Python 3 interpreter
@@ -36,7 +33,6 @@
3633

3734
class PythonEvaluationSuite(DataSuite):
3835
files = ['pythoneval.test',
39-
'python2eval.test',
4036
'pythoneval-asyncio.test']
4137
cache_dir = TemporaryDirectory()
4238

@@ -59,18 +55,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None
5955
'--no-silence-site-packages',
6056
'--no-error-summary',
6157
]
62-
py2 = testcase.name.lower().endswith('python2')
63-
if py2:
64-
mypy_cmdline.append('--py2')
65-
interpreter = try_find_python2_interpreter()
66-
if interpreter is None:
67-
# Skip, can't find a Python 2 interpreter.
68-
pytest.skip()
69-
# placate the type checker
70-
return
71-
else:
72-
interpreter = python3_path
73-
mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}")
58+
interpreter = python3_path
59+
mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}")
7460

7561
m = re.search('# flags: (.*)$', '\n'.join(testcase.input), re.MULTILINE)
7662
if m:

mypy/test/testtransform.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ class TransformSuite(DataSuite):
2222
'semanal-types.test',
2323
'semanal-modules.test',
2424
'semanal-statements.test',
25-
'semanal-abstractclasses.test',
26-
'semanal-python2.test']
25+
'semanal-abstractclasses.test']
2726
native_sep = True
2827

2928
def run_case(self, testcase: DataDrivenTestCase) -> None:

test-data/unit/check-async-await.test

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,6 @@ async def g():
362362
main:3: error: "yield from" in async function
363363
main:5: error: "yield from" in async function
364364

365-
[case testNoAsyncDefInPY2_python2]
366-
367-
async def f(): # E: invalid syntax
368-
pass
369-
370365
[case testYieldFromNoAwaitable]
371366

372367
from typing import Any, Generator

test-data/unit/check-attr.test

Lines changed: 1 addition & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "Lis
3535
A(1, [2], '3', 4, 5) # E: Too many arguments for "A"
3636
[builtins fixtures/list.pyi]
3737

38-
[case testAttrsPython2Annotations]
38+
[case testAttrsTypeComments]
3939
import attr
4040
from typing import List, ClassVar
4141
@attr.s
@@ -1032,28 +1032,6 @@ class C:
10321032
reveal_type(C) # N: Revealed type is "def (a: builtins.int, b: builtins.int) -> __main__.C"
10331033
[builtins fixtures/bool.pyi]
10341034

1035-
[case testAttrsNewStyleClassPy2]
1036-
# flags: --py2
1037-
import attr
1038-
@attr.s
1039-
class Good(object):
1040-
pass
1041-
@attr.s
1042-
class Bad: # E: attrs only works with new-style classes
1043-
pass
1044-
@attr.s
1045-
class SubclassOfBad(Bad):
1046-
pass
1047-
[builtins_py2 fixtures/bool.pyi]
1048-
1049-
[case testAttrsAutoAttribsPy2]
1050-
# flags: --py2
1051-
import attr
1052-
@attr.s(auto_attribs=True) # E: auto_attribs is not supported in Python 2
1053-
class A(object):
1054-
x = attr.ib()
1055-
[builtins_py2 fixtures/bool.pyi]
1056-
10571035
[case testAttrsFrozenSubclass]
10581036
import attr
10591037

@@ -1291,17 +1269,6 @@ class C:
12911269

12921270
[builtins fixtures/attr.pyi]
12931271

1294-
[case testAttrsKwOnlyPy2]
1295-
# flags: --py2
1296-
import attr
1297-
@attr.s(kw_only=True) # E: kw_only is not supported in Python 2
1298-
class A(object):
1299-
x = attr.ib()
1300-
@attr.s
1301-
class B(object):
1302-
x = attr.ib(kw_only=True) # E: kw_only is not supported in Python 2
1303-
[builtins_py2 fixtures/bool.pyi]
1304-
13051272
[case testAttrsDisallowUntypedWorksForward]
13061273
# flags: --disallow-untyped-defs
13071274
import attr

test-data/unit/check-classes.test

Lines changed: 3 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2207,7 +2207,7 @@ reveal_type(Num3() + Num1()) # N: Revealed type is "__main__.Num3"
22072207
reveal_type(Num2() + Num3()) # N: Revealed type is "__main__.Num2"
22082208
reveal_type(Num3() + Num2()) # N: Revealed type is "__main__.Num3"
22092209

2210-
[case testDivReverseOperatorPython3]
2210+
[case testDivReverseOperator]
22112211
# No error: __div__ has no special meaning in Python 3
22122212
class A1:
22132213
def __div__(self, x: B1) -> int: ...
@@ -2222,37 +2222,6 @@ class B2:
22222222
A1() / B1() # E: Unsupported left operand type for / ("A1")
22232223
reveal_type(A2() / B2()) # N: Revealed type is "builtins.int"
22242224

2225-
[case testDivReverseOperatorPython2]
2226-
# flags: --python-version 2.7
2227-
2228-
# Note: if 'from __future__ import division' is called, we use
2229-
# __truediv__. Otherwise, we use __div__. So, we check both:
2230-
class A1:
2231-
def __div__(self, x):
2232-
# type: (B1) -> int
2233-
pass
2234-
class B1:
2235-
def __rdiv__(self, x): # E: Signatures of "__rdiv__" of "B1" and "__div__" of "A1" are unsafely overlapping
2236-
# type: (A1) -> str
2237-
pass
2238-
2239-
class A2:
2240-
def __truediv__(self, x):
2241-
# type: (B2) -> int
2242-
pass
2243-
class B2:
2244-
def __rtruediv__(self, x): # E: Signatures of "__rtruediv__" of "B2" and "__truediv__" of "A2" are unsafely overlapping
2245-
# type: (A2) -> str
2246-
pass
2247-
2248-
# That said, mypy currently doesn't handle the actual division operation very
2249-
# gracefully -- it doesn't correctly switch to using __truediv__ when
2250-
# 'from __future__ import division' is included, it doesn't display a very
2251-
# graceful error if __div__ is missing but __truediv__ is present...
2252-
# Also see https://github.com/python/mypy/issues/2048
2253-
reveal_type(A1() / B1()) # N: Revealed type is "builtins.int"
2254-
A2() / B2() # E: "A2" has no attribute "__div__"
2255-
22562225
[case testReverseOperatorMethodForwardIsAny]
22572226
from typing import Any
22582227
def deco(f: Any) -> Any: return f
@@ -2502,17 +2471,7 @@ reveal_type(B() + y) # N: Revealed type is "Union[__main__.Out2, __main__.Out4]
25022471
reveal_type(x + C()) # N: Revealed type is "Union[__main__.Out3, __main__.Out2]"
25032472
reveal_type(x + D()) # N: Revealed type is "Union[__main__.Out1, __main__.Out4]"
25042473

2505-
[case testOperatorDoubleUnionDivisionPython2]
2506-
# flags: --python-version 2.7
2507-
from typing import Union
2508-
def f(a):
2509-
# type: (Union[int, float]) -> None
2510-
a /= 1.1
2511-
b = a / 1.1
2512-
reveal_type(b) # N: Revealed type is "builtins.float"
2513-
[builtins_py2 fixtures/ops.pyi]
2514-
2515-
[case testOperatorDoubleUnionDivisionPython3]
2474+
[case testOperatorDoubleUnionDivision]
25162475
from typing import Union
25172476
def f(a):
25182477
# type: (Union[int, float]) -> None
@@ -5084,16 +5043,6 @@ reveal_type(type(A).x) # N: Revealed type is "builtins.int"
50845043
reveal_type(type(B).x) # N: Revealed type is "builtins.int"
50855044
[builtins fixtures/tuple.pyi]
50865045

5087-
[case testSixMetaclass_python2]
5088-
import six
5089-
class M(type):
5090-
x = 5
5091-
class A(six.with_metaclass(M)): pass
5092-
@six.add_metaclass(M)
5093-
class B: pass
5094-
reveal_type(type(A).x) # N: Revealed type is "builtins.int"
5095-
reveal_type(type(B).x) # N: Revealed type is "builtins.int"
5096-
50975046
[case testFromSixMetaclass]
50985047
from six import with_metaclass, add_metaclass
50995048
class M(type):
@@ -5217,13 +5166,6 @@ class CQA(Q1): pass # E: Inconsistent metaclass structure for "CQA"
52175166
class CQW(six.with_metaclass(M, Q1)): pass # E: Inconsistent metaclass structure for "CQW"
52185167
[builtins fixtures/tuple.pyi]
52195168

5220-
[case testSixMetaclassErrors_python2]
5221-
# flags: --python-version 2.7
5222-
import six
5223-
class M(type): pass
5224-
class C4(six.with_metaclass(M)): # E: Multiple metaclass definitions
5225-
__metaclass__ = M
5226-
52275169
[case testSixMetaclassAny]
52285170
import t # type: ignore
52295171
import six
@@ -5244,13 +5186,6 @@ class A(future.utils.with_metaclass(M)): pass
52445186
reveal_type(type(A).x) # N: Revealed type is "builtins.int"
52455187
[builtins fixtures/tuple.pyi]
52465188

5247-
[case testFutureMetaclass_python2]
5248-
import future.utils
5249-
class M(type):
5250-
x = 5
5251-
class A(future.utils.with_metaclass(M)): pass
5252-
reveal_type(type(A).x) # N: Revealed type is "builtins.int"
5253-
52545189
[case testFromFutureMetaclass]
52555190
from future.utils import with_metaclass
52565191
class M(type):
@@ -5336,13 +5271,6 @@ class Q1(metaclass=M1): pass
53365271
class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Inconsistent metaclass structure for "CQW"
53375272
[builtins fixtures/tuple.pyi]
53385273

5339-
[case testFutureMetaclassErrors_python2]
5340-
# flags: --python-version 2.7
5341-
import future.utils
5342-
class M(type): pass
5343-
class C4(future.utils.with_metaclass(M)): # E: Multiple metaclass definitions
5344-
__metaclass__ = M
5345-
53465274
[case testFutureMetaclassAny]
53475275
import t # type: ignore
53485276
import future.utils
@@ -7323,7 +7251,7 @@ def foo(self: Any) -> str:
73237251
from typing import Any, Callable, TypeVar
73247252

73257253
class Parent:
7326-
foo = Callable[..., int]
7254+
foo = Callable[..., int]
73277255
class bar:
73287256
pass
73297257
import typing as baz

test-data/unit/check-columns.test

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -170,22 +170,6 @@ z: Iterable[bad] # E:13: Variable "__main__.bad" is not valid as a type \
170170
h: bad[int] # E:4: Variable "__main__.bad" is not valid as a type \
171171
# N:4: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
172172

173-
[case testColumnInvalidType_python2]
174-
175-
from typing import Iterable
176-
177-
bad = 0
178-
179-
if int():
180-
def g(x): # E:5: Variable "__main__.bad" is not valid as a type \
181-
# N:5: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
182-
# type: (bad) -> None
183-
y = 0 # type: bad # E:9: Variable "__main__.bad" is not valid as a type \
184-
# N:9: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
185-
186-
z = () # type: Iterable[bad] # E:5: Variable "__main__.bad" is not valid as a type \
187-
# N:5: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
188-
189173
[case testColumnFunctionMissingTypeAnnotation]
190174
# flags: --disallow-untyped-defs
191175
if int():
@@ -216,14 +200,6 @@ def f(x, y): pass
216200
(f()) # E:2: Missing positional arguments "x", "y" in call to "f"
217201
(f(y=1)) # E:2: Missing positional argument "x" in call to "f"
218202

219-
[case testColumnTooFewSuperArgs_python2]
220-
class A:
221-
def f(self):
222-
pass
223-
class B(A):
224-
def f(self): # type: () -> None
225-
super().f() # E:9: Too few arguments for "super"
226-
227203
[case testColumnListOrDictItemHasIncompatibleType]
228204
from typing import List, Dict
229205
x: List[int] = [
@@ -316,12 +292,6 @@ if int():
316292
# type: (int) -> None
317293
pass
318294

319-
[case testColumnTypeSignatureHasTooFewArguments_python2]
320-
if int():
321-
def f(x, y): # E:5: Type signature has too few arguments
322-
# type: (int) -> None
323-
pass
324-
325295
[case testColumnRevealedType]
326296
if int():
327297
reveal_type(1) # N:17: Revealed type is "Literal[1]?"
@@ -373,22 +343,6 @@ class B(A):
373343
def x(self) -> int: pass
374344
[builtins fixtures/property.pyi]
375345

376-
[case testColumnProperty_python2]
377-
class A:
378-
@property
379-
def x(self): # type: () -> int
380-
pass
381-
382-
@x.setter
383-
def x(self, x): # type: (int) -> None
384-
pass
385-
386-
class B(A):
387-
@property # E:5: Read-only property cannot override read-write property
388-
def x(self): # type: () -> int
389-
pass
390-
[builtins_py2 fixtures/property_py2.pyi]
391-
392346
[case testColumnOverloaded]
393347
from typing import overload, Any
394348
class A:

0 commit comments

Comments
 (0)