1
0
forked from VimPlug/jedi

Fix ClassVar filter for instances

This commit is contained in:
Dave Halter
2019-06-26 22:56:30 +02:00
parent fafd6b2ac6
commit a9ff58683e
5 changed files with 74 additions and 15 deletions

View File

@@ -462,12 +462,13 @@ class InstanceClassFilter(AbstractFilter):
origin_scope=origin_scope,
is_instance=True,
))
assert isinstance(self._class_filter, ClassFilter), self._class_filter
def get(self, name):
return self._convert(self._class_filter.get(name))
return self._convert(self._class_filter.get(name, from_instance=True))
def values(self):
return self._convert(self._class_filter.values())
return self._convert(self._class_filter.values(from_instance=True))
def _convert(self, names):
return [LazyInstanceClassName(self._instance, self._class_context, n) for n in names]

View File

@@ -109,13 +109,27 @@ class ClassFilter(ParserTreeFilter):
node = get_cached_parent_scope(self._used_names, node)
return False
def _access_possible(self, name):
def _access_possible(self, name, from_instance):
# Filter for ClassVar variables
# TODO this is not properly done, yet. It just checks for the string
# ClassVar in the annotation, which can be quite imprecise. If we
# wanted to do this correct, we would have to resolve the ClassVar.
if not from_instance:
expr_stmt = name.get_definition()
if expr_stmt is not None and expr_stmt.type == 'expr_stmt':
annassign = expr_stmt.children[1]
if annassign.type == 'annassign':
# TODO this is not proper matching
if 'ClassVar' not in annassign.children[1].get_code():
return False
# Filter for name mangling of private variables like __foo
return not name.value.startswith('__') or name.value.endswith('__') \
or self._equals_origin_scope()
def _filter(self, names):
def _filter(self, names, from_instance=False):
names = super(ClassFilter, self)._filter(names)
return [name for name in names if self._access_possible(name)]
return [name for name in names if self._access_possible(name, from_instance)]
class ClassMixin(object):