diff --git a/unpythonic/syntax/astcompat.py b/unpythonic/syntax/astcompat.py deleted file mode 100644 index 50be21b8..00000000 --- a/unpythonic/syntax/astcompat.py +++ /dev/null @@ -1,87 +0,0 @@ -# -*- coding: utf-8 -*- -"""Conditionally import AST node types only supported by recent enough Python versions.""" - -__all__ = ["NamedExpr", - "Match", "match_case", "MatchValue", "MatchSingleton", "MatchSequence", "MatchStar", "MatchMapping", "MatchClass", "MatchAs", "MatchOr", - "TryStar", - "TypeAlias", "TypeVar", "ParamSpec", "TypeVarTuple", - "Num", "Str", "Bytes", "NameConstant", "Ellipsis", - "Index", "ExtSlice", - "getconstant"] - -import ast - -from ..symbol import gensym - -_NoSuchNodeType = gensym("_NoSuchNodeType") - -# -------------------------------------------------------------------------------- -# New AST node types - -# Minimum language version supported by this module is Python 3.6. - -# No new AST node types in Python 3.7. - -try: # Python 3.8+ - from ast import NamedExpr # a.k.a. walrus operator ":=" -except ImportError: # pragma: no cover - NamedExpr = _NoSuchNodeType - -# No new AST node types in Python 3.9. - -try: # Python 3.10+ - from ast import (Match, match_case, - MatchValue, MatchSingleton, MatchSequence, MatchStar, - MatchMapping, MatchClass, MatchAs, MatchOr) # `match`/`case` -except ImportError: # pragma: no cover - Match = match_case = MatchValue = MatchSingleton = MatchSequence = MatchStar = MatchMapping = MatchClass = MatchAs = MatchOr = _NoSuchNodeType - -try: # Python 3.11+ - from ast import TryStar # `try`/`except*` (exception groups) -except ImportError: # pragma: no cover - TryStar = _NoSuchNodeType - -try: # Python 3.12+ - from ast import TypeAlias, TypeVar, ParamSpec, TypeVarTuple # `type` statement (type alias) -except ImportError: # pragma: no cover - TypeAlias = TypeVar = ParamSpec = TypeVarTuple = _NoSuchNodeType - -# -------------------------------------------------------------------------------- -# Deprecated AST node types - -try: # Python 3.8+, https://docs.python.org/3/whatsnew/3.8.html#deprecated - from ast import Num, Str, Bytes, NameConstant, Ellipsis -except ImportError: # pragma: no cover - Num = Str = Bytes = NameConstant = Ellipsis = _NoSuchNodeType - -try: # Python 3.9+, https://docs.python.org/3/whatsnew/3.9.html#deprecated - from ast import Index, ExtSlice - # We ignore the internal classes Suite, Param, AugLoad, AugStore, - # which were never used in Python 3.x. -except ImportError: # pragma: no cover - Index = ExtSlice = _NoSuchNodeType - -# -------------------------------------------------------------------------------- -# Compatibility functions - -def getconstant(tree): - """Given an AST node `tree` representing a constant, return the contained raw value. - - This encapsulates the AST differences between Python 3.8+ and older versions. - - There are no `setconstant` or `makeconstant` counterparts, because you can - just create an `ast.Constant` in Python 3.6 and later. The parser doesn't - emit them until Python 3.8, but Python 3.6+ compile `ast.Constant` just fine. - """ - if type(tree) is ast.Constant: # Python 3.8+ - return tree.value - # up to Python 3.7 - elif type(tree) is ast.NameConstant: # up to Python 3.7 # pragma: no cover - return tree.value - elif type(tree) is ast.Num: # pragma: no cover - return tree.n - elif type(tree) in (ast.Str, ast.Bytes): # pragma: no cover - return tree.s - elif type(tree) is ast.Ellipsis: # `ast.Ellipsis` is the AST node type, `builtins.Ellipsis` is `...`. # pragma: no cover - return ... - raise TypeError(f"Not an AST node representing a constant: {type(tree)} with value {repr(tree)}") # pragma: no cover diff --git a/unpythonic/syntax/autocurry.py b/unpythonic/syntax/autocurry.py index 18c83f91..0124c3b5 100644 --- a/unpythonic/syntax/autocurry.py +++ b/unpythonic/syntax/autocurry.py @@ -7,10 +7,10 @@ from mcpyrate.quotes import macros, q, a, h # noqa: F401 +from mcpyrate.astcompat import TypeAlias from mcpyrate.quotes import is_captured_value from mcpyrate.walkers import ASTTransformer -from .astcompat import TypeAlias from .util import (suggest_decorator_index, isx, has_curry, sort_lambda_decorators) from ..dynassign import dyn diff --git a/unpythonic/syntax/autoref.py b/unpythonic/syntax/autoref.py index e1119730..739b22d1 100644 --- a/unpythonic/syntax/autoref.py +++ b/unpythonic/syntax/autoref.py @@ -9,11 +9,11 @@ from mcpyrate.quotes import macros, q, u, n, a, h # noqa: F401 from mcpyrate import gensym, parametricmacro +from mcpyrate.astcompat import getconstant from mcpyrate.astfixers import fix_ctx from mcpyrate.quotes import is_captured_value from mcpyrate.walkers import ASTTransformer -from .astcompat import getconstant from .nameutil import isx from .util import ExpandedAutorefMarker from .letdoutil import isdo, islet, ExpandedDoView, ExpandedLetView diff --git a/unpythonic/syntax/lambdatools.py b/unpythonic/syntax/lambdatools.py index 1b089392..4b12fd21 100644 --- a/unpythonic/syntax/lambdatools.py +++ b/unpythonic/syntax/lambdatools.py @@ -14,6 +14,7 @@ from mcpyrate.quotes import macros, q, u, n, a, h # noqa: F401 from mcpyrate import gensym +from mcpyrate.astcompat import getconstant, Str, NamedExpr from mcpyrate.expander import MacroExpander from mcpyrate.quotes import is_captured_value from mcpyrate.splicing import splice_expression @@ -25,7 +26,6 @@ from ..misc import namelambda from ..symbol import sym -from .astcompat import getconstant, Str, NamedExpr from .letdo import _implicit_do, _do from .letdoutil import islet, isenvassign, UnexpandedLetView, UnexpandedEnvAssignView, ExpandedDoView from .nameutil import getname diff --git a/unpythonic/syntax/lazify.py b/unpythonic/syntax/lazify.py index c63a78e4..af2207b7 100644 --- a/unpythonic/syntax/lazify.py +++ b/unpythonic/syntax/lazify.py @@ -9,12 +9,12 @@ from mcpyrate.quotes import macros, q, u, a, h # noqa: F401 +from mcpyrate.astcompat import TypeAlias from mcpyrate.astfixers import fix_ctx from mcpyrate.quotes import capture_as_macro, is_captured_value from mcpyrate.unparser import unparse from mcpyrate.walkers import ASTTransformer -from .astcompat import TypeAlias from .util import (suggest_decorator_index, sort_lambda_decorators, detect_lambda, isx, getname, is_decorator) from .letdoutil import islet, isdo, ExpandedLetView diff --git a/unpythonic/syntax/letdoutil.py b/unpythonic/syntax/letdoutil.py index 0b7e20be..d286d0e7 100644 --- a/unpythonic/syntax/letdoutil.py +++ b/unpythonic/syntax/letdoutil.py @@ -11,9 +11,9 @@ import sys from mcpyrate import unparse +from mcpyrate.astcompat import getconstant, Str, NamedExpr from mcpyrate.core import Done -from .astcompat import getconstant, Str, NamedExpr from .nameutil import isx, getname letf_name = "letter" # must match what ``unpythonic.syntax.letdo._let_expr_impl`` uses in its output. diff --git a/unpythonic/syntax/scopeanalyzer.py b/unpythonic/syntax/scopeanalyzer.py index ba8b5ddf..8a2634eb 100644 --- a/unpythonic/syntax/scopeanalyzer.py +++ b/unpythonic/syntax/scopeanalyzer.py @@ -80,11 +80,10 @@ Import, ImportFrom, Try, ListComp, SetComp, GeneratorExp, DictComp, Store, Del, Global, Nonlocal) +from mcpyrate.astcompat import TryStar, MatchStar, MatchMapping, MatchClass, MatchAs from mcpyrate.core import Done from mcpyrate.walkers import ASTTransformer, ASTVisitor -from .astcompat import TryStar, MatchStar, MatchMapping, MatchClass, MatchAs - from ..it import uniqify def isnewscope(tree): diff --git a/unpythonic/syntax/tailtools.py b/unpythonic/syntax/tailtools.py index b0b33077..cb5f5e41 100644 --- a/unpythonic/syntax/tailtools.py +++ b/unpythonic/syntax/tailtools.py @@ -22,11 +22,11 @@ from mcpyrate.quotes import macros, q, u, n, a, h # noqa: F401 from mcpyrate import gensym +from mcpyrate.astcompat import getconstant, NameConstant, TryStar from mcpyrate.quotes import capture_as_macro, is_captured_value from mcpyrate.utils import NestingLevelTracker from mcpyrate.walkers import ASTTransformer, ASTVisitor -from .astcompat import getconstant, NameConstant, TryStar from .ifexprs import aif, it from .letdoutil import isdo, islet, ExpandedLetView, ExpandedDoView from .util import (isx, isec, diff --git a/unpythonic/syntax/tests/test_letdoutil.py b/unpythonic/syntax/tests/test_letdoutil.py index 9b59a78d..c6d2fc18 100644 --- a/unpythonic/syntax/tests/test_letdoutil.py +++ b/unpythonic/syntax/tests/test_letdoutil.py @@ -4,6 +4,7 @@ from ...syntax import macros, test, test_raises, warn, the # noqa: F401 from ...test.fixtures import session, testset +from mcpyrate.astcompat import getconstant, Num from mcpyrate.quotes import macros, q, n # noqa: F401, F811 from mcpyrate.metatools import macros, expandrq # noqa: F811 @@ -16,7 +17,6 @@ from mcpyrate import unparse -from ...syntax.astcompat import getconstant, Num from ...syntax.letdoutil import (canonize_bindings, isenvassign, islet, isdo, UnexpandedEnvAssignView, diff --git a/unpythonic/syntax/tests/test_util.py b/unpythonic/syntax/tests/test_util.py index 738f09dc..807c5da7 100644 --- a/unpythonic/syntax/tests/test_util.py +++ b/unpythonic/syntax/tests/test_util.py @@ -4,10 +4,10 @@ from ...syntax import macros, do, local, test, test_raises, fail, the # noqa: F401 from ...test.fixtures import session, testset +from mcpyrate.astcompat import getconstant, Num, Str from mcpyrate.quotes import macros, q, n, h # noqa: F401, F811 from mcpyrate.metatools import macros, expandrq # noqa: F401, F811 -from ...syntax.astcompat import getconstant, Num, Str from ...syntax.util import (isec, detect_callec, detect_lambda, is_decorator, has_tco, has_curry, has_deco, diff --git a/unpythonic/syntax/util.py b/unpythonic/syntax/util.py index f1afbf14..721b8b30 100644 --- a/unpythonic/syntax/util.py +++ b/unpythonic/syntax/util.py @@ -18,12 +18,12 @@ from ast import Call, Lambda, FunctionDef, AsyncFunctionDef, If, stmt +from mcpyrate.astcompat import getconstant from mcpyrate.core import add_postprocessor from mcpyrate.markers import ASTMarker, delete_markers from mcpyrate.quotes import is_captured_value from mcpyrate.walkers import ASTTransformer, ASTVisitor -from .astcompat import getconstant from .letdoutil import isdo, ExpandedDoView from .nameutil import isx, getname