A couple of 3.6 bugs...

remove parens around decorators by adjusting precidence
Partial handling of quotes within 3.6 format strings
This commit is contained in:
rocky
2018-03-21 19:54:28 -04:00
parent d41a858f80
commit 7fc7e083c3
7 changed files with 44 additions and 8 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,5 +1,18 @@
# Self-checking 3.6+ string interpolation tests
var1 = 'x' var1 = 'x'
var2 = 'y' var2 = 'y'
print(f'interpolate {var1} strings {var2!r} {var2!s} py36') abc = 'def'
print(f'{abc}0') assert (f'interpolate {var1} strings {var2!r} {var2!s} py36' ==
print(f'{abc}{abc!s}') "interpolate x strings 'y' y py36")
assert 'def0' == f'{abc}0'
assert 'defdef' == f'{abc}{abc!s}'
# From 3.6 functools.py
# Bug was handling format operator strings.
k, v = "1", ["2"]
x = f"{k}={v!r}"
y = f"functools.{x}({', '.join(v)})"
assert x == "1=['2']"
assert y == "functools.1=['2'](2)"

View File

@@ -1,5 +1,13 @@
# From 3.6 _markupbase _parse_doctype_subset() # From 3.6 _markupbase _parse_doctype_subset()
def bug(self, j): def bug(self, j, a, b):
self.parse_comment(j, report=0) self.parse_comment(j, report=0)
self.parse_comment(j, report=1, foo=2) self.parse_comment(j, report=1, foo=2)
self.parse_comment(a, b, report=3) self.parse_comment(a, b, report=3)
# From 3.6 fnmatch.py
# Bug was precidence parenthesis around decorator
import functools
@functools.lru_cache(maxsize=256, typed=True)
def _compile_pattern(pat):
pass

View File

@@ -317,6 +317,10 @@ MAP = {
# See https://docs.python.org/2/reference/expressions.html # See https://docs.python.org/2/reference/expressions.html
# or https://docs.python.org/3/reference/expressions.html # or https://docs.python.org/3/reference/expressions.html
# for a list. # for a list.
# Things at the top of this list below with low-value precidence will
# tend to have parenthesis around them. Things at the bottom
# of the list will tend not to have parenthesis around them.
PRECEDENCE = { PRECEDENCE = {
'list': 0, 'list': 0,
'dict': 0, 'dict': 0,
@@ -377,8 +381,9 @@ PRECEDENCE = {
'ret_cond_not': 28, 'ret_cond_not': 28,
'_mklambda': 30, '_mklambda': 30,
'yield': 101, 'call_kw': 100, # 100 seems to to be module/function precidence
'yield_from': 101 'yield': 101,
'yield_from': 101
} }
ASSIGN_TUPLE_PARAM = lambda param_name: \ ASSIGN_TUPLE_PARAM = lambda param_name: \

View File

@@ -357,8 +357,10 @@ def customize_for_version(self, is_pypy, version):
'tryfinally36': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n', 'tryfinally36': ( '%|try:\n%+%c%-%|finally:\n%+%c%-\n\n',
(1, 'returns'), 3 ), (1, 'returns'), 3 ),
'fstring_expr': ( "{%c%{conversion}}", 0), 'fstring_expr': ( "{%c%{conversion}}", 0),
'fstring_single': ( "f'{%c%{conversion}}'", 0), # FIXME: the below assumes the format strings
'fstring_multi': ( "f'%c'", 0), # don't have ''' in them. Fix this properly
'fstring_single': ( "f'''{%c%{conversion}}'''", 0),
'fstring_multi': ( "f'''%c'''", 0),
'func_args36': ( "%c(**", 0), 'func_args36': ( "%c(**", 0),
'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ), 'try_except36': ( '%|try:\n%+%c%-%c\n\n', 1, 2 ),
'unpack_list': ( '*%c', (0, 'list') ), 'unpack_list': ( '*%c', (0, 'list') ),
@@ -603,6 +605,14 @@ def customize_for_version(self, is_pypy, version):
FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'} FSTRING_CONVERSION_MAP = {1: '!s', 2: '!r', 3: '!a'}
def n_formatted_value(node):
if node[0] == 'LOAD_CONST':
self.write(node[0].attr)
self.prune()
else:
self.default(node)
self.n_formatted_value = n_formatted_value
def f_conversion(node): def f_conversion(node):
node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '') node.conversion = FSTRING_CONVERSION_MAP.get(node.data[1].attr, '')