Make sure to use _stub_to_python_value_set for all conversions, see #1466

This commit is contained in:
Dave Halter
2020-01-07 01:27:50 +01:00
parent d8deceb4b1
commit 9b9cacfbf9
6 changed files with 53 additions and 25 deletions

View File

@@ -59,28 +59,23 @@ def _try_stub_to_python_names(names, prefer_stub_to_compiled=False):
yield name yield name
continue continue
name_list = name.get_qualified_names() if name.api_type == 'module':
if name_list is None: values = convert_values(name.infer(), ignore_compiled=prefer_stub_to_compiled)
values = NO_VALUES if values:
else: for v in values:
values = _infer_from_stub( yield v.name
module_context,
name_list[:-1],
ignore_compiled=prefer_stub_to_compiled,
)
if values and name_list:
new_names = values.goto(name_list[-1])
for new_name in new_names:
yield new_name
if new_names:
continue continue
elif values: else:
for c in values: v = name.get_defining_qualified_value()
yield c.name if v is not None:
continue converted = _stub_to_python_value_set(v, ignore_compiled=prefer_stub_to_compiled)
# This is the part where if we haven't found anything, just return the if converted:
# stub name. converted_names = converted.goto(name.get_public_name())
yield name if converted_names:
for n in converted_names:
yield n
continue
yield name
def _load_stub_module(module): def _load_stub_module(module):

View File

@@ -79,6 +79,13 @@ class AbstractNameDefinition(object):
def api_type(self): def api_type(self):
return self.parent_context.api_type return self.parent_context.api_type
def get_defining_qualified_value(self):
"""
Returns either None or the value that is public and qualified. Won't
return a function, because a name in a function is never public.
"""
return None
class AbstractArbitraryName(AbstractNameDefinition): class AbstractArbitraryName(AbstractNameDefinition):
""" """
@@ -124,6 +131,15 @@ class AbstractTreeName(AbstractNameDefinition):
return None return None
return parent_names + (self.tree_name.value,) return parent_names + (self.tree_name.value,)
def get_defining_qualified_value(self):
if self.is_import():
raise 1
elif self.parent_context:
values = self.parent_context.name.infer()
if len(values) == 1:
return next(iter(values))
return None
def goto(self): def goto(self):
context = self.parent_context context = self.parent_context
name = self.tree_name name = self.tree_name

View File

@@ -509,6 +509,9 @@ class SelfName(TreeNameDefinition):
def parent_context(self): def parent_context(self):
return self._instance.create_instance_context(self.class_context, self.tree_name) return self._instance.create_instance_context(self.class_context, self.tree_name)
def get_defining_qualified_value(self):
return self._instance
class LazyInstanceClassName(NameWrapper): class LazyInstanceClassName(NameWrapper):
def __init__(self, instance, class_member_name): def __init__(self, instance, class_member_name):
@@ -524,6 +527,9 @@ class LazyInstanceClassName(NameWrapper):
def get_signatures(self): def get_signatures(self):
return self.infer().get_signatures() return self.infer().get_signatures()
def get_defining_qualified_value(self):
return self._instance
class InstanceClassFilter(AbstractFilter): class InstanceClassFilter(AbstractFilter):
""" """

View File

@@ -74,6 +74,10 @@ class ClassName(TreeNameDefinition):
else: else:
yield result_value yield result_value
@property
def defining_qualified_value(self):
return self._class_value
class ClassFilter(ParserTreeFilter): class ClassFilter(ParserTreeFilter):
def __init__(self, class_value, node_context=None, until_position=None, def __init__(self, class_value, node_context=None, until_position=None,

View File

@@ -437,16 +437,17 @@ def test_import(names):
assert n.name == 'os' assert n.name == 'os'
assert n.type == 'module' assert n.type == 'module'
n = nms[2].goto()[0] nms = nms[2].goto()
assert n.name == 'path' assert nms
assert n.type == 'module' assert all(n.type == 'module' for n in nms)
assert 'posixpath' in {n.name for n in nms}
nms = names('import os.path', references=True) nms = names('import os.path', references=True)
n = nms[0].goto()[0] n = nms[0].goto()[0]
assert n.name == 'os' assert n.name == 'os'
assert n.type == 'module' assert n.type == 'module'
n = nms[1].goto()[0] n = nms[1].goto()[0]
# This is very special, normally the name doesn't chance, but since # This is very special, normally the name doesn't change, but since
# os.path is a sys.modules hack, it does. # os.path is a sys.modules hack, it does.
assert n.name in ('macpath', 'ntpath', 'posixpath', 'os2emxpath') assert n.name in ('macpath', 'ntpath', 'posixpath', 'os2emxpath')
assert n.type == 'module' assert n.type == 'module'

View File

@@ -152,6 +152,12 @@ def test_method_doc_with_signature(Script):
assert c.docstring() == 'writelines(lines: Iterable[AnyStr]) -> None' assert c.docstring() == 'writelines(lines: Iterable[AnyStr]) -> None'
def test_method_doc_with_signature2(Script):
code = 'f = open("")\nf.writelines'
d, = Script(code).goto()
assert d.docstring() == 'writelines(lines: Iterable[AnyStr]) -> None'
def test_with_stmt_error_recovery(Script): def test_with_stmt_error_recovery(Script):
assert Script('with open('') as foo: foo.\na').complete(line=1) assert Script('with open('') as foo: foo.\na').complete(line=1)