Format bytes string (#6166)

<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

## Summary

Format bytes string

Closes #6064

## Test Plan

Added a fixture based on string's one
This commit is contained in:
Luc Khai Hai 2023-07-31 17:46:40 +09:00 committed by GitHub
parent de898c52eb
commit b95fc6d162
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 577 additions and 89 deletions

View file

@ -0,0 +1,8 @@
[
{
"quote_style": "double"
},
{
"quote_style": "single"
}
]

View file

@ -0,0 +1,120 @@
b"' test"
b'" test'
b"\" test"
b'\' test'
# Prefer single quotes for string with more double quotes
b"' \" \" '' \" \" '"
# Prefer double quotes for string with more single quotes
b'\' " " \'\' " " \''
# Prefer double quotes for string with equal amount of single and double quotes
b'" \' " " \'\''
b"' \" '' \" \""
b"\\' \"\""
b'\\\' ""'
b"Test"
B"Test"
rb"Test"
Rb"Test"
b'This string will not include \
backslashes or newline characters.'
if True:
b'This string will not include \
backslashes or newline characters.'
b"""Multiline
String \"
"""
b'''Multiline
String \'
'''
b'''Multiline
String ""
'''
b'''Multiline
String """
'''
b'''Multiline
String "'''
b"""Multiline
String '''
"""
b"""Multiline
String '"""
b'''Multiline
String \"\"\"
'''
# String continuation
b"Let's" b"start" b"with" b"a" b"simple" b"example"
b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident"
(
b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident"
)
if (
a + b"Let's"
b"start"
b"with"
b"a"
b"simple"
b"example"
b"now repeat after me:"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
):
pass
if b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident":
pass
(
# leading
b"a" # trailing part comment
# leading part comment
b"b" # trailing second part comment
# trailing
)
test_particular = [
# squares
b'1.00000000100000000025',
b'1.0000000000000000000000000100000000000000000000000' #...
b'00025',
b'1.0000000000000000000000000000000000000000000010000' #...
b'0000000000000000000000000000000000000000025',
]
# Parenthesized string continuation with messed up indentation
{
"key": (
[],
b'a'
b'b'
b'c'
)
}

View file

@ -9,7 +9,7 @@ use crate::expression::number::{FormatComplex, FormatFloat, FormatInt};
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses}; use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
use crate::expression::string::{FormatString, StringLayout, StringPrefix, StringQuotes}; use crate::expression::string::{FormatString, StringLayout, StringPrefix, StringQuotes};
use crate::prelude::*; use crate::prelude::*;
use crate::{not_yet_implemented_custom_text, FormatNodeRule}; use crate::FormatNodeRule;
#[derive(Default)] #[derive(Default)]
pub struct FormatExprConstant { pub struct FormatExprConstant {
@ -51,16 +51,13 @@ impl FormatNodeRule<ExprConstant> for FormatExprConstant {
Constant::Int(_) => FormatInt::new(item).fmt(f), Constant::Int(_) => FormatInt::new(item).fmt(f),
Constant::Float(_) => FormatFloat::new(item).fmt(f), Constant::Float(_) => FormatFloat::new(item).fmt(f),
Constant::Complex { .. } => FormatComplex::new(item).fmt(f), Constant::Complex { .. } => FormatComplex::new(item).fmt(f),
Constant::Str(_) => { Constant::Str(_) | Constant::Bytes(_) => {
let string_layout = match self.layout { let string_layout = match self.layout {
ExprConstantLayout::Default => StringLayout::Default, ExprConstantLayout::Default => StringLayout::Default,
ExprConstantLayout::String(layout) => layout, ExprConstantLayout::String(layout) => layout,
}; };
FormatString::new(item).with_layout(string_layout).fmt(f) FormatString::new(item).with_layout(string_layout).fmt(f)
} }
Constant::Bytes(_) => {
not_yet_implemented_custom_text(r#"b"NOT_YET_IMPLEMENTED_BYTE_STRING""#).fmt(f)
}
} }
} }
@ -79,7 +76,7 @@ impl NeedsParentheses for ExprConstant {
_parent: AnyNodeRef, _parent: AnyNodeRef,
context: &PyFormatContext, context: &PyFormatContext,
) -> OptionalParentheses { ) -> OptionalParentheses {
if self.value.is_str() { if self.value.is_str() || self.value.is_bytes() {
let contents = context.locator().slice(self.range()); let contents = context.locator().slice(self.range());
// Don't wrap triple quoted strings // Don't wrap triple quoted strings
if is_multiline_string(self, context.source()) || !is_implicit_concatenation(contents) { if is_multiline_string(self, context.source()) || !is_implicit_concatenation(contents) {
@ -94,7 +91,7 @@ impl NeedsParentheses for ExprConstant {
} }
pub(super) fn is_multiline_string(constant: &ExprConstant, source: &str) -> bool { pub(super) fn is_multiline_string(constant: &ExprConstant, source: &str) -> bool {
if constant.value.is_str() { if constant.value.is_str() || constant.value.is_bytes() {
let contents = &source[constant.range()]; let contents = &source[constant.range()];
let prefix = StringPrefix::parse(contents); let prefix = StringPrefix::parse(contents);
let quotes = let quotes =

View file

@ -31,7 +31,7 @@ pub enum StringLayout {
impl<'a> FormatString<'a> { impl<'a> FormatString<'a> {
pub(super) fn new(constant: &'a ExprConstant) -> Self { pub(super) fn new(constant: &'a ExprConstant) -> Self {
debug_assert!(constant.value.is_str()); debug_assert!(constant.value.is_str() || constant.value.is_bytes());
Self { Self {
constant, constant,
layout: StringLayout::Default, layout: StringLayout::Default,
@ -70,7 +70,7 @@ struct FormatStringContinuation<'a> {
impl<'a> FormatStringContinuation<'a> { impl<'a> FormatStringContinuation<'a> {
fn new(constant: &'a ExprConstant) -> Self { fn new(constant: &'a ExprConstant) -> Self {
debug_assert!(constant.value.is_str()); debug_assert!(constant.value.is_str() || constant.value.is_bytes());
Self { constant } Self { constant }
} }
} }

View file

@ -191,15 +191,6 @@ instruction()#comment with bad spacing
) )
# Please keep __all__ alphabetized within each category. # Please keep __all__ alphabetized within each category.
@@ -45,7 +45,7 @@
# user-defined types and objects
Cheese,
Cheese("Wensleydale"),
- SubBytes(b"spam"),
+ SubBytes(b"NOT_YET_IMPLEMENTED_BYTE_STRING"),
]
if "PYTHON" in os.environ:
@@ -60,8 +60,12 @@ @@ -60,8 +60,12 @@
# Comment before function. # Comment before function.
def inline_comments_in_brackets_ruin_everything(): def inline_comments_in_brackets_ruin_everything():
@ -314,7 +305,7 @@ not_shareables = [
# user-defined types and objects # user-defined types and objects
Cheese, Cheese,
Cheese("Wensleydale"), Cheese("Wensleydale"),
SubBytes(b"NOT_YET_IMPLEMENTED_BYTE_STRING"), SubBytes(b"spam"),
] ]
if "PYTHON" in os.environ: if "PYTHON" in os.environ:

View file

@ -266,14 +266,6 @@ last_call()
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,6 +1,6 @@
...
"some_string"
-b"\\xa3"
+b"NOT_YET_IMPLEMENTED_BYTE_STRING"
Name
None
True
@@ -31,7 +31,7 @@ @@ -31,7 +31,7 @@
-1 -1
~int and not v1 ^ 123 + v2 | True ~int and not v1 ^ 123 + v2 | True
@ -299,22 +291,7 @@ last_call()
1 if True else 2 1 if True else 2
str or None if True else str or bytes or None str or None if True else str or bytes or None
(str or None) if True else (str or bytes or None) (str or None) if True else (str or bytes or None)
@@ -57,7 +58,13 @@ @@ -115,7 +116,7 @@
{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
{**a, **b, **c}
{"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")}
-({"a": "b"}, (True or False), (+value), "string", b"bytes") or None
+(
+ {"a": "b"},
+ (True or False),
+ (+value),
+ "string",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+) or None
()
(1,)
(1, 2)
@@ -115,7 +122,7 @@
arg, arg,
another, another,
kwarg="hey", kwarg="hey",
@ -323,11 +300,10 @@ last_call()
) # note: no trailing comma pre-3.6 ) # note: no trailing comma pre-3.6
call(*gidgets[:2]) call(*gidgets[:2])
call(a, *gidgets[:2]) call(a, *gidgets[:2])
@@ -207,25 +214,15 @@ @@ -208,24 +209,14 @@
)
what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set( what_is_up_with_those_new_coord_names = (coord_names | set(vars_to_create)) - set(
vars_to_remove vars_to_remove
-) )
-result = ( -result = (
- session.query(models.Customer.id) - session.query(models.Customer.id)
- .filter( - .filter(
@ -335,7 +311,7 @@ last_call()
- ) - )
- .order_by(models.Customer.id.asc()) - .order_by(models.Customer.id.asc())
- .all() - .all()
) -)
-result = ( -result = (
- session.query(models.Customer.id) - session.query(models.Customer.id)
- .filter( - .filter(
@ -357,7 +333,7 @@ last_call()
Ø = set() Ø = set()
authors.łukasz.say_thanks() authors.łukasz.say_thanks()
mapping = { mapping = {
@@ -328,13 +325,18 @@ @@ -328,13 +319,18 @@
): ):
return True return True
if ( if (
@ -379,7 +355,7 @@ last_call()
^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n ^ aaaaaaaa.i << aaaaaaaa.k >> aaaaaaaa.l**aaaaaaaa.m // aaaaaaaa.n
): ):
return True return True
@@ -342,7 +344,8 @@ @@ -342,7 +338,8 @@
~aaaaaaaaaaaaaaaa.a ~aaaaaaaaaaaaaaaa.a
+ aaaaaaaaaaaaaaaa.b + aaaaaaaaaaaaaaaa.b
- aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e - aaaaaaaaaaaaaaaa.c * aaaaaaaaaaaaaaaa.d @ aaaaaaaaaaaaaaaa.e
@ -396,7 +372,7 @@ last_call()
```py ```py
... ...
"some_string" "some_string"
b"NOT_YET_IMPLEMENTED_BYTE_STRING" b"\\xa3"
Name Name
None None
True True
@ -454,13 +430,7 @@ str or None if (1 if True else 2) else str or bytes or None
{"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}} {"2.7": dead, "3.7": (long_live or die_hard), **{"3.6": verygood}}
{**a, **b, **c} {**a, **b, **c}
{"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")} {"2.7", "3.6", "3.7", "3.8", "3.9", ("4.0" if gilectomy else "3.10")}
( ({"a": "b"}, (True or False), (+value), "string", b"bytes") or None
{"a": "b"},
(True or False),
(+value),
"string",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
) or None
() ()
(1,) (1,)
(1, 2) (1, 2)

View file

@ -32,19 +32,17 @@ def docstring_multiline():
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -1,13 +1,31 @@ @@ -1,12 +1,21 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
name = "Łukasz" name = "Łukasz"
-(f"hello {name}", f"hello {name}") -(f"hello {name}", f"hello {name}")
-(b"", b"")
+(f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr") +(f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr")
+(b"NOT_YET_IMPLEMENTED_BYTE_STRING", b"NOT_YET_IMPLEMENTED_BYTE_STRING") (b"", b"")
("", "") ("", "")
(r"", R"") (r"", R"")
-(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"") -(rf"", rf"", Rf"", Rf"", rf"", rf"", Rf"", Rf"")
-(rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
+( +(
+ f"NOT_YET_IMPLEMENTED_ExprJoinedStr", + f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
+ f"NOT_YET_IMPLEMENTED_ExprJoinedStr", + f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
@ -55,19 +53,9 @@ def docstring_multiline():
+ f"NOT_YET_IMPLEMENTED_ExprJoinedStr", + f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
+ f"NOT_YET_IMPLEMENTED_ExprJoinedStr", + f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
+) +)
+( (rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+ b"NOT_YET_IMPLEMENTED_BYTE_STRING",
+)
def docstring_singleline():
``` ```
## Ruff Output ## Ruff Output
@ -77,7 +65,7 @@ def docstring_multiline():
name = "Łukasz" name = "Łukasz"
(f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr") (f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr")
(b"NOT_YET_IMPLEMENTED_BYTE_STRING", b"NOT_YET_IMPLEMENTED_BYTE_STRING") (b"", b"")
("", "") ("", "")
(r"", R"") (r"", R"")
@ -91,16 +79,7 @@ name = "Łukasz"
f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
f"NOT_YET_IMPLEMENTED_ExprJoinedStr", f"NOT_YET_IMPLEMENTED_ExprJoinedStr",
) )
( (rb"", rb"", Rb"", Rb"", rb"", rb"", Rb"", Rb"")
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
b"NOT_YET_IMPLEMENTED_BYTE_STRING",
)
def docstring_singleline(): def docstring_singleline():

View file

@ -19,7 +19,7 @@ this_will_be_wrapped_in_parens, = struct.unpack(b"12345678901234567890")
```diff ```diff
--- Black --- Black
+++ Ruff +++ Ruff
@@ -4,9 +4,9 @@ @@ -4,7 +4,7 @@
sdfjsdfjlksdljkfsdlkf, sdfjsdfjlksdljkfsdlkf,
sdfsdjfklsdfjlksdljkf, sdfsdjfklsdfjlksdljkf,
sdsfsdfjskdflsfsdf, sdsfsdfjskdflsfsdf,
@ -27,10 +27,7 @@ this_will_be_wrapped_in_parens, = struct.unpack(b"12345678901234567890")
+) = 1, 2, 3 +) = 1, 2, 3
# This is as well. # This is as well.
-(this_will_be_wrapped_in_parens,) = struct.unpack(b"12345678901234567890") (this_will_be_wrapped_in_parens,) = struct.unpack(b"12345678901234567890")
+(this_will_be_wrapped_in_parens,) = struct.unpack(b"NOT_YET_IMPLEMENTED_BYTE_STRING")
(a,) = call()
``` ```
## Ruff Output ## Ruff Output
@ -45,7 +42,7 @@ this_will_be_wrapped_in_parens, = struct.unpack(b"12345678901234567890")
) = 1, 2, 3 ) = 1, 2, 3
# This is as well. # This is as well.
(this_will_be_wrapped_in_parens,) = struct.unpack(b"NOT_YET_IMPLEMENTED_BYTE_STRING") (this_will_be_wrapped_in_parens,) = struct.unpack(b"12345678901234567890")
(a,) = call() (a,) = call()
``` ```

View file

@ -0,0 +1,426 @@
---
source: crates/ruff_python_formatter/tests/fixtures.rs
input_file: crates/ruff_python_formatter/resources/test/fixtures/ruff/expression/bytes.py
---
## Input
```py
b"' test"
b'" test'
b"\" test"
b'\' test'
# Prefer single quotes for string with more double quotes
b"' \" \" '' \" \" '"
# Prefer double quotes for string with more single quotes
b'\' " " \'\' " " \''
# Prefer double quotes for string with equal amount of single and double quotes
b'" \' " " \'\''
b"' \" '' \" \""
b"\\' \"\""
b'\\\' ""'
b"Test"
B"Test"
rb"Test"
Rb"Test"
b'This string will not include \
backslashes or newline characters.'
if True:
b'This string will not include \
backslashes or newline characters.'
b"""Multiline
String \"
"""
b'''Multiline
String \'
'''
b'''Multiline
String ""
'''
b'''Multiline
String """
'''
b'''Multiline
String "'''
b"""Multiline
String '''
"""
b"""Multiline
String '"""
b'''Multiline
String \"\"\"
'''
# String continuation
b"Let's" b"start" b"with" b"a" b"simple" b"example"
b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident"
(
b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident"
)
if (
a + b"Let's"
b"start"
b"with"
b"a"
b"simple"
b"example"
b"now repeat after me:"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
):
pass
if b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident":
pass
(
# leading
b"a" # trailing part comment
# leading part comment
b"b" # trailing second part comment
# trailing
)
test_particular = [
# squares
b'1.00000000100000000025',
b'1.0000000000000000000000000100000000000000000000000' #...
b'00025',
b'1.0000000000000000000000000000000000000000000010000' #...
b'0000000000000000000000000000000000000000025',
]
# Parenthesized string continuation with messed up indentation
{
"key": (
[],
b'a'
b'b'
b'c'
)
}
```
## Outputs
### Output 1
```
indent-style = Spaces, size: 4
line-width = 88
quote-style = Double
magic-trailing-comma = Respect
```
```py
b"' test"
b'" test'
b'" test'
b"' test"
# Prefer single quotes for string with more double quotes
b"' \" \" '' \" \" '"
# Prefer double quotes for string with more single quotes
b"' \" \" '' \" \" '"
# Prefer double quotes for string with equal amount of single and double quotes
b"\" ' \" \" ''"
b"' \" '' \" \""
b'\\\' ""'
b'\\\' ""'
b"Test"
b"Test"
rb"Test"
Rb"Test"
b"This string will not include \
backslashes or newline characters."
if True:
b"This string will not include \
backslashes or newline characters."
b"""Multiline
String \"
"""
b"""Multiline
String \'
"""
b"""Multiline
String ""
"""
b'''Multiline
String """
'''
b'''Multiline
String "'''
b"""Multiline
String '''
"""
b"""Multiline
String '"""
b"""Multiline
String \"\"\"
"""
# String continuation
b"Let's" b"start" b"with" b"a" b"simple" b"example"
b"Let's" b"start" b"with" b"a" b"simple" b"example" b"now repeat after me:" b"I am confident" b"I am confident" b"I am confident" b"I am confident" b"I am confident"
(
b"Let's"
b"start"
b"with"
b"a"
b"simple"
b"example"
b"now repeat after me:"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
)
if (
a
+ b"Let's"
b"start"
b"with"
b"a"
b"simple"
b"example"
b"now repeat after me:"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
):
pass
if (
b"Let's"
b"start"
b"with"
b"a"
b"simple"
b"example"
b"now repeat after me:"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
b"I am confident"
):
pass
(
# leading
b"a" # trailing part comment
# leading part comment
b"b" # trailing second part comment
# trailing
)
test_particular = [
# squares
b"1.00000000100000000025",
b"1.0000000000000000000000000100000000000000000000000" # ...
b"00025",
b"1.0000000000000000000000000000000000000000000010000" # ...
b"0000000000000000000000000000000000000000025",
]
# Parenthesized string continuation with messed up indentation
{"key": ([], b"a" b"b" b"c")}
```
### Output 2
```
indent-style = Spaces, size: 4
line-width = 88
quote-style = Single
magic-trailing-comma = Respect
```
```py
b"' test"
b'" test'
b'" test'
b"' test"
# Prefer single quotes for string with more double quotes
b'\' " " \'\' " " \''
# Prefer double quotes for string with more single quotes
b'\' " " \'\' " " \''
# Prefer double quotes for string with equal amount of single and double quotes
b'" \' " " \'\''
b'\' " \'\' " "'
b'\\\' ""'
b'\\\' ""'
b'Test'
b'Test'
rb'Test'
Rb'Test'
b'This string will not include \
backslashes or newline characters.'
if True:
b'This string will not include \
backslashes or newline characters.'
b'''Multiline
String \"
'''
b'''Multiline
String \'
'''
b'''Multiline
String ""
'''
b'''Multiline
String """
'''
b'''Multiline
String "'''
b"""Multiline
String '''
"""
b"""Multiline
String '"""
b'''Multiline
String \"\"\"
'''
# String continuation
b"Let's" b'start' b'with' b'a' b'simple' b'example'
b"Let's" b'start' b'with' b'a' b'simple' b'example' b'now repeat after me:' b'I am confident' b'I am confident' b'I am confident' b'I am confident' b'I am confident'
(
b"Let's"
b'start'
b'with'
b'a'
b'simple'
b'example'
b'now repeat after me:'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
)
if (
a
+ b"Let's"
b'start'
b'with'
b'a'
b'simple'
b'example'
b'now repeat after me:'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
):
pass
if (
b"Let's"
b'start'
b'with'
b'a'
b'simple'
b'example'
b'now repeat after me:'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
b'I am confident'
):
pass
(
# leading
b'a' # trailing part comment
# leading part comment
b'b' # trailing second part comment
# trailing
)
test_particular = [
# squares
b'1.00000000100000000025',
b'1.0000000000000000000000000100000000000000000000000' # ...
b'00025',
b'1.0000000000000000000000000000000000000000000010000' # ...
b'0000000000000000000000000000000000000000025',
]
# Parenthesized string continuation with messed up indentation
{'key': ([], b'a' b'b' b'c')}
```