From eb321aa9ec088eb4a97ef61ab1bc6a9bb10dfb03 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Mon, 27 Sep 2021 19:00:25 -0400 Subject: [PATCH 01/13] Changed dict key-matching regex to capture any valid dict key --- bpython/line.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 7ced3bf1..e8fcbc5f 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -34,7 +34,7 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: return LinePart(start, end, word) -_current_dict_key_re = LazyReCompile(r"""[\w_][\w0-9._]*\[([\w0-9._(), '"]*)""") +_current_dict_key_re = LazyReCompile(r"""[\w_][\w0-9._]*\[(.*)""") def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: @@ -45,7 +45,7 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: return None -_current_dict_re = LazyReCompile(r"""([\w_][\w0-9._]*)\[([\w0-9._(), '"]*)""") +_current_dict_re = LazyReCompile(r"""([\w_][\w0-9._]*)\[(.*)""") def current_dict(cursor_offset: int, line: str) -> Optional[LinePart]: From 3f20d8e2c27d17784b0dcdc7b740324e6ead55c0 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Tue, 28 Sep 2021 00:45:18 -0400 Subject: [PATCH 02/13] dict key matching regex no longer matches beyond the end of a key --- bpython/line.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index e8fcbc5f..7b57e2c3 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -34,7 +34,9 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: return LinePart(start, end, word) -_current_dict_key_re = LazyReCompile(r"""[\w_][\w0-9._]*\[(.*)""") +_current_dict_key_re = LazyReCompile( + r"""[\w_][\w0-9._]*\[('[^']*|"[^"]*|[\w0-9._(), '"]*)""" +) def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: @@ -45,7 +47,9 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: return None -_current_dict_re = LazyReCompile(r"""([\w_][\w0-9._]*)\[(.*)""") +_current_dict_re = LazyReCompile( + r"""([\w_][\w0-9._]*)\[('[^']*|"[^"]*|[\w0-9._(), '"]*)""" +) def current_dict(cursor_offset: int, line: str) -> Optional[LinePart]: From 97d6b19403a93bdc74792ebd3d0bf3226e9eb531 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Tue, 28 Sep 2021 22:12:34 -0400 Subject: [PATCH 03/13] Updated regex to handle str, bytes, int, float, tuple dict keys --- bpython/line.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 7b57e2c3..340a0d66 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -34,8 +34,32 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: return LinePart(start, end, word) +# pieces of regex to match repr() of several hashable built-in types +_match_identifiers_and_functions = r"""[a-zA-Z_][a-zA-Z0-9_.(),\[\] ]*""" +_match_single_quote_str_bytes = \ + r"""b?'(?:\\(?:\\\\)*['"nabfrtvxuU]|[^'\\])*(?:\\\\)*\\?'?""" +_match_double_quote_str_bytes = r"""b?"[^"]*"?""" +_match_int_and_float = r"""\-?\d+(?:\.\d*)?|\-""" +_match_str_bytes_int_float = \ + f'(?:{_match_single_quote_str_bytes}|{_match_double_quote_str_bytes}|' \ + f'{_match_int_and_float})' +_match_tuple = r"""\((?:""" \ + f'{_match_str_bytes_int_float}' \ + r""", )*(?:""" \ + f'{_match_str_bytes_int_float}' \ + r"""\,|""" \ + f'{_match_str_bytes_int_float}' \ + r""")?\)?""" + +_current_dict_key_re_base = r"""[\w_][\w0-9._]*\[""" _current_dict_key_re = LazyReCompile( - r"""[\w_][\w0-9._]*\[('[^']*|"[^"]*|[\w0-9._(), '"]*)""" + f'{_current_dict_key_re_base}(' + f'{_match_identifiers_and_functions}|' + f'{_match_single_quote_str_bytes}|' + f'{_match_double_quote_str_bytes}|' + f'{_match_int_and_float}|' + f'{_match_tuple}|' + ')' ) @@ -47,8 +71,15 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: return None +_current_dict_re_base = r"""([\w_][\w0-9._]*)\[""" _current_dict_re = LazyReCompile( - r"""([\w_][\w0-9._]*)\[('[^']*|"[^"]*|[\w0-9._(), '"]*)""" + f'{_current_dict_re_base}(' + f'{_match_identifiers_and_functions}|' + f'{_match_single_quote_str_bytes}|' + f'{_match_double_quote_str_bytes}|' + f'{_match_int_and_float}|' + f'{_match_tuple}|' + ')' ) @@ -56,6 +87,7 @@ def current_dict(cursor_offset: int, line: str) -> Optional[LinePart]: """If in dictionary completion, return the dict that should be used""" for m in _current_dict_re.finditer(line): if m.start(2) <= cursor_offset <= m.end(2): + print(LinePart(m.start(1), m.end(1), m.group(1))) # TODO return LinePart(m.start(1), m.end(1), m.group(1)) return None From 5bfd09c4f388f2ba9c7a4d8fe626802673e20bb3 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Tue, 28 Sep 2021 22:14:29 -0400 Subject: [PATCH 04/13] Added tests for regex changes in prior commit --- bpython/test/test_line_properties.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index fe1b0813..79f72441 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -178,10 +178,19 @@ def test_simple(self): self.assertAccess("asdf[<(>|]") self.assertAccess("asdf[<(1>|]") self.assertAccess("asdf[<(1,>|]") + self.assertAccess("asdf[<(1,)>|]") self.assertAccess("asdf[<(1, >|]") self.assertAccess("asdf[<(1, 2)>|]") # TODO self.assertAccess('d[d[<12|>') self.assertAccess("d[<'a>|") + self.assertAccess("object.dict['a\'bcd'], object.dict[<'abc>|") + self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|") + self.assertAccess("object.dict[<\"abc'>|") + self.assertAccess("object.dict[<(1, 'apple', 2.134>|]") + self.assertAccess("object.dict[<(1, 'apple', 2.134)>|]") + self.assertAccess("object.dict[<-1000>|") + self.assertAccess("object.dict[<-0.23948>|") + self.assertAccess("object.dict[<'\U0001ffff>|") class TestCurrentDict(LineTestCase): From e470176e27659bf708ed72112c7d4c6d1a8a51da Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Tue, 28 Sep 2021 22:27:10 -0400 Subject: [PATCH 05/13] removed erroneous print() --- bpython/line.py | 1 - 1 file changed, 1 deletion(-) diff --git a/bpython/line.py b/bpython/line.py index 340a0d66..95e1501b 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -87,7 +87,6 @@ def current_dict(cursor_offset: int, line: str) -> Optional[LinePart]: """If in dictionary completion, return the dict that should be used""" for m in _current_dict_re.finditer(line): if m.start(2) <= cursor_offset <= m.end(2): - print(LinePart(m.start(1), m.end(1), m.group(1))) # TODO return LinePart(m.start(1), m.end(1), m.group(1)) return None From 5299f2b10c363e781f514372038153a2644efa55 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Wed, 29 Sep 2021 17:51:56 -0400 Subject: [PATCH 06/13] Added comments to regex using re.VERBOSE flag --- bpython/line.py | 89 ++++++++++++++++++++++++++++++++++++------------- 1 file changed, 66 insertions(+), 23 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 95e1501b..9487ac34 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -6,6 +6,7 @@ from itertools import chain from typing import Optional, NamedTuple +import re from .lazyre import LazyReCompile @@ -35,31 +36,71 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: # pieces of regex to match repr() of several hashable built-in types -_match_identifiers_and_functions = r"""[a-zA-Z_][a-zA-Z0-9_.(),\[\] ]*""" +_match_all_dict_keys = r"""[^\]]*""" + +# https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals _match_single_quote_str_bytes = \ - r"""b?'(?:\\(?:\\\\)*['"nabfrtvxuU]|[^'\\])*(?:\\\\)*\\?'?""" -_match_double_quote_str_bytes = r"""b?"[^"]*"?""" -_match_int_and_float = r"""\-?\d+(?:\.\d*)?|\-""" -_match_str_bytes_int_float = \ - f'(?:{_match_single_quote_str_bytes}|{_match_double_quote_str_bytes}|' \ - f'{_match_int_and_float})' -_match_tuple = r"""\((?:""" \ - f'{_match_str_bytes_int_float}' \ - r""", )*(?:""" \ - f'{_match_str_bytes_int_float}' \ - r"""\,|""" \ - f'{_match_str_bytes_int_float}' \ - r""")?\)?""" - -_current_dict_key_re_base = r"""[\w_][\w0-9._]*\[""" +r""" # bytes repr() begins with `b` character; bytes and str begin with `'` + b?' + # after an even number of `\`, next `\` and subsequent char are interpreted + # as an escape sequence; this handles `\'` in the string repr() + (?:\\(?:\\\\)*['"nabfrtvxuU]| + # or match any non-`\` and non-single-quote character (most of the string) + [^'\\])* + # any even number of `\`; ensures `\\'` is interpreted as the end of string + (?:\\\\)* + # matches hanging `\` if one is present + \\? + # end matching at closing single-quote if one is present + '? +""" + +# bytes and str repr() only uses double quotes if the string contains 1 or more +# `'` character and exactly 0 `"` characters +_match_double_quote_str_bytes = \ +r""" # bytes repr() begins with `b` character + b?" + # string continues until a `"` character is reached + [^"]* + # end matching at closing double-quote if one is present + "?""" + +_match_int_and_float = \ +r"""\-? # match a negative sign if present + \d+ # match any number of digits + (?:\.\d*)? # if there is a decimal point, match it and subsequent digits + |\- # if only a negative sign has been entered, match it +""" + +# used to match possible elements in a tuple +_match_tuple_element = ( + f'(?:{_match_single_quote_str_bytes}|' # match single quote str/bytes repr + f'{_match_double_quote_str_bytes}|' # or double quote str/bytes repr + f'{_match_int_and_float})' # or int or float repr +) + +_match_tuple = \ +rf""" # match open parenthesis + \( + # matches any number of tuple elements followed by `,` then ` ` + (?:{_match_tuple_element},[ ])* + # followed by another element being typed or one element tuple i.e. `(1,)` + (?:{_match_tuple_element},?)? + # match close parentesis if present + \)? +""" + +# match valid identifier name followed by `[` character +_match_dict_before_key = r"""[\w_][\w0-9._]*\[""" + _current_dict_key_re = LazyReCompile( - f'{_current_dict_key_re_base}(' - f'{_match_identifiers_and_functions}|' + f'{_match_dict_before_key}(' f'{_match_single_quote_str_bytes}|' f'{_match_double_quote_str_bytes}|' f'{_match_int_and_float}|' f'{_match_tuple}|' - ')' + f'{_match_all_dict_keys}|)', + re.VERBOSE ) @@ -71,15 +112,17 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: return None -_current_dict_re_base = r"""([\w_][\w0-9._]*)\[""" +# capture valid identifier name if followed by `[` character +_capture_dict_name = r"""([\w_][\w0-9._]*)\[""" + _current_dict_re = LazyReCompile( - f'{_current_dict_re_base}(' - f'{_match_identifiers_and_functions}|' + f'{_capture_dict_name}(' f'{_match_single_quote_str_bytes}|' f'{_match_double_quote_str_bytes}|' f'{_match_int_and_float}|' f'{_match_tuple}|' - ')' + f'{_match_all_dict_keys}|)', + re.VERBOSE ) From 12ff50d035743678b20106bfa10a69650c1642a9 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Wed, 29 Sep 2021 18:08:12 -0400 Subject: [PATCH 07/13] Removed unnecessary regular expressions --- bpython/line.py | 39 ++++++--------------------------------- 1 file changed, 6 insertions(+), 33 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 9487ac34..5f47a1eb 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -65,41 +65,14 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: # end matching at closing double-quote if one is present "?""" -_match_int_and_float = \ -r"""\-? # match a negative sign if present - \d+ # match any number of digits - (?:\.\d*)? # if there is a decimal point, match it and subsequent digits - |\- # if only a negative sign has been entered, match it -""" - -# used to match possible elements in a tuple -_match_tuple_element = ( - f'(?:{_match_single_quote_str_bytes}|' # match single quote str/bytes repr - f'{_match_double_quote_str_bytes}|' # or double quote str/bytes repr - f'{_match_int_and_float})' # or int or float repr -) - -_match_tuple = \ -rf""" # match open parenthesis - \( - # matches any number of tuple elements followed by `,` then ` ` - (?:{_match_tuple_element},[ ])* - # followed by another element being typed or one element tuple i.e. `(1,)` - (?:{_match_tuple_element},?)? - # match close parentesis if present - \)? -""" - # match valid identifier name followed by `[` character _match_dict_before_key = r"""[\w_][\w0-9._]*\[""" _current_dict_key_re = LazyReCompile( - f'{_match_dict_before_key}(' + f'{_match_dict_before_key}((?:' f'{_match_single_quote_str_bytes}|' f'{_match_double_quote_str_bytes}|' - f'{_match_int_and_float}|' - f'{_match_tuple}|' - f'{_match_all_dict_keys}|)', + f'{_match_all_dict_keys}|)*)', re.VERBOSE ) @@ -116,12 +89,12 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: _capture_dict_name = r"""([\w_][\w0-9._]*)\[""" _current_dict_re = LazyReCompile( - f'{_capture_dict_name}(' + f'{_capture_dict_name}((?:' f'{_match_single_quote_str_bytes}|' f'{_match_double_quote_str_bytes}|' - f'{_match_int_and_float}|' - f'{_match_tuple}|' - f'{_match_all_dict_keys}|)', + # f'{_match_int_and_float}|' + # f'{_match_tuple}|' + f'{_match_all_dict_keys}|)*)', re.VERBOSE ) From d57f0088486f955f1cdd1463485b916f015328ad Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Wed, 29 Sep 2021 18:20:43 -0400 Subject: [PATCH 08/13] Removed old commented-out code --- bpython/line.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 5f47a1eb..6890085d 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -92,8 +92,6 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: f'{_capture_dict_name}((?:' f'{_match_single_quote_str_bytes}|' f'{_match_double_quote_str_bytes}|' - # f'{_match_int_and_float}|' - # f'{_match_tuple}|' f'{_match_all_dict_keys}|)*)', re.VERBOSE ) From a0f7fae37ef567c15a9dc7901336ffe623fa788c Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Wed, 29 Sep 2021 19:39:57 -0400 Subject: [PATCH 09/13] minor formatting changes to pass black linter test --- bpython/line.py | 28 ++++++++++++++-------------- bpython/test/test_line_properties.py | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 6890085d..91e617fd 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -39,8 +39,8 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: _match_all_dict_keys = r"""[^\]]*""" # https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals -_match_single_quote_str_bytes = \ -r""" # bytes repr() begins with `b` character; bytes and str begin with `'` +_match_single_quote_str_bytes = r""" + # bytes repr() begins with `b` character; bytes and str begin with `'` b?' # after an even number of `\`, next `\` and subsequent char are interpreted # as an escape sequence; this handles `\'` in the string repr() @@ -57,8 +57,8 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: # bytes and str repr() only uses double quotes if the string contains 1 or more # `'` character and exactly 0 `"` characters -_match_double_quote_str_bytes = \ -r""" # bytes repr() begins with `b` character +_match_double_quote_str_bytes = r""" + # bytes repr() begins with `b` character b?" # string continues until a `"` character is reached [^"]* @@ -69,11 +69,11 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: _match_dict_before_key = r"""[\w_][\w0-9._]*\[""" _current_dict_key_re = LazyReCompile( - f'{_match_dict_before_key}((?:' - f'{_match_single_quote_str_bytes}|' - f'{_match_double_quote_str_bytes}|' - f'{_match_all_dict_keys}|)*)', - re.VERBOSE + f"{_match_dict_before_key}((?:" + f"{_match_single_quote_str_bytes}|" + f"{_match_double_quote_str_bytes}|" + f"{_match_all_dict_keys}|)*)", + re.VERBOSE, ) @@ -89,11 +89,11 @@ def current_dict_key(cursor_offset: int, line: str) -> Optional[LinePart]: _capture_dict_name = r"""([\w_][\w0-9._]*)\[""" _current_dict_re = LazyReCompile( - f'{_capture_dict_name}((?:' - f'{_match_single_quote_str_bytes}|' - f'{_match_double_quote_str_bytes}|' - f'{_match_all_dict_keys}|)*)', - re.VERBOSE + f"{_capture_dict_name}((?:" + f"{_match_single_quote_str_bytes}|" + f"{_match_double_quote_str_bytes}|" + f"{_match_all_dict_keys}|)*)", + re.VERBOSE, ) diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index 79f72441..40567ecd 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -183,7 +183,7 @@ def test_simple(self): self.assertAccess("asdf[<(1, 2)>|]") # TODO self.assertAccess('d[d[<12|>') self.assertAccess("d[<'a>|") - self.assertAccess("object.dict['a\'bcd'], object.dict[<'abc>|") + self.assertAccess("object.dict['a'bcd'], object.dict[<'abc>|") self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|") self.assertAccess("object.dict[<\"abc'>|") self.assertAccess("object.dict[<(1, 'apple', 2.134>|]") From 236dc0b39d45d8b5b92e7180f45e26132d9a63b6 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Fri, 1 Oct 2021 11:12:54 -0400 Subject: [PATCH 10/13] formatting change; adjusted single-quote string regex; added tests --- bpython/line.py | 16 ++++++---------- bpython/test/test_line_properties.py | 4 ++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/bpython/line.py b/bpython/line.py index 91e617fd..b98302dd 100644 --- a/bpython/line.py +++ b/bpython/line.py @@ -4,9 +4,10 @@ Python code, and return None, or a tuple of the start index, end index, and the word.""" +import re + from itertools import chain from typing import Optional, NamedTuple -import re from .lazyre import LazyReCompile @@ -42,17 +43,12 @@ def current_word(cursor_offset: int, line: str) -> Optional[LinePart]: _match_single_quote_str_bytes = r""" # bytes repr() begins with `b` character; bytes and str begin with `'` b?' - # after an even number of `\`, next `\` and subsequent char are interpreted - # as an escape sequence; this handles `\'` in the string repr() - (?:\\(?:\\\\)*['"nabfrtvxuU]| + # match escape sequence; this handles `\'` in the string repr() + (?:\\['"nabfrtvxuU\\]| # or match any non-`\` and non-single-quote character (most of the string) [^'\\])* - # any even number of `\`; ensures `\\'` is interpreted as the end of string - (?:\\\\)* - # matches hanging `\` if one is present - \\? - # end matching at closing single-quote if one is present - '? + # matches hanging `\` or ending `'` if one is present + [\\']? """ # bytes and str repr() only uses double quotes if the string contains 1 or more diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index 40567ecd..09a8e949 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -184,6 +184,7 @@ def test_simple(self): # TODO self.assertAccess('d[d[<12|>') self.assertAccess("d[<'a>|") self.assertAccess("object.dict['a'bcd'], object.dict[<'abc>|") + self.assertAccess("object.dict[<'a'bcd'>|], object.dict['abc") self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|") self.assertAccess("object.dict[<\"abc'>|") self.assertAccess("object.dict[<(1, 'apple', 2.134>|]") @@ -191,6 +192,9 @@ def test_simple(self): self.assertAccess("object.dict[<-1000>|") self.assertAccess("object.dict[<-0.23948>|") self.assertAccess("object.dict[<'\U0001ffff>|") + self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|]") + self.assertAccess("object.dict[<\"abc'\">|]") + self.assertAccess("object.dict[<-1029.19384>|]") class TestCurrentDict(LineTestCase): From 286d71c6f8f1e8c4fd0784eb548b9f274f754c88 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Fri, 1 Oct 2021 11:17:43 -0400 Subject: [PATCH 11/13] modified test to test strings containing '[' and ']' --- bpython/test/test_line_properties.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index 09a8e949..eb1a940f 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -192,9 +192,9 @@ def test_simple(self): self.assertAccess("object.dict[<-1000>|") self.assertAccess("object.dict[<-0.23948>|") self.assertAccess("object.dict[<'\U0001ffff>|") - self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|]") - self.assertAccess("object.dict[<\"abc'\">|]") - self.assertAccess("object.dict[<-1029.19384>|]") + self.assertAccess(r"object.dict[<'a\'\\\"\n\\|[[]'>") + self.assertAccess("object.dict[<\"a]bc[|]\">]") + self.assertAccess("object.dict[<'abcd[]>|") class TestCurrentDict(LineTestCase): From 01ed93bb8b38f4e8702bd09d4c251d5e5fe1ec5c Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Fri, 1 Oct 2021 11:25:26 -0400 Subject: [PATCH 12/13] added test case for string dict key being typed inside [] --- bpython/test/test_line_properties.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index eb1a940f..0315bc59 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -192,6 +192,7 @@ def test_simple(self): self.assertAccess("object.dict[<-1000>|") self.assertAccess("object.dict[<-0.23948>|") self.assertAccess("object.dict[<'\U0001ffff>|") + self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|]") self.assertAccess(r"object.dict[<'a\'\\\"\n\\|[[]'>") self.assertAccess("object.dict[<\"a]bc[|]\">]") self.assertAccess("object.dict[<'abcd[]>|") From 0a08f41ee568559c9b19d6fdb3076bf900c041e8 Mon Sep 17 00:00:00 2001 From: Arian Deimling Date: Fri, 1 Oct 2021 19:26:44 -0400 Subject: [PATCH 13/13] ran black formatter on file --- bpython/test/test_line_properties.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bpython/test/test_line_properties.py b/bpython/test/test_line_properties.py index 0315bc59..592a6176 100644 --- a/bpython/test/test_line_properties.py +++ b/bpython/test/test_line_properties.py @@ -194,7 +194,7 @@ def test_simple(self): self.assertAccess("object.dict[<'\U0001ffff>|") self.assertAccess(r"object.dict[<'a\'\\\"\n\\'>|]") self.assertAccess(r"object.dict[<'a\'\\\"\n\\|[[]'>") - self.assertAccess("object.dict[<\"a]bc[|]\">]") + self.assertAccess('object.dict[<"a]bc[|]">]') self.assertAccess("object.dict[<'abcd[]>|")