diff --git a/libcst/_parser/conversions/expression.py b/libcst/_parser/conversions/expression.py index a3eecbdb..59a8c039 100644 --- a/libcst/_parser/conversions/expression.py +++ b/libcst/_parser/conversions/expression.py @@ -1459,7 +1459,8 @@ def convert_yield_expr( return WithLeadingWhitespace(yield_node, yield_token.whitespace_before) -@with_production("yield_arg", "'from' test | testlist") +@with_production("yield_arg", "'from' test | testlist", version="<=3.7") +@with_production("yield_arg", "'from' test | testlist_star_expr", version=">=3.8") def convert_yield_arg( config: ParserConfig, children: typing.Sequence[typing.Any] ) -> typing.Any: diff --git a/libcst/_parser/conversions/statement.py b/libcst/_parser/conversions/statement.py index c87a0c95..2f395226 100644 --- a/libcst/_parser/conversions/statement.py +++ b/libcst/_parser/conversions/statement.py @@ -262,7 +262,8 @@ def convert_expr_stmt(config: ParserConfig, children: Sequence[Any]) -> Any: ) -@with_production("annassign", "':' test ['=' test]", version=">=3.6") +@with_production("annassign", "':' test ['=' test]", version=">=3.6,<3.8") +@with_production("annassign", "':' test ['=' (yield_expr|testlist_star_expr)]", version=">=3.8") def convert_annassign(config: ParserConfig, children: Sequence[Any]) -> Any: if len(children) == 2: # Variable annotation only @@ -362,7 +363,8 @@ def convert_break_stmt(config: ParserConfig, children: Sequence[Any]) -> Any: return WithLeadingWhitespace(Break(), name.whitespace_before) -@with_production("return_stmt", "'return' [testlist]") +@with_production("return_stmt", "'return' [testlist]", version="<=3.7") +@with_production("return_stmt", "'return' [testlist_star_expr]", version=">=3.8") def convert_return_stmt(config: ParserConfig, children: Sequence[Any]) -> Any: if len(children) == 1: (keyword,) = children diff --git a/libcst/_parser/types/config.py b/libcst/_parser/types/config.py index eaa9479a..efac0e09 100644 --- a/libcst/_parser/types/config.py +++ b/libcst/_parser/types/config.py @@ -83,7 +83,7 @@ class PartialParserConfig: #: run LibCST. For example, you can parse code as 3.7 with a CPython 3.6 #: interpreter. #: - #: Currently, only Python 3.5, 3.6 and 3.7 syntax is supported. + #: Currently, only Python 3.5, 3.6, 3.7 and 3.8 syntax is supported. python_version: Union[str, AutoConfig] = AutoConfig.token #: A named tuple with the ``major`` and ``minor`` Python version numbers. This is @@ -121,11 +121,12 @@ class PartialParserConfig: PythonVersionInfo(3, 5), PythonVersionInfo(3, 6), PythonVersionInfo(3, 7), + PythonVersionInfo(3, 8), ): raise ValueError( "LibCST can only parse code using one of the following versions of " - + "Python's grammar: 3.5, 3.6, 3.7. More versions may be supported " - + "by future releases." + + "Python's grammar: 3.5, 3.6, 3.7, 3.8. More versions may be " + + "supported by future releases." ) object.__setattr__(self, "parsed_python_version", parsed_python_version) diff --git a/libcst/_parser/types/tests/test_config.py b/libcst/_parser/types/tests/test_config.py index b30f8c8f..39110bb3 100644 --- a/libcst/_parser/types/tests/test_config.py +++ b/libcst/_parser/types/tests/test_config.py @@ -33,7 +33,7 @@ class TestConfig(UnitTest): "The given version is not in the right format", ), "python_version_unsupported": ( - lambda: PartialParserConfig(python_version="3.8"), + lambda: PartialParserConfig(python_version="3.4"), "LibCST can only parse code using one of the following versions of Python's grammar", ), "encoding": (