forked from VimPlug/jedi
Ignore Final/ClassVar if they don't have a generic assignment
This commit is contained in:
@@ -34,7 +34,7 @@ _TYPE_ALIAS_TYPES = {
|
|||||||
'Deque': 'collections.deque',
|
'Deque': 'collections.deque',
|
||||||
}
|
}
|
||||||
_PROXY_TYPES = ['Optional', 'Union', 'ClassVar', 'Annotated', 'Final']
|
_PROXY_TYPES = ['Optional', 'Union', 'ClassVar', 'Annotated', 'Final']
|
||||||
_IGNORE_ANNOTATION_PARTS = ['ClassVar', 'Annotated', 'Final']
|
IGNORE_ANNOTATION_PARTS = ['ClassVar', 'Annotated', 'Final']
|
||||||
|
|
||||||
|
|
||||||
class TypingModuleName(NameWrapper):
|
class TypingModuleName(NameWrapper):
|
||||||
@@ -115,7 +115,7 @@ class ProxyWithGenerics(BaseTypingClassWithGenerics):
|
|||||||
elif string_name == 'Type':
|
elif string_name == 'Type':
|
||||||
# The type is actually already given in the index_value
|
# The type is actually already given in the index_value
|
||||||
return self._generics_manager[0]
|
return self._generics_manager[0]
|
||||||
elif string_name in _IGNORE_ANNOTATION_PARTS:
|
elif string_name in IGNORE_ANNOTATION_PARTS:
|
||||||
# For now don't do anything here, ClassVars are always used.
|
# For now don't do anything here, ClassVars are always used.
|
||||||
return self._generics_manager[0].execute_annotation()
|
return self._generics_manager[0].execute_annotation()
|
||||||
|
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ from jedi.inference.names import TreeNameDefinition
|
|||||||
from jedi.inference.context import CompForContext
|
from jedi.inference.context import CompForContext
|
||||||
from jedi.inference.value.decorator import Decoratee
|
from jedi.inference.value.decorator import Decoratee
|
||||||
from jedi.plugins import plugin_manager
|
from jedi.plugins import plugin_manager
|
||||||
|
from jedi.inference.gradual.typing import ProxyTypingValue, IGNORE_ANNOTATION_PARTS
|
||||||
|
|
||||||
operator_to_magic_method = {
|
operator_to_magic_method = {
|
||||||
'+': '__add__',
|
'+': '__add__',
|
||||||
@@ -701,16 +702,24 @@ def tree_name_to_values(inference_state, context, tree_name):
|
|||||||
correct_scope = parser_utils.get_parent_scope(name) == context.tree_node
|
correct_scope = parser_utils.get_parent_scope(name) == context.tree_node
|
||||||
ann_assign = expr_stmt.children[1]
|
ann_assign = expr_stmt.children[1]
|
||||||
if correct_scope:
|
if correct_scope:
|
||||||
found_annotation = True
|
|
||||||
if (
|
if (
|
||||||
(ann_assign.children[1].type == 'name')
|
(ann_assign.children[1].type == 'name')
|
||||||
and (ann_assign.children[1].value == tree_name.value)
|
and (ann_assign.children[1].value == tree_name.value)
|
||||||
and context.parent_context
|
and context.parent_context
|
||||||
):
|
):
|
||||||
context = context.parent_context
|
context = context.parent_context
|
||||||
value_set |= annotation.infer_annotation(
|
found = annotation.infer_annotation(
|
||||||
context, expr_stmt.children[1].children[1]
|
context, expr_stmt.children[1].children[1]
|
||||||
).execute_annotation()
|
)
|
||||||
|
set_found_annotation = True
|
||||||
|
if len(found) == 1:
|
||||||
|
first = next(iter(found))
|
||||||
|
set_found_annotation = not (
|
||||||
|
isinstance(first, ProxyTypingValue)
|
||||||
|
and first.name.string_name in IGNORE_ANNOTATION_PARTS
|
||||||
|
)
|
||||||
|
found_annotation = set_found_annotation
|
||||||
|
value_set |= found.execute_annotation()
|
||||||
if found_annotation:
|
if found_annotation:
|
||||||
return value_set
|
return value_set
|
||||||
|
|
||||||
|
|||||||
@@ -555,15 +555,3 @@ def typed_dict_test_foo(arg: Bar):
|
|||||||
arg['an_int']
|
arg['an_int']
|
||||||
#? int()
|
#? int()
|
||||||
arg['another_variable']
|
arg['another_variable']
|
||||||
|
|
||||||
# -------------------------
|
|
||||||
# Final
|
|
||||||
# -------------------------
|
|
||||||
|
|
||||||
x: Final[str] = 1
|
|
||||||
y: Final = 1
|
|
||||||
#? str()
|
|
||||||
x
|
|
||||||
# TODO
|
|
||||||
#?
|
|
||||||
y
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ class VarClass:
|
|||||||
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
|
var_class3 = None
|
||||||
|
var_class4: typing.ClassVar = ""
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
#? int()
|
#? int()
|
||||||
@@ -71,7 +72,7 @@ class VarClass:
|
|||||||
d.var_class2
|
d.var_class2
|
||||||
#? []
|
#? []
|
||||||
d.int
|
d.int
|
||||||
#? ['var_class1', 'var_class2', 'var_instance1', 'var_instance2', 'var_class3']
|
#? ['var_class1', 'var_class2', 'var_instance1', 'var_instance2', 'var_class3', 'var_class4']
|
||||||
self.var_
|
self.var_
|
||||||
|
|
||||||
class VarClass2(VarClass):
|
class VarClass2(VarClass):
|
||||||
@@ -81,7 +82,7 @@ class VarClass2(VarClass):
|
|||||||
#? int()
|
#? int()
|
||||||
self.var_class3
|
self.var_class3
|
||||||
|
|
||||||
#? ['var_class1', 'var_class2', 'var_instance1', 'var_class3', 'var_instance2']
|
#? ['var_class1', 'var_class2', 'var_class4', 'var_instance1', 'var_class3', 'var_instance2']
|
||||||
VarClass.var_
|
VarClass.var_
|
||||||
#? int()
|
#? int()
|
||||||
VarClass.var_instance1
|
VarClass.var_instance1
|
||||||
@@ -91,11 +92,13 @@ VarClass.var_instance2
|
|||||||
VarClass.var_class1
|
VarClass.var_class1
|
||||||
#? bytes()
|
#? bytes()
|
||||||
VarClass.var_class2
|
VarClass.var_class2
|
||||||
|
#? str()
|
||||||
|
VarClass.var_class4
|
||||||
#? []
|
#? []
|
||||||
VarClass.int
|
VarClass.int
|
||||||
|
|
||||||
d = VarClass()
|
d = VarClass()
|
||||||
#? ['var_class1', 'var_class2', 'var_class3', 'var_instance1', 'var_instance2']
|
#? ['var_class1', 'var_class2', 'var_class3', 'var_class4', 'var_instance1', 'var_instance2']
|
||||||
d.var_
|
d.var_
|
||||||
#? int()
|
#? int()
|
||||||
d.var_instance1
|
d.var_instance1
|
||||||
@@ -105,6 +108,8 @@ d.var_instance2
|
|||||||
d.var_class1
|
d.var_class1
|
||||||
#? bytes()
|
#? bytes()
|
||||||
d.var_class2
|
d.var_class2
|
||||||
|
#? str()
|
||||||
|
d.var_class4
|
||||||
#? []
|
#? []
|
||||||
d.int
|
d.int
|
||||||
|
|
||||||
@@ -117,3 +122,39 @@ class DC:
|
|||||||
|
|
||||||
#? int()
|
#? int()
|
||||||
DC().name
|
DC().name
|
||||||
|
|
||||||
|
# -------------------------
|
||||||
|
# Final
|
||||||
|
# -------------------------
|
||||||
|
|
||||||
|
# TODO this is wrong, but shouldn't matter that much
|
||||||
|
#? 0 int()
|
||||||
|
x: typing.Final[str] = 1
|
||||||
|
#? 0 int()
|
||||||
|
y: typing.Final = 1
|
||||||
|
#? str()
|
||||||
|
x
|
||||||
|
#? int()
|
||||||
|
y
|
||||||
|
|
||||||
|
def f(x: typing.Final[str]):
|
||||||
|
#? str()
|
||||||
|
x
|
||||||
|
|
||||||
|
class C:
|
||||||
|
x: typing.Final[bytes] = 1
|
||||||
|
#? 4 str()
|
||||||
|
y: typing.Final = ""
|
||||||
|
#? bytes()
|
||||||
|
x
|
||||||
|
#? str()
|
||||||
|
y
|
||||||
|
|
||||||
|
#? bytes()
|
||||||
|
C.x
|
||||||
|
#? str()
|
||||||
|
C.y
|
||||||
|
#? bytes()
|
||||||
|
C().x
|
||||||
|
#? str()
|
||||||
|
C().y
|
||||||
|
|||||||
Reference in New Issue
Block a user