Skip to content

Commit

Permalink
move unpythonic.syntax.astcompat to mcpyrate.astcompat
Browse files Browse the repository at this point in the history
  • Loading branch information
Technologicat committed Sep 27, 2024
1 parent 8e1a14e commit 1046bff
Showing 1 changed file with 86 additions and 0 deletions.
86 changes: 86 additions & 0 deletions mcpyrate/astcompat.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
# -*- 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

class _NoSuchNodeType(ast.AST):
pass

# --------------------------------------------------------------------------------
# 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

0 comments on commit 1046bff

Please sign in to comment.