summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Sottile <asottile@umich.edu>2022-11-27 12:38:53 -0800
committerGitHub <noreply@github.com>2022-11-27 15:38:53 -0500
commit98d4fa33ccacf74c62c5a17cc35ce572fd35b223 (patch)
treef9b6b5fca55e2834bd86505aca117db2be624934
parent37f203ed6ec9c54ea4ded0b8480846ac750a1747 (diff)
downloadpyflakes-98d4fa33ccacf74c62c5a17cc35ce572fd35b223.tar.gz
pyflakes: python3.8+ (#752)
-rw-r--r--.github/workflows/test.yml6
-rw-r--r--pyflakes/checker.py59
-rw-r--r--pyflakes/messages.py7
-rw-r--r--pyflakes/reporter.py2
-rw-r--r--pyflakes/test/test_api.py29
-rw-r--r--pyflakes/test/test_doctests.py13
-rw-r--r--pyflakes/test/test_other.py46
-rw-r--r--pyflakes/test/test_type_annotations.py3
-rwxr-xr-xsetup.py7
-rw-r--r--tox.ini3
10 files changed, 31 insertions, 144 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 74c2759..d023ba1 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -12,12 +12,12 @@ jobs:
strategy:
fail-fast: false
matrix:
- python-version: ["3.6", "3.7", "3.8", "3.9", "3.10", "3.11.0-beta - 3.11.999", "pypy-3.9"]
+ python-version: ["3.8", "3.9", "3.10", "3.11", "pypy-3.9"]
os: [ubuntu-latest]
# Include minimum py3 + maximum py3 + pypy3 on Windows
include:
- - { os: "windows-latest" , python-version: "3.6" }
- - { os: "windows-latest" , python-version: "3.10" }
+ - { os: "windows-latest" , python-version: "3.8" }
+ - { os: "windows-latest" , python-version: "3.11" }
- { os: "windows-latest" , python-version: "pypy-3.9" }
steps:
diff --git a/pyflakes/checker.py b/pyflakes/checker.py
index a79de56..13d2452 100644
--- a/pyflakes/checker.py
+++ b/pyflakes/checker.py
@@ -18,7 +18,6 @@ import warnings
from pyflakes import messages
-PY38_PLUS = sys.version_info >= (3, 8)
PYPY = hasattr(sys, 'pypy_version_info')
builtin_vars = dir(builtins)
@@ -35,15 +34,12 @@ def getAlternatives(n):
FOR_TYPES = (ast.For, ast.AsyncFor)
-if PY38_PLUS:
- def _is_singleton(node): # type: (ast.AST) -> bool
- return (
- isinstance(node, ast.Constant) and
- isinstance(node.value, (bool, type(Ellipsis), type(None)))
- )
-else:
- def _is_singleton(node): # type: (ast.AST) -> bool
- return isinstance(node, (ast.NameConstant, ast.Ellipsis))
+
+def _is_singleton(node): # type: (ast.AST) -> bool
+ return (
+ isinstance(node, ast.Constant) and
+ isinstance(node.value, (bool, type(Ellipsis), type(None)))
+ )
def _is_tuple_constant(node): # type: (ast.AST) -> bool
@@ -53,16 +49,8 @@ def _is_tuple_constant(node): # type: (ast.AST) -> bool
)
-if PY38_PLUS:
- def _is_constant(node):
- return isinstance(node, ast.Constant) or _is_tuple_constant(node)
-else:
- def _is_constant(node):
- return (
- isinstance(node, (ast.Str, ast.Num, ast.Bytes)) or
- _is_singleton(node) or
- _is_tuple_constant(node)
- )
+def _is_constant(node):
+ return isinstance(node, ast.Constant) or _is_tuple_constant(node)
def _is_const_non_singleton(node): # type: (ast.AST) -> bool
@@ -1176,7 +1164,7 @@ class Checker:
)
):
binding = ExportBinding(name, node._pyflakes_parent, self.scope)
- elif PY38_PLUS and isinstance(parent_stmt, ast.NamedExpr):
+ elif isinstance(parent_stmt, ast.NamedExpr):
binding = NamedExprAssignment(name, node)
else:
binding = Assignment(name, node)
@@ -1252,13 +1240,7 @@ class Checker:
if not isinstance(node, ast.Str):
return (None, None)
- if PYPY or PY38_PLUS:
- doctest_lineno = node.lineno - 1
- else:
- # Computed incorrectly if the docstring has backslash
- doctest_lineno = node.lineno - node.s.count('\n') - 1
-
- return (node.s, doctest_lineno)
+ return (node.s, node.lineno - 1)
def handleNode(self, node, parent):
if node is None:
@@ -1729,12 +1711,9 @@ class Checker:
else:
self.deferFunction(fn)
- if PY38_PLUS:
- def CONSTANT(self, node):
- if isinstance(node.value, str):
- return self.STR(node)
- else:
- NUM = BYTES = ELLIPSIS = CONSTANT = ignore
+ def CONSTANT(self, node):
+ if isinstance(node.value, str):
+ return self.STR(node)
# "slice" type nodes
SLICE = EXTSLICE = INDEX = handleChildren
@@ -1900,11 +1879,6 @@ class Checker:
return
if isinstance(n, (ast.FunctionDef, ast.ClassDef)):
break
- # Handle Try/TryFinally difference in Python < and >= 3.3
- if hasattr(n, 'finalbody') and isinstance(node, ast.Continue):
- if n_child in n.finalbody and not PY38_PLUS:
- self.report(messages.ContinueInFinally, node)
- return
if isinstance(node, ast.Continue):
self.report(messages.ContinueOutsideLoop, node)
else: # ast.Break
@@ -1952,10 +1926,9 @@ class Checker:
args = []
annotations = []
- if PY38_PLUS:
- for arg in node.args.posonlyargs:
- args.append(arg.arg)
- annotations.append(arg.annotation)
+ for arg in node.args.posonlyargs:
+ args.append(arg.arg)
+ annotations.append(arg.annotation)
for arg in node.args.args + node.args.kwonlyargs:
args.append(arg.arg)
annotations.append(arg.annotation)
diff --git a/pyflakes/messages.py b/pyflakes/messages.py
index f45fd46..86cf6c7 100644
--- a/pyflakes/messages.py
+++ b/pyflakes/messages.py
@@ -198,13 +198,6 @@ class BreakOutsideLoop(Message):
message = '\'break\' outside loop'
-class ContinueInFinally(Message):
- """
- Indicates a continue statement in a finally block in a while or for loop.
- """
- message = '\'continue\' not supported inside \'finally\' clause'
-
-
class DefaultExceptNotLast(Message):
"""
Indicates an except: block as not the last exception handler.
diff --git a/pyflakes/reporter.py b/pyflakes/reporter.py
index 1babbb4..af834d1 100644
--- a/pyflakes/reporter.py
+++ b/pyflakes/reporter.py
@@ -60,8 +60,6 @@ class Reporter:
lineno = max(lineno, 1)
if offset is not None:
- if sys.version_info < (3, 8) and text is not None:
- offset = offset - (len(text) - len(line)) + 1
# some versions of python emit an offset of -1 for certain encoding errors
offset = max(offset, 1)
self._stderr.write('%s:%d:%d: %s\n' %
diff --git a/pyflakes/test/test_api.py b/pyflakes/test/test_api.py
index 535e701..5c1879c 100644
--- a/pyflakes/test/test_api.py
+++ b/pyflakes/test/test_api.py
@@ -233,9 +233,7 @@ class TestReporter(TestCase):
"""
err = io.StringIO()
reporter = Reporter(None, err)
- reporter.syntaxError('foo.py', 'a problem', 3,
- 8 if sys.version_info >= (3, 8) else 7,
- 'bad line of source')
+ reporter.syntaxError('foo.py', 'a problem', 3, 8, 'bad line of source')
self.assertEqual(
("foo.py:3:8: a problem\n"
"bad line of source\n"
@@ -281,11 +279,10 @@ class TestReporter(TestCase):
reporter = Reporter(None, err)
reporter.syntaxError('foo.py', 'a problem', 3, len(lines[0]) + 7,
'\n'.join(lines))
- column = 25 if sys.version_info >= (3, 8) else 7
self.assertEqual(
- ("foo.py:3:%d: a problem\n" % column +
+ ("foo.py:3:25: a problem\n" +
lines[-1] + "\n" +
- " " * (column - 1) + "^\n"),
+ " " * 24 + "^\n"),
err.getvalue())
def test_unexpectedError(self):
@@ -417,10 +414,8 @@ def baz():
if PYPY or sys.version_info >= (3, 10):
column = 12
- elif sys.version_info >= (3, 8):
- column = 8
else:
- column = 11
+ column = 8
self.assertHasErrors(
sourcePath,
["""\
@@ -487,10 +482,8 @@ def foo(bar=baz, bax):
column = 18
elif sys.version_info >= (3, 9):
column = 21
- elif sys.version_info >= (3, 8):
- column = 9
else:
- column = 8
+ column = 9
last_line = ' ' * (column - 1) + '^\n'
columnstr = '%d:' % column
self.assertHasErrors(
@@ -512,7 +505,7 @@ foo(bar=baz, bax)
with self.makeTempFile(source) as sourcePath:
if sys.version_info >= (3, 9):
column = 17
- elif not PYPY and sys.version_info >= (3, 8):
+ elif not PYPY:
column = 14
else:
column = 13
@@ -679,18 +672,10 @@ x = "%s"
"max(1 for i in range(10), key=lambda x: x+1)",
" ^",
]
- elif sys.version_info >= (3, 8):
+ else:
expected_error = [
"<stdin>:1:5: Generator expression must be parenthesized",
]
- elif sys.version_info >= (3, 7):
- expected_error = [
- "<stdin>:1:4: Generator expression must be parenthesized",
- ]
- elif sys.version_info >= (3, 6):
- expected_error = [
- "<stdin>:1:4: Generator expression must be parenthesized if not sole argument", # noqa: E501
- ]
self.assertEqual(errlines, expected_error)
diff --git a/pyflakes/test/test_doctests.py b/pyflakes/test/test_doctests.py
index 6c8e69e..63cea4d 100644
--- a/pyflakes/test/test_doctests.py
+++ b/pyflakes/test/test_doctests.py
@@ -1,4 +1,3 @@
-import sys
import textwrap
from pyflakes import messages as m
@@ -323,7 +322,7 @@ class Test(TestCase):
m.DoctestSyntaxError).messages
exc = exceptions[0]
self.assertEqual(exc.lineno, 4)
- if not PYPY and sys.version_info >= (3, 8):
+ if not PYPY:
self.assertEqual(exc.col, 18)
else:
self.assertEqual(exc.col, 26)
@@ -339,10 +338,7 @@ class Test(TestCase):
self.assertEqual(exc.col, 16)
exc = exceptions[2]
self.assertEqual(exc.lineno, 6)
- if PYPY or sys.version_info >= (3, 8):
- self.assertEqual(exc.col, 13)
- else:
- self.assertEqual(exc.col, 18)
+ self.assertEqual(exc.col, 13)
def test_indentationErrorInDoctest(self):
exc = self.flakes('''
@@ -353,10 +349,7 @@ class Test(TestCase):
"""
''', m.DoctestSyntaxError).messages[0]
self.assertEqual(exc.lineno, 5)
- if PYPY or sys.version_info >= (3, 8):
- self.assertEqual(exc.col, 13)
- else:
- self.assertEqual(exc.col, 16)
+ self.assertEqual(exc.col, 13)
def test_offsetWithMultiLineArgs(self):
(exc1, exc2) = self.flakes(
diff --git a/pyflakes/test/test_other.py b/pyflakes/test/test_other.py
index ce742a5..42e99ae 100644
--- a/pyflakes/test/test_other.py
+++ b/pyflakes/test/test_other.py
@@ -445,36 +445,6 @@ class Test(TestCase):
continue
''')
- @skipIf(version_info > (3, 8), "Python <= 3.8 only")
- def test_continueInFinally(self):
- # 'continue' inside 'finally' is a special syntax error
- # that is removed in 3.8
- self.flakes('''
- while True:
- try:
- pass
- finally:
- continue
- ''', m.ContinueInFinally)
-
- self.flakes('''
- while True:
- try:
- pass
- finally:
- if 1:
- if 2:
- continue
- ''', m.ContinueInFinally)
-
- # Even when not in a loop, this is the error Python gives
- self.flakes('''
- try:
- pass
- finally:
- continue
- ''', m.ContinueInFinally)
-
def test_breakOutsideLoop(self):
self.flakes('''
break
@@ -1716,7 +1686,6 @@ class TestUnusedAssignment(TestCase):
print(f'\x7b4*baz\N{RIGHT CURLY BRACKET}')
''')
- @skipIf(version_info < (3, 8), 'new in Python 3.8')
def test_assign_expr(self):
"""Test PEP 572 assignment expressions are treated as usage / write."""
self.flakes('''
@@ -1725,7 +1694,6 @@ class TestUnusedAssignment(TestCase):
print(x)
''')
- @skipIf(version_info < (3, 8), 'new in Python 3.8')
def test_assign_expr_generator_scope(self):
"""Test assignment expressions in generator expressions."""
self.flakes('''
@@ -1733,7 +1701,6 @@ class TestUnusedAssignment(TestCase):
print(y)
''')
- @skipIf(version_info < (3, 8), 'new in Python 3.8')
def test_assign_expr_nested(self):
"""Test assignment expressions in nested expressions."""
self.flakes('''
@@ -1972,19 +1939,6 @@ class TestAsyncStatements(TestCase):
return output
''', m.BreakOutsideLoop)
- @skipIf(version_info > (3, 8), "Python <= 3.8 only")
- def test_continueInAsyncForFinally(self):
- self.flakes('''
- async def read_data(db):
- output = []
- async for row in db.cursor():
- try:
- output.append(row)
- finally:
- continue
- return output
- ''', m.ContinueInFinally)
-
def test_asyncWith(self):
self.flakes('''
async def commit(session, data):
diff --git a/pyflakes/test/test_type_annotations.py b/pyflakes/test/test_type_annotations.py
index 885302c..2f27b06 100644
--- a/pyflakes/test/test_type_annotations.py
+++ b/pyflakes/test/test_type_annotations.py
@@ -379,7 +379,6 @@ class TestTypeAnnotations(TestCase):
async def func(c: c) -> None: pass
''')
- @skipIf(version_info < (3, 7), 'new in Python 3.7')
def test_postponed_annotations(self):
self.flakes('''
from __future__ import annotations
@@ -434,7 +433,6 @@ class TestTypeAnnotations(TestCase):
return Y
""", m.UndefinedName)
- @skipIf(version_info < (3, 8), 'new in Python 3.8')
def test_positional_only_argument_annotations(self):
self.flakes("""
from x import C
@@ -584,7 +582,6 @@ class TestTypeAnnotations(TestCase):
return None
""")
- @skipIf(version_info < (3, 7), 'new in Python 3.7')
def test_partial_string_annotations_with_future_annotations(self):
self.flakes("""
from __future__ import annotations
diff --git a/setup.py b/setup.py
index 673a76d..3cc2fbd 100755
--- a/setup.py
+++ b/setup.py
@@ -42,7 +42,7 @@ setup(
author_email="code-quality@python.org",
url="https://github.com/PyCQA/pyflakes",
packages=["pyflakes", "pyflakes.scripts", "pyflakes.test"],
- python_requires='>=3.6',
+ python_requires='>=3.8',
classifiers=[
"Development Status :: 6 - Mature",
"Environment :: Console",
@@ -50,11 +50,6 @@ setup(
"License :: OSI Approved :: MIT License",
"Programming Language :: Python",
"Programming Language :: Python :: 3",
- "Programming Language :: Python :: 3.6",
- "Programming Language :: Python :: 3.7",
- "Programming Language :: Python :: 3.8",
- "Programming Language :: Python :: 3.9",
- "Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
diff --git a/tox.ini b/tox.ini
index 9e9a9e9..84d5b71 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,6 @@
[tox]
skip_missing_interpreters = True
-envlist =
- py36,py37,py38,py39,py310,pypy3
+envlist = py,pypy3
[testenv]
deps = flake8==4.0.1