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.

mixins.py 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. # Copyright (c) 2010-2011, 2013-2014 LOGILAB S.A. (Paris, FRANCE) <contact@logilab.fr>
  2. # Copyright (c) 2014 Google, Inc.
  3. # Copyright (c) 2015-2016 Cara Vinson <ceridwenv@gmail.com>
  4. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  5. # For details: https://github.com/PyCQA/astroid/blob/master/COPYING.LESSER
  6. """This module contains some mixins for the different nodes.
  7. """
  8. import warnings
  9. from astroid import decorators
  10. from astroid import exceptions
  11. class BlockRangeMixIn(object):
  12. """override block range """
  13. @decorators.cachedproperty
  14. def blockstart_tolineno(self):
  15. return self.lineno
  16. def _elsed_block_range(self, lineno, orelse, last=None):
  17. """handle block line numbers range for try/finally, for, if and while
  18. statements
  19. """
  20. if lineno == self.fromlineno:
  21. return lineno, lineno
  22. if orelse:
  23. if lineno >= orelse[0].fromlineno:
  24. return lineno, orelse[-1].tolineno
  25. return lineno, orelse[0].fromlineno - 1
  26. return lineno, last or self.tolineno
  27. class FilterStmtsMixin(object):
  28. """Mixin for statement filtering and assignment type"""
  29. def _get_filtered_stmts(self, _, node, _stmts, mystmt):
  30. """method used in _filter_stmts to get statements and trigger break"""
  31. if self.statement() is mystmt:
  32. # original node's statement is the assignment, only keep
  33. # current node (gen exp, list comp)
  34. return [node], True
  35. return _stmts, False
  36. def assign_type(self):
  37. return self
  38. def ass_type(self):
  39. warnings.warn('%s.ass_type() is deprecated and slated for removal '
  40. 'in astroid 2.0, use %s.assign_type() instead.'
  41. % (type(self).__name__, type(self).__name__),
  42. PendingDeprecationWarning, stacklevel=2)
  43. return self.assign_type()
  44. class AssignTypeMixin(object):
  45. def assign_type(self):
  46. return self
  47. def ass_type(self):
  48. warnings.warn('%s.ass_type() is deprecated and slated for removal '
  49. 'in astroid 2.0, use %s.assign_type() instead.'
  50. % (type(self).__name__, type(self).__name__),
  51. PendingDeprecationWarning, stacklevel=2)
  52. return self.assign_type()
  53. def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt):
  54. """method used in filter_stmts"""
  55. if self is mystmt:
  56. return _stmts, True
  57. if self.statement() is mystmt:
  58. # original node's statement is the assignment, only keep
  59. # current node (gen exp, list comp)
  60. return [node], True
  61. return _stmts, False
  62. class ParentAssignTypeMixin(AssignTypeMixin):
  63. def assign_type(self):
  64. return self.parent.assign_type()
  65. def ass_type(self):
  66. warnings.warn('%s.ass_type() is deprecated and slated for removal '
  67. 'in astroid 2.0, use %s.assign_type() instead.'
  68. % (type(self).__name__, type(self).__name__),
  69. PendingDeprecationWarning, stacklevel=2)
  70. return self.assign_type()
  71. class ImportFromMixin(FilterStmtsMixin):
  72. """MixIn for From and Import Nodes"""
  73. def _infer_name(self, frame, name):
  74. return name
  75. def do_import_module(self, modname=None):
  76. """return the ast for a module whose name is <modname> imported by <self>
  77. """
  78. # handle special case where we are on a package node importing a module
  79. # using the same name as the package, which may end in an infinite loop
  80. # on relative imports
  81. # XXX: no more needed ?
  82. mymodule = self.root()
  83. level = getattr(self, 'level', None) # Import as no level
  84. if modname is None:
  85. modname = self.modname
  86. # XXX we should investigate deeper if we really want to check
  87. # importing itself: modname and mymodule.name be relative or absolute
  88. if mymodule.relative_to_absolute_name(modname, level) == mymodule.name:
  89. # FIXME: we used to raise InferenceError here, but why ?
  90. return mymodule
  91. return mymodule.import_module(modname, level=level,
  92. relative_only=level and level >= 1)
  93. def real_name(self, asname):
  94. """get name from 'as' name"""
  95. for name, _asname in self.names:
  96. if name == '*':
  97. return asname
  98. if not _asname:
  99. name = name.split('.', 1)[0]
  100. _asname = name
  101. if asname == _asname:
  102. return name
  103. raise exceptions.AttributeInferenceError(
  104. 'Could not find original name for {attribute} in {target!r}',
  105. target=self, attribute=asname)