Development of an internal social media platform with personalised dashboards for students
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

dunder_lookup.py 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. # Copyright (c) 2016 Claudiu Popa <pcmanticore@gmail.com>
  2. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  3. # For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
  4. """Contains logic for retrieving special methods.
  5. This implementation does not rely on the dot attribute access
  6. logic, found in ``.getattr()``. The difference between these two
  7. is that the dunder methods are looked with the type slots
  8. (you can find more about these here
  9. http://lucumr.pocoo.org/2014/8/16/the-python-i-would-like-to-see/)
  10. As such, the lookup for the special methods is actually simpler than
  11. the dot attribute access.
  12. """
  13. import itertools
  14. import astroid
  15. from astroid import exceptions
  16. def _lookup_in_mro(node, name):
  17. attrs = node.locals.get(name, [])
  18. nodes = itertools.chain.from_iterable(
  19. ancestor.locals.get(name, [])
  20. for ancestor in node.ancestors(recurs=True)
  21. )
  22. values = list(itertools.chain(attrs, nodes))
  23. if not values:
  24. raise exceptions.AttributeInferenceError(
  25. attribute=name,
  26. target=node
  27. )
  28. return values
  29. def lookup(node, name):
  30. """Lookup the given special method name in the given *node*
  31. If the special method was found, then a list of attributes
  32. will be returned. Otherwise, `astroid.AttributeInferenceError`
  33. is going to be raised.
  34. """
  35. if isinstance(node, (astroid.List,
  36. astroid.Tuple,
  37. astroid.Const,
  38. astroid.Dict,
  39. astroid.Set)):
  40. return _builtin_lookup(node, name)
  41. elif isinstance(node, astroid.Instance):
  42. return _lookup_in_mro(node, name)
  43. elif isinstance(node, astroid.ClassDef):
  44. return _class_lookup(node, name)
  45. raise exceptions.AttributeInferenceError(
  46. attribute=name,
  47. target=node
  48. )
  49. def _class_lookup(node, name):
  50. metaclass = node.metaclass()
  51. if metaclass is None:
  52. raise exceptions.AttributeInferenceError(
  53. attribute=name,
  54. target=node
  55. )
  56. return _lookup_in_mro(metaclass, name)
  57. def _builtin_lookup(node, name):
  58. values = node.locals.get(name, [])
  59. if not values:
  60. raise exceptions.AttributeInferenceError(
  61. attribute=name,
  62. target=node
  63. )
  64. return values