Skip to content

Commit

Permalink
No longer support checking Python 2 (#13135)
Browse files Browse the repository at this point in the history
Linking #12237
  • Loading branch information
hauntsaninja authored Jul 26, 2022
1 parent c0851f0 commit 5718dff
Show file tree
Hide file tree
Showing 42 changed files with 42 additions and 3,716 deletions.
5 changes: 5 additions & 0 deletions mypy/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -955,6 +955,11 @@ def set_strict_flags() -> None:
# The python_version is either the default, which can be overridden via a config file,
# or stored in special_opts and is passed via the command line.
options.python_version = special_opts.python_version or options.python_version
if options.python_version < (3,):
parser.error(
"Mypy no longer supports checking Python 2 code. "
"Consider pinning to mypy<0.980 if you need to check Python 2 code."
)
try:
infer_python_executable(options, special_opts)
except PythonExecutableInferenceError as e:
Expand Down
5 changes: 2 additions & 3 deletions mypy/test/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -286,16 +286,15 @@ def num_skipped_suffix_lines(a1: List[str], a2: List[str]) -> int:


def testfile_pyversion(path: str) -> Tuple[int, int]:
if path.endswith('python2.test'):
return defaults.PYTHON2_VERSION
elif path.endswith('python310.test'):
if path.endswith('python310.test'):
return 3, 10
else:
return defaults.PYTHON3_VERSION


def testcase_pyversion(path: str, testcase_name: str) -> Tuple[int, int]:
if testcase_name.endswith('python2'):
raise ValueError(testcase_name)
return defaults.PYTHON2_VERSION
else:
return testfile_pyversion(path)
Expand Down
4 changes: 1 addition & 3 deletions mypy/test/testdeps.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from typing import List, Tuple, Dict, Optional, Set
from typing_extensions import DefaultDict

from mypy import build, defaults
from mypy import build
from mypy.modulefinder import BuildSource
from mypy.errors import CompileError
from mypy.nodes import MypyFile, Expression
Expand All @@ -29,8 +29,6 @@ def run_case(self, testcase: DataDrivenTestCase) -> None:
src = '\n'.join(testcase.input)
dump_all = '# __dump_all__' in src
options = parse_options(src, testcase, incremental_step=1)
if testcase.name.endswith('python2'):
options.python_version = defaults.PYTHON2_VERSION
options.use_builtins_fixtures = True
options.show_traceback = True
options.cache_dir = os.devnull
Expand Down
4 changes: 1 addition & 3 deletions mypy/test/testparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@ def test_parser(testcase: DataDrivenTestCase) -> None:
"""
options = Options()

if testcase.file.endswith('python2.test'):
options.python_version = defaults.PYTHON2_VERSION
elif testcase.file.endswith('python310.test'):
if testcase.file.endswith('python310.test'):
options.python_version = (3, 10)
else:
options.python_version = defaults.PYTHON3_VERSION
Expand Down
18 changes: 2 additions & 16 deletions mypy/test/testpythoneval.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,12 @@
import sys
from tempfile import TemporaryDirectory

import pytest

from typing import List

from mypy.defaults import PYTHON3_VERSION
from mypy.test.config import test_temp_dir
from mypy.test.data import DataDrivenTestCase, DataSuite
from mypy.test.helpers import assert_string_arrays_equal, split_lines
from mypy.util import try_find_python2_interpreter
from mypy import api

# Path to Python 3 interpreter
Expand All @@ -36,7 +33,6 @@

class PythonEvaluationSuite(DataSuite):
files = ['pythoneval.test',
'python2eval.test',
'pythoneval-asyncio.test']
cache_dir = TemporaryDirectory()

Expand All @@ -59,18 +55,8 @@ def test_python_evaluation(testcase: DataDrivenTestCase, cache_dir: str) -> None
'--no-silence-site-packages',
'--no-error-summary',
]
py2 = testcase.name.lower().endswith('python2')
if py2:
mypy_cmdline.append('--py2')
interpreter = try_find_python2_interpreter()
if interpreter is None:
# Skip, can't find a Python 2 interpreter.
pytest.skip()
# placate the type checker
return
else:
interpreter = python3_path
mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}")
interpreter = python3_path
mypy_cmdline.append(f"--python-version={'.'.join(map(str, PYTHON3_VERSION))}")

m = re.search('# flags: (.*)$', '\n'.join(testcase.input), re.MULTILINE)
if m:
Expand Down
3 changes: 1 addition & 2 deletions mypy/test/testtransform.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@ class TransformSuite(DataSuite):
'semanal-types.test',
'semanal-modules.test',
'semanal-statements.test',
'semanal-abstractclasses.test',
'semanal-python2.test']
'semanal-abstractclasses.test']
native_sep = True

def run_case(self, testcase: DataDrivenTestCase) -> None:
Expand Down
5 changes: 0 additions & 5 deletions test-data/unit/check-async-await.test
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,6 @@ async def g():
main:3: error: "yield from" in async function
main:5: error: "yield from" in async function

[case testNoAsyncDefInPY2_python2]

async def f(): # E: invalid syntax
pass

[case testYieldFromNoAwaitable]

from typing import Any, Generator
Expand Down
35 changes: 1 addition & 34 deletions test-data/unit/check-attr.test
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ A(1, 2, 3, 4) # E: Argument 2 to "A" has incompatible type "int"; expected "Lis
A(1, [2], '3', 4, 5) # E: Too many arguments for "A"
[builtins fixtures/list.pyi]

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

[case testAttrsNewStyleClassPy2]
# flags: --py2
import attr
@attr.s
class Good(object):
pass
@attr.s
class Bad: # E: attrs only works with new-style classes
pass
@attr.s
class SubclassOfBad(Bad):
pass
[builtins_py2 fixtures/bool.pyi]

[case testAttrsAutoAttribsPy2]
# flags: --py2
import attr
@attr.s(auto_attribs=True) # E: auto_attribs is not supported in Python 2
class A(object):
x = attr.ib()
[builtins_py2 fixtures/bool.pyi]

[case testAttrsFrozenSubclass]
import attr

Expand Down Expand Up @@ -1291,17 +1269,6 @@ class C:

[builtins fixtures/attr.pyi]

[case testAttrsKwOnlyPy2]
# flags: --py2
import attr
@attr.s(kw_only=True) # E: kw_only is not supported in Python 2
class A(object):
x = attr.ib()
@attr.s
class B(object):
x = attr.ib(kw_only=True) # E: kw_only is not supported in Python 2
[builtins_py2 fixtures/bool.pyi]

[case testAttrsDisallowUntypedWorksForward]
# flags: --disallow-untyped-defs
import attr
Expand Down
78 changes: 3 additions & 75 deletions test-data/unit/check-classes.test
Original file line number Diff line number Diff line change
Expand Up @@ -2207,7 +2207,7 @@ reveal_type(Num3() + Num1()) # N: Revealed type is "__main__.Num3"
reveal_type(Num2() + Num3()) # N: Revealed type is "__main__.Num2"
reveal_type(Num3() + Num2()) # N: Revealed type is "__main__.Num3"

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

[case testDivReverseOperatorPython2]
# flags: --python-version 2.7

# Note: if 'from __future__ import division' is called, we use
# __truediv__. Otherwise, we use __div__. So, we check both:
class A1:
def __div__(self, x):
# type: (B1) -> int
pass
class B1:
def __rdiv__(self, x): # E: Signatures of "__rdiv__" of "B1" and "__div__" of "A1" are unsafely overlapping
# type: (A1) -> str
pass

class A2:
def __truediv__(self, x):
# type: (B2) -> int
pass
class B2:
def __rtruediv__(self, x): # E: Signatures of "__rtruediv__" of "B2" and "__truediv__" of "A2" are unsafely overlapping
# type: (A2) -> str
pass

# That said, mypy currently doesn't handle the actual division operation very
# gracefully -- it doesn't correctly switch to using __truediv__ when
# 'from __future__ import division' is included, it doesn't display a very
# graceful error if __div__ is missing but __truediv__ is present...
# Also see https://github.com/python/mypy/issues/2048
reveal_type(A1() / B1()) # N: Revealed type is "builtins.int"
A2() / B2() # E: "A2" has no attribute "__div__"

[case testReverseOperatorMethodForwardIsAny]
from typing import Any
def deco(f: Any) -> Any: return f
Expand Down Expand Up @@ -2502,17 +2471,7 @@ reveal_type(B() + y) # N: Revealed type is "Union[__main__.Out2, __main__.Out4]
reveal_type(x + C()) # N: Revealed type is "Union[__main__.Out3, __main__.Out2]"
reveal_type(x + D()) # N: Revealed type is "Union[__main__.Out1, __main__.Out4]"

[case testOperatorDoubleUnionDivisionPython2]
# flags: --python-version 2.7
from typing import Union
def f(a):
# type: (Union[int, float]) -> None
a /= 1.1
b = a / 1.1
reveal_type(b) # N: Revealed type is "builtins.float"
[builtins_py2 fixtures/ops.pyi]

[case testOperatorDoubleUnionDivisionPython3]
[case testOperatorDoubleUnionDivision]
from typing import Union
def f(a):
# type: (Union[int, float]) -> None
Expand Down Expand Up @@ -5084,16 +5043,6 @@ reveal_type(type(A).x) # N: Revealed type is "builtins.int"
reveal_type(type(B).x) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]

[case testSixMetaclass_python2]
import six
class M(type):
x = 5
class A(six.with_metaclass(M)): pass
@six.add_metaclass(M)
class B: pass
reveal_type(type(A).x) # N: Revealed type is "builtins.int"
reveal_type(type(B).x) # N: Revealed type is "builtins.int"

[case testFromSixMetaclass]
from six import with_metaclass, add_metaclass
class M(type):
Expand Down Expand Up @@ -5217,13 +5166,6 @@ class CQA(Q1): pass # E: Inconsistent metaclass structure for "CQA"
class CQW(six.with_metaclass(M, Q1)): pass # E: Inconsistent metaclass structure for "CQW"
[builtins fixtures/tuple.pyi]

[case testSixMetaclassErrors_python2]
# flags: --python-version 2.7
import six
class M(type): pass
class C4(six.with_metaclass(M)): # E: Multiple metaclass definitions
__metaclass__ = M

[case testSixMetaclassAny]
import t # type: ignore
import six
Expand All @@ -5244,13 +5186,6 @@ class A(future.utils.with_metaclass(M)): pass
reveal_type(type(A).x) # N: Revealed type is "builtins.int"
[builtins fixtures/tuple.pyi]

[case testFutureMetaclass_python2]
import future.utils
class M(type):
x = 5
class A(future.utils.with_metaclass(M)): pass
reveal_type(type(A).x) # N: Revealed type is "builtins.int"

[case testFromFutureMetaclass]
from future.utils import with_metaclass
class M(type):
Expand Down Expand Up @@ -5336,13 +5271,6 @@ class Q1(metaclass=M1): pass
class CQW(future.utils.with_metaclass(M, Q1)): pass # E: Inconsistent metaclass structure for "CQW"
[builtins fixtures/tuple.pyi]

[case testFutureMetaclassErrors_python2]
# flags: --python-version 2.7
import future.utils
class M(type): pass
class C4(future.utils.with_metaclass(M)): # E: Multiple metaclass definitions
__metaclass__ = M

[case testFutureMetaclassAny]
import t # type: ignore
import future.utils
Expand Down Expand Up @@ -7323,7 +7251,7 @@ def foo(self: Any) -> str:
from typing import Any, Callable, TypeVar

class Parent:
foo = Callable[..., int]
foo = Callable[..., int]
class bar:
pass
import typing as baz
Expand Down
46 changes: 0 additions & 46 deletions test-data/unit/check-columns.test
Original file line number Diff line number Diff line change
Expand Up @@ -170,22 +170,6 @@ z: Iterable[bad] # E:13: Variable "__main__.bad" is not valid as a type \
h: bad[int] # E:4: Variable "__main__.bad" is not valid as a type \
# N:4: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases

[case testColumnInvalidType_python2]

from typing import Iterable

bad = 0

if int():
def g(x): # E:5: Variable "__main__.bad" is not valid as a type \
# N:5: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases
# type: (bad) -> None
y = 0 # type: bad # E:9: Variable "__main__.bad" is not valid as a type \
# N:9: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases

z = () # type: Iterable[bad] # E:5: Variable "__main__.bad" is not valid as a type \
# N:5: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases

[case testColumnFunctionMissingTypeAnnotation]
# flags: --disallow-untyped-defs
if int():
Expand Down Expand Up @@ -216,14 +200,6 @@ def f(x, y): pass
(f()) # E:2: Missing positional arguments "x", "y" in call to "f"
(f(y=1)) # E:2: Missing positional argument "x" in call to "f"

[case testColumnTooFewSuperArgs_python2]
class A:
def f(self):
pass
class B(A):
def f(self): # type: () -> None
super().f() # E:9: Too few arguments for "super"

[case testColumnListOrDictItemHasIncompatibleType]
from typing import List, Dict
x: List[int] = [
Expand Down Expand Up @@ -316,12 +292,6 @@ if int():
# type: (int) -> None
pass

[case testColumnTypeSignatureHasTooFewArguments_python2]
if int():
def f(x, y): # E:5: Type signature has too few arguments
# type: (int) -> None
pass

[case testColumnRevealedType]
if int():
reveal_type(1) # N:17: Revealed type is "Literal[1]?"
Expand Down Expand Up @@ -373,22 +343,6 @@ class B(A):
def x(self) -> int: pass
[builtins fixtures/property.pyi]

[case testColumnProperty_python2]
class A:
@property
def x(self): # type: () -> int
pass

@x.setter
def x(self, x): # type: (int) -> None
pass

class B(A):
@property # E:5: Read-only property cannot override read-write property
def x(self): # type: () -> int
pass
[builtins_py2 fixtures/property_py2.pyi]

[case testColumnOverloaded]
from typing import overload, Any
class A:
Expand Down
Loading

0 comments on commit 5718dff

Please sign in to comment.