mirror of
https://github.com/gristlabs/grist-core.git
synced 2024-10-27 20:44:07 +00:00
(core) Fix updating attributes inside f-strings when columns are renamed
Summary: Upgrades asttokens and uses the newly released support for astroid trees in `asttokens.ASTText` which is needed to deal with f-strings (as opposed to `asttokens.ASTTokens`). Test Plan: Added a Python unit test Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D4027
This commit is contained in:
parent
8644f346af
commit
525613216c
@ -397,7 +397,7 @@ def parse_grist_names(builder):
|
|||||||
|
|
||||||
with use_inferences(InferReferenceColumn, InferReferenceFormula, InferLookupReference,
|
with use_inferences(InferReferenceColumn, InferReferenceFormula, InferLookupReference,
|
||||||
InferLookupComprehension, InferAllReference, InferAllComprehension):
|
InferLookupComprehension, InferAllReference, InferAllComprehension):
|
||||||
atok = asttokens.ASTTokens(code_text, tree=astroid.builder.parse(code_text))
|
atok = asttokens.ASTText(code_text, tree=astroid.builder.parse(code_text))
|
||||||
|
|
||||||
def make_tuple(start, end, table_id, col_id):
|
def make_tuple(start, end, table_id, col_id):
|
||||||
name = col_id or table_id
|
name = col_id or table_id
|
||||||
@ -413,7 +413,7 @@ def parse_grist_names(builder):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
parsed_names = []
|
parsed_names = []
|
||||||
for node in asttokens.util.walk(atok.tree):
|
for node in asttokens.util.walk(atok.tree, include_joined_str=True):
|
||||||
if isinstance(node, astroid.nodes.Name):
|
if isinstance(node, astroid.nodes.Name):
|
||||||
obj = infer(node)
|
obj = infer(node)
|
||||||
if _is_table(obj) and not _is_local(node):
|
if _is_table(obj) and not _is_local(node):
|
||||||
@ -425,17 +425,19 @@ def parse_grist_names(builder):
|
|||||||
if isinstance(obj, astroid.bases.Instance):
|
if isinstance(obj, astroid.bases.Instance):
|
||||||
cls = obj._proxied
|
cls = obj._proxied
|
||||||
if _is_table(cls):
|
if _is_table(cls):
|
||||||
tok = node.last_token
|
end = atok.get_text_range(node)[1]
|
||||||
start, end = tok.startpos, tok.endpos
|
start = end - len(node.attrname)
|
||||||
parsed_names.append(make_tuple(start, end, cls.name, node.attrname))
|
if code_text[start:end] == node.attrname:
|
||||||
|
parsed_names.append(make_tuple(start, end, cls.name, node.attrname))
|
||||||
elif isinstance(node, astroid.nodes.Keyword):
|
elif isinstance(node, astroid.nodes.Keyword):
|
||||||
func = node.parent.func
|
func = node.parent.func
|
||||||
if isinstance(func, astroid.nodes.Attribute) and func.attrname in _lookup_method_names:
|
if isinstance(func, astroid.nodes.Attribute) and func.attrname in _lookup_method_names:
|
||||||
obj = infer(func.expr)
|
obj = infer(func.expr)
|
||||||
if _is_table(obj):
|
if _is_table(obj):
|
||||||
tok = node.first_token
|
start = atok.get_text_range(node)[0]
|
||||||
start, end = tok.startpos, tok.endpos
|
end = start + len(node.arg)
|
||||||
parsed_names.append(make_tuple(start, end, obj.name, node.arg))
|
if code_text[start:end] == node.arg:
|
||||||
|
parsed_names.append(make_tuple(start, end, obj.name, node.arg))
|
||||||
|
|
||||||
return [name for name in parsed_names if name]
|
return [name for name in parsed_names if name]
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import logging
|
import logging
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
import testutil
|
import testutil
|
||||||
import test_engine
|
import test_engine
|
||||||
@ -78,6 +81,20 @@ class TestRenames(test_engine.EngineTestCase):
|
|||||||
}]
|
}]
|
||||||
]})
|
]})
|
||||||
|
|
||||||
|
@unittest.skipUnless(six.PY3, "Python 3 only")
|
||||||
|
def test_rename_inside_fstring(self):
|
||||||
|
self.load_sample(self.sample)
|
||||||
|
self.add_column("People", "CityUpper", formula="f'{$city.upper()}'")
|
||||||
|
out_actions = self.apply_user_action(["RenameColumn", "People", "city", "ciudad"])
|
||||||
|
self.assertPartialOutActions(out_actions, { "stored": [
|
||||||
|
["RenameColumn", "People", "city", "ciudad"],
|
||||||
|
["ModifyColumn", "People", "CityUpper", {"formula": "f'{$ciudad.upper()}'"}],
|
||||||
|
["BulkUpdateRecord", "_grist_Tables_column", [24, 25], {
|
||||||
|
"colId": ["ciudad", "CityUpper"],
|
||||||
|
"formula": ["$addr.city", "f'{$ciudad.upper()}'"]
|
||||||
|
}]
|
||||||
|
]})
|
||||||
|
|
||||||
def test_rename_reference_attribute(self):
|
def test_rename_reference_attribute(self):
|
||||||
# Slightly harder: renaming `$ref.COLUMN`
|
# Slightly harder: renaming `$ref.COLUMN`
|
||||||
self.load_sample(self.sample)
|
self.load_sample(self.sample)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
### python 2 requirements, see requirements3.txt for python 3
|
### python 2 requirements, see requirements3.txt for python 3
|
||||||
|
|
||||||
astroid==1.6.6
|
astroid==1.6.6
|
||||||
asttokens==2.2.1
|
asttokens==2.4.0
|
||||||
backports.functools-lru-cache==1.6.4
|
backports.functools-lru-cache==1.6.4
|
||||||
chardet==4.0.0
|
chardet==4.0.0
|
||||||
enum34==1.1.10
|
enum34==1.1.10
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
astroid==2.14.2
|
astroid==2.14.2
|
||||||
# via -r core/sandbox/requirements3.in
|
# via -r core/sandbox/requirements3.in
|
||||||
asttokens==2.2.1
|
asttokens==2.4.0
|
||||||
# via
|
# via
|
||||||
# friendly-traceback
|
# friendly-traceback
|
||||||
# stack-data
|
# stack-data
|
||||||
|
Loading…
Reference in New Issue
Block a user