From e7e2f44440bb9d7cc61260f66f82a20efdac8eff Mon Sep 17 00:00:00 2001 From: Louis Dispa Date: Mon, 10 Jul 2023 21:23:49 +0200 Subject: [PATCH] Format `raise` statement (#5595) ## Summary This PR implements the formatting of `raise` statements. I haven't looked at the black implementation, this is inspired from from the `return` statements formatting. ## Test Plan The black differences with insta. I also compared manually some edge cases with very long string and call chaining and it seems to do the same formatting as black. There is one issue: ```python # input raise OsError( "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" ) from a.aaaaa(aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa).a(aaaa) # black raise OsError( "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" ) from a.aaaaa( aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa ).a( aaaa ) # ruff raise OsError( "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" ) from a.aaaaa( aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa ).a(aaaa) ``` But I'm not sure this diff is the raise formatting implementation. --------- Co-authored-by: Louis Dispa --- .../test/fixtures/ruff/expression/tuple.py | 9 +- .../test/fixtures/ruff/statement/raise.py | 85 +++++++ .../ruff_python_formatter/src/comments/mod.rs | 4 +- .../src/expression/expr_tuple.rs | 31 ++- .../src/statement/stmt_raise.rs | 35 ++- ...ompatibility@py_311__pep_654_style.py.snap | 70 +----- ...mpatibility@simple_cases__fmtonoff.py.snap | 4 +- ...mpatibility@simple_cases__function.py.snap | 11 +- ...simple_cases__remove_except_parens.py.snap | 54 +---- .../format@expression__tuple.py.snap | 16 +- .../snapshots/format@statement__raise.py.snap | 220 ++++++++++++++++++ 11 files changed, 409 insertions(+), 130 deletions(-) create mode 100644 crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/raise.py create mode 100644 crates/ruff_python_formatter/tests/snapshots/format@statement__raise.py.snap diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/tuple.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/tuple.py index 517f5d39e7..13859fb27d 100644 --- a/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/tuple.py +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/tuple.py @@ -35,9 +35,16 @@ e4 = ( # Empty tuples and comments f1 = ( - # empty + # empty ) f2 = () +f3 = ( # end-of-line + # own-line +) # trailing +f4 = ( # end-of-line + # own-line + # own-line 2 +) # trailing # Comments in other tuples g1 = ( # a diff --git a/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/raise.py b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/raise.py new file mode 100644 index 0000000000..db15be22e8 --- /dev/null +++ b/crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/raise.py @@ -0,0 +1,85 @@ +raise a from aksjdhflsakhdflkjsadlfajkslhf +raise a from (aksjdhflsakhdflkjsadlfajkslhf,) +raise (aaaaa.aaa(a).a) from (aksjdhflsakhdflkjsadlfajkslhf) + +raise a from (aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,) +raise a from OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") + +# some comment +raise a from aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa # some comment +# some comment + +raise OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") from e + + +raise OsError( + # should i stay + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" # mhhh very long + # or should i go +) from e # here is e + +raise OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") from OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") + +raise OsError( + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" +) from a.aaaaa( + aaa +).a(aaaa) + +raise OsError( + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" +) from a.aaaaa(aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa).a(aaaa) + +raise aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccc + ddddddddddddddddddddddddd +raise aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + (cccccccccccccccccccccc + ddddddddddddddddddddddddd) +raise (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccc + ddddddddddddddddddddddddd) + + +raise ( # hey + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + # Holala + + bbbbbbbbbbbbbbbbbbbbbbbbbb # stay + + cccccccccccccccccccccc + ddddddddddddddddddddddddd # where I'm going + # I don't know +) # whaaaaat +# the end + +raise ( # hey 2 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + # Holala + "bbbbbbbbbbbbbbbbbbbbbbbb" # stay + "ccccccccccccccccccccccc" "dddddddddddddddddddddddd" # where I'm going + # I don't know +) # whaaaaat + +# some comment +raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbb] + +raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa < aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa = MultiMap, SourceComment>; /// The comments of a syntax tree stored by node. /// /// Cloning `comments` is cheap as it only involves bumping a reference counter. -#[derive(Clone, Default)] +#[derive(Debug, Clone, Default)] pub(crate) struct Comments<'a> { /// The implementation uses an [Rc] so that [Comments] has a lifetime independent from the [crate::Formatter]. /// Independent lifetimes are necessary to support the use case where a (formattable object)[crate::Format] @@ -400,7 +400,7 @@ impl<'a> Comments<'a> { } } -#[derive(Default)] +#[derive(Debug, Default)] struct CommentsData<'a> { comments: CommentsMap<'a>, } diff --git a/crates/ruff_python_formatter/src/expression/expr_tuple.rs b/crates/ruff_python_formatter/src/expression/expr_tuple.rs index de97a5bac9..82d716ae1d 100644 --- a/crates/ruff_python_formatter/src/expression/expr_tuple.rs +++ b/crates/ruff_python_formatter/src/expression/expr_tuple.rs @@ -1,5 +1,5 @@ use crate::builders::optional_parentheses; -use crate::comments::{dangling_node_comments, Comments}; +use crate::comments::{dangling_comments, CommentLinePosition, Comments}; use crate::expression::parentheses::{ default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses, Parenthesize, @@ -57,16 +57,33 @@ impl FormatNodeRule for FormatExprTuple { } = item; // Handle the edge cases of an empty tuple and a tuple with one element + // + // there can be dangling comments, and they can be in two + // positions: + // ```python + // a3 = ( # end-of-line + // # own line + // ) + // ``` + // In all other cases comments get assigned to a list element match elts.as_slice() { [] => { + let comments = f.context().comments().clone(); + let dangling = comments.dangling_comments(item); + let end_of_line_split = dangling.partition_point(|comment| { + comment.line_position() == CommentLinePosition::EndOfLine + }); + debug_assert!(dangling[end_of_line_split..] + .iter() + .all(|comment| comment.line_position() == CommentLinePosition::OwnLine)); write!( f, - [ - // An empty tuple always needs parentheses, but does not have a comma - &text("("), - block_indent(&dangling_node_comments(item)), - &text(")"), - ] + [group(&format_args![ + text("("), + dangling_comments(&dangling[..end_of_line_split]), + soft_block_indent(&dangling_comments(&dangling[end_of_line_split..])), + text(")") + ])] ) } [single] => { diff --git a/crates/ruff_python_formatter/src/statement/stmt_raise.rs b/crates/ruff_python_formatter/src/statement/stmt_raise.rs index 47372372a5..5159d3ab35 100644 --- a/crates/ruff_python_formatter/src/statement/stmt_raise.rs +++ b/crates/ruff_python_formatter/src/statement/stmt_raise.rs @@ -1,5 +1,8 @@ -use crate::{not_yet_implemented, FormatNodeRule, PyFormatter}; -use ruff_formatter::{write, Buffer, FormatResult}; +use crate::expression::parentheses::Parenthesize; +use crate::{AsFormat, FormatNodeRule, PyFormatter}; +use ruff_formatter::prelude::{space, text}; +use ruff_formatter::{write, Buffer, Format, FormatResult}; + use rustpython_parser::ast::StmtRaise; #[derive(Default)] @@ -7,6 +10,32 @@ pub struct FormatStmtRaise; impl FormatNodeRule for FormatStmtRaise { fn fmt_fields(&self, item: &StmtRaise, f: &mut PyFormatter) -> FormatResult<()> { - write!(f, [not_yet_implemented(item)]) + let StmtRaise { + range: _, + exc, + cause, + } = item; + + text("raise").fmt(f)?; + + if let Some(value) = exc { + write!( + f, + [space(), value.format().with_options(Parenthesize::Optional)] + )?; + } + + if let Some(value) = cause { + write!( + f, + [ + space(), + text("from"), + space(), + value.format().with_options(Parenthesize::Optional) + ] + )?; + } + Ok(()) } } diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_311__pep_654_style.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_311__pep_654_style.py.snap index 19568a1176..b0bc8e8f17 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_311__pep_654_style.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@py_311__pep_654_style.py.snap @@ -67,68 +67,22 @@ except ExceptionGroup as e: ```diff --- Black +++ Ruff -@@ -1,5 +1,5 @@ - try: -- raise OSError("blah") -+ NOT_YET_IMPLEMENTED_StmtRaise - except* ExceptionGroup as e: - pass - -@@ -14,10 +14,10 @@ - +@@ -39,7 +39,7 @@ try: try: -- raise ValueError(42) -+ NOT_YET_IMPLEMENTED_StmtRaise - except: - try: -- raise TypeError(int) -+ NOT_YET_IMPLEMENTED_StmtRaise - except* Exception: - pass - 1 / 0 -@@ -26,10 +26,10 @@ - - try: - try: -- raise FalsyEG("eg", [TypeError(1), ValueError(2)]) -+ NOT_YET_IMPLEMENTED_StmtRaise - except* TypeError as e: - tes = e -- raise -+ NOT_YET_IMPLEMENTED_StmtRaise - except* ValueError as e: - ves = e - pass -@@ -38,16 +38,16 @@ - - try: - try: -- raise orig + raise orig - except* (TypeError, ValueError, *OTHER_EXCEPTIONS) as e: -- raise SyntaxError(3) from e -+ NOT_YET_IMPLEMENTED_StmtRaise + except* (TypeError, ValueError, *NOT_YET_IMPLEMENTED_ExprStarred) as e: -+ NOT_YET_IMPLEMENTED_StmtRaise + raise SyntaxError(3) from e except BaseException as e: exc = e - - try: - try: -- raise orig -+ NOT_YET_IMPLEMENTED_StmtRaise - except* OSError as e: -- raise TypeError(3) from e -+ NOT_YET_IMPLEMENTED_StmtRaise - except ExceptionGroup as e: - exc = e ``` ## Ruff Output ```py try: - NOT_YET_IMPLEMENTED_StmtRaise + raise OSError("blah") except* ExceptionGroup as e: pass @@ -143,10 +97,10 @@ except* ValueError: try: try: - NOT_YET_IMPLEMENTED_StmtRaise + raise ValueError(42) except: try: - NOT_YET_IMPLEMENTED_StmtRaise + raise TypeError(int) except* Exception: pass 1 / 0 @@ -155,10 +109,10 @@ except Exception as e: try: try: - NOT_YET_IMPLEMENTED_StmtRaise + raise FalsyEG("eg", [TypeError(1), ValueError(2)]) except* TypeError as e: tes = e - NOT_YET_IMPLEMENTED_StmtRaise + raise except* ValueError as e: ves = e pass @@ -167,17 +121,17 @@ except Exception as e: try: try: - NOT_YET_IMPLEMENTED_StmtRaise + raise orig except* (TypeError, ValueError, *NOT_YET_IMPLEMENTED_ExprStarred) as e: - NOT_YET_IMPLEMENTED_StmtRaise + raise SyntaxError(3) from e except BaseException as e: exc = e try: try: - NOT_YET_IMPLEMENTED_StmtRaise + raise orig except* OSError as e: - NOT_YET_IMPLEMENTED_StmtRaise + raise TypeError(3) from e except ExceptionGroup as e: exc = e ``` diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap index 48167498b5..883baf2298 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__fmtonoff.py.snap @@ -227,7 +227,7 @@ d={'a':1, + b + c + if True: -+ NOT_YET_IMPLEMENTED_StmtRaise ++ raise RuntimeError + if False: + ... + for i in range(10): @@ -425,7 +425,7 @@ def func_no_args(): b c if True: - NOT_YET_IMPLEMENTED_StmtRaise + raise RuntimeError if False: ... for i in range(10): diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap index 2ccef6cead..87611ac5b9 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__function.py.snap @@ -117,15 +117,6 @@ def __await__(): return (yield) def func_no_args(): -@@ -14,7 +13,7 @@ - b - c - if True: -- raise RuntimeError -+ NOT_YET_IMPLEMENTED_StmtRaise - if False: - ... - for i in range(10): @@ -41,12 +40,12 @@ debug: bool = False, **kwargs, @@ -207,7 +198,7 @@ def func_no_args(): b c if True: - NOT_YET_IMPLEMENTED_StmtRaise + raise RuntimeError if False: ... for i in range(10): diff --git a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap index 5990c185cd..1b9f9e5d08 100644 --- a/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/black_compatibility@simple_cases__remove_except_parens.py.snap @@ -47,55 +47,17 @@ except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.ov ```diff --- Black +++ Ruff -@@ -2,7 +2,7 @@ - try: - a.something - except AttributeError as err: -- raise err -+ NOT_YET_IMPLEMENTED_StmtRaise - - # This is tuple of exceptions. - # Although this could be replaced with just the exception, -@@ -10,28 +10,26 @@ - try: - a.something - except (AttributeError,) as err: -- raise err -+ NOT_YET_IMPLEMENTED_StmtRaise - - # This is a tuple of exceptions. Do not remove brackets. - try: - a.something - except (AttributeError, ValueError) as err: -- raise err -+ NOT_YET_IMPLEMENTED_StmtRaise - +@@ -21,9 +21,7 @@ # Test long variants. try: a.something -except ( - some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error -) as err: -- raise err +except some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error as err: -+ NOT_YET_IMPLEMENTED_StmtRaise + raise err try: - a.something - except ( - some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, - ) as err: -- raise err -+ NOT_YET_IMPLEMENTED_StmtRaise - - try: - a.something -@@ -39,4 +37,4 @@ - some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, - some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, - ) as err: -- raise err -+ NOT_YET_IMPLEMENTED_StmtRaise ``` ## Ruff Output @@ -105,7 +67,7 @@ except (some.really.really.really.looooooooooooooooooooooooooooooooong.module.ov try: a.something except AttributeError as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err # This is tuple of exceptions. # Although this could be replaced with just the exception, @@ -113,26 +75,26 @@ except AttributeError as err: try: a.something except (AttributeError,) as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err # This is a tuple of exceptions. Do not remove brackets. try: a.something except (AttributeError, ValueError) as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err # Test long variants. try: a.something except some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err try: a.something except ( some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, ) as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err try: a.something @@ -140,7 +102,7 @@ except ( some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, some.really.really.really.looooooooooooooooooooooooooooooooong.module.over89.chars.Error, ) as err: - NOT_YET_IMPLEMENTED_StmtRaise + raise err ``` ## Black Output diff --git a/crates/ruff_python_formatter/tests/snapshots/format@expression__tuple.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@expression__tuple.py.snap index 39b0d747e8..e398db039b 100644 --- a/crates/ruff_python_formatter/tests/snapshots/format@expression__tuple.py.snap +++ b/crates/ruff_python_formatter/tests/snapshots/format@expression__tuple.py.snap @@ -41,9 +41,16 @@ e4 = ( # Empty tuples and comments f1 = ( - # empty + # empty ) f2 = () +f3 = ( # end-of-line + # own-line +) # trailing +f4 = ( # end-of-line + # own-line + # own-line 2 +) # trailing # Comments in other tuples g1 = ( # a @@ -232,6 +239,13 @@ f1 = ( # empty ) f2 = () +f3 = ( # end-of-line + # own-line +) # trailing +f4 = ( # end-of-line + # own-line + # own-line 2 +) # trailing # Comments in other tuples g1 = ( diff --git a/crates/ruff_python_formatter/tests/snapshots/format@statement__raise.py.snap b/crates/ruff_python_formatter/tests/snapshots/format@statement__raise.py.snap new file mode 100644 index 0000000000..d36d48fbfb --- /dev/null +++ b/crates/ruff_python_formatter/tests/snapshots/format@statement__raise.py.snap @@ -0,0 +1,220 @@ +--- +source: crates/ruff_python_formatter/tests/fixtures.rs +input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/statement/raise.py +--- +## Input +```py +raise a from aksjdhflsakhdflkjsadlfajkslhf +raise a from (aksjdhflsakhdflkjsadlfajkslhf,) +raise (aaaaa.aaa(a).a) from (aksjdhflsakhdflkjsadlfajkslhf) + +raise a from (aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa,) +raise a from OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") + +# some comment +raise a from aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa # some comment +# some comment + +raise OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") from e + + +raise OsError( + # should i stay + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" # mhhh very long + # or should i go +) from e # here is e + +raise OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") from OsError("aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa") + +raise OsError( + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" +) from a.aaaaa( + aaa +).a(aaaa) + +raise OsError( + "aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa" +) from a.aaaaa(aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa).a(aaaa) + +raise aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccc + ddddddddddddddddddddddddd +raise aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + (cccccccccccccccccccccc + ddddddddddddddddddddddddd) +raise (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbbbbbbbbbb + cccccccccccccccccccccc + ddddddddddddddddddddddddd) + + +raise ( # hey + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + # Holala + + bbbbbbbbbbbbbbbbbbbbbbbbbb # stay + + cccccccccccccccccccccc + ddddddddddddddddddddddddd # where I'm going + # I don't know +) # whaaaaat +# the end + +raise ( # hey 2 + "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + # Holala + "bbbbbbbbbbbbbbbbbbbbbbbb" # stay + "ccccccccccccccccccccccc" "dddddddddddddddddddddddd" # where I'm going + # I don't know +) # whaaaaat + +# some comment +raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa[aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:bbbbbbbbbbbbbbbbbbbbbbbbbb] + +raise aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa < aksjdhflsakhdflkjsadlfajkslhfdkjsaldajlahflashdfljahlfksajlhfajfjfsaahflakjslhdfkjalhdskjfa