mirror of
https://github.com/davidhalter/jedi.git
synced 2025-12-06 14:04:26 +08:00
3
.gitignore
vendored
3
.gitignore
vendored
@@ -14,3 +14,6 @@ record.json
|
|||||||
/.pytest_cache
|
/.pytest_cache
|
||||||
/.mypy_cache
|
/.mypy_cache
|
||||||
/venv/
|
/venv/
|
||||||
|
.nvimrc
|
||||||
|
poetry.lock
|
||||||
|
pyproject.toml
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
from abc import abstractproperty
|
from abc import abstractproperty
|
||||||
|
|
||||||
from parso.tree import search_ancestor
|
from parso.tree import search_ancestor
|
||||||
|
from parso.python.tree import Name
|
||||||
|
|
||||||
from jedi import debug
|
from jedi import debug
|
||||||
from jedi import settings
|
from jedi import settings
|
||||||
@@ -231,6 +232,8 @@ class _BaseTreeInstance(AbstractInstanceValue):
|
|||||||
func_node = new
|
func_node = new
|
||||||
new = search_ancestor(new, 'funcdef', 'classdef')
|
new = search_ancestor(new, 'funcdef', 'classdef')
|
||||||
if class_context.tree_node is new:
|
if class_context.tree_node is new:
|
||||||
|
if isinstance(func_node, Name):
|
||||||
|
func_node = new
|
||||||
func = FunctionValue.from_context(class_context, func_node)
|
func = FunctionValue.from_context(class_context, func_node)
|
||||||
bound_method = BoundMethod(self, class_context, func)
|
bound_method = BoundMethod(self, class_context, func)
|
||||||
if func_node.name.value == '__init__':
|
if func_node.name.value == '__init__':
|
||||||
@@ -582,6 +585,11 @@ class SelfAttributeFilter(ClassFilter):
|
|||||||
# filter.
|
# filter.
|
||||||
if self._is_in_right_scope(trailer.parent.children[0], name):
|
if self._is_in_right_scope(trailer.parent.children[0], name):
|
||||||
yield name
|
yield name
|
||||||
|
elif trailer.type == "expr_stmt" \
|
||||||
|
and len(trailer.parent.children) == 2:
|
||||||
|
if name.is_definition() and self._access_possible(name):
|
||||||
|
if trailer.children[1].type == "annassign":
|
||||||
|
yield name
|
||||||
|
|
||||||
def _is_in_right_scope(self, self_name, name):
|
def _is_in_right_scope(self, self_name, name):
|
||||||
self_context = self._node_context.create_context(self_name)
|
self_context = self._node_context.create_context(self_name)
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ class VarClass:
|
|||||||
var_instance2: float
|
var_instance2: float
|
||||||
var_class1: typing.ClassVar[str] = 1
|
var_class1: typing.ClassVar[str] = 1
|
||||||
var_class2: typing.ClassVar[bytes]
|
var_class2: typing.ClassVar[bytes]
|
||||||
|
var_class3 = None
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
#? int()
|
#? int()
|
||||||
@@ -70,11 +71,17 @@ class VarClass:
|
|||||||
d.var_class2
|
d.var_class2
|
||||||
#? []
|
#? []
|
||||||
d.int
|
d.int
|
||||||
#? ['var_class1', 'var_class2', 'var_instance1', 'var_instance2']
|
#? ['var_class1', 'var_class2', 'var_instance1', 'var_instance2', 'var_class3']
|
||||||
self.var_
|
self.var_
|
||||||
|
|
||||||
|
class VarClass2(VarClass):
|
||||||
|
var_class3: typing.ClassVar[int]
|
||||||
|
|
||||||
#? ['var_class1', 'var_class2', 'var_instance1']
|
def __init__(self):
|
||||||
|
#? int()
|
||||||
|
self.var_class3
|
||||||
|
|
||||||
|
#? ['var_class1', 'var_class2', 'var_instance1', 'var_class3']
|
||||||
VarClass.var_
|
VarClass.var_
|
||||||
#? int()
|
#? int()
|
||||||
VarClass.var_instance1
|
VarClass.var_instance1
|
||||||
@@ -88,7 +95,7 @@ VarClass.var_class2
|
|||||||
VarClass.int
|
VarClass.int
|
||||||
|
|
||||||
d = VarClass()
|
d = VarClass()
|
||||||
#? ['var_class1', 'var_class2', 'var_instance1', 'var_instance2']
|
#? ['var_class1', 'var_class2', 'var_class3', 'var_instance1', 'var_instance2']
|
||||||
d.var_
|
d.var_
|
||||||
#? int()
|
#? int()
|
||||||
d.var_instance1
|
d.var_instance1
|
||||||
|
|||||||
@@ -41,6 +41,26 @@ def test_in_empty_space(Script):
|
|||||||
assert def_.name == 'X'
|
assert def_.name == 'X'
|
||||||
|
|
||||||
|
|
||||||
|
def test_classvar_completion(Script):
|
||||||
|
code = dedent('''\
|
||||||
|
from typing import ClassVar # 1
|
||||||
|
class Foo: # 2
|
||||||
|
var_class = None # 3
|
||||||
|
def __init__(self, var_class=None): # 4
|
||||||
|
self.var_class = var_class # 5
|
||||||
|
class Bar(Foo): # 6
|
||||||
|
var_class: ClassVar[int] # 7
|
||||||
|
|
||||||
|
def __init__(self): # 9
|
||||||
|
self.var_class.
|
||||||
|
int().
|
||||||
|
''')
|
||||||
|
expected_value = set(completion.name for completion in Script(code).complete(11, 14))
|
||||||
|
for completion in Script(code).complete(10, 23):
|
||||||
|
expected_value.remove(completion.name)
|
||||||
|
assert len(expected_value) == 0
|
||||||
|
|
||||||
|
|
||||||
def test_indent_value(Script):
|
def test_indent_value(Script):
|
||||||
"""
|
"""
|
||||||
If an INDENT is the next supposed token, we should still be able to
|
If an INDENT is the next supposed token, we should still be able to
|
||||||
|
|||||||
Reference in New Issue
Block a user