Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
name=visit_required(self, "name", self.name, visitor),
whitespace_after_as=visit_required(
self, "whitespace_after_as", self.whitespace_after_as, visitor
),
)
def _codegen_impl(self, state: CodegenState) -> None:
self.whitespace_before_as._codegen(state)
state.add_token("as")
self.whitespace_after_as._codegen(state)
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] = ()
state.add_token("yield")
whitespace_after_yield = self.whitespace_after_yield
if isinstance(whitespace_after_yield, BaseParenthesizableWhitespace):
whitespace_after_yield._codegen(state)
else:
# Only need a space after yield if there is a value to yield.
if self.value is not None:
state.add_token(" ")
value = self.value
if isinstance(value, From):
value._codegen(state, default_space="")
elif value is not None:
value._codegen(state)
class _BaseElementImpl(CSTNode, ABC):
"""
An internal base class for :class:`Element` and :class:`DictElement`.
"""
value: BaseExpression
comma: Union[Comma, MaybeSentinel] = MaybeSentinel.DEFAULT
def _codegen_comma(
self,
state: CodegenState,
default_comma: bool = False,
default_comma_whitespace: bool = False, # False for a single-item collection
) -> None:
"""
Called by `_codegen_impl` in subclasses to generate the comma.
"""
"""
#: The comment itself. Valid values start with the pound (``#``) character followed
#: by zero or more non-newline characters. Comments cannot include newlines.
value: str
def _validate(self) -> None:
if COMMENT_RE.fullmatch(self.value) is None:
raise CSTValidationError(
f"Got non-comment value for comment node: {repr(self.value)}"
)
@add_slots
@dataclass(frozen=True)
class TrailingWhitespace(CSTNode):
"""
The whitespace at the end of a line after a statement. If a line contains only
whitespace, :class:`EmptyLine` should be used instead.
"""
#: Any simple whitespace before any comment or newline.
whitespace: SimpleWhitespace = SimpleWhitespace.field("")
#: An optional comment appearing after any simple whitespace.
comment: Optional[Comment] = None
#: The newline character that terminates this trailing whitespace.
newline: Newline = Newline.field()
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "TrailingWhitespace":
return TrailingWhitespace(
for i, arg in enumerate(args):
arg._codegen(state, default_comma=(i != last_arg))
rpar = self.rpar
if isinstance(rpar, MaybeSentinel):
if self.bases or self.keywords:
state.add_token(")")
elif isinstance(rpar, RightParen):
rpar._codegen(state)
self.whitespace_before_colon._codegen(state)
state.add_token(":")
self.body._codegen(state)
@add_slots
@dataclass(frozen=True)
class WithItem(CSTNode):
"""
A single context manager in a :class:`With` block, with an optional variable name.
"""
#: Expression that evaluates to a context manager.
item: BaseExpression
#: Variable to assign the context manager to, if it is needed in the
#: :class:`With` body.
asname: Optional[AsName] = None
#: This is forbidden for the last :class:`WithItem` in a :class:`With`, but all
#: other items inside a with block must contain a comma to separate them.
comma: Union[Comma, MaybeSentinel] = MaybeSentinel.DEFAULT
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "WithItem":
and not isinstance(self.params.star_arg, Param)
and len(self.params.kwonly_params) == 0
and self.params.star_kwarg is None
):
# We have one or more params, provide a space
state.add_token(" ")
elif isinstance(whitespace_after_lambda, BaseParenthesizableWhitespace):
whitespace_after_lambda._codegen(state)
self.params._codegen(state)
self.colon._codegen(state)
self.body._codegen(state)
@add_slots
@dataclass(frozen=True)
class Arg(CSTNode):
"""
A single argument to a :class:`Call`.
This supports named keyword arguments in the form of ``keyword=value`` and variable
argument expansion using ``*args`` or ``**kwargs`` syntax.
"""
#: The argument expression itself, not including a preceding keyword, or any of
#: the surrounding the value, like a comma or asterisks.
value: BaseExpression
#: Optional keyword for the argument.
keyword: Optional[Name] = None
#: The equals sign used to denote assignment if there is a keyword.
equal: Union[AssignEqual, MaybeSentinel] = MaybeSentinel.DEFAULT
def deep_equals(a: object, b: object) -> bool:
if isinstance(a, CSTNode) and isinstance(b, CSTNode):
return _deep_equals_cst_node(a, b)
elif (
isinstance(a, Sequence)
and not isinstance(a, (str, bytes))
and isinstance(b, Sequence)
and not isinstance(b, (str, bytes))
):
return _deep_equals_sequence(a, b)
else:
return a == b
def __init__(self) -> None:
self.children: List[CSTNode] = []
with state.record_syntactic_position(self):
self.target._codegen(state)
self.operator._codegen(state)
self.value._codegen(state)
semicolon = self.semicolon
if isinstance(semicolon, MaybeSentinel):
if default_semicolon:
state.add_token("; ")
elif isinstance(semicolon, Semicolon):
semicolon._codegen(state)
@add_slots
@dataclass(frozen=True)
class Decorator(CSTNode):
"""
A single decorator that decorates a :class:`FunctionDef` or a :class:`ClassDef`.
"""
#: The decorator that will return a new function wrapping the parent
#: of this decorator.
decorator: Union[Name, Attribute, Call]
#: Line comments and empty lines before this decorator. The parent
#: :class:`FunctionDef` or :class:`ClassDef` node owns leading lines before
#: the first decorator so that if the first decorator is removed, spacing is preserved.
leading_lines: Sequence[EmptyLine] = ()
#: Whitespace after the ``@`` and before the decorator expression itself.
whitespace_after_at: SimpleWhitespace = SimpleWhitespace.field("")
Colon,
Comma,
Dot,
In,
Is,
IsNot,
Not,
NotIn,
)
from libcst._nodes.whitespace import BaseParenthesizableWhitespace, SimpleWhitespace
from libcst._visitors import CSTVisitorT
@add_slots
@dataclass(frozen=True)
class LeftSquareBracket(CSTNode):
"""
Used by various nodes to denote a subscript or list section. This doesn't own
the whitespace to the left of it since this is owned by the parent node.
"""
#: Any space that appears directly after this left square bracket.
whitespace_after: BaseParenthesizableWhitespace = SimpleWhitespace.field("")
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "LeftSquareBracket":
return LeftSquareBracket(
whitespace_after=visit_required(
self, "whitespace_after", self.whitespace_after, visitor
)
)
def _codegen_impl(self, state: CodegenState) -> None:
state.add_token("except")
self.whitespace_after_except._codegen(state)
typenode = self.type
if typenode is not None:
typenode._codegen(state)
namenode = self.name
if namenode is not None:
namenode._codegen(state)
self.whitespace_before_colon._codegen(state)
state.add_token(":")
self.body._codegen(state)
@add_slots
@dataclass(frozen=True)
class Finally(CSTNode):
"""
A ``finally`` clause that appears optionally after a :class:`Try` statement.
"""
#: The body of the except.
body: BaseSuite
#: Sequence of empty lines appearing before this compound statement line.
leading_lines: Sequence[EmptyLine] = ()
#: The whitespace that appears after the ``finally`` keyword but before
#: the colon.
whitespace_before_colon: SimpleWhitespace = SimpleWhitespace.field("")
def _visit_and_replace_children(self, visitor: CSTVisitorT) -> "Finally":
return Finally(