Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.10/site-packages/astroid/interpreter/dunder_lookup.py: 50%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

34 statements  

1# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html 

2# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE 

3# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt 

4 

5"""Contains logic for retrieving special methods. 

6 

7This implementation does not rely on the dot attribute access 

8logic, found in ``.getattr()``. The difference between these two 

9is that the dunder methods are looked with the type slots 

10(you can find more about these here 

11http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/) 

12As such, the lookup for the special methods is actually simpler than 

13the dot attribute access. 

14""" 

15from __future__ import annotations 

16 

17import itertools 

18from typing import TYPE_CHECKING 

19 

20import astroid 

21from astroid.exceptions import AttributeInferenceError 

22 

23if TYPE_CHECKING: 

24 from astroid import nodes 

25 from astroid.context import InferenceContext 

26 

27 

28def _lookup_in_mro(node, name) -> list: 

29 attrs = node.locals.get(name, []) 

30 

31 nodes = itertools.chain.from_iterable( 

32 ancestor.locals.get(name, []) for ancestor in node.ancestors(recurs=True) 

33 ) 

34 values = list(itertools.chain(attrs, nodes)) 

35 if not values: 

36 raise AttributeInferenceError(attribute=name, target=node) 

37 

38 return values 

39 

40 

41def lookup( 

42 node: nodes.NodeNG, name: str, context: InferenceContext | None = None 

43) -> list: 

44 """Lookup the given special method name in the given *node*. 

45 

46 If the special method was found, then a list of attributes 

47 will be returned. Otherwise, `astroid.AttributeInferenceError` 

48 is going to be raised. 

49 """ 

50 if isinstance( 

51 node, (astroid.List, astroid.Tuple, astroid.Const, astroid.Dict, astroid.Set) 

52 ): 

53 return _builtin_lookup(node, name) 

54 if isinstance(node, astroid.Instance): 

55 return _lookup_in_mro(node, name) 

56 if isinstance(node, astroid.ClassDef): 

57 return _class_lookup(node, name, context=context) 

58 

59 raise AttributeInferenceError(attribute=name, target=node) 

60 

61 

62def _class_lookup( 

63 node: nodes.ClassDef, name: str, context: InferenceContext | None = None 

64) -> list: 

65 metaclass = node.metaclass(context=context) 

66 if metaclass is None: 

67 raise AttributeInferenceError(attribute=name, target=node) 

68 

69 return _lookup_in_mro(metaclass, name) 

70 

71 

72def _builtin_lookup(node, name) -> list: 

73 values = node.locals.get(name, []) 

74 if not values: 

75 raise AttributeInferenceError(attribute=name, target=node) 

76 

77 return values