diff options
author | Claudiu Popa <pcmanticore@gmail.com> | 2020-03-06 09:30:30 +0100 |
---|---|---|
committer | Claudiu Popa <pcmanticore@gmail.com> | 2020-03-06 09:30:30 +0100 |
commit | 0ef2a0cf7b87090c247d653abb014d9d7f5f564c (patch) | |
tree | 9dd076325d1d5dbe652f8f9e643d2b55ff37cd10 | |
parent | aaef3665b6dfbd7f46f2dac905d1c2efb3db3f97 (diff) | |
download | astroid-git-0ef2a0cf7b87090c247d653abb014d9d7f5f564c.tar.gz |
Merge AsStringVisitor3 into AsStringVisitor since we no longer support Python 2
-rw-r--r-- | astroid/as_string.py | 181 |
1 files changed, 71 insertions, 110 deletions
diff --git a/astroid/as_string.py b/astroid/as_string.py index 6b20f46c..84038ba3 100644 --- a/astroid/as_string.py +++ b/astroid/as_string.py @@ -80,6 +80,15 @@ class AsStringVisitor: ## visit_<node> methods ########################################### + def visit_await(self, node): + return "await %s" % node.value.accept(self) + + def visit_asyncwith(self, node): + return "async %s" % self.visit_with(node) + + def visit_asyncfor(self, node): + return "async %s" % self.visit_for(node) + def visit_arguments(self, node): """return an astroid.Function node as string""" return node.format_args() @@ -180,11 +189,12 @@ class AsStringVisitor: def visit_comprehension(self, node): """return an astroid.Comprehension node as string""" ifs = "".join(" if %s" % n.accept(self) for n in node.ifs) - return "for %s in %s%s" % ( + generated = "for %s in %s%s" % ( node.target.accept(self), node.iter.accept(self), ifs, ) + return "%s%s" % ("async " if node.is_async else "", generated) def visit_const(self, node): """return an astroid.Const node as string""" @@ -248,7 +258,7 @@ class AsStringVisitor: def visit_excepthandler(self, node): if node.type: if node.name: - excs = "except %s, %s" % ( + excs = "except %s as %s" % ( node.type.accept(self), node.name.accept(self), ) @@ -300,6 +310,41 @@ class AsStringVisitor: _import_string(node.names), ) + def visit_joinedstr(self, node): + string = "".join( + # Use repr on the string literal parts + # to get proper escapes, e.g. \n, \\, \" + # But strip the quotes off the ends + # (they will always be one character: ' or ") + repr(value.value)[1:-1] + # Literal braces must be doubled to escape them + .replace("{", "{{").replace("}", "}}") + # Each value in values is either a string literal (Const) + # or a FormattedValue + if type(value).__name__ == "Const" else value.accept(self) + for value in node.values + ) + + # Try to find surrounding quotes that don't appear at all in the string. + # Because the formatted values inside {} can't contain backslash (\) + # using a triple quote is sometimes necessary + for quote in ["'", '"', '"""', "'''"]: + if quote not in string: + break + + return "f" + quote + string + quote + + def visit_formattedvalue(self, node): + result = node.value.accept(self) + if node.conversion and node.conversion >= 0: + # e.g. if node.conversion == 114: result += "!r" + result += "!" + chr(node.conversion) + if node.format_spec: + # The format spec is itself a JoinedString, i.e. an f-string + # We strip the f and quotes of the ends + result += ":" + node.format_spec.accept(self)[2:-1] + return "{%s}" % result + def handle_functiondef(self, node, keyword): """return a (possibly async) function definition node as string""" decorate = node.decorators.accept(self) if node.decorators else "" @@ -401,6 +446,16 @@ class AsStringVisitor: """return an astroid.Name node as string""" return node.name + def visit_namedexpr(self, node): + """Return an assignment expression node as string""" + target = node.target.accept(self) + value = node.value.accept(self) + return "%s := %s" % (target, value) + + def visit_nonlocal(self, node): + """return an astroid.Nonlocal node as string""" + return "nonlocal %s" % ", ".join(node.names) + def visit_pass(self, node): """return an astroid.Pass node as string""" return "pass" @@ -417,14 +472,11 @@ class AsStringVisitor: def visit_raise(self, node): """return an astroid.Raise node as string""" if node.exc: - if node.inst: - if node.tback: - return "raise %s, %s, %s" % ( - node.exc.accept(self), - node.inst.accept(self), - node.tback.accept(self), - ) - return "raise %s, %s" % (node.exc.accept(self), node.inst.accept(self)) + if node.cause: + return "raise %s from %s" % ( + node.exc.accept(self), + node.cause.accept(self), + ) return "raise %s" % node.exc.accept(self) return "raise" @@ -529,6 +581,15 @@ class AsStringVisitor: return "(%s)" % (expr,) + def visit_yieldfrom(self, node): + """ Return an astroid.YieldFrom node as string. """ + yi_val = (" " + node.value.accept(self)) if node.value else "" + expr = "yield from" + yi_val + if node.parent.is_statement: + return expr + + return "(%s)" % (expr,) + def visit_starred(self, node): """return Starred node as string""" return "*" + node.value.accept(self) @@ -548,104 +609,6 @@ class AsStringVisitor: return node.function.accept(self) -class AsStringVisitor3(AsStringVisitor): - """AsStringVisitor3 overwrites some AsStringVisitor methods""" - - def visit_excepthandler(self, node): - if node.type: - if node.name: - excs = "except %s as %s" % ( - node.type.accept(self), - node.name.accept(self), - ) - else: - excs = "except %s" % node.type.accept(self) - else: - excs = "except" - return "%s:\n%s" % (excs, self._stmt_list(node.body)) - - def visit_nonlocal(self, node): - """return an astroid.Nonlocal node as string""" - return "nonlocal %s" % ", ".join(node.names) - - def visit_raise(self, node): - """return an astroid.Raise node as string""" - if node.exc: - if node.cause: - return "raise %s from %s" % ( - node.exc.accept(self), - node.cause.accept(self), - ) - return "raise %s" % node.exc.accept(self) - return "raise" - - def visit_yieldfrom(self, node): - """ Return an astroid.YieldFrom node as string. """ - yi_val = (" " + node.value.accept(self)) if node.value else "" - expr = "yield from" + yi_val - if node.parent.is_statement: - return expr - - return "(%s)" % (expr,) - - def visit_await(self, node): - return "await %s" % node.value.accept(self) - - def visit_asyncwith(self, node): - return "async %s" % self.visit_with(node) - - def visit_asyncfor(self, node): - return "async %s" % self.visit_for(node) - - def visit_joinedstr(self, node): - string = "".join( - # Use repr on the string literal parts - # to get proper escapes, e.g. \n, \\, \" - # But strip the quotes off the ends - # (they will always be one character: ' or ") - repr(value.value)[1:-1] - # Literal braces must be doubled to escape them - .replace("{", "{{").replace("}", "}}") - # Each value in values is either a string literal (Const) - # or a FormattedValue - if type(value).__name__ == "Const" else value.accept(self) - for value in node.values - ) - - # Try to find surrounding quotes that don't appear at all in the string. - # Because the formatted values inside {} can't contain backslash (\) - # using a triple quote is sometimes necessary - for quote in ["'", '"', '"""', "'''"]: - if quote not in string: - break - - return "f" + quote + string + quote - - def visit_formattedvalue(self, node): - result = node.value.accept(self) - if node.conversion and node.conversion >= 0: - # e.g. if node.conversion == 114: result += "!r" - result += "!" + chr(node.conversion) - if node.format_spec: - # The format spec is itself a JoinedString, i.e. an f-string - # We strip the f and quotes of the ends - result += ":" + node.format_spec.accept(self)[2:-1] - return "{%s}" % result - - def visit_comprehension(self, node): - """return an astroid.Comprehension node as string""" - return "%s%s" % ( - "async " if node.is_async else "", - super(AsStringVisitor3, self).visit_comprehension(node), - ) - - def visit_namedexpr(self, node): - """Return an assignment expression node as string""" - target = node.target.accept(self) - value = node.value.accept(self) - return "%s := %s" % (target, value) - - def _import_string(names): """return a list of (name, asname) formatted as a string""" _names = [] @@ -657,7 +620,5 @@ def _import_string(names): return ", ".join(_names) -AsStringVisitor = AsStringVisitor3 - # This sets the default indent to 4 spaces. to_code = AsStringVisitor(" ") |