MCPcopy Index your code
hub / github.com/python/mypy / expr_attrs

Method expr_attrs

mypy/inspections.py:313–359  ·  view source on GitHub ↗

Format attributes that are valid for a given expression. If expression type is not an Instance, try using fallback. Attributes are returned as a JSON (ordered by MRO) that maps base class name to list of attributes. Attributes may appear in multiple bases if overridden (we s

(self, expression: Expression)

Source from the content-addressed store, hash-verified

311 attrs_strs.append(f'"{cls_name}": [{", ".join(attrs)}]')
312
313 def expr_attrs(self, expression: Expression) -> tuple[str, bool]:
314 """Format attributes that are valid for a given expression.
315
316 If expression type is not an Instance, try using fallback. Attributes are
317 returned as a JSON (ordered by MRO) that maps base class name to list of
318 attributes. Attributes may appear in multiple bases if overridden (we simply
319 follow usual mypy logic for creating new Vars etc).
320 """
321 expr_type = self.fg_manager.manager.all_types.get(expression)
322 if expr_type is None:
323 return self.missing_type(expression), False
324
325 expr_type = get_proper_type(expr_type)
326 instances = get_instance_fallback(expr_type)
327 if not instances:
328 # Everything is an object in Python.
329 instances = [self.object_type()]
330
331 attrs_dict = self.collect_attrs(instances)
332
333 # Special case: modules have names apart from those from ModuleType.
334 if isinstance(expression, RefExpr) and isinstance(expression.node, MypyFile):
335 node = expression.node
336 names = sorted(node.names)
337 if "__builtins__" in names:
338 # This is just to make tests stable. No one will really need this name.
339 names.remove("__builtins__")
340 mod_dict = {f'"<{node.fullname}>"': [f'"{name}"' for name in names]}
341 else:
342 mod_dict = {}
343
344 # Special case: for class callables, prepend with the class attributes.
345 # TODO: also handle cases when such callable appears in a union.
346 if isinstance(expr_type, FunctionLike) and expr_type.is_type_obj():
347 template = fill_typevars_with_any(expr_type.type_object())
348 class_dict = self.collect_attrs(get_instance_fallback(template))
349 else:
350 class_dict = {}
351
352 # We don't use JSON dump to be sure keys order is always preserved.
353 base_attrs = []
354 if mod_dict:
355 for mod in mod_dict:
356 base_attrs.append(f'{mod}: [{", ".join(mod_dict[mod])}]')
357 self._fill_from_dict(base_attrs, class_dict)
358 self._fill_from_dict(base_attrs, attrs_dict)
359 return self.add_prefixes(f'{{{", ".join(base_attrs)}}}', expression), True
360
361 def format_node(self, module: State, node: FuncBase | SymbolNode) -> str:
362 return f"{module.path}:{node.line}:{node.column + 1}:{node.name}"

Callers

nothing calls this directly

Calls 15

missing_typeMethod · 0.95
object_typeMethod · 0.95
collect_attrsMethod · 0.95
_fill_from_dictMethod · 0.95
add_prefixesMethod · 0.95
get_proper_typeFunction · 0.90
fill_typevars_with_anyFunction · 0.90
get_instance_fallbackFunction · 0.85
isinstanceFunction · 0.85
sortedFunction · 0.85
appendMethod · 0.80
getMethod · 0.45

Tested by

no test coverage detected