<!-- Changes to Black's terminal output and error messages -->
+- Black no longer attempts to provide special errors for attempting to format Python 2
+ code (#3933)
+
### _Blackd_
<!-- Changes to blackd -->
"""
import ast
import sys
-from typing import Final, Iterable, Iterator, List, Set, Tuple
+from typing import Iterable, Iterator, List, Set, Tuple
from black.mode import VERSION_TO_FEATURES, Feature, TargetVersion, supports_feature
from black.nodes import syms
from blib2to3.pgen2.tokenize import TokenError
from blib2to3.pytree import Leaf, Node
-PY2_HINT: Final = "Python 2 support was removed in version 22.0."
-
class InvalidInput(ValueError):
"""Raised when input source code fails all parse attempts."""
# No target_version specified, so try all grammars.
return [
# Python 3.7-3.9
- pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords,
+ pygram.python_grammar_async_keywords,
# Python 3.0-3.6
- pygram.python_grammar_no_print_statement_no_exec_statement,
+ pygram.python_grammar,
# Python 3.10+
pygram.python_grammar_soft_keywords,
]
target_versions, Feature.ASYNC_IDENTIFIERS
) and not supports_feature(target_versions, Feature.PATTERN_MATCHING):
# Python 3.7-3.9
- grammars.append(
- pygram.python_grammar_no_print_statement_no_exec_statement_async_keywords
- )
+ grammars.append(pygram.python_grammar_async_keywords)
if not supports_feature(target_versions, Feature.ASYNC_KEYWORDS):
# Python 3.0-3.6
- grammars.append(pygram.python_grammar_no_print_statement_no_exec_statement)
+ grammars.append(pygram.python_grammar)
if any(Feature.PATTERN_MATCHING in VERSION_TO_FEATURES[v] for v in target_versions):
# Python 3.10+
grammars.append(pygram.python_grammar_soft_keywords)
# Choose the latest version when raising the actual parsing error.
assert len(errors) >= 1
exc = errors[max(errors)]
-
- if matches_grammar(src_txt, pygram.python_grammar) or matches_grammar(
- src_txt, pygram.python_grammar_no_print_statement
- ):
- original_msg = exc.args[0]
- msg = f"{original_msg}\n{PY2_HINT}"
- raise InvalidInput(msg) from None
-
raise exc from None
if isinstance(result, Leaf):
stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
-small_stmt: (type_stmt | expr_stmt | print_stmt | del_stmt | pass_stmt | flow_stmt |
- import_stmt | global_stmt | exec_stmt | assert_stmt)
+small_stmt: (type_stmt | expr_stmt | del_stmt | pass_stmt | flow_stmt |
+ import_stmt | global_stmt | assert_stmt)
expr_stmt: testlist_star_expr (annassign | augassign (yield_expr|testlist) |
('=' (yield_expr|testlist_star_expr))*)
annassign: ':' test ['=' (yield_expr|testlist_star_expr)]
augassign: ('+=' | '-=' | '*=' | '@=' | '/=' | '%=' | '&=' | '|=' | '^=' |
'<<=' | '>>=' | '**=' | '//=')
# For normal and annotated assignments, additional restrictions enforced by the interpreter
-print_stmt: 'print' ( [ test (',' test)* [','] ] |
- '>>' test [ (',' test)+ [','] ] )
del_stmt: 'del' exprlist
pass_stmt: 'pass'
flow_stmt: break_stmt | continue_stmt | return_stmt | raise_stmt | yield_stmt
dotted_as_names: dotted_as_name (',' dotted_as_name)*
dotted_name: NAME ('.' NAME)*
global_stmt: ('global' | 'nonlocal') NAME (',' NAME)*
-exec_stmt: 'exec' expr ['in' test [',' test]]
assert_stmt: 'assert' test [',' test]
type_stmt: "type" NAME [typeparams] '=' expr
encoding_decl: int
eval_input: int
except_clause: int
- exec_stmt: int
expr: int
expr_stmt: int
exprlist: int
pattern: int
patterns: int
power: int
- print_stmt: int
raise_stmt: int
return_stmt: int
shift_expr: int
python_grammar: Grammar
-python_grammar_no_print_statement: Grammar
-python_grammar_no_print_statement_no_exec_statement: Grammar
-python_grammar_no_print_statement_no_exec_statement_async_keywords: Grammar
-python_grammar_no_exec_statement: Grammar
-pattern_grammar: Grammar
+python_grammar_async_keywords: Grammar
python_grammar_soft_keywords: Grammar
-
+pattern_grammar: Grammar
python_symbols: _python_symbols
pattern_symbols: _pattern_symbols
def initialize(cache_dir: Union[str, "os.PathLike[str]", None] = None) -> None:
global python_grammar
- global python_grammar_no_print_statement
- global python_grammar_no_print_statement_no_exec_statement
- global python_grammar_no_print_statement_no_exec_statement_async_keywords
+ global python_grammar_async_keywords
global python_grammar_soft_keywords
global python_symbols
global pattern_grammar
os.path.dirname(__file__), "PatternGrammar.txt"
)
- # Python 2
python_grammar = driver.load_packaged_grammar("blib2to3", _GRAMMAR_FILE, cache_dir)
- python_grammar.version = (2, 0)
+ assert "print" not in python_grammar.keywords
+ assert "exec" not in python_grammar.keywords
soft_keywords = python_grammar.soft_keywords.copy()
python_grammar.soft_keywords.clear()
python_symbols = _python_symbols(python_grammar)
- # Python 2 + from __future__ import print_function
- python_grammar_no_print_statement = python_grammar.copy()
- del python_grammar_no_print_statement.keywords["print"]
-
# Python 3.0-3.6
- python_grammar_no_print_statement_no_exec_statement = python_grammar.copy()
- del python_grammar_no_print_statement_no_exec_statement.keywords["print"]
- del python_grammar_no_print_statement_no_exec_statement.keywords["exec"]
- python_grammar_no_print_statement_no_exec_statement.version = (3, 0)
+ python_grammar.version = (3, 0)
# Python 3.7+
- python_grammar_no_print_statement_no_exec_statement_async_keywords = (
- python_grammar_no_print_statement_no_exec_statement.copy()
- )
- python_grammar_no_print_statement_no_exec_statement_async_keywords.async_keywords = (
- True
- )
- python_grammar_no_print_statement_no_exec_statement_async_keywords.version = (3, 7)
+ python_grammar_async_keywords = python_grammar.copy()
+ python_grammar_async_keywords.async_keywords = True
+ python_grammar_async_keywords.version = (3, 7)
# Python 3.10+
- python_grammar_soft_keywords = (
- python_grammar_no_print_statement_no_exec_statement_async_keywords.copy()
- )
+ python_grammar_soft_keywords = python_grammar_async_keywords.copy()
python_grammar_soft_keywords.soft_keywords = soft_keywords
python_grammar_soft_keywords.version = (3, 10)
assert_format(source, expected, fast=True)
-def test_python_2_hint() -> None:
- with pytest.raises(black.parsing.InvalidInput) as exc_info:
- assert_format("print 'daylily'", "print 'daylily'")
- exc_info.match(black.parsing.PY2_HINT)
-
-
@pytest.mark.filterwarnings("ignore:invalid escape sequence.*:DeprecationWarning")
def test_docstring_no_string_normalization() -> None:
"""Like test_docstring but with string normalization off."""