Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
self.func._codegen(state)
self.whitespace_after_func._codegen(state)
state.add_token("(")
self.whitespace_before_args._codegen(state)
lastarg = len(self.args) - 1
for i, arg in enumerate(self.args):
arg._codegen(state, default_comma=(i != lastarg))
state.add_token(")")
@add_slots
@dataclass(frozen=True)
class Await(BaseExpression):
"""
An await expression. Await expressions are only valid inside the body of an
asynchronous :class:`FunctionDef` or (as of Python 3.7) inside of an asynchronous
:class:`GeneratorExp` nodes.
"""
#: The actual expression we need to wait for.
expression: BaseExpression
lpar: Sequence[LeftParen] = ()
#: Sequence of parenthesis for precedence dictation.
rpar: Sequence[RightParen] = ()
#: Whitespace that appears after the ``async`` keyword, but before the inner
#: ``expression``.
whitespace_after_await: BaseParenthesizableWhitespace = SimpleWhitespace.field(" ")
Python's grammar defines all expression as valid in this position, but the AST
compiler further restricts the allowed types, which is what this type attempts to
express.
This is similar to a :class:`BaseDelTargetExpression`, but it also includes
:class:`StarredElement` as a valid node.
The set of valid nodes are defined as part of `CPython's AST context computation
`_.
"""
pass
class BaseDelTargetExpression(BaseExpression, ABC):
"""
An expression that's valid on the right side of a :class:`Del` statement.
Python's grammar defines all expression as valid in this position, but the AST
compiler further restricts the allowed types, which is what this type attempts to
express.
This is similar to a :class:`BaseAssignTargetExpression`, but it excludes
:class:`StarredElement`.
The set of valid nodes are defined as part of `CPython's AST context computation
`_ and as part
of `CPython's bytecode compiler
`_.
"""
semicolon._codegen(state)
@add_slots
@dataclass(frozen=True)
class AnnAssign(BaseSmallStatement):
"""
An assignment statement such as ``x: int = 5`` or ``x: int``. This only
allows for one assignment target unlike :class:`Assign` but it includes
a variable annotation. Also unlike :class:`Assign`, the assignment target
is optional, as it is possible to annotate an expression without assigning
to it.
"""
#: The target that is being annotated and possibly assigned to.
target: BaseExpression
#: The annotation for the target.
annotation: Annotation
#: The optional expression being assigned to the target.
value: Optional[BaseExpression] = None
#: The equals sign used to denote assignment if there is a value.
equal: Union[AssignEqual, MaybeSentinel] = MaybeSentinel.DEFAULT
#: Optional semicolon when this is used in a statement line. This semicolon
#: owns the whitespace on both sides of it when it is used.
semicolon: Union[Semicolon, MaybeSentinel] = MaybeSentinel.DEFAULT
def _validate(self) -> None:
if self.value is None and isinstance(self.equal, AssignEqual):
)
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "ComparisonTarget":
return ComparisonTarget(
operator=visit_required(self, "operator", self.operator, visitor),
comparator=visit_required(self, "comparator", self.comparator, visitor),
)
def _codegen_impl(self, state: CodegenState) -> None:
self.operator._codegen(state)
self.comparator._codegen(state)
@add_slots
@dataclass(frozen=True)
class Comparison(BaseExpression):
"""
A comparison between multiple values such as ``x < y``, ``x < y < z``, or
``x in [y, z]``. These comparisions typically result in boolean values.
Unlike :class:`BinaryOperation` and :class:`BooleanOperation`, comparisons are not
restricted to a left and right child. Instead they can contain an arbitrary number
of :class:`ComparisonTarget` children.
``x < y < z`` is not equivalent to ``(x < y) < z`` or ``x < (y < z)``. Instead,
it's roughly equivalent to ``x < y and y < z``.
For more details, see `Python's documentation on comparisons
`_.
::
lpar=visit_sequence(self, "lpar", self.lpar, visitor),
value=self.value,
rpar=visit_sequence(self, "rpar", self.rpar, visitor),
)
def _validate(self) -> None:
super(Imaginary, self)._validate()
if not re.fullmatch(IMAGNUMBER_RE, self.value):
raise CSTValidationError("Number is not a valid imaginary.")
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
state.add_token(self.value)
class BaseString(BaseExpression, ABC):
"""
A type that can be used anywhere that you need to take any string. This includes
:class:`SimpleString`, :class:`ConcatenatedString`, and :class:`FormattedString`.
"""
pass
class _BasePrefixedString(BaseString, ABC):
@abstractmethod
def _get_prefix(self) -> str:
...
def _safe_to_use_with_word_operator(self, position: ExpressionPosition) -> bool:
"""
``"a"in"abc`` is okay, but if you add a prefix, (e.g. ``b"a"inb"abc"``), the string
TYPED_FUNCTION_RETURN_MAPPING: TypingDict[Type[CSTNode], object] = {
Add: BaseBinaryOp,
AddAssign: BaseAugOp,
And: BaseBooleanOp,
AnnAssign: Union[BaseSmallStatement, RemovalSentinel],
Annotation: Annotation,
Arg: Union[Arg, RemovalSentinel],
AsName: AsName,
Assert: Union[BaseSmallStatement, RemovalSentinel],
Assign: Union[BaseSmallStatement, RemovalSentinel],
AssignEqual: Union[AssignEqual, MaybeSentinel],
AssignTarget: Union[AssignTarget, RemovalSentinel],
Asynchronous: Asynchronous,
Attribute: BaseExpression,
AugAssign: Union[BaseSmallStatement, RemovalSentinel],
Await: BaseExpression,
BinaryOperation: BaseExpression,
BitAnd: BaseBinaryOp,
BitAndAssign: BaseAugOp,
BitInvert: BaseUnaryOp,
BitOr: BaseBinaryOp,
BitOrAssign: BaseAugOp,
BitXor: BaseBinaryOp,
BitXorAssign: BaseAugOp,
BooleanOperation: BaseExpression,
Break: Union[BaseSmallStatement, RemovalSentinel],
Call: BaseExpression,
ClassDef: Union[BaseStatement, RemovalSentinel],
Colon: Union[Colon, MaybeSentinel],
Comma: Union[Comma, MaybeSentinel],
self.name._codegen(state)
@add_slots
@dataclass(frozen=True)
class ExceptHandler(CSTNode):
"""
An ``except`` clause that appears optionally after a :class:`Try` statement.
"""
#: The body of the except.
body: BaseSuite
#: The type of exception this catches. Can be a tuple in some cases,
#: or ``None`` if the code is catching all exceptions.
type: Optional[BaseExpression] = None
#: The optional name that a caught exception is assigned to.
name: Optional[AsName] = None
#: Sequence of empty lines appearing before this compound statement line.
leading_lines: Sequence[EmptyLine] = ()
#: The whitespace between the ``except`` keyword and the type attribute.
whitespace_after_except: SimpleWhitespace = SimpleWhitespace.field(" ")
#: The whitespace after any type or name node (whichever comes last) and
#: the colon.
whitespace_before_colon: SimpleWhitespace = SimpleWhitespace.field("")
def _validate(self) -> None:
name = self.name
equal = self.equal
if equal is MaybeSentinel.DEFAULT and self.keyword is not None:
state.add_token(" = ")
elif isinstance(equal, AssignEqual):
equal._codegen(state)
self.value._codegen(state)
comma = self.comma
if comma is MaybeSentinel.DEFAULT and default_comma:
state.add_token(", ")
elif isinstance(comma, Comma):
comma._codegen(state)
self.whitespace_after_arg._codegen(state)
class _BaseExpressionWithArgs(BaseExpression, ABC):
"""
Arguments are complicated enough that we can't represent them easily
in typing. So, we have common validation functions here.
"""
#: Sequence of arguments that will be passed to the function call.
args: Sequence[Arg] = ()
def _check_kwargs_or_keywords(
self, arg: Arg
) -> Optional[Callable[[Arg], Callable]]:
"""
Validates that we only have a mix of "keyword=arg" and "**arg" expansion.
"""
if arg.keyword is not None:
def _codegen_impl(self, state: CodegenState, default_space: str = "") -> None:
whitespace_before_from = self.whitespace_before_from
if isinstance(whitespace_before_from, BaseParenthesizableWhitespace):
whitespace_before_from._codegen(state)
else:
state.add_token(default_space)
with state.record_syntactic_position(self):
state.add_token("from")
self.whitespace_after_from._codegen(state)
self.item._codegen(state)
@add_slots
@dataclass(frozen=True)
class Yield(BaseExpression):
"""
A yield expression similar to ``yield x`` or ``yield from fun()``.
To learn more about the ways that yield can be used in generators, refer to
`Python's language reference
`__.
"""
#: The value yielded from the generator, in the case of a :class:`From` clause, a
#: sub-generator to iterate over.
value: Optional[Union[BaseExpression, From]] = None
lpar: Sequence[LeftParen] = ()
#: Sequence of parenthesis for precedence dictation.
rpar: Sequence[RightParen] = ()
lpar=visit_sequence(self, "lpar", self.lpar, visitor),
left=visit_required(self, "left", self.left, visitor),
comparisons=visit_sequence(self, "comparisons", self.comparisons, visitor),
rpar=visit_sequence(self, "rpar", self.rpar, visitor),
)
def _codegen_impl(self, state: CodegenState) -> None:
with self._parenthesize(state):
self.left._codegen(state)
for comp in self.comparisons:
comp._codegen(state)
@add_slots
@dataclass(frozen=True)
class UnaryOperation(BaseExpression):
"""
Any generic unary expression, such as ``not x`` or ``-x``. :class:`UnaryOperation`
nodes apply a :class:`BaseUnaryOp` to an expression.
"""
#: The unary operator that applies some operation (e.g. negation) to the
#: ``expression``.
operator: BaseUnaryOp
#: The expression that should be transformed (e.g. negated) by the operator to
#: create a new value.
expression: BaseExpression
lpar: Sequence[LeftParen] = ()
#: Sequence of parenthesis for precedence dictation.
rpar: Sequence[RightParen] = ()