mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-07 22:44:27 +08:00
Basic implementation support for namedexpr, fixes #1647
This commit is contained in:
@@ -16,6 +16,7 @@ Unreleased
|
|||||||
- Functions with ``@property`` now return ``property`` instead of ``function``
|
- Functions with ``@property`` now return ``property`` instead of ``function``
|
||||||
in ``Name().type``
|
in ``Name().type``
|
||||||
- Started using annotations
|
- Started using annotations
|
||||||
|
- Better support for the walrus operator
|
||||||
- Project attributes are now read accessible
|
- Project attributes are now read accessible
|
||||||
|
|
||||||
This is likely going to be the last minor release before 1.0.
|
This is likely going to be the last minor release before 1.0.
|
||||||
|
|||||||
@@ -170,6 +170,8 @@ class InferenceState:
|
|||||||
return tree_name_to_values(self, context, name)
|
return tree_name_to_values(self, context, name)
|
||||||
elif type_ == 'param':
|
elif type_ == 'param':
|
||||||
return context.py__getattribute__(name.value, position=name.end_pos)
|
return context.py__getattribute__(name.value, position=name.end_pos)
|
||||||
|
elif type_ == 'namedexpr_test':
|
||||||
|
return context.infer_node(def_)
|
||||||
else:
|
else:
|
||||||
result = follow_error_node_imports_if_possible(context, name)
|
result = follow_error_node_imports_if_possible(context, name)
|
||||||
if result is not None:
|
if result is not None:
|
||||||
|
|||||||
@@ -753,6 +753,8 @@ def tree_name_to_values(inference_state, context, tree_name):
|
|||||||
types = NO_VALUES
|
types = NO_VALUES
|
||||||
elif typ == 'del_stmt':
|
elif typ == 'del_stmt':
|
||||||
types = NO_VALUES
|
types = NO_VALUES
|
||||||
|
elif typ == 'namedexpr_test':
|
||||||
|
types = infer_node(context, node)
|
||||||
else:
|
else:
|
||||||
raise ValueError("Should not happen. type: %s" % typ)
|
raise ValueError("Should not happen. type: %s" % typ)
|
||||||
return types
|
return types
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ def get_flow_branch_keyword(flow_node, node):
|
|||||||
first_leaf = child.get_first_leaf()
|
first_leaf = child.get_first_leaf()
|
||||||
if first_leaf in _FLOW_KEYWORDS:
|
if first_leaf in _FLOW_KEYWORDS:
|
||||||
keyword = first_leaf
|
keyword = first_leaf
|
||||||
return 0
|
return None
|
||||||
|
|
||||||
|
|
||||||
def clean_scope_docstring(scope_node):
|
def clean_scope_docstring(scope_node):
|
||||||
@@ -239,7 +239,7 @@ def get_parent_scope(node, include_flows=False):
|
|||||||
return None # It's a module already.
|
return None # It's a module already.
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
if is_scope(scope) or include_flows and isinstance(scope, tree.Flow):
|
if is_scope(scope):
|
||||||
if scope.type in ('classdef', 'funcdef', 'lambdef'):
|
if scope.type in ('classdef', 'funcdef', 'lambdef'):
|
||||||
index = scope.children.index(':')
|
index = scope.children.index(':')
|
||||||
if scope.children[index].start_pos >= node.start_pos:
|
if scope.children[index].start_pos >= node.start_pos:
|
||||||
@@ -251,6 +251,14 @@ def get_parent_scope(node, include_flows=False):
|
|||||||
scope = scope.parent
|
scope = scope.parent
|
||||||
continue
|
continue
|
||||||
return scope
|
return scope
|
||||||
|
elif include_flows and isinstance(scope, tree.Flow):
|
||||||
|
# The cursor might be on `if foo`, so the parent scope will not be
|
||||||
|
# the if, but the parent of the if.
|
||||||
|
if not (scope.type == 'if_stmt'
|
||||||
|
and any(n.start_pos <= node.start_pos < n.end_pos
|
||||||
|
for n in scope.get_test_nodes())):
|
||||||
|
return scope
|
||||||
|
|
||||||
scope = scope.parent
|
scope = scope.parent
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
x = 3
|
x = 3
|
||||||
if NOT_DEFINED:
|
if NOT_DEFINED:
|
||||||
x = ''
|
x = ''
|
||||||
#? 6 int()
|
#? 6 int() str()
|
||||||
elif x:
|
elif x:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
# For assignment expressions / named expressions / walrus operators / whatever
|
||||||
|
# they are called.
|
||||||
|
|
||||||
# python >= 3.8
|
# python >= 3.8
|
||||||
b = (a:=1, a)
|
b = (a:=1, a)
|
||||||
|
|
||||||
@@ -11,3 +14,39 @@ b = ('':=1,)
|
|||||||
|
|
||||||
#? int()
|
#? int()
|
||||||
b[0]
|
b[0]
|
||||||
|
|
||||||
|
def test_assignments():
|
||||||
|
match = ''
|
||||||
|
#? str()
|
||||||
|
match
|
||||||
|
#? 8 int()
|
||||||
|
if match := 1:
|
||||||
|
#? int()
|
||||||
|
match
|
||||||
|
#? int()
|
||||||
|
match
|
||||||
|
|
||||||
|
def test_assignments2():
|
||||||
|
class Foo:
|
||||||
|
match = ''
|
||||||
|
#? str()
|
||||||
|
Foo.match
|
||||||
|
#? 13 int()
|
||||||
|
if Foo.match := 1:
|
||||||
|
#? str()
|
||||||
|
Foo.match
|
||||||
|
#? str()
|
||||||
|
Foo.match
|
||||||
|
|
||||||
|
#?
|
||||||
|
y
|
||||||
|
#? 16 str()
|
||||||
|
if y := Foo.match:
|
||||||
|
#? str()
|
||||||
|
y
|
||||||
|
#? str()
|
||||||
|
y
|
||||||
|
|
||||||
|
#? 8 str()
|
||||||
|
if z := Foo.match:
|
||||||
|
pass
|
||||||
|
|||||||
Reference in New Issue
Block a user