Skip to content

Commit

Permalink
Fix unit tests in Python 3.10 (Closes: #192)
Browse files Browse the repository at this point in the history
  • Loading branch information
jspricke committed Dec 5, 2022
1 parent 6b6b59f commit cf5969d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
51 changes: 41 additions & 10 deletions parso/python/errors.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
import codecs
import sys
import warnings
import re
from contextlib import contextmanager
Expand Down Expand Up @@ -33,7 +34,10 @@ def _get_rhs_name(node, version):
return "literal"
else:
if second.children[1] == ":" or second.children[0] == "**":
return "dict display"
if version < (3, 10):
return "dict display"
else:
return "dict literal"
else:
return "set display"
elif (
Expand All @@ -47,7 +51,10 @@ def _get_rhs_name(node, version):
elif first == "[":
return "list"
elif first == "{" and second == "}":
return "dict display"
if version < (3, 10):
return "dict display"
else:
return "dict literal"
elif first == "{" and len(node.children) > 2:
return "set display"
elif type_ == "keyword":
Expand All @@ -58,7 +65,10 @@ def _get_rhs_name(node, version):
else:
return str(node.value)
elif type_ == "operator" and node.value == "...":
return "Ellipsis"
if version < (3, 10):
return "Ellipsis"
else:
return "ellipsis"
elif type_ == "comparison":
return "comparison"
elif type_ in ("string", "number", "strings"):
Expand All @@ -83,7 +93,10 @@ def _get_rhs_name(node, version):
or "_test" in type_
or type_ in ("term", "factor")
):
return "operator"
if version < (3, 10):
return "operator"
else:
return "expression"
elif type_ == "star_expr":
return "starred"
elif type_ == "testlist_star_expr":
Expand Down Expand Up @@ -610,7 +623,10 @@ def is_issue(self, leaf):

@ErrorFinder.register_rule(type='string')
class _StringChecks(SyntaxRule):
message = "bytes can only contain ASCII literal characters."
if sys.version_info < (3, 10):
message = "bytes can only contain ASCII literal characters."
else:
message = "bytes can only contain ASCII literal characters"

def is_issue(self, leaf):
string_prefix = leaf.string_prefix.lower()
Expand Down Expand Up @@ -1043,14 +1059,20 @@ def _check_assignment(self, node, is_deletion=False, is_namedexpr=False, is_aug_
error = 'literal'
else:
if second.children[1] == ':':
error = 'dict display'
if self._normalizer.version < (3, 10):
error = 'dict display'
else:
error = 'dict literal'
else:
error = 'set display'
elif first == "{" and second == "}":
if self._normalizer.version < (3, 8):
error = 'literal'
else:
error = "dict display"
if self._normalizer.version < (3, 10):
error = "dict display"
else:
error = "dict literal"
elif first == "{" and len(node.children) > 2:
if self._normalizer.version < (3, 8):
error = 'literal'
Expand Down Expand Up @@ -1083,7 +1105,10 @@ def _check_assignment(self, node, is_deletion=False, is_namedexpr=False, is_aug_
error = str(node.value)
elif type_ == 'operator':
if node.value == '...':
error = 'Ellipsis'
if self._normalizer.version < (3, 10):
error = 'Ellipsis'
else:
error = 'ellipsis'
elif type_ == 'comparison':
error = 'comparison'
elif type_ in ('string', 'number', 'strings'):
Expand All @@ -1098,7 +1123,10 @@ def _check_assignment(self, node, is_deletion=False, is_namedexpr=False, is_aug_
if node.children[0] == 'await':
error = 'await expression'
elif node.children[-2] == '**':
error = 'operator'
if self._normalizer.version < (3, 10):
error = 'operator'
else:
error = 'expression'
else:
# Has a trailer
trailer = node.children[-1]
Expand All @@ -1120,7 +1148,10 @@ def _check_assignment(self, node, is_deletion=False, is_namedexpr=False, is_aug_
elif ('expr' in type_ and type_ != 'star_expr' # is a substring
or '_test' in type_
or type_ in ('term', 'factor')):
error = 'operator'
if self._normalizer.version < (3, 10):
error = 'operator'
else:
error = 'expression'
elif type_ == "star_expr":
if is_deletion:
if self._normalizer.version >= (3, 9):
Expand Down
23 changes: 23 additions & 0 deletions test/test_python_errors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Testing if parso finds syntax errors and indentation errors.
"""
import re
import sys
import warnings

Expand Down Expand Up @@ -136,6 +137,28 @@ def _get_actual_exception(code):
wanted = 'SyntaxError: invalid syntax'
elif wanted == "SyntaxError: f-string: single '}' is not allowed":
wanted = 'SyntaxError: invalid syntax'
elif "Maybe you meant '==' instead of '='?" in wanted:
wanted = wanted.removesuffix(" here. Maybe you meant '==' instead of '='?")
elif re.match(
r"SyntaxError: unterminated string literal \(detected at line \d+\)", wanted
):
wanted = "SyntaxError: EOL while scanning string literal"
elif re.match(
r"SyntaxError: unterminated triple-quoted string literal \(detected at line \d+\)",
wanted,
):
wanted = 'SyntaxError: EOF while scanning triple-quoted string literal'
elif wanted == 'SyntaxError: cannot use starred expression here':
wanted = "SyntaxError: can't use starred expression here"
elif wanted == 'SyntaxError: f-string: cannot use starred expression here':
wanted = "SyntaxError: f-string: can't use starred expression here"
elif re.match(
r"IndentationError: expected an indented block after '[^']*' statement on line \d",
wanted,
):
wanted = 'IndentationError: expected an indented block'
elif wanted == 'SyntaxError: unterminated string literal':
wanted = 'SyntaxError: EOL while scanning string literal'
return [wanted], line_nr


Expand Down

4 comments on commit cf5969d

@kloczek
Copy link

@kloczek kloczek commented on cf5969d Apr 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without it pytest fails in many units

=========================== short test summary info ============================
FAILED test/test_python_errors.py::test_python_exception_matches[{} += 1] - a...
FAILED test/test_python_errors.py::test_python_exception_matches[{a:b} += 1]
FAILED test/test_python_errors.py::test_python_exception_matches[... += 1] - ...
FAILED test/test_python_errors.py::test_python_exception_matches[a + b += 1]
FAILED test/test_python_errors.py::test_python_exception_matches[+a += 1] - a...
FAILED test/test_python_errors.py::test_python_exception_matches[a and b += 1]
FAILED test/test_python_errors.py::test_python_exception_matches[[x for x in y] = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[{x for x in y} = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[{x:x for x in y} = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[... = 1] - a...
FAILED test/test_python_errors.py::test_python_exception_matches[{a, b} = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[{a: b} = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[1 = 1] - ass...
FAILED test/test_python_errors.py::test_python_exception_matches["" = 1] - as...
FAILED test/test_python_errors.py::test_python_exception_matches[b"" = 1_0]
FAILED test/test_python_errors.py::test_python_exception_matches[b"" = 1_1]
FAILED test/test_python_errors.py::test_python_exception_matches["" "" = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[1 | 1 = 3]
FAILED test/test_python_errors.py::test_python_exception_matches[1**1 = 3] - ...
FAILED test/test_python_errors.py::test_python_exception_matches[~ 1 = 3] - a...
FAILED test/test_python_errors.py::test_python_exception_matches[not 1 = 3]
FAILED test/test_python_errors.py::test_python_exception_matches[1 and 1 = 3]
FAILED test/test_python_errors.py::test_python_exception_matches[def foo(): (yield 1) = 3]
FAILED test/test_python_errors.py::test_python_exception_matches[async def foo(): await x = 3]
FAILED test/test_python_errors.py::test_python_exception_matches[(a if a else a) = a]
FAILED test/test_python_errors.py::test_python_exception_matches[a, 1 = x] - ...
FAILED test/test_python_errors.py::test_python_exception_matches[foo() = 1]
FAILED test/test_python_errors.py::test_python_exception_matches[for (not 1) in []: pass]
FAILED test/test_python_errors.py::test_python_exception_matches[u"\\"] - Ass...
FAILED test/test_python_errors.py::test_python_exception_matches[b"\\"] - Ass...
FAILED test/test_python_errors.py::test_python_exception_matches[b"\xe4"] - A...
FAILED test/test_python_errors.py::test_python_exception_matches[del x + y]
FAILED test/test_python_errors.py::test_python_exception_matches[del {}] - As...
FAILED test/test_python_errors.py::test_python_exception_matches[(*x)] - asse...
FAILED test/test_python_errors.py::test_python_exception_matches[((*x))] - as...
FAILED test/test_python_errors.py::test_python_exception_matches[1 + (*x)] - ...
FAILED test/test_python_errors.py::test_python_exception_matches[f"{*x}"] - a...
FAILED test/test_python_errors.py::test_python_exception_matches["""] - Asser...
FAILED test/test_python_errors.py::test_python_exception_matches["] - Asserti...
FAILED test/test_python_errors.py::test_python_exception_matches['''] - Asser...
FAILED test/test_python_errors.py::test_python_exception_matches['] - Asserti...
FAILED test/test_python_errors.py::test_python_exception_matches[if 1:\nfoo]
FAILED test/test_python_errors.py::test_python_exception_matches[if 1: blubb\nif 1:\npass\nTrue and False]
FAILED test/test_python_errors.py::test_python_exception_matches[del ...] - A...
FAILED test/test_python_errors.py::test_python_exception_matches[({a: b} := {1: 2})]
FAILED test/test_python_errors.py::test_python_exception_matches[(a + b := 1)]
======================= 46 failed, 1305 passed in 8.57s ========================

IMO it would be good to release new version because this commit.
doable? 🤔

@davidhalter
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Released parso 0.8.4: https://pypi.org/project/parso/ Have fun :)

@kloczek
Copy link

@kloczek kloczek commented on cf5969d Apr 5, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you ! 👍 😄

BTW .. is it possible to start making github releases?🤔
On create github release entry is created email notification to those whom have set in your repo the web UI Watch->Releases.
gh release can contain additional comments (li changelog) or additional assets like release tar balls (by default it contains only assets from git tag) however all those part are not obligatory.
In simplest variant gh release can be empty because subiekt of the sent email contains git tag name.

I'm asking because my automation process uses those email notifications by trying to make preliminary automated upgrades of building packages, which allows saving some time on maintaining packaging procedures.
Probably other people may be interested to be instantly informed about release new version as well.

Documentation and examples of generate gh releases:
https://docs.github.com/en/repositories/releasing-projects-on-github/managing-releases-in-a-repository
https://cli.github.com/manual/gh_release_upload/
jbms/sphinx-immaterial#282
https://github.com/marketplace/actions/github-release
https://pgjones.dev/blog/trusted-plublishing-2023/
jbms/sphinx-immaterial#281 (comment)
tox target to publish on pypi and make gh release https://github.com/jaraco/skeleton/blob/928e9a86d61d3a660948bcba7689f90216cc8243/tox.ini#L42-L58

@davidhalter
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, sorry. That's extra work that I currently don't want to do. But we always create tags, so you can just use that.

Please sign in to comment.