3.x docsting escaping works differently?

This commit is contained in:
rocky
2019-05-24 09:53:56 -04:00
parent cccf33573b
commit 47ed0795b2
6 changed files with 28 additions and 92 deletions

View File

@@ -1,78 +0,0 @@
import sys
from uncompyle6 import PYTHON3
if PYTHON3:
from io import StringIO
minint = -sys.maxsize-1
maxint = sys.maxsize
else:
from StringIO import StringIO
minint = -sys.maxint-1
maxint = sys.maxint
from uncompyle6.semantics.helper import print_docstring
class PrintFake():
def __init__(self):
self.pending_newlines = 0
self.f = StringIO()
def write(self, *data):
if (len(data) == 0) or (len(data) == 1 and data[0] == ''):
return
out = ''.join((str(j) for j in data))
n = 0
for i in out:
if i == '\n':
n += 1
if n == len(out):
self.pending_newlines = max(self.pending_newlines, n)
return
elif n:
self.pending_newlines = max(self.pending_newlines, n)
out = out[n:]
break
else:
break
if self.pending_newlines > 0:
self.f.write('\n'*self.pending_newlines)
self.pending_newlines = 0
for i in out[::-1]:
if i == '\n':
self.pending_newlines += 1
else:
break
if self.pending_newlines:
out = out[:-self.pending_newlines]
self.f.write(out)
def println(self, *data):
if data and not(len(data) == 1 and data[0] == ''):
self.write(*data)
self.pending_newlines = max(self.pending_newlines, 1)
return
pass
def test_docstring():
for doc, expect in (
("Now is the time",
' """Now is the time"""'),
("""
Now is the time
""",
''' """
Now is the time
"""''')
# (r'''func placeholder - ' and with ("""\nstring\n """)''',
# """ r'''func placeholder - ' and with (\"\"\"\nstring\n\"\"\")'''"""),
# (r"""func placeholder - ' and with ('''\nstring\n''') and \"\"\"\nstring\n\"\"\" """,
# """ r\"\"\"func placeholder - ' and with ('''\nstring\n''') and \"\"\"\nstring\n\"\"\" \"\"\"""")
):
o = PrintFake()
# print(doc)
# print(expect)
print_docstring(o, ' ', doc)
assert expect == o.f.getvalue()

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -99,14 +99,9 @@ def strip_quotes(str):
def print_docstring(self, indent, docstring): def print_docstring(self, indent, docstring):
try: quote = '"""'
if docstring.find('"""') == -1: if docstring.find("'''") == -1:
quote = '"""' quote = "'''"
else:
quote = "'''"
docstring = docstring.replace("'''", "\\'''")
except:
return False
self.write(indent) self.write(indent)
if not PYTHON3 and not isinstance(docstring, str): if not PYTHON3 and not isinstance(docstring, str):
# Must be unicode in Python2 # Must be unicode in Python2
@@ -132,18 +127,31 @@ def print_docstring(self, indent, docstring):
and (docstring[-1] != '"' and (docstring[-1] != '"'
or docstring[-2] == '\t')): or docstring[-2] == '\t')):
self.write('r') # raw string self.write('r') # raw string
# restore backslashes unescaped since raw # Restore backslashes unescaped since raw
docstring = docstring.replace('\t', '\\') docstring = docstring.replace('\t', '\\')
else: else:
# Escape '"' if it's the last character, so it doesn't # Escape '"' if it's the last character, so it doesn't
# ruin the ending triple quote # ruin the ending triple quote
if len(docstring) and docstring[-1] == '"': if len(docstring) and docstring[-1] == '"':
docstring = docstring[:-1] + '\\"' docstring = docstring[:-1] + '\\"'
# Restore escaped backslashes
# Escape triple quote when needed
if quote == '"""':
if self.version > 2.7:
replace_str = '\\"""'
else:
replace_str = '\\"\\"\\"'
docstring = docstring.replace(quote, replace_str)
else:
assert quote == "'''"
if self.version > 2.7:
replace_str = "\\'''"
else:
replace_str = "\\'\\'\\'"
docstring = docstring.replace(quote, replace_str)
docstring = docstring.replace('\t', '\\\\') docstring = docstring.replace('\t', '\\\\')
# Escape triple quote when needed
if quote == '""""':
docstring = docstring.replace('"""', '\\"\\"\\"')
lines = docstring.split('\n') lines = docstring.split('\n')
calculate_indent = maxint calculate_indent = maxint
for line in lines[1:]: for line in lines[1:]:
@@ -152,6 +160,7 @@ def print_docstring(self, indent, docstring):
calculate_indent = min(calculate_indent, len(line) - len(stripped)) calculate_indent = min(calculate_indent, len(line) - len(stripped))
calculate_indent = min(calculate_indent, len(lines[-1]) - len(lines[-1].lstrip())) calculate_indent = min(calculate_indent, len(lines[-1]) - len(lines[-1].lstrip()))
# Remove indentation (first line is special): # Remove indentation (first line is special):
trimmed = [lines[0]] trimmed = [lines[0]]
if calculate_indent < maxint: if calculate_indent < maxint:
trimmed += [line[calculate_indent:] for line in lines[1:]] trimmed += [line[calculate_indent:] for line in lines[1:]]
@@ -164,7 +173,12 @@ def print_docstring(self, indent, docstring):
else: else:
self.println(trimmed[0]) self.println(trimmed[0])
for line in trimmed[1:-1]: for line in trimmed[1:-1]:
self.println( indent, line ) if line:
self.println( indent, line )
else:
self.println( "\n\n" )
pass
pass
self.println(indent, trimmed[-1], quote) self.println(indent, trimmed[-1], quote)
return True return True