From 017d343327d91b1205a42f25235883fac1f5c548 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Tue, 3 Mar 2020 18:59:34 +0300 Subject: [PATCH 1/5] bpo-38870: Correctly unparse empty docstrings --- Lib/ast.py | 2 +- Lib/test/test_unparse.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Lib/ast.py b/Lib/ast.py index 93ffa1edc84d55f..bfe62349249dd46 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1004,7 +1004,7 @@ def _write_docstring(self, node): # Preserve quotes in the docstring by escaping them value = node.value.replace("\\", "\\\\") value = value.replace('"""', '""\"') - if value[-1] == '"': + if len(value) > 0 and value[-1] == '"': value = value.replace('"', '\\"', -1) self.write(f'"""{value}"""') diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index d04db4d5f46e1ad..4515e18fff3713a 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -354,6 +354,7 @@ def test_docstrings(self): empty newline"""''', '"""With some \t"""', '"""Foo "bar" baz """', + '""""""', ) for prefix in docstring_prefixes: From 225296287b1cd7f9aa0c9eb66255765373079455 Mon Sep 17 00:00:00 2001 From: Pablo Galindo Date: Tue, 3 Mar 2020 16:40:53 +0000 Subject: [PATCH 2/5] Apply suggestions from code review --- Lib/ast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Lib/ast.py b/Lib/ast.py index bfe62349249dd46..1b76cc7f9016d69 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1004,7 +1004,7 @@ def _write_docstring(self, node): # Preserve quotes in the docstring by escaping them value = node.value.replace("\\", "\\\\") value = value.replace('"""', '""\"') - if len(value) > 0 and value[-1] == '"': + if value and value[-1] == '"': value = value.replace('"', '\\"', -1) self.write(f'"""{value}"""') From a389c39bb966442f4ab7ef9de8bd6b75b6ba42d6 Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Tue, 3 Mar 2020 21:06:38 +0300 Subject: [PATCH 3/5] add an early exit --- Lib/ast.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index 1b76cc7f9016d69..72d1057fcc49775 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1001,11 +1001,13 @@ def _write_docstring(self, node): if node.kind == "u": self.write("u") - # Preserve quotes in the docstring by escaping them - value = node.value.replace("\\", "\\\\") - value = value.replace('"""', '""\"') - if value and value[-1] == '"': - value = value.replace('"', '\\"', -1) + value = node.value + if value: + # Preserve quotes in the docstring by escaping them + value = value.replace("\\", "\\\\") + value = value.replace('"""', '""\"') + if value[-1] == '"': + value = value.replace('"', '\\"', -1) self.write(f'"""{value}"""') From 55894b37463ea42bd274732332ce31e67647a9da Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 4 Mar 2020 22:07:38 +0300 Subject: [PATCH 4/5] Fix \r bug --- Lib/ast.py | 1 + Lib/test/test_unparse.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/Lib/ast.py b/Lib/ast.py index 72d1057fcc49775..fb8460798157f07 100644 --- a/Lib/ast.py +++ b/Lib/ast.py @@ -1006,6 +1006,7 @@ def _write_docstring(self, node): # Preserve quotes in the docstring by escaping them value = value.replace("\\", "\\\\") value = value.replace('"""', '""\"') + value = value.replace("\r", "\\r") if value[-1] == '"': value = value.replace('"', '\\"', -1) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index 4515e18fff3713a..47208ca4593d6d0 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -304,11 +304,18 @@ def test_invalid_yield_from(self): def test_docstrings(self): docstrings = ( 'this ends with double quote"', - 'this includes a """triple quote"""' + 'this includes a """triple quote"""', + '\r', + '\\r', + '\t', + '\\t', + '\n', + '\\n', + '\r\\r\t\\t\n\\n' ) for docstring in docstrings: # check as Module docstrings for easy testing - self.check_ast_roundtrip(f"'{docstring}'") + self.check_ast_roundtrip(f"'''{docstring}'''") class CosmeticTestCase(ASTTestCase): @@ -354,6 +361,7 @@ def test_docstrings(self): empty newline"""''', '"""With some \t"""', '"""Foo "bar" baz """', + '"""\\r"""', '""""""', ) From b4938ca1b8359569889a36bc84276ec80a8b6d8b Mon Sep 17 00:00:00 2001 From: Batuhan Taskaya Date: Wed, 4 Mar 2020 22:10:03 +0300 Subject: [PATCH 5/5] add single quoted tests --- Lib/test/test_unparse.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/test/test_unparse.py b/Lib/test/test_unparse.py index 47208ca4593d6d0..086a1b6ae851e19 100644 --- a/Lib/test/test_unparse.py +++ b/Lib/test/test_unparse.py @@ -363,6 +363,8 @@ def test_docstrings(self): '"""Foo "bar" baz """', '"""\\r"""', '""""""', + '"""\'\'\'"""', + '"""\'\'\'\'\'\'"""', ) for prefix in docstring_prefixes: