Blob Blame History Raw
From e8d84098da10d013ee686027e174814dbe4dd908 Mon Sep 17 00:00:00 2001
From: Anthony Sottile <asottile@umich.edu>
Date: Mon, 12 Jun 2023 20:11:49 -0400
Subject: [PATCH] get testsuite passing on 3.12

---
 pycodestyle.py             |  4 +--
 testsuite/E10.py           |  5 ---
 testsuite/E90.py           | 10 ------
 testsuite/python312.py     |  9 ++++++
 testsuite/test_E101.py     | 18 +++++++++++
 testsuite/test_E901.py     | 29 ++++++++++++++++++
 testsuite/test_api.py      | 62 ++++++++++++++++----------------------
 7 files changed, 84 insertions(+), 53 deletions(-)
 create mode 100644 testsuite/python312.py
 create mode 100644 testsuite/test_E101.py
 create mode 100644 testsuite/test_E901.py

diff --git a/pycodestyle.py b/pycodestyle.py
index 4a97372..2ee3dac 100755
--- a/pycodestyle.py
+++ b/pycodestyle.py
@@ -196,7 +196,6 @@ def tabs_or_spaces(physical_line, indent_char):
     These options are highly recommended!
 
     Okay: if a == 0:\n    a = 1\n    b = 1
-    E101: if a == 0:\n        a = 1\n\tb = 1
     """
     indent = INDENT_REGEX.match(physical_line).group(1)
     for offset, char in enumerate(indent):
@@ -802,9 +801,10 @@ def whitespace_before_parameters(logical_line, tokens):
             (index < 2 or tokens[index - 2][1] != 'class') and
             # Allow "return (a.foo for a in range(5))"
             not keyword.iskeyword(prev_text) and
-            # 'match' and 'case' are only soft keywords
             (
                 sys.version_info < (3, 9) or
+                # 3.12+: type is a soft keyword but no braces after
+                prev_text == 'type' or
                 not keyword.issoftkeyword(prev_text)
             )
         ):
diff --git a/testsuite/E10.py b/testsuite/E10.py
index 7b42594..1a90112 100644
--- a/testsuite/E10.py
+++ b/testsuite/E10.py
@@ -1,8 +1,3 @@
-#: E101 W191
-for a in 'abc':
-    for b in 'xyz':
-        print a  # indented with 8 spaces
-	print b  # indented with 1 tab
 #: E101 E122 W191 W191
 if True:
 	pass
diff --git a/testsuite/E90.py b/testsuite/E90.py
index 2c18e9a..e0a10d0 100644
--- a/testsuite/E90.py
+++ b/testsuite/E90.py
@@ -1,6 +1,4 @@
 #: E901
-}
-#: E901
 = [x
 #: E901 E101 W191
 while True:
@@ -8,14 +6,6 @@ while True:
 	    pass
 	except:
 		print 'Whoops'
-#: E122 E225 E251 E251
-
-# Do not crash if code is invalid
-if msg:
-    errmsg = msg % progress.get(cr_dbname))
-
-def lasting(self, duration=300):
-    progress = self._progress.setdefault('foo', {}
 #: Okay
 
 # Issue #119
diff --git a/testsuite/python312.py b/testsuite/python312.py
new file mode 100644
index 0000000..2b42833
--- /dev/null
+++ b/testsuite/python312.py
@@ -0,0 +1,9 @@
+#: Okay
+# https://github.com/python/cpython/issues/90432: fixed in 3.12
+def foo():
+    pas
+
+\
+
+def bar():
+    pass
diff --git a/testsuite/test_E101.py b/testsuite/test_E101.py
new file mode 100644
index 0000000..ba7d707
--- /dev/null
+++ b/testsuite/test_E101.py
@@ -0,0 +1,18 @@
+"""moved from testsuite files due to 3.12 making this a TokenError"""
+import unittest
+import sys
+
+from testsuite.support import errors_from_src
+
+
+class E101Test(unittest.TestCase):
+    def test_E101(self):
+        errors = errors_from_src(
+            'if True:\n'
+            '\tprint(1)  # tabs\n'
+            '        print(2)  # spaces\n'
+        )
+        if sys.version_info >= (3, 12):
+            self.assertEqual(errors, ['W191:2:1', 'E901:3:28'])
+        else:
+            self.assertEqual(errors, ['W191:2:1', 'E101:3:1'])
diff --git a/testsuite/test_E901.py b/testsuite/test_E901.py
new file mode 100644
index 0000000..3633822
--- /dev/null
+++ b/testsuite/test_E901.py
@@ -0,0 +1,29 @@
+"""moved from testsuite files due to 3.12 changing syntax errors"""
+import unittest
+import sys
+
+from testsuite.support import errors_from_src
+
+
+class E901Test(unittest.TestCase):
+    def test_closing_brace(self):
+        errors = errors_from_src('}\n')
+        if sys.version_info < (3, 12):
+            self.assertEqual(errors, ['E901:2:1'])
+        else:
+            self.assertEqual(errors, [])
+
+    def test_unclosed_brace(self):
+        src = '''\
+if msg:
+    errmsg = msg % progress.get(cr_dbname))
+
+def lasting(self, duration=300):
+    progress = self._progress.setdefault('foo', {}
+'''
+        errors = errors_from_src(src)
+        if sys.version_info < (3, 12):
+            expected = ['E122:4:1', 'E225:4:27', 'E251:5:13', 'E251:5:15']
+        else:
+            expected = ['E122:4:1', 'E225:4:27', 'E251:5:13', 'E251:5:15', 'E901:5:1']  # noqa: E501
+        self.assertEqual(errors, expected)
diff --git a/testsuite/test_api.py b/testsuite/test_api.py
index 38e34ac..fa4d8a0 100644
--- a/testsuite/test_api.py
+++ b/testsuite/test_api.py
@@ -329,15 +329,18 @@ class APITestCase(unittest.TestCase):
         count_errors = pep8style.input_file('stdin', lines=['\x00\n'])
 
         stdout = sys.stdout.getvalue()
-        if sys.version_info < (3, 12):
-            expected = "stdin:1:1: E901 ValueError"
+        if sys.version_info < (3, 11, 4):
+            expected = ["stdin:1:1: E901 ValueError: source code string cannot contain null bytes"]  # noqa: E501
+        elif sys.version_info < (3, 12):
+            expected = ["stdin:1:1: E901 SyntaxError: source code string cannot contain null bytes"]  # noqa: E501
         else:
-            expected = "stdin:1:1: E901 SyntaxError: source code string cannot contain null bytes"  # noqa: E501
-        self.assertTrue(stdout.startswith(expected),
-                        msg='Output %r does not start with %r' %
-                        (stdout, expected))
+            expected = [
+                "stdin:1:1: E901 SyntaxError: source code string cannot contain null bytes",   # noqa: E501
+                "stdin:1:1: E901 TokenError: source code cannot contain null bytes",   # noqa: E501
+            ]
+        self.assertEqual(stdout.splitlines(), expected)
         self.assertFalse(sys.stderr)
-        self.assertEqual(count_errors, 1)
+        self.assertEqual(count_errors, len(expected))
 
     def test_styleguide_unmatched_triple_quotes(self):
         pycodestyle.register_check(DummyChecker, ['Z701'])
@@ -350,35 +353,22 @@ class APITestCase(unittest.TestCase):
         pep8style.input_file('stdin', lines=lines)
         stdout = sys.stdout.getvalue()
 
-        expected = 'stdin:2:5: E901 TokenError: EOF in multi-line string'
-        self.assertTrue(expected in stdout)
-
-    def test_styleguide_continuation_line_outdented(self):
-        pycodestyle.register_check(DummyChecker, ['Z701'])
-        lines = [
-            'def foo():\n',
-            '    pass\n',
-            '\n',
-            '\\\n',
-            '\n',
-            'def bar():\n',
-            '    pass\n',
-        ]
-
-        pep8style = pycodestyle.StyleGuide()
-        count_errors = pep8style.input_file('stdin', lines=lines)
-        self.assertEqual(count_errors, 2)
-        stdout = sys.stdout.getvalue()
-        expected = (
-            'stdin:6:1: '
-            'E122 continuation line missing indentation or outdented'
-        )
-        self.assertTrue(expected in stdout)
-        expected = 'stdin:6:1: E302 expected 2 blank lines, found 1'
-        self.assertTrue(expected in stdout)
-
-        # TODO: runner
-        # TODO: input_file
+        if sys.version_info < (3, 10):
+            expected = [
+                'stdin:2:5: E901 TokenError: EOF in multi-line string',
+                'stdin:2:26: E901 SyntaxError: EOF while scanning triple-quoted string literal',  # noqa: E501
+            ]
+        elif sys.version_info < (3, 12):
+            expected = [
+                'stdin:2:5: E901 TokenError: EOF in multi-line string',
+                'stdin:2:6: E901 SyntaxError: unterminated triple-quoted string literal (detected at line 2)',  # noqa: E501
+            ]
+        else:
+            expected = [
+                'stdin:2:6: E901 SyntaxError: unterminated triple-quoted string literal (detected at line 2)',  # noqa: E501
+                'stdin:2:6: E901 TokenError: EOF in multi-line string',
+            ]
+        self.assertEqual(stdout.splitlines(), expected)
 
     def test_styleguides_other_indent_size(self):
         pycodestyle.register_check(DummyChecker, ['Z701'])
-- 
2.41.0