diff --git a/jedi/api/refactoring.py b/jedi/api/refactoring.py index c536eb0c..b63cb874 100644 --- a/jedi/api/refactoring.py +++ b/jedi/api/refactoring.py @@ -9,12 +9,14 @@ from jedi.api.exceptions import RefactoringError from jedi.common.utils import indent_block _EXPRESSION_PARTS = ( - 'or_test and_test not_test comparison' - 'xor_expr and_expr shift_expr arith_expr term factor power atom_expr ' + 'or_test and_test not_test comparison ' + 'expr xor_expr and_expr shift_expr arith_expr term factor power atom_expr' ).split() _EXTRACT_USE_PARENT = _EXPRESSION_PARTS + ['trailer'] _DEFINITION_SCOPES = ('suite', 'file_input') -_NON_EXCTRACABLE = ('param',) +_VARIABLE_EXCTRACTABLE = _EXPRESSION_PARTS + \ + ('keyword atom name number string testlist_star_expr test_list test ' + 'lambdef lambdef_nocond').split() class ChangedFile(object): @@ -245,10 +247,11 @@ def extract_variable(grammar, path, module_node, new_name, pos, until_pos): nodes = _remove_unwanted_expression_nodes(parent_node, pos, until_pos) if any(node.type == 'name' and node.is_definition() for node in nodes): - raise RefactoringError('Cannot extract a definition of a name') - if any(node.type in _NON_EXCTRACABLE for node in nodes) \ + raise RefactoringError('Cannot extract a name that defines something') + if nodes[0].type not in _VARIABLE_EXCTRACTABLE \ or nodes[0].type == 'keyword' and nodes[0].value not in ('None', 'True', 'False'): - raise RefactoringError('Cannot extract a %s' % node.type) + print(nodes) + raise RefactoringError('Cannot extract a "%s"' % nodes[0].type) definition = _get_parent_definition(nodes[0]) first_definition_leaf = definition.get_first_leaf() diff --git a/test/refactor/extract_variable.py b/test/refactor/extract_variable.py index 22ba2787..002bf9ce 100644 --- a/test/refactor/extract_variable.py +++ b/test/refactor/extract_variable.py @@ -50,13 +50,13 @@ def test(): def test(p1): return # ++++++++++++++++++++++++++++++++++++++++++++++++++ -Cannot extract a definition of a name +Cannot extract a name that defines something # -------------------------------------------------- for-param-error-2 #? 12 error {'new_name': 'x'} def test(p1= 3): return # ++++++++++++++++++++++++++++++++++++++++++++++++++ -Cannot extract a param +Cannot extract a "param" # -------------------------------------------------- for-param-1 #? 12 text {'new_name': 'x'} def test(p1=20): @@ -97,12 +97,12 @@ class Foo(x): #? 12 error {'new_name': 'x'} def x(): pass # ++++++++++++++++++++++++++++++++++++++++++++++++++ -Cannot extract a keyword +Cannot extract a "keyword" # -------------------------------------------------- keyword-continue #? 5 error {'new_name': 'x'} continue # ++++++++++++++++++++++++++++++++++++++++++++++++++ -Cannot extract a keyword +Cannot extract a "keyword" # -------------------------------------------------- keyword-None if 1: #? 4 text {'new_name': 'x'} @@ -196,3 +196,26 @@ z = (y+1*2+3) #? 9 text {'new_name': 'x', 'until_column': 13} x = (y+1*2+3) z = x +# -------------------------------------------------- extract-weird-1 +#? 0 error {'new_name': 'x', 'until_column': 7} +foo = 3 +# ++++++++++++++++++++++++++++++++++++++++++++++++++ +Cannot extract a "expr_stmt" +# -------------------------------------------------- extract-weird-2 +#? 0 error {'new_name': 'x', 'until_column': 5} +def x(): + foo = 3 +# ++++++++++++++++++++++++++++++++++++++++++++++++++ +Cannot extract a "funcdef" +# -------------------------------------------------- extract-weird-3 +def x(): +#? 4 error {'new_name': 'x', 'until_column': 8} + if 1: + pass +# ++++++++++++++++++++++++++++++++++++++++++++++++++ +Cannot extract a "if_stmt" +# -------------------------------------------------- extract-weird-4 +#? 4 error {'new_name': 'x', 'until_column': 7} +x = foo = 4 +# ++++++++++++++++++++++++++++++++++++++++++++++++++ +Cannot extract a name that defines something