Skip to content

Commit eee0af7

Browse files
andreaguarinoguillaume-dequenne
authored andcommitted
SONARPY-938 Serialize information about typeshed imported modules into protobuf
1 parent 71ed57b commit eee0af7

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

python-frontend/src/main/protobuf/symbols.proto

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,5 +95,6 @@ message VarSymbol {
9595
string name = 1;
9696
string fully_qualified_name = 2;
9797
optional Type type_annotation = 3;
98-
repeated string valid_for = 4;
98+
bool is_imported_module = 4;
99+
repeated string valid_for = 5;
99100
}

python-frontend/typeshed_serializer/serializer/symbols.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,15 @@ def to_proto(self) -> symbols_pb2.ClassSymbol:
320320

321321

322322
class VarSymbol:
323-
def __init__(self, var: mpn.Var):
324-
self.name = var.name
325-
self.fullname = var.fullname
326-
if var.type:
327-
self.type = TypeDescriptor(var.type)
323+
def __init__(self, name: str, fullname: str, is_imported_module=False, type_descriptor: TypeDescriptor = None):
324+
self.name = name
325+
self.fullname = fullname
326+
self.is_imported_module = is_imported_module
327+
self.type = type_descriptor
328+
329+
@classmethod
330+
def from_var(cls, var: mpn.Var):
331+
return cls(var.name, var.fullname, type_descriptor=TypeDescriptor(var.type) if var.type else None)
328332

329333
def __eq__(self, other):
330334
return isinstance(other, VarSymbol) and self.to_proto() == other.to_proto()
@@ -333,7 +337,9 @@ def to_proto(self) -> symbols_pb2.VarSymbol:
333337
pb_var = symbols_pb2.VarSymbol()
334338
pb_var.name = self.name
335339
pb_var.fully_qualified_name = self.fullname
336-
pb_var.type_annotation.CopyFrom(self.type.to_proto())
340+
if self.type is not None:
341+
pb_var.type_annotation.CopyFrom(self.type.to_proto())
342+
pb_var.is_imported_module = self.is_imported_module
337343
return pb_var
338344

339345

@@ -354,7 +360,11 @@ def __init__(self, mypy_file: mpn.MypyFile):
354360
if isinstance(symbol_table_node, mpn.TypeInfo):
355361
self.classes.append(ClassSymbol(symbol_table_node))
356362
if isinstance(symbol_table_node, mpn.Var) and symbol_table_node.name not in DEFAULT_EXPORTED_VARS:
357-
self.vars.append(VarSymbol(symbol_table_node))
363+
self.vars.append(VarSymbol.from_var(symbol_table_node))
364+
if isinstance(symbol_table_node, mpn.MypyFile):
365+
module_name = symbol_table_node.fullname
366+
if module_name != "builtins":
367+
self.vars.append(VarSymbol(key, module_name, is_imported_module=True))
358368

359369
def to_proto(self) -> symbols_pb2.ModuleSymbol:
360370
pb_module = symbols_pb2.ModuleSymbol()

python-frontend/typeshed_serializer/tests/test_symbols.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,17 @@ def test_module_symbol(typeshed_stdlib):
3737
assert pb_module.fully_qualified_name == "abc"
3838
assert len(pb_module.classes) == 5
3939
assert len(pb_module.functions) == 4
40+
imported_modules = [imported_module for imported_module in pb_module.vars if imported_module.is_imported_module is True]
41+
assert len(imported_modules) == 0
42+
43+
os_module = typeshed_stdlib.files.get("os")
44+
pb_module = symbols.ModuleSymbol(os_module).to_proto()
45+
imported_modules = [imported_module for imported_module in pb_module.vars if imported_module.is_imported_module is True]
46+
assert len(imported_modules) == 3
47+
imported_modules = map(lambda m: (m.fully_qualified_name, m.name), imported_modules)
48+
assert ("sys", "sys") in imported_modules
49+
assert ("os.path", "_path") in imported_modules
50+
assert ("os.path", "path") in imported_modules
4051

4152

4253
def test_class_symbol(typeshed_stdlib):

python-frontend/typeshed_serializer/tests/test_symbols_merger.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,15 @@ def test_actual_module_merge(fake_module_36_38):
205205
assert len(fakemodule_proto.overloaded_functions) == len(flattened_overloaded_funcs)
206206

207207
all_vars = merged_fakemodule_module.vars
208-
assert len(all_vars) == 5
208+
assert len(all_vars) == 6
209209
common_var = all_vars['fakemodule.common_var']
210210
assert len(common_var) == 1
211211
assert common_var[0].valid_for == ["36", "38"]
212212
var_symbol = common_var[0].var_symbol
213213
assert var_symbol.name == "common_var"
214214
assert var_symbol.fullname == "fakemodule.common_var"
215215
assert var_symbol.type.fully_qualified_name == "builtins.bool"
216+
assert var_symbol.is_imported_module is False
216217

217218
unique_var_36 = all_vars['fakemodule.unique_var_36']
218219
assert len(unique_var_36) == 1
@@ -237,6 +238,10 @@ def test_actual_module_merge(fake_module_36_38):
237238
assert alias_symbol.type.fully_qualified_name is None
238239
assert alias_symbol.type.is_unknown is True
239240

241+
imported_sys = all_vars['sys']
242+
assert len(imported_sys) == 1
243+
assert imported_sys[0].var_symbol.is_imported_module is True
244+
240245

241246
def assert_merged_class_symbol_to_proto(merged_classes_proto, merged_classes):
242247
assert len(merged_classes_proto) == len(merged_classes)

0 commit comments

Comments
 (0)