scoped_nodes.py 105 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100
  1. # Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
  2. # For details: https://github.com/PyCQA/astroid/blob/main/LICENSE
  3. # Copyright (c) https://github.com/PyCQA/astroid/blob/main/CONTRIBUTORS.txt
  4. """
  5. This module contains the classes for "scoped" node, i.e. which are opening a
  6. new local scope in the language definition : Module, ClassDef, FunctionDef (and
  7. Lambda, GeneratorExp, DictComp and SetComp to some extent).
  8. """
  9. from __future__ import annotations
  10. import io
  11. import itertools
  12. import os
  13. import sys
  14. import warnings
  15. from collections.abc import Generator, Iterator
  16. from functools import lru_cache
  17. from typing import TYPE_CHECKING, ClassVar, NoReturn, TypeVar, overload
  18. from astroid import bases
  19. from astroid import decorators as decorators_mod
  20. from astroid import util
  21. from astroid.const import IS_PYPY, PY38, PY38_PLUS, PY39_PLUS, PYPY_7_3_11_PLUS
  22. from astroid.context import (
  23. CallContext,
  24. InferenceContext,
  25. bind_context_to_node,
  26. copy_context,
  27. )
  28. from astroid.exceptions import (
  29. AstroidBuildingError,
  30. AstroidTypeError,
  31. AttributeInferenceError,
  32. DuplicateBasesError,
  33. InconsistentMroError,
  34. InferenceError,
  35. MroError,
  36. StatementMissing,
  37. TooManyLevelsError,
  38. )
  39. from astroid.interpreter.dunder_lookup import lookup
  40. from astroid.interpreter.objectmodel import ClassModel, FunctionModel, ModuleModel
  41. from astroid.manager import AstroidManager
  42. from astroid.nodes import Arguments, Const, NodeNG, _base_nodes, node_classes
  43. from astroid.nodes.scoped_nodes.mixin import ComprehensionScope, LocalsDictNodeNG
  44. from astroid.nodes.scoped_nodes.utils import builtin_lookup
  45. from astroid.nodes.utils import Position
  46. from astroid.typing import InferBinaryOp, InferenceResult, SuccessfulInferenceResult
  47. if sys.version_info >= (3, 8):
  48. from functools import cached_property
  49. from typing import Literal
  50. else:
  51. from typing_extensions import Literal
  52. from astroid.decorators import cachedproperty as cached_property
  53. if TYPE_CHECKING:
  54. from astroid import nodes
  55. ITER_METHODS = ("__iter__", "__getitem__")
  56. EXCEPTION_BASE_CLASSES = frozenset({"Exception", "BaseException"})
  57. objects = util.lazy_import("objects")
  58. BUILTIN_DESCRIPTORS = frozenset(
  59. {"classmethod", "staticmethod", "builtins.classmethod", "builtins.staticmethod"}
  60. )
  61. _T = TypeVar("_T")
  62. def _c3_merge(sequences, cls, context):
  63. """Merges MROs in *sequences* to a single MRO using the C3 algorithm.
  64. Adapted from http://www.python.org/download/releases/2.3/mro/.
  65. """
  66. result = []
  67. while True:
  68. sequences = [s for s in sequences if s] # purge empty sequences
  69. if not sequences:
  70. return result
  71. for s1 in sequences: # find merge candidates among seq heads
  72. candidate = s1[0]
  73. for s2 in sequences:
  74. if candidate in s2[1:]:
  75. candidate = None
  76. break # reject the current head, it appears later
  77. else:
  78. break
  79. if not candidate:
  80. # Show all the remaining bases, which were considered as
  81. # candidates for the next mro sequence.
  82. raise InconsistentMroError(
  83. message="Cannot create a consistent method resolution order "
  84. "for MROs {mros} of class {cls!r}.",
  85. mros=sequences,
  86. cls=cls,
  87. context=context,
  88. )
  89. result.append(candidate)
  90. # remove the chosen candidate
  91. for seq in sequences:
  92. if seq[0] == candidate:
  93. del seq[0]
  94. return None
  95. def clean_typing_generic_mro(sequences: list[list[ClassDef]]) -> None:
  96. """A class can inherit from typing.Generic directly, as base,
  97. and as base of bases. The merged MRO must however only contain the last entry.
  98. To prepare for _c3_merge, remove some typing.Generic entries from
  99. sequences if multiple are present.
  100. This method will check if Generic is in inferred_bases and also
  101. part of bases_mro. If true, remove it from inferred_bases
  102. as well as its entry the bases_mro.
  103. Format sequences: [[self]] + bases_mro + [inferred_bases]
  104. """
  105. bases_mro = sequences[1:-1]
  106. inferred_bases = sequences[-1]
  107. # Check if Generic is part of inferred_bases
  108. for i, base in enumerate(inferred_bases):
  109. if base.qname() == "typing.Generic":
  110. position_in_inferred_bases = i
  111. break
  112. else:
  113. return
  114. # Check if also part of bases_mro
  115. # Ignore entry for typing.Generic
  116. for i, seq in enumerate(bases_mro):
  117. if i == position_in_inferred_bases:
  118. continue
  119. if any(base.qname() == "typing.Generic" for base in seq):
  120. break
  121. else:
  122. return
  123. # Found multiple Generics in mro, remove entry from inferred_bases
  124. # and the corresponding one from bases_mro
  125. inferred_bases.pop(position_in_inferred_bases)
  126. bases_mro.pop(position_in_inferred_bases)
  127. def clean_duplicates_mro(sequences, cls, context):
  128. for sequence in sequences:
  129. names = [
  130. (node.lineno, node.qname()) if node.name else None for node in sequence
  131. ]
  132. last_index = dict(map(reversed, enumerate(names)))
  133. if names and names[0] is not None and last_index[names[0]] != 0:
  134. raise DuplicateBasesError(
  135. message="Duplicates found in MROs {mros} for {cls!r}.",
  136. mros=sequences,
  137. cls=cls,
  138. context=context,
  139. )
  140. yield [
  141. node
  142. for i, (node, name) in enumerate(zip(sequence, names))
  143. if name is None or last_index[name] == i
  144. ]
  145. def function_to_method(n, klass):
  146. if isinstance(n, FunctionDef):
  147. if n.type == "classmethod":
  148. return bases.BoundMethod(n, klass)
  149. if n.type == "property":
  150. return n
  151. if n.type != "staticmethod":
  152. return bases.UnboundMethod(n)
  153. return n
  154. class Module(LocalsDictNodeNG):
  155. """Class representing an :class:`ast.Module` node.
  156. >>> import astroid
  157. >>> node = astroid.extract_node('import astroid')
  158. >>> node
  159. <Import l.1 at 0x7f23b2e4e5c0>
  160. >>> node.parent
  161. <Module l.0 at 0x7f23b2e4eda0>
  162. """
  163. _astroid_fields = ("doc_node", "body")
  164. fromlineno: Literal[0] = 0
  165. """The first line that this node appears on in the source code."""
  166. lineno: Literal[0] = 0
  167. """The line that this node appears on in the source code."""
  168. # attributes below are set by the builder module or by raw factories
  169. file_bytes: str | bytes | None = None
  170. """The string/bytes that this ast was built from."""
  171. file_encoding: str | None = None
  172. """The encoding of the source file.
  173. This is used to get unicode out of a source file.
  174. Python 2 only.
  175. """
  176. special_attributes = ModuleModel()
  177. """The names of special attributes that this module has."""
  178. # names of module attributes available through the global scope
  179. scope_attrs = {"__name__", "__doc__", "__file__", "__path__", "__package__"}
  180. """The names of module attributes available through the global scope."""
  181. _other_fields = (
  182. "name",
  183. "doc",
  184. "file",
  185. "path",
  186. "package",
  187. "pure_python",
  188. "future_imports",
  189. )
  190. _other_other_fields = ("locals", "globals")
  191. col_offset: None
  192. end_lineno: None
  193. end_col_offset: None
  194. parent: None
  195. @decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
  196. def __init__(
  197. self,
  198. name: str,
  199. doc: str | None = None,
  200. file: str | None = None,
  201. path: list[str] | None = None,
  202. package: bool | None = None,
  203. parent: None = None,
  204. pure_python: bool | None = True,
  205. ) -> None:
  206. """
  207. :param name: The name of the module.
  208. :param doc: The module docstring.
  209. :param file: The path to the file that this ast has been extracted from.
  210. :param path:
  211. :param package: Whether the node represents a package or a module.
  212. :param parent: The parent node in the syntax tree.
  213. :param pure_python: Whether the ast was built from source.
  214. """
  215. self.name = name
  216. """The name of the module."""
  217. self._doc = doc
  218. """The module docstring."""
  219. self.file = file
  220. """The path to the file that this ast has been extracted from.
  221. This will be ``None`` when the representation has been built from a
  222. built-in module.
  223. """
  224. self.path = path
  225. self.package = package
  226. """Whether the node represents a package or a module."""
  227. self.pure_python = pure_python
  228. """Whether the ast was built from source."""
  229. self.globals: dict[str, list[node_classes.NodeNG]]
  230. """A map of the name of a global variable to the node defining the global."""
  231. self.locals = self.globals = {}
  232. """A map of the name of a local variable to the node defining the local."""
  233. self.body: list[node_classes.NodeNG] | None = []
  234. """The contents of the module."""
  235. self.doc_node: Const | None = None
  236. """The doc node associated with this node."""
  237. self.future_imports: set[str] = set()
  238. """The imports from ``__future__``."""
  239. super().__init__(lineno=0, parent=parent)
  240. # pylint: enable=redefined-builtin
  241. def postinit(self, body=None, *, doc_node: Const | None = None):
  242. """Do some setup after initialisation.
  243. :param body: The contents of the module.
  244. :type body: list(NodeNG) or None
  245. :param doc_node: The doc node associated with this node.
  246. """
  247. self.body = body
  248. self.doc_node = doc_node
  249. if doc_node:
  250. self._doc = doc_node.value
  251. @property
  252. def doc(self) -> str | None:
  253. """The module docstring."""
  254. warnings.warn(
  255. "The 'Module.doc' attribute is deprecated, "
  256. "use 'Module.doc_node' instead.",
  257. DeprecationWarning,
  258. stacklevel=2,
  259. )
  260. return self._doc
  261. @doc.setter
  262. def doc(self, value: str | None) -> None:
  263. warnings.warn(
  264. "Setting the 'Module.doc' attribute is deprecated, "
  265. "use 'Module.doc_node' instead.",
  266. DeprecationWarning,
  267. stacklevel=2,
  268. )
  269. self._doc = value
  270. def _get_stream(self):
  271. if self.file_bytes is not None:
  272. return io.BytesIO(self.file_bytes)
  273. if self.file is not None:
  274. # pylint: disable=consider-using-with
  275. stream = open(self.file, "rb")
  276. return stream
  277. return None
  278. def stream(self):
  279. """Get a stream to the underlying file or bytes.
  280. :type: file or io.BytesIO or None
  281. """
  282. return self._get_stream()
  283. def block_range(self, lineno):
  284. """Get a range from where this node starts to where this node ends.
  285. :param lineno: Unused.
  286. :type lineno: int
  287. :returns: The range of line numbers that this node belongs to.
  288. :rtype: tuple(int, int)
  289. """
  290. return self.fromlineno, self.tolineno
  291. def scope_lookup(self, node, name, offset=0):
  292. """Lookup where the given variable is assigned.
  293. :param node: The node to look for assignments up to.
  294. Any assignments after the given node are ignored.
  295. :type node: NodeNG
  296. :param name: The name of the variable to find assignments for.
  297. :type name: str
  298. :param offset: The line offset to filter statements up to.
  299. :type offset: int
  300. :returns: This scope node and the list of assignments associated to the
  301. given name according to the scope where it has been found (locals,
  302. globals or builtin).
  303. :rtype: tuple(str, list(NodeNG))
  304. """
  305. if name in self.scope_attrs and name not in self.locals:
  306. try:
  307. return self, self.getattr(name)
  308. except AttributeInferenceError:
  309. return self, ()
  310. return self._scope_lookup(node, name, offset)
  311. def pytype(self) -> Literal["builtins.module"]:
  312. """Get the name of the type that this node represents.
  313. :returns: The name of the type.
  314. """
  315. return "builtins.module"
  316. def display_type(self) -> str:
  317. """A human readable type of this node.
  318. :returns: The type of this node.
  319. :rtype: str
  320. """
  321. return "Module"
  322. def getattr(
  323. self, name, context: InferenceContext | None = None, ignore_locals=False
  324. ):
  325. if not name:
  326. raise AttributeInferenceError(target=self, attribute=name, context=context)
  327. result = []
  328. name_in_locals = name in self.locals
  329. if name in self.special_attributes and not ignore_locals and not name_in_locals:
  330. result = [self.special_attributes.lookup(name)]
  331. elif not ignore_locals and name_in_locals:
  332. result = self.locals[name]
  333. elif self.package:
  334. try:
  335. result = [self.import_module(name, relative_only=True)]
  336. except (AstroidBuildingError, SyntaxError) as exc:
  337. raise AttributeInferenceError(
  338. target=self, attribute=name, context=context
  339. ) from exc
  340. result = [n for n in result if not isinstance(n, node_classes.DelName)]
  341. if result:
  342. return result
  343. raise AttributeInferenceError(target=self, attribute=name, context=context)
  344. def igetattr(self, name, context: InferenceContext | None = None):
  345. """Infer the possible values of the given variable.
  346. :param name: The name of the variable to infer.
  347. :type name: str
  348. :returns: The inferred possible values.
  349. :rtype: iterable(NodeNG) or None
  350. """
  351. # set lookup name since this is necessary to infer on import nodes for
  352. # instance
  353. context = copy_context(context)
  354. context.lookupname = name
  355. try:
  356. return bases._infer_stmts(self.getattr(name, context), context, frame=self)
  357. except AttributeInferenceError as error:
  358. raise InferenceError(
  359. str(error), target=self, attribute=name, context=context
  360. ) from error
  361. def fully_defined(self) -> bool:
  362. """Check if this module has been build from a .py file.
  363. If so, the module contains a complete representation,
  364. including the code.
  365. :returns: Whether the module has been built from a .py file.
  366. """
  367. return self.file is not None and self.file.endswith(".py")
  368. @overload
  369. def statement(self, *, future: None = ...) -> Module:
  370. ...
  371. @overload
  372. def statement(self, *, future: Literal[True]) -> NoReturn:
  373. ...
  374. def statement(self, *, future: Literal[None, True] = None) -> Module | NoReturn:
  375. """The first parent node, including self, marked as statement node.
  376. When called on a :class:`Module` with the future parameter this raises an error.
  377. TODO: Deprecate the future parameter and only raise StatementMissing
  378. :raises StatementMissing: If no self has no parent attribute and future is True
  379. """
  380. if future:
  381. raise StatementMissing(target=self)
  382. warnings.warn(
  383. "In astroid 3.0.0 NodeNG.statement() will return either a nodes.Statement "
  384. "or raise a StatementMissing exception. nodes.Module will no longer be "
  385. "considered a statement. This behaviour can already be triggered "
  386. "by passing 'future=True' to a statement() call.",
  387. DeprecationWarning,
  388. stacklevel=2,
  389. )
  390. return self
  391. def previous_sibling(self):
  392. """The previous sibling statement.
  393. :returns: The previous sibling statement node.
  394. :rtype: NodeNG or None
  395. """
  396. def next_sibling(self):
  397. """The next sibling statement node.
  398. :returns: The next sibling statement node.
  399. :rtype: NodeNG or None
  400. """
  401. _absolute_import_activated = True
  402. def absolute_import_activated(self) -> bool:
  403. """Whether :pep:`328` absolute import behaviour has been enabled.
  404. :returns: Whether :pep:`328` has been enabled.
  405. """
  406. return self._absolute_import_activated
  407. def import_module(
  408. self,
  409. modname: str | None,
  410. relative_only: bool = False,
  411. level: int | None = None,
  412. use_cache: bool = True,
  413. ) -> Module:
  414. """Get the ast for a given module as if imported from this module.
  415. :param modname: The name of the module to "import".
  416. :param relative_only: Whether to only consider relative imports.
  417. :param level: The level of relative import.
  418. :param use_cache: Whether to use the astroid_cache of modules.
  419. :returns: The imported module ast.
  420. """
  421. if relative_only and level is None:
  422. level = 0
  423. absmodname = self.relative_to_absolute_name(modname, level)
  424. try:
  425. return AstroidManager().ast_from_module_name(
  426. absmodname, use_cache=use_cache
  427. )
  428. except AstroidBuildingError:
  429. # we only want to import a sub module or package of this module,
  430. # skip here
  431. if relative_only:
  432. raise
  433. return AstroidManager().ast_from_module_name(modname)
  434. def relative_to_absolute_name(
  435. self, modname: str | None, level: int | None
  436. ) -> str | None:
  437. """Get the absolute module name for a relative import.
  438. The relative import can be implicit or explicit.
  439. :param modname: The module name to convert.
  440. :param level: The level of relative import.
  441. :returns: The absolute module name.
  442. :raises TooManyLevelsError: When the relative import refers to a
  443. module too far above this one.
  444. """
  445. # XXX this returns non sens when called on an absolute import
  446. # like 'pylint.checkers.astroid.utils'
  447. # XXX doesn't return absolute name if self.name isn't absolute name
  448. if self.absolute_import_activated() and level is None:
  449. return modname
  450. if level:
  451. if self.package:
  452. level = level - 1
  453. package_name = self.name.rsplit(".", level)[0]
  454. elif (
  455. self.path
  456. and not os.path.exists(os.path.dirname(self.path[0]) + "/__init__.py")
  457. and os.path.exists(
  458. os.path.dirname(self.path[0]) + "/" + modname.split(".")[0]
  459. )
  460. ):
  461. level = level - 1
  462. package_name = ""
  463. else:
  464. package_name = self.name.rsplit(".", level)[0]
  465. if level and self.name.count(".") < level:
  466. raise TooManyLevelsError(level=level, name=self.name)
  467. elif self.package:
  468. package_name = self.name
  469. else:
  470. package_name = self.name.rsplit(".", 1)[0]
  471. if package_name:
  472. if not modname:
  473. return package_name
  474. return f"{package_name}.{modname}"
  475. return modname
  476. def wildcard_import_names(self):
  477. """The list of imported names when this module is 'wildcard imported'.
  478. It doesn't include the '__builtins__' name which is added by the
  479. current CPython implementation of wildcard imports.
  480. :returns: The list of imported names.
  481. :rtype: list(str)
  482. """
  483. # We separate the different steps of lookup in try/excepts
  484. # to avoid catching too many Exceptions
  485. default = [name for name in self.keys() if not name.startswith("_")]
  486. try:
  487. all_values = self["__all__"]
  488. except KeyError:
  489. return default
  490. try:
  491. explicit = next(all_values.assigned_stmts())
  492. except (InferenceError, StopIteration):
  493. return default
  494. except AttributeError:
  495. # not an assignment node
  496. # XXX infer?
  497. return default
  498. # Try our best to detect the exported name.
  499. inferred = []
  500. try:
  501. explicit = next(explicit.infer())
  502. except (InferenceError, StopIteration):
  503. return default
  504. if not isinstance(explicit, (node_classes.Tuple, node_classes.List)):
  505. return default
  506. def str_const(node) -> bool:
  507. return isinstance(node, node_classes.Const) and isinstance(node.value, str)
  508. for node in explicit.elts:
  509. if str_const(node):
  510. inferred.append(node.value)
  511. else:
  512. try:
  513. inferred_node = next(node.infer())
  514. except (InferenceError, StopIteration):
  515. continue
  516. if str_const(inferred_node):
  517. inferred.append(inferred_node.value)
  518. return inferred
  519. def public_names(self):
  520. """The list of the names that are publicly available in this module.
  521. :returns: The list of public names.
  522. :rtype: list(str)
  523. """
  524. return [name for name in self.keys() if not name.startswith("_")]
  525. def bool_value(self, context: InferenceContext | None = None) -> bool:
  526. """Determine the boolean value of this node.
  527. :returns: The boolean value of this node.
  528. For a :class:`Module` this is always ``True``.
  529. """
  530. return True
  531. def get_children(self):
  532. yield from self.body
  533. def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
  534. """The node's frame node.
  535. A frame node is a :class:`Module`, :class:`FunctionDef`,
  536. :class:`ClassDef` or :class:`Lambda`.
  537. :returns: The node itself.
  538. """
  539. return self
  540. class GeneratorExp(ComprehensionScope):
  541. """Class representing an :class:`ast.GeneratorExp` node.
  542. >>> import astroid
  543. >>> node = astroid.extract_node('(thing for thing in things if thing)')
  544. >>> node
  545. <GeneratorExp l.1 at 0x7f23b2e4e400>
  546. """
  547. _astroid_fields = ("elt", "generators")
  548. _other_other_fields = ("locals",)
  549. elt = None
  550. """The element that forms the output of the expression.
  551. :type: NodeNG or None
  552. """
  553. def __init__(
  554. self,
  555. lineno=None,
  556. col_offset=None,
  557. parent=None,
  558. *,
  559. end_lineno=None,
  560. end_col_offset=None,
  561. ):
  562. """
  563. :param lineno: The line that this node appears on in the source code.
  564. :type lineno: int or None
  565. :param col_offset: The column that this node appears on in the
  566. source code.
  567. :type col_offset: int or None
  568. :param parent: The parent node in the syntax tree.
  569. :type parent: NodeNG or None
  570. :param end_lineno: The last line this node appears on in the source code.
  571. :type end_lineno: Optional[int]
  572. :param end_col_offset: The end column this node appears on in the
  573. source code. Note: This is after the last symbol.
  574. :type end_col_offset: Optional[int]
  575. """
  576. self.locals = {}
  577. """A map of the name of a local variable to the node defining the local."""
  578. super().__init__(
  579. lineno=lineno,
  580. col_offset=col_offset,
  581. end_lineno=end_lineno,
  582. end_col_offset=end_col_offset,
  583. parent=parent,
  584. )
  585. def postinit(self, elt=None, generators: list[nodes.Comprehension] | None = None):
  586. """Do some setup after initialisation.
  587. :param elt: The element that forms the output of the expression.
  588. :type elt: NodeNG or None
  589. :param generators: The generators that are looped through.
  590. """
  591. self.elt = elt
  592. if generators is None:
  593. self.generators = []
  594. else:
  595. self.generators = generators
  596. def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
  597. """Determine the boolean value of this node.
  598. :returns: The boolean value of this node.
  599. For a :class:`GeneratorExp` this is always ``True``.
  600. """
  601. return True
  602. def get_children(self):
  603. yield self.elt
  604. yield from self.generators
  605. class DictComp(ComprehensionScope):
  606. """Class representing an :class:`ast.DictComp` node.
  607. >>> import astroid
  608. >>> node = astroid.extract_node('{k:v for k, v in things if k > v}')
  609. >>> node
  610. <DictComp l.1 at 0x7f23b2e41d68>
  611. """
  612. _astroid_fields = ("key", "value", "generators")
  613. _other_other_fields = ("locals",)
  614. key = None
  615. """What produces the keys.
  616. :type: NodeNG or None
  617. """
  618. value = None
  619. """What produces the values.
  620. :type: NodeNG or None
  621. """
  622. def __init__(
  623. self,
  624. lineno=None,
  625. col_offset=None,
  626. parent=None,
  627. *,
  628. end_lineno=None,
  629. end_col_offset=None,
  630. ):
  631. """
  632. :param lineno: The line that this node appears on in the source code.
  633. :type lineno: int or None
  634. :param col_offset: The column that this node appears on in the
  635. source code.
  636. :type col_offset: int or None
  637. :param parent: The parent node in the syntax tree.
  638. :type parent: NodeNG or None
  639. :param end_lineno: The last line this node appears on in the source code.
  640. :type end_lineno: Optional[int]
  641. :param end_col_offset: The end column this node appears on in the
  642. source code. Note: This is after the last symbol.
  643. :type end_col_offset: Optional[int]
  644. """
  645. self.locals = {}
  646. """A map of the name of a local variable to the node defining the local."""
  647. super().__init__(
  648. lineno=lineno,
  649. col_offset=col_offset,
  650. end_lineno=end_lineno,
  651. end_col_offset=end_col_offset,
  652. parent=parent,
  653. )
  654. def postinit(
  655. self,
  656. key=None,
  657. value=None,
  658. generators: list[nodes.Comprehension] | None = None,
  659. ):
  660. """Do some setup after initialisation.
  661. :param key: What produces the keys.
  662. :type key: NodeNG or None
  663. :param value: What produces the values.
  664. :type value: NodeNG or None
  665. :param generators: The generators that are looped through.
  666. """
  667. self.key = key
  668. self.value = value
  669. if generators is None:
  670. self.generators = []
  671. else:
  672. self.generators = generators
  673. def bool_value(self, context: InferenceContext | None = None):
  674. """Determine the boolean value of this node.
  675. :returns: The boolean value of this node.
  676. For a :class:`DictComp` this is always :class:`Uninferable`.
  677. :rtype: Uninferable
  678. """
  679. return util.Uninferable
  680. def get_children(self):
  681. yield self.key
  682. yield self.value
  683. yield from self.generators
  684. class SetComp(ComprehensionScope):
  685. """Class representing an :class:`ast.SetComp` node.
  686. >>> import astroid
  687. >>> node = astroid.extract_node('{thing for thing in things if thing}')
  688. >>> node
  689. <SetComp l.1 at 0x7f23b2e41898>
  690. """
  691. _astroid_fields = ("elt", "generators")
  692. _other_other_fields = ("locals",)
  693. elt = None
  694. """The element that forms the output of the expression.
  695. :type: NodeNG or None
  696. """
  697. def __init__(
  698. self,
  699. lineno=None,
  700. col_offset=None,
  701. parent=None,
  702. *,
  703. end_lineno=None,
  704. end_col_offset=None,
  705. ):
  706. """
  707. :param lineno: The line that this node appears on in the source code.
  708. :type lineno: int or None
  709. :param col_offset: The column that this node appears on in the
  710. source code.
  711. :type col_offset: int or None
  712. :param parent: The parent node in the syntax tree.
  713. :type parent: NodeNG or None
  714. :param end_lineno: The last line this node appears on in the source code.
  715. :type end_lineno: Optional[int]
  716. :param end_col_offset: The end column this node appears on in the
  717. source code. Note: This is after the last symbol.
  718. :type end_col_offset: Optional[int]
  719. """
  720. self.locals = {}
  721. """A map of the name of a local variable to the node defining the local."""
  722. super().__init__(
  723. lineno=lineno,
  724. col_offset=col_offset,
  725. end_lineno=end_lineno,
  726. end_col_offset=end_col_offset,
  727. parent=parent,
  728. )
  729. def postinit(self, elt=None, generators: list[nodes.Comprehension] | None = None):
  730. """Do some setup after initialisation.
  731. :param elt: The element that forms the output of the expression.
  732. :type elt: NodeNG or None
  733. :param generators: The generators that are looped through.
  734. """
  735. self.elt = elt
  736. if generators is None:
  737. self.generators = []
  738. else:
  739. self.generators = generators
  740. def bool_value(self, context: InferenceContext | None = None):
  741. """Determine the boolean value of this node.
  742. :returns: The boolean value of this node.
  743. For a :class:`SetComp` this is always :class:`Uninferable`.
  744. :rtype: Uninferable
  745. """
  746. return util.Uninferable
  747. def get_children(self):
  748. yield self.elt
  749. yield from self.generators
  750. class ListComp(ComprehensionScope):
  751. """Class representing an :class:`ast.ListComp` node.
  752. >>> import astroid
  753. >>> node = astroid.extract_node('[thing for thing in things if thing]')
  754. >>> node
  755. <ListComp l.1 at 0x7f23b2e418d0>
  756. """
  757. _astroid_fields = ("elt", "generators")
  758. _other_other_fields = ("locals",)
  759. elt = None
  760. """The element that forms the output of the expression.
  761. :type: NodeNG or None
  762. """
  763. def __init__(
  764. self,
  765. lineno=None,
  766. col_offset=None,
  767. parent=None,
  768. *,
  769. end_lineno=None,
  770. end_col_offset=None,
  771. ):
  772. self.locals = {}
  773. """A map of the name of a local variable to the node defining it."""
  774. super().__init__(
  775. lineno=lineno,
  776. col_offset=col_offset,
  777. end_lineno=end_lineno,
  778. end_col_offset=end_col_offset,
  779. parent=parent,
  780. )
  781. def postinit(self, elt=None, generators: list[nodes.Comprehension] | None = None):
  782. """Do some setup after initialisation.
  783. :param elt: The element that forms the output of the expression.
  784. :type elt: NodeNG or None
  785. :param generators: The generators that are looped through.
  786. :type generators: list(Comprehension) or None
  787. """
  788. self.elt = elt
  789. if generators is None:
  790. self.generators = []
  791. else:
  792. self.generators = generators
  793. def bool_value(self, context: InferenceContext | None = None):
  794. """Determine the boolean value of this node.
  795. :returns: The boolean value of this node.
  796. For a :class:`ListComp` this is always :class:`Uninferable`.
  797. :rtype: Uninferable
  798. """
  799. return util.Uninferable
  800. def get_children(self):
  801. yield self.elt
  802. yield from self.generators
  803. def _infer_decorator_callchain(node):
  804. """Detect decorator call chaining and see if the end result is a
  805. static or a classmethod.
  806. """
  807. if not isinstance(node, FunctionDef):
  808. return None
  809. if not node.parent:
  810. return None
  811. try:
  812. result = next(node.infer_call_result(node.parent), None)
  813. except InferenceError:
  814. return None
  815. if isinstance(result, bases.Instance):
  816. result = result._proxied
  817. if isinstance(result, ClassDef):
  818. if result.is_subtype_of("builtins.classmethod"):
  819. return "classmethod"
  820. if result.is_subtype_of("builtins.staticmethod"):
  821. return "staticmethod"
  822. if isinstance(result, FunctionDef):
  823. if not result.decorators:
  824. return None
  825. # Determine if this function is decorated with one of the builtin descriptors we want.
  826. for decorator in result.decorators.nodes:
  827. if isinstance(decorator, node_classes.Name):
  828. if decorator.name in BUILTIN_DESCRIPTORS:
  829. return decorator.name
  830. if (
  831. isinstance(decorator, node_classes.Attribute)
  832. and isinstance(decorator.expr, node_classes.Name)
  833. and decorator.expr.name == "builtins"
  834. and decorator.attrname in BUILTIN_DESCRIPTORS
  835. ):
  836. return decorator.attrname
  837. return None
  838. class Lambda(_base_nodes.FilterStmtsBaseNode, LocalsDictNodeNG):
  839. """Class representing an :class:`ast.Lambda` node.
  840. >>> import astroid
  841. >>> node = astroid.extract_node('lambda arg: arg + 1')
  842. >>> node
  843. <Lambda.<lambda> l.1 at 0x7f23b2e41518>
  844. """
  845. _astroid_fields = ("args", "body")
  846. _other_other_fields = ("locals",)
  847. name = "<lambda>"
  848. is_lambda = True
  849. special_attributes = FunctionModel()
  850. """The names of special attributes that this function has."""
  851. def implicit_parameters(self) -> Literal[0]:
  852. return 0
  853. @property
  854. def type(self) -> Literal["method", "function"]:
  855. """Whether this is a method or function.
  856. :returns: 'method' if this is a method, 'function' otherwise.
  857. """
  858. if self.args.arguments and self.args.arguments[0].name == "self":
  859. if isinstance(self.parent.scope(), ClassDef):
  860. return "method"
  861. return "function"
  862. def __init__(
  863. self,
  864. lineno=None,
  865. col_offset=None,
  866. parent=None,
  867. *,
  868. end_lineno=None,
  869. end_col_offset=None,
  870. ):
  871. """
  872. :param lineno: The line that this node appears on in the source code.
  873. :type lineno: int or None
  874. :param col_offset: The column that this node appears on in the
  875. source code.
  876. :type col_offset: int or None
  877. :param parent: The parent node in the syntax tree.
  878. :type parent: NodeNG or None
  879. :param end_lineno: The last line this node appears on in the source code.
  880. :type end_lineno: Optional[int]
  881. :param end_col_offset: The end column this node appears on in the
  882. source code. Note: This is after the last symbol.
  883. :type end_col_offset: Optional[int]
  884. """
  885. self.locals = {}
  886. """A map of the name of a local variable to the node defining it."""
  887. self.args: Arguments
  888. """The arguments that the function takes."""
  889. self.body = []
  890. """The contents of the function body.
  891. :type: list(NodeNG)
  892. """
  893. self.instance_attrs: dict[str, list[NodeNG]] = {}
  894. super().__init__(
  895. lineno=lineno,
  896. col_offset=col_offset,
  897. end_lineno=end_lineno,
  898. end_col_offset=end_col_offset,
  899. parent=parent,
  900. )
  901. def postinit(self, args: Arguments, body):
  902. """Do some setup after initialisation.
  903. :param args: The arguments that the function takes.
  904. :param body: The contents of the function body.
  905. :type body: list(NodeNG)
  906. """
  907. self.args = args
  908. self.body = body
  909. def pytype(self) -> Literal["bultins.instancemethod", "builtins.function"]:
  910. """Get the name of the type that this node represents.
  911. :returns: The name of the type.
  912. """
  913. if "method" in self.type:
  914. return "builtins.instancemethod"
  915. return "builtins.function"
  916. def display_type(self) -> str:
  917. """A human readable type of this node.
  918. :returns: The type of this node.
  919. :rtype: str
  920. """
  921. if "method" in self.type:
  922. return "Method"
  923. return "Function"
  924. def callable(self) -> Literal[True]:
  925. """Whether this node defines something that is callable.
  926. :returns: Whether this defines something that is callable
  927. For a :class:`Lambda` this is always ``True``.
  928. """
  929. return True
  930. def argnames(self) -> list[str]:
  931. """Get the names of each of the arguments, including that
  932. of the collections of variable-length arguments ("args", "kwargs",
  933. etc.), as well as positional-only and keyword-only arguments.
  934. :returns: The names of the arguments.
  935. :rtype: list(str)
  936. """
  937. if self.args.arguments: # maybe None with builtin functions
  938. names = _rec_get_names(self.args.arguments)
  939. else:
  940. names = []
  941. if self.args.vararg:
  942. names.append(self.args.vararg)
  943. names += [elt.name for elt in self.args.kwonlyargs]
  944. if self.args.kwarg:
  945. names.append(self.args.kwarg)
  946. return names
  947. def infer_call_result(self, caller, context: InferenceContext | None = None):
  948. """Infer what the function returns when called.
  949. :param caller: Unused
  950. :type caller: object
  951. """
  952. # pylint: disable=no-member; github.com/pycqa/astroid/issues/291
  953. # args is in fact redefined later on by postinit. Can't be changed
  954. # to None due to a strong interaction between Lambda and FunctionDef.
  955. return self.body.infer(context)
  956. def scope_lookup(self, node, name, offset=0):
  957. """Lookup where the given names is assigned.
  958. :param node: The node to look for assignments up to.
  959. Any assignments after the given node are ignored.
  960. :type node: NodeNG
  961. :param name: The name to find assignments for.
  962. :type name: str
  963. :param offset: The line offset to filter statements up to.
  964. :type offset: int
  965. :returns: This scope node and the list of assignments associated to the
  966. given name according to the scope where it has been found (locals,
  967. globals or builtin).
  968. :rtype: tuple(str, list(NodeNG))
  969. """
  970. if node in self.args.defaults or node in self.args.kw_defaults:
  971. frame = self.parent.frame(future=True)
  972. # line offset to avoid that def func(f=func) resolve the default
  973. # value to the defined function
  974. offset = -1
  975. else:
  976. # check this is not used in function decorators
  977. frame = self
  978. return frame._scope_lookup(node, name, offset)
  979. def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
  980. """Determine the boolean value of this node.
  981. :returns: The boolean value of this node.
  982. For a :class:`Lambda` this is always ``True``.
  983. """
  984. return True
  985. def get_children(self):
  986. yield self.args
  987. yield self.body
  988. def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
  989. """The node's frame node.
  990. A frame node is a :class:`Module`, :class:`FunctionDef`,
  991. :class:`ClassDef` or :class:`Lambda`.
  992. :returns: The node itself.
  993. """
  994. return self
  995. def getattr(
  996. self, name: str, context: InferenceContext | None = None
  997. ) -> list[NodeNG]:
  998. if not name:
  999. raise AttributeInferenceError(target=self, attribute=name, context=context)
  1000. found_attrs = []
  1001. if name in self.instance_attrs:
  1002. found_attrs = self.instance_attrs[name]
  1003. if name in self.special_attributes:
  1004. found_attrs.append(self.special_attributes.lookup(name))
  1005. if found_attrs:
  1006. return found_attrs
  1007. raise AttributeInferenceError(target=self, attribute=name)
  1008. class FunctionDef(_base_nodes.MultiLineBlockNode, _base_nodes.Statement, Lambda):
  1009. """Class representing an :class:`ast.FunctionDef`.
  1010. >>> import astroid
  1011. >>> node = astroid.extract_node('''
  1012. ... def my_func(arg):
  1013. ... return arg + 1
  1014. ... ''')
  1015. >>> node
  1016. <FunctionDef.my_func l.2 at 0x7f23b2e71e10>
  1017. """
  1018. _astroid_fields = ("decorators", "args", "returns", "doc_node", "body")
  1019. _multi_line_block_fields = ("body",)
  1020. returns = None
  1021. decorators: node_classes.Decorators | None = None
  1022. """The decorators that are applied to this method or function."""
  1023. is_function = True
  1024. """Whether this node indicates a function.
  1025. For a :class:`FunctionDef` this is always ``True``.
  1026. :type: bool
  1027. """
  1028. type_annotation = None
  1029. """If present, this will contain the type annotation passed by a type comment
  1030. :type: NodeNG or None
  1031. """
  1032. type_comment_args = None
  1033. """
  1034. If present, this will contain the type annotation for arguments
  1035. passed by a type comment
  1036. """
  1037. type_comment_returns = None
  1038. """If present, this will contain the return type annotation, passed by a type comment"""
  1039. # attributes below are set by the builder module or by raw factories
  1040. _other_fields = ("name", "doc", "position")
  1041. _other_other_fields = (
  1042. "locals",
  1043. "_type",
  1044. "type_comment_returns",
  1045. "type_comment_args",
  1046. )
  1047. _type = None
  1048. @decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
  1049. def __init__(
  1050. self,
  1051. name=None,
  1052. doc: str | None = None,
  1053. lineno=None,
  1054. col_offset=None,
  1055. parent=None,
  1056. *,
  1057. end_lineno=None,
  1058. end_col_offset=None,
  1059. ):
  1060. """
  1061. :param name: The name of the function.
  1062. :type name: str or None
  1063. :param doc: The function docstring.
  1064. :param lineno: The line that this node appears on in the source code.
  1065. :type lineno: int or None
  1066. :param col_offset: The column that this node appears on in the
  1067. source code.
  1068. :type col_offset: int or None
  1069. :param parent: The parent node in the syntax tree.
  1070. :type parent: NodeNG or None
  1071. :param end_lineno: The last line this node appears on in the source code.
  1072. :type end_lineno: Optional[int]
  1073. :param end_col_offset: The end column this node appears on in the
  1074. source code. Note: This is after the last symbol.
  1075. :type end_col_offset: Optional[int]
  1076. """
  1077. self.name = name
  1078. """The name of the function.
  1079. :type name: str or None
  1080. """
  1081. self._doc = doc
  1082. """The function docstring."""
  1083. self.doc_node: Const | None = None
  1084. """The doc node associated with this node."""
  1085. self.instance_attrs = {}
  1086. super().__init__(
  1087. lineno=lineno,
  1088. col_offset=col_offset,
  1089. end_lineno=end_lineno,
  1090. end_col_offset=end_col_offset,
  1091. parent=parent,
  1092. )
  1093. if parent:
  1094. frame = parent.frame(future=True)
  1095. frame.set_local(name, self)
  1096. def postinit(
  1097. self,
  1098. args: Arguments,
  1099. body,
  1100. decorators: node_classes.Decorators | None = None,
  1101. returns=None,
  1102. type_comment_returns=None,
  1103. type_comment_args=None,
  1104. *,
  1105. position: Position | None = None,
  1106. doc_node: Const | None = None,
  1107. ):
  1108. """Do some setup after initialisation.
  1109. :param args: The arguments that the function takes.
  1110. :param body: The contents of the function body.
  1111. :type body: list(NodeNG)
  1112. :param decorators: The decorators that are applied to this
  1113. method or function.
  1114. :type decorators: Decorators or None
  1115. :params type_comment_returns:
  1116. The return type annotation passed via a type comment.
  1117. :params type_comment_args:
  1118. The args type annotation passed via a type comment.
  1119. :params position:
  1120. Position of function keyword(s) and name.
  1121. :param doc_node:
  1122. The doc node associated with this node.
  1123. """
  1124. self.args = args
  1125. self.body = body
  1126. self.decorators = decorators
  1127. self.returns = returns
  1128. self.type_comment_returns = type_comment_returns
  1129. self.type_comment_args = type_comment_args
  1130. self.position = position
  1131. self.doc_node = doc_node
  1132. if doc_node:
  1133. self._doc = doc_node.value
  1134. @property
  1135. def doc(self) -> str | None:
  1136. """The function docstring."""
  1137. warnings.warn(
  1138. "The 'FunctionDef.doc' attribute is deprecated, "
  1139. "use 'FunctionDef.doc_node' instead.",
  1140. DeprecationWarning,
  1141. stacklevel=2,
  1142. )
  1143. return self._doc
  1144. @doc.setter
  1145. def doc(self, value: str | None) -> None:
  1146. warnings.warn(
  1147. "Setting the 'FunctionDef.doc' attribute is deprecated, "
  1148. "use 'FunctionDef.doc_node' instead.",
  1149. DeprecationWarning,
  1150. stacklevel=2,
  1151. )
  1152. self._doc = value
  1153. @cached_property
  1154. def extra_decorators(self) -> list[node_classes.Call]:
  1155. """The extra decorators that this function can have.
  1156. Additional decorators are considered when they are used as
  1157. assignments, as in ``method = staticmethod(method)``.
  1158. The property will return all the callables that are used for
  1159. decoration.
  1160. """
  1161. frame = self.parent.frame(future=True)
  1162. if not isinstance(frame, ClassDef):
  1163. return []
  1164. decorators: list[node_classes.Call] = []
  1165. for assign in frame._get_assign_nodes():
  1166. if isinstance(assign.value, node_classes.Call) and isinstance(
  1167. assign.value.func, node_classes.Name
  1168. ):
  1169. for assign_node in assign.targets:
  1170. if not isinstance(assign_node, node_classes.AssignName):
  1171. # Support only `name = callable(name)`
  1172. continue
  1173. if assign_node.name != self.name:
  1174. # Interested only in the assignment nodes that
  1175. # decorates the current method.
  1176. continue
  1177. try:
  1178. meth = frame[self.name]
  1179. except KeyError:
  1180. continue
  1181. else:
  1182. # Must be a function and in the same frame as the
  1183. # original method.
  1184. if (
  1185. isinstance(meth, FunctionDef)
  1186. and assign_node.frame(future=True) == frame
  1187. ):
  1188. decorators.append(assign.value)
  1189. return decorators
  1190. @cached_property
  1191. def type(self) -> str: # pylint: disable=too-many-return-statements # noqa: C901
  1192. """The function type for this node.
  1193. Possible values are: method, function, staticmethod, classmethod.
  1194. """
  1195. for decorator in self.extra_decorators:
  1196. if decorator.func.name in BUILTIN_DESCRIPTORS:
  1197. return decorator.func.name
  1198. frame = self.parent.frame(future=True)
  1199. type_name = "function"
  1200. if isinstance(frame, ClassDef):
  1201. if self.name == "__new__":
  1202. return "classmethod"
  1203. if self.name == "__init_subclass__":
  1204. return "classmethod"
  1205. if self.name == "__class_getitem__":
  1206. return "classmethod"
  1207. type_name = "method"
  1208. if not self.decorators:
  1209. return type_name
  1210. for node in self.decorators.nodes:
  1211. if isinstance(node, node_classes.Name):
  1212. if node.name in BUILTIN_DESCRIPTORS:
  1213. return node.name
  1214. if (
  1215. isinstance(node, node_classes.Attribute)
  1216. and isinstance(node.expr, node_classes.Name)
  1217. and node.expr.name == "builtins"
  1218. and node.attrname in BUILTIN_DESCRIPTORS
  1219. ):
  1220. return node.attrname
  1221. if isinstance(node, node_classes.Call):
  1222. # Handle the following case:
  1223. # @some_decorator(arg1, arg2)
  1224. # def func(...)
  1225. #
  1226. try:
  1227. current = next(node.func.infer())
  1228. except (InferenceError, StopIteration):
  1229. continue
  1230. _type = _infer_decorator_callchain(current)
  1231. if _type is not None:
  1232. return _type
  1233. try:
  1234. for inferred in node.infer():
  1235. # Check to see if this returns a static or a class method.
  1236. _type = _infer_decorator_callchain(inferred)
  1237. if _type is not None:
  1238. return _type
  1239. if not isinstance(inferred, ClassDef):
  1240. continue
  1241. for ancestor in inferred.ancestors():
  1242. if not isinstance(ancestor, ClassDef):
  1243. continue
  1244. if ancestor.is_subtype_of("builtins.classmethod"):
  1245. return "classmethod"
  1246. if ancestor.is_subtype_of("builtins.staticmethod"):
  1247. return "staticmethod"
  1248. except InferenceError:
  1249. pass
  1250. return type_name
  1251. @cached_property
  1252. def fromlineno(self) -> int | None:
  1253. """The first line that this node appears on in the source code."""
  1254. # lineno is the line number of the first decorator, we want the def
  1255. # statement lineno. Similar to 'ClassDef.fromlineno'
  1256. lineno = self.lineno
  1257. if self.decorators is not None:
  1258. lineno += sum(
  1259. node.tolineno - node.lineno + 1 for node in self.decorators.nodes
  1260. )
  1261. return lineno
  1262. @cached_property
  1263. def blockstart_tolineno(self):
  1264. """The line on which the beginning of this block ends.
  1265. :type: int
  1266. """
  1267. return self.args.tolineno
  1268. def implicit_parameters(self) -> Literal[0, 1]:
  1269. return 1 if self.is_bound() else 0
  1270. def block_range(self, lineno):
  1271. """Get a range from the given line number to where this node ends.
  1272. :param lineno: Unused.
  1273. :type lineno: int
  1274. :returns: The range of line numbers that this node belongs to,
  1275. :rtype: tuple(int, int)
  1276. """
  1277. return self.fromlineno, self.tolineno
  1278. def igetattr(self, name, context: InferenceContext | None = None):
  1279. """Inferred getattr, which returns an iterator of inferred statements."""
  1280. try:
  1281. return bases._infer_stmts(self.getattr(name, context), context, frame=self)
  1282. except AttributeInferenceError as error:
  1283. raise InferenceError(
  1284. str(error), target=self, attribute=name, context=context
  1285. ) from error
  1286. def is_method(self) -> bool:
  1287. """Check if this function node represents a method.
  1288. :returns: Whether this is a method.
  1289. """
  1290. # check we are defined in a ClassDef, because this is usually expected
  1291. # (e.g. pylint...) when is_method() return True
  1292. return self.type != "function" and isinstance(
  1293. self.parent.frame(future=True), ClassDef
  1294. )
  1295. @decorators_mod.cached
  1296. def decoratornames(self, context: InferenceContext | None = None):
  1297. """Get the qualified names of each of the decorators on this function.
  1298. :param context:
  1299. An inference context that can be passed to inference functions
  1300. :returns: The names of the decorators.
  1301. :rtype: set(str)
  1302. """
  1303. result = set()
  1304. decoratornodes = []
  1305. if self.decorators is not None:
  1306. decoratornodes += self.decorators.nodes
  1307. decoratornodes += self.extra_decorators
  1308. for decnode in decoratornodes:
  1309. try:
  1310. for infnode in decnode.infer(context=context):
  1311. result.add(infnode.qname())
  1312. except InferenceError:
  1313. continue
  1314. return result
  1315. def is_bound(self) -> bool:
  1316. """Check if the function is bound to an instance or class.
  1317. :returns: Whether the function is bound to an instance or class.
  1318. """
  1319. return self.type in {"method", "classmethod"}
  1320. def is_abstract(self, pass_is_abstract=True, any_raise_is_abstract=False) -> bool:
  1321. """Check if the method is abstract.
  1322. A method is considered abstract if any of the following is true:
  1323. * The only statement is 'raise NotImplementedError'
  1324. * The only statement is 'raise <SomeException>' and any_raise_is_abstract is True
  1325. * The only statement is 'pass' and pass_is_abstract is True
  1326. * The method is annotated with abc.astractproperty/abc.abstractmethod
  1327. :returns: Whether the method is abstract.
  1328. """
  1329. if self.decorators:
  1330. for node in self.decorators.nodes:
  1331. try:
  1332. inferred = next(node.infer())
  1333. except (InferenceError, StopIteration):
  1334. continue
  1335. if inferred and inferred.qname() in {
  1336. "abc.abstractproperty",
  1337. "abc.abstractmethod",
  1338. }:
  1339. return True
  1340. for child_node in self.body:
  1341. if isinstance(child_node, node_classes.Raise):
  1342. if any_raise_is_abstract:
  1343. return True
  1344. if child_node.raises_not_implemented():
  1345. return True
  1346. return pass_is_abstract and isinstance(child_node, node_classes.Pass)
  1347. # empty function is the same as function with a single "pass" statement
  1348. if pass_is_abstract:
  1349. return True
  1350. return False
  1351. def is_generator(self) -> bool:
  1352. """Check if this is a generator function.
  1353. :returns: Whether this is a generator function.
  1354. """
  1355. return bool(next(self._get_yield_nodes_skip_lambdas(), False))
  1356. def infer_yield_result(self, context: InferenceContext | None = None):
  1357. """Infer what the function yields when called
  1358. :returns: What the function yields
  1359. :rtype: iterable(NodeNG or Uninferable) or None
  1360. """
  1361. # pylint: disable=not-an-iterable
  1362. # https://github.com/PyCQA/astroid/issues/1015
  1363. for yield_ in self.nodes_of_class(node_classes.Yield):
  1364. if yield_.value is None:
  1365. const = node_classes.Const(None)
  1366. const.parent = yield_
  1367. const.lineno = yield_.lineno
  1368. yield const
  1369. elif yield_.scope() == self:
  1370. yield from yield_.value.infer(context=context)
  1371. def infer_call_result(self, caller=None, context: InferenceContext | None = None):
  1372. """Infer what the function returns when called.
  1373. :returns: What the function returns.
  1374. :rtype: iterable(NodeNG or Uninferable) or None
  1375. """
  1376. if self.is_generator():
  1377. if isinstance(self, AsyncFunctionDef):
  1378. generator_cls = bases.AsyncGenerator
  1379. else:
  1380. generator_cls = bases.Generator
  1381. result = generator_cls(self, generator_initial_context=context)
  1382. yield result
  1383. return
  1384. # This is really a gigantic hack to work around metaclass generators
  1385. # that return transient class-generating functions. Pylint's AST structure
  1386. # cannot handle a base class object that is only used for calling __new__,
  1387. # but does not contribute to the inheritance structure itself. We inject
  1388. # a fake class into the hierarchy here for several well-known metaclass
  1389. # generators, and filter it out later.
  1390. if (
  1391. self.name == "with_metaclass"
  1392. and caller is not None
  1393. and len(self.args.args) == 1
  1394. and self.args.vararg is not None
  1395. ):
  1396. if isinstance(caller.args, Arguments):
  1397. metaclass = next(caller.args.args[0].infer(context), None)
  1398. elif isinstance(caller.args, list):
  1399. metaclass = next(caller.args[0].infer(context), None)
  1400. else:
  1401. raise TypeError( # pragma: no cover
  1402. f"caller.args was neither Arguments nor list; got {type(caller.args)}"
  1403. )
  1404. if isinstance(metaclass, ClassDef):
  1405. try:
  1406. class_bases = [
  1407. # Find the first non-None inferred base value
  1408. next(
  1409. b
  1410. for b in arg.infer(context=context.clone())
  1411. if not (isinstance(b, Const) and b.value is None)
  1412. )
  1413. for arg in caller.args[1:]
  1414. ]
  1415. except StopIteration as e:
  1416. raise InferenceError(node=caller.args[1:], context=context) from e
  1417. new_class = ClassDef(name="temporary_class")
  1418. new_class.hide = True
  1419. new_class.parent = self
  1420. new_class.postinit(
  1421. bases=[
  1422. base
  1423. for base in class_bases
  1424. if not isinstance(base, util.UninferableBase)
  1425. ],
  1426. body=[],
  1427. decorators=[],
  1428. metaclass=metaclass,
  1429. )
  1430. yield new_class
  1431. return
  1432. returns = self._get_return_nodes_skip_functions()
  1433. first_return = next(returns, None)
  1434. if not first_return:
  1435. if self.body:
  1436. if self.is_abstract(pass_is_abstract=True, any_raise_is_abstract=True):
  1437. yield util.Uninferable
  1438. else:
  1439. yield node_classes.Const(None)
  1440. return
  1441. raise InferenceError("The function does not have any return statements")
  1442. for returnnode in itertools.chain((first_return,), returns):
  1443. if returnnode.value is None:
  1444. yield node_classes.Const(None)
  1445. else:
  1446. try:
  1447. yield from returnnode.value.infer(context)
  1448. except InferenceError:
  1449. yield util.Uninferable
  1450. def bool_value(self, context: InferenceContext | None = None) -> bool:
  1451. """Determine the boolean value of this node.
  1452. :returns: The boolean value of this node.
  1453. For a :class:`FunctionDef` this is always ``True``.
  1454. """
  1455. return True
  1456. def get_children(self):
  1457. if self.decorators is not None:
  1458. yield self.decorators
  1459. yield self.args
  1460. if self.returns is not None:
  1461. yield self.returns
  1462. yield from self.body
  1463. def scope_lookup(self, node, name, offset=0):
  1464. """Lookup where the given name is assigned."""
  1465. if name == "__class__":
  1466. # __class__ is an implicit closure reference created by the compiler
  1467. # if any methods in a class body refer to either __class__ or super.
  1468. # In our case, we want to be able to look it up in the current scope
  1469. # when `__class__` is being used.
  1470. frame = self.parent.frame(future=True)
  1471. if isinstance(frame, ClassDef):
  1472. return self, [frame]
  1473. return super().scope_lookup(node, name, offset)
  1474. def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
  1475. """The node's frame node.
  1476. A frame node is a :class:`Module`, :class:`FunctionDef`,
  1477. :class:`ClassDef` or :class:`Lambda`.
  1478. :returns: The node itself.
  1479. """
  1480. return self
  1481. class AsyncFunctionDef(FunctionDef):
  1482. """Class representing an :class:`ast.FunctionDef` node.
  1483. A :class:`AsyncFunctionDef` is an asynchronous function
  1484. created with the `async` keyword.
  1485. >>> import astroid
  1486. >>> node = astroid.extract_node('''
  1487. async def func(things):
  1488. async for thing in things:
  1489. print(thing)
  1490. ''')
  1491. >>> node
  1492. <AsyncFunctionDef.func l.2 at 0x7f23b2e416d8>
  1493. >>> node.body[0]
  1494. <AsyncFor l.3 at 0x7f23b2e417b8>
  1495. """
  1496. def _rec_get_names(args, names: list[str] | None = None) -> list[str]:
  1497. """return a list of all argument names"""
  1498. if names is None:
  1499. names = []
  1500. for arg in args:
  1501. if isinstance(arg, node_classes.Tuple):
  1502. _rec_get_names(arg.elts, names)
  1503. else:
  1504. names.append(arg.name)
  1505. return names
  1506. def _is_metaclass(klass, seen=None) -> bool:
  1507. """Return if the given class can be
  1508. used as a metaclass.
  1509. """
  1510. if klass.name == "type":
  1511. return True
  1512. if seen is None:
  1513. seen = set()
  1514. for base in klass.bases:
  1515. try:
  1516. for baseobj in base.infer():
  1517. baseobj_name = baseobj.qname()
  1518. if baseobj_name in seen:
  1519. continue
  1520. seen.add(baseobj_name)
  1521. if isinstance(baseobj, bases.Instance):
  1522. # not abstract
  1523. return False
  1524. if baseobj is klass:
  1525. continue
  1526. if not isinstance(baseobj, ClassDef):
  1527. continue
  1528. if baseobj._type == "metaclass":
  1529. return True
  1530. if _is_metaclass(baseobj, seen):
  1531. return True
  1532. except InferenceError:
  1533. continue
  1534. return False
  1535. def _class_type(klass, ancestors=None):
  1536. """return a ClassDef node type to differ metaclass and exception
  1537. from 'regular' classes
  1538. """
  1539. # XXX we have to store ancestors in case we have an ancestor loop
  1540. if klass._type is not None:
  1541. return klass._type
  1542. if _is_metaclass(klass):
  1543. klass._type = "metaclass"
  1544. elif klass.name.endswith("Exception"):
  1545. klass._type = "exception"
  1546. else:
  1547. if ancestors is None:
  1548. ancestors = set()
  1549. klass_name = klass.qname()
  1550. if klass_name in ancestors:
  1551. # XXX we are in loop ancestors, and have found no type
  1552. klass._type = "class"
  1553. return "class"
  1554. ancestors.add(klass_name)
  1555. for base in klass.ancestors(recurs=False):
  1556. name = _class_type(base, ancestors)
  1557. if name != "class":
  1558. if name == "metaclass" and not _is_metaclass(klass):
  1559. # don't propagate it if the current class
  1560. # can't be a metaclass
  1561. continue
  1562. klass._type = base.type
  1563. break
  1564. if klass._type is None:
  1565. klass._type = "class"
  1566. return klass._type
  1567. def get_wrapping_class(node):
  1568. """Get the class that wraps the given node.
  1569. We consider that a class wraps a node if the class
  1570. is a parent for the said node.
  1571. :returns: The class that wraps the given node
  1572. :rtype: ClassDef or None
  1573. """
  1574. klass = node.frame(future=True)
  1575. while klass is not None and not isinstance(klass, ClassDef):
  1576. if klass.parent is None:
  1577. klass = None
  1578. else:
  1579. klass = klass.parent.frame(future=True)
  1580. return klass
  1581. # pylint: disable=too-many-instance-attributes
  1582. class ClassDef(
  1583. _base_nodes.FilterStmtsBaseNode, LocalsDictNodeNG, _base_nodes.Statement
  1584. ):
  1585. """Class representing an :class:`ast.ClassDef` node.
  1586. >>> import astroid
  1587. >>> node = astroid.extract_node('''
  1588. class Thing:
  1589. def my_meth(self, arg):
  1590. return arg + self.offset
  1591. ''')
  1592. >>> node
  1593. <ClassDef.Thing l.2 at 0x7f23b2e9e748>
  1594. """
  1595. # some of the attributes below are set by the builder module or
  1596. # by a raw factories
  1597. # a dictionary of class instances attributes
  1598. _astroid_fields = ("decorators", "bases", "keywords", "doc_node", "body") # name
  1599. decorators = None
  1600. """The decorators that are applied to this class.
  1601. :type: Decorators or None
  1602. """
  1603. special_attributes = ClassModel()
  1604. """The names of special attributes that this class has.
  1605. :type: objectmodel.ClassModel
  1606. """
  1607. _type = None
  1608. _metaclass: NodeNG | None = None
  1609. _metaclass_hack = False
  1610. hide = False
  1611. type = property(
  1612. _class_type,
  1613. doc=(
  1614. "The class type for this node.\n\n"
  1615. "Possible values are: class, metaclass, exception.\n\n"
  1616. ":type: str"
  1617. ),
  1618. )
  1619. _other_fields = ("name", "doc", "is_dataclass", "position")
  1620. _other_other_fields = ("locals", "_newstyle")
  1621. _newstyle = None
  1622. @decorators_mod.deprecate_arguments(doc="Use the postinit arg 'doc_node' instead")
  1623. def __init__(
  1624. self,
  1625. name=None,
  1626. doc: str | None = None,
  1627. lineno=None,
  1628. col_offset=None,
  1629. parent=None,
  1630. *,
  1631. end_lineno=None,
  1632. end_col_offset=None,
  1633. ):
  1634. """
  1635. :param name: The name of the class.
  1636. :type name: str or None
  1637. :param doc: The class docstring.
  1638. :param lineno: The line that this node appears on in the source code.
  1639. :type lineno: int or None
  1640. :param col_offset: The column that this node appears on in the
  1641. source code.
  1642. :type col_offset: int or None
  1643. :param parent: The parent node in the syntax tree.
  1644. :type parent: NodeNG or None
  1645. :param end_lineno: The last line this node appears on in the source code.
  1646. :type end_lineno: Optional[int]
  1647. :param end_col_offset: The end column this node appears on in the
  1648. source code. Note: This is after the last symbol.
  1649. :type end_col_offset: Optional[int]
  1650. """
  1651. self.instance_attrs = {}
  1652. self.locals = {}
  1653. """A map of the name of a local variable to the node defining it."""
  1654. self.keywords = []
  1655. """The keywords given to the class definition.
  1656. This is usually for :pep:`3115` style metaclass declaration.
  1657. :type: list(Keyword) or None
  1658. """
  1659. self.bases: list[NodeNG] = []
  1660. """What the class inherits from."""
  1661. self.body = []
  1662. """The contents of the class body.
  1663. :type: list(NodeNG)
  1664. """
  1665. self.name = name
  1666. """The name of the class.
  1667. :type name: str or None
  1668. """
  1669. self._doc = doc
  1670. """The class docstring."""
  1671. self.doc_node: Const | None = None
  1672. """The doc node associated with this node."""
  1673. self.is_dataclass: bool = False
  1674. """Whether this class is a dataclass."""
  1675. super().__init__(
  1676. lineno=lineno,
  1677. col_offset=col_offset,
  1678. end_lineno=end_lineno,
  1679. end_col_offset=end_col_offset,
  1680. parent=parent,
  1681. )
  1682. if parent is not None:
  1683. parent.frame(future=True).set_local(name, self)
  1684. for local_name, node in self.implicit_locals():
  1685. self.add_local_node(node, local_name)
  1686. infer_binary_op: ClassVar[InferBinaryOp[ClassDef]]
  1687. @property
  1688. def doc(self) -> str | None:
  1689. """The class docstring."""
  1690. warnings.warn(
  1691. "The 'ClassDef.doc' attribute is deprecated, "
  1692. "use 'ClassDef.doc_node' instead.",
  1693. DeprecationWarning,
  1694. stacklevel=2,
  1695. )
  1696. return self._doc
  1697. @doc.setter
  1698. def doc(self, value: str | None) -> None:
  1699. warnings.warn(
  1700. "Setting the 'ClassDef.doc' attribute is deprecated, "
  1701. "use 'ClassDef.doc_node.value' instead.",
  1702. DeprecationWarning,
  1703. stacklevel=2,
  1704. )
  1705. self._doc = value
  1706. def implicit_parameters(self) -> Literal[1]:
  1707. return 1
  1708. def implicit_locals(self):
  1709. """Get implicitly defined class definition locals.
  1710. :returns: the the name and Const pair for each local
  1711. :rtype: tuple(tuple(str, node_classes.Const), ...)
  1712. """
  1713. locals_ = (("__module__", self.special_attributes.attr___module__),)
  1714. # __qualname__ is defined in PEP3155
  1715. locals_ += (("__qualname__", self.special_attributes.attr___qualname__),)
  1716. return locals_
  1717. # pylint: disable=redefined-outer-name
  1718. def postinit(
  1719. self,
  1720. bases,
  1721. body,
  1722. decorators,
  1723. newstyle=None,
  1724. metaclass: NodeNG | None = None,
  1725. keywords=None,
  1726. *,
  1727. position: Position | None = None,
  1728. doc_node: Const | None = None,
  1729. ):
  1730. """Do some setup after initialisation.
  1731. :param bases: What the class inherits from.
  1732. :type bases: list(NodeNG)
  1733. :param body: The contents of the class body.
  1734. :type body: list(NodeNG)
  1735. :param decorators: The decorators that are applied to this class.
  1736. :type decorators: Decorators or None
  1737. :param newstyle: Whether this is a new style class or not.
  1738. :type newstyle: bool or None
  1739. :param metaclass: The metaclass of this class.
  1740. :param keywords: The keywords given to the class definition.
  1741. :type keywords: list(Keyword) or None
  1742. :param position: Position of class keyword and name.
  1743. :param doc_node: The doc node associated with this node.
  1744. """
  1745. if keywords is not None:
  1746. self.keywords = keywords
  1747. self.bases = bases
  1748. self.body = body
  1749. self.decorators = decorators
  1750. if newstyle is not None:
  1751. self._newstyle = newstyle
  1752. if metaclass is not None:
  1753. self._metaclass = metaclass
  1754. self.position = position
  1755. self.doc_node = doc_node
  1756. if doc_node:
  1757. self._doc = doc_node.value
  1758. def _newstyle_impl(self, context: InferenceContext | None = None):
  1759. if context is None:
  1760. context = InferenceContext()
  1761. if self._newstyle is not None:
  1762. return self._newstyle
  1763. for base in self.ancestors(recurs=False, context=context):
  1764. if base._newstyle_impl(context):
  1765. self._newstyle = True
  1766. break
  1767. klass = self.declared_metaclass()
  1768. # could be any callable, we'd need to infer the result of klass(name,
  1769. # bases, dict). punt if it's not a class node.
  1770. if klass is not None and isinstance(klass, ClassDef):
  1771. self._newstyle = klass._newstyle_impl(context)
  1772. if self._newstyle is None:
  1773. self._newstyle = False
  1774. return self._newstyle
  1775. _newstyle = None
  1776. newstyle = property(
  1777. _newstyle_impl,
  1778. doc=("Whether this is a new style class or not\n\n" ":type: bool or None"),
  1779. )
  1780. @cached_property
  1781. def fromlineno(self) -> int | None:
  1782. """The first line that this node appears on in the source code."""
  1783. if not PY38_PLUS or IS_PYPY and PY38 and not PYPY_7_3_11_PLUS:
  1784. # For Python < 3.8 the lineno is the line number of the first decorator.
  1785. # We want the class statement lineno. Similar to 'FunctionDef.fromlineno'
  1786. # PyPy (3.8): Fixed with version v7.3.11
  1787. lineno = self.lineno
  1788. if self.decorators is not None:
  1789. lineno += sum(
  1790. node.tolineno - node.lineno + 1 for node in self.decorators.nodes
  1791. )
  1792. return lineno
  1793. return super().fromlineno
  1794. @cached_property
  1795. def blockstart_tolineno(self):
  1796. """The line on which the beginning of this block ends.
  1797. :type: int
  1798. """
  1799. if self.bases:
  1800. return self.bases[-1].tolineno
  1801. return self.fromlineno
  1802. def block_range(self, lineno):
  1803. """Get a range from the given line number to where this node ends.
  1804. :param lineno: Unused.
  1805. :type lineno: int
  1806. :returns: The range of line numbers that this node belongs to,
  1807. :rtype: tuple(int, int)
  1808. """
  1809. return self.fromlineno, self.tolineno
  1810. def pytype(self) -> Literal["builtins.type", "builtins.classobj"]:
  1811. """Get the name of the type that this node represents.
  1812. :returns: The name of the type.
  1813. """
  1814. if self.newstyle:
  1815. return "builtins.type"
  1816. return "builtins.classobj"
  1817. def display_type(self) -> str:
  1818. """A human readable type of this node.
  1819. :returns: The type of this node.
  1820. :rtype: str
  1821. """
  1822. return "Class"
  1823. def callable(self) -> bool:
  1824. """Whether this node defines something that is callable.
  1825. :returns: Whether this defines something that is callable.
  1826. For a :class:`ClassDef` this is always ``True``.
  1827. """
  1828. return True
  1829. def is_subtype_of(self, type_name, context: InferenceContext | None = None) -> bool:
  1830. """Whether this class is a subtype of the given type.
  1831. :param type_name: The name of the type of check against.
  1832. :type type_name: str
  1833. :returns: Whether this class is a subtype of the given type.
  1834. """
  1835. if self.qname() == type_name:
  1836. return True
  1837. return any(anc.qname() == type_name for anc in self.ancestors(context=context))
  1838. def _infer_type_call(self, caller, context):
  1839. try:
  1840. name_node = next(caller.args[0].infer(context))
  1841. except StopIteration as e:
  1842. raise InferenceError(node=caller.args[0], context=context) from e
  1843. if isinstance(name_node, node_classes.Const) and isinstance(
  1844. name_node.value, str
  1845. ):
  1846. name = name_node.value
  1847. else:
  1848. return util.Uninferable
  1849. result = ClassDef(name)
  1850. # Get the bases of the class.
  1851. try:
  1852. class_bases = next(caller.args[1].infer(context))
  1853. except StopIteration as e:
  1854. raise InferenceError(node=caller.args[1], context=context) from e
  1855. if isinstance(class_bases, (node_classes.Tuple, node_classes.List)):
  1856. bases = []
  1857. for base in class_bases.itered():
  1858. inferred = next(base.infer(context=context), None)
  1859. if inferred:
  1860. bases.append(
  1861. node_classes.EvaluatedObject(original=base, value=inferred)
  1862. )
  1863. result.bases = bases
  1864. else:
  1865. # There is currently no AST node that can represent an 'unknown'
  1866. # node (Uninferable is not an AST node), therefore we simply return Uninferable here
  1867. # although we know at least the name of the class.
  1868. return util.Uninferable
  1869. # Get the members of the class
  1870. try:
  1871. members = next(caller.args[2].infer(context))
  1872. except (InferenceError, StopIteration):
  1873. members = None
  1874. if members and isinstance(members, node_classes.Dict):
  1875. for attr, value in members.items:
  1876. if isinstance(attr, node_classes.Const) and isinstance(attr.value, str):
  1877. result.locals[attr.value] = [value]
  1878. result.parent = caller.parent
  1879. return result
  1880. def infer_call_result(self, caller, context: InferenceContext | None = None):
  1881. """infer what a class is returning when called"""
  1882. if self.is_subtype_of("builtins.type", context) and len(caller.args) == 3:
  1883. result = self._infer_type_call(caller, context)
  1884. yield result
  1885. return
  1886. dunder_call = None
  1887. try:
  1888. metaclass = self.metaclass(context=context)
  1889. if metaclass is not None:
  1890. # Only get __call__ if it's defined locally for the metaclass.
  1891. # Otherwise we will find ObjectModel.__call__ which will
  1892. # return an instance of the metaclass. Instantiating the class is
  1893. # handled later.
  1894. if "__call__" in metaclass.locals:
  1895. dunder_call = next(metaclass.igetattr("__call__", context))
  1896. except (AttributeInferenceError, StopIteration):
  1897. pass
  1898. if dunder_call and dunder_call.qname() != "builtins.type.__call__":
  1899. # Call type.__call__ if not set metaclass
  1900. # (since type is the default metaclass)
  1901. context = bind_context_to_node(context, self)
  1902. context.callcontext.callee = dunder_call
  1903. yield from dunder_call.infer_call_result(caller, context)
  1904. else:
  1905. yield self.instantiate_class()
  1906. def scope_lookup(self, node, name, offset=0):
  1907. """Lookup where the given name is assigned.
  1908. :param node: The node to look for assignments up to.
  1909. Any assignments after the given node are ignored.
  1910. :type node: NodeNG
  1911. :param name: The name to find assignments for.
  1912. :type name: str
  1913. :param offset: The line offset to filter statements up to.
  1914. :type offset: int
  1915. :returns: This scope node and the list of assignments associated to the
  1916. given name according to the scope where it has been found (locals,
  1917. globals or builtin).
  1918. :rtype: tuple(str, list(NodeNG))
  1919. """
  1920. # If the name looks like a builtin name, just try to look
  1921. # into the upper scope of this class. We might have a
  1922. # decorator that it's poorly named after a builtin object
  1923. # inside this class.
  1924. lookup_upper_frame = (
  1925. isinstance(node.parent, node_classes.Decorators)
  1926. and name in AstroidManager().builtins_module
  1927. )
  1928. if (
  1929. any(node == base or base.parent_of(node) for base in self.bases)
  1930. or lookup_upper_frame
  1931. ):
  1932. # Handle the case where we have either a name
  1933. # in the bases of a class, which exists before
  1934. # the actual definition or the case where we have
  1935. # a Getattr node, with that name.
  1936. #
  1937. # name = ...
  1938. # class A(name):
  1939. # def name(self): ...
  1940. #
  1941. # import name
  1942. # class A(name.Name):
  1943. # def name(self): ...
  1944. frame = self.parent.frame(future=True)
  1945. # line offset to avoid that class A(A) resolve the ancestor to
  1946. # the defined class
  1947. offset = -1
  1948. else:
  1949. frame = self
  1950. return frame._scope_lookup(node, name, offset)
  1951. @property
  1952. def basenames(self):
  1953. """The names of the parent classes
  1954. Names are given in the order they appear in the class definition.
  1955. :type: list(str)
  1956. """
  1957. return [bnode.as_string() for bnode in self.bases]
  1958. def ancestors(
  1959. self, recurs: bool = True, context: InferenceContext | None = None
  1960. ) -> Generator[ClassDef, None, None]:
  1961. """Iterate over the base classes in prefixed depth first order.
  1962. :param recurs: Whether to recurse or return direct ancestors only.
  1963. :returns: The base classes
  1964. """
  1965. # FIXME: should be possible to choose the resolution order
  1966. # FIXME: inference make infinite loops possible here
  1967. yielded = {self}
  1968. if context is None:
  1969. context = InferenceContext()
  1970. if not self.bases and self.qname() != "builtins.object":
  1971. yield builtin_lookup("object")[1][0]
  1972. return
  1973. for stmt in self.bases:
  1974. with context.restore_path():
  1975. try:
  1976. for baseobj in stmt.infer(context):
  1977. if not isinstance(baseobj, ClassDef):
  1978. if isinstance(baseobj, bases.Instance):
  1979. baseobj = baseobj._proxied
  1980. else:
  1981. continue
  1982. if not baseobj.hide:
  1983. if baseobj in yielded:
  1984. continue
  1985. yielded.add(baseobj)
  1986. yield baseobj
  1987. if not recurs:
  1988. continue
  1989. for grandpa in baseobj.ancestors(recurs=True, context=context):
  1990. if grandpa is self:
  1991. # This class is the ancestor of itself.
  1992. break
  1993. if grandpa in yielded:
  1994. continue
  1995. yielded.add(grandpa)
  1996. yield grandpa
  1997. except InferenceError:
  1998. continue
  1999. def local_attr_ancestors(self, name, context: InferenceContext | None = None):
  2000. """Iterate over the parents that define the given name.
  2001. :param name: The name to find definitions for.
  2002. :type name: str
  2003. :returns: The parents that define the given name.
  2004. :rtype: iterable(NodeNG)
  2005. """
  2006. # Look up in the mro if we can. This will result in the
  2007. # attribute being looked up just as Python does it.
  2008. try:
  2009. ancestors = self.mro(context)[1:]
  2010. except MroError:
  2011. # Fallback to use ancestors, we can't determine
  2012. # a sane MRO.
  2013. ancestors = self.ancestors(context=context)
  2014. for astroid in ancestors:
  2015. if name in astroid:
  2016. yield astroid
  2017. def instance_attr_ancestors(self, name, context: InferenceContext | None = None):
  2018. """Iterate over the parents that define the given name as an attribute.
  2019. :param name: The name to find definitions for.
  2020. :type name: str
  2021. :returns: The parents that define the given name as
  2022. an instance attribute.
  2023. :rtype: iterable(NodeNG)
  2024. """
  2025. for astroid in self.ancestors(context=context):
  2026. if name in astroid.instance_attrs:
  2027. yield astroid
  2028. def has_base(self, node) -> bool:
  2029. """Whether this class directly inherits from the given node.
  2030. :param node: The node to check for.
  2031. :type node: NodeNG
  2032. :returns: Whether this class directly inherits from the given node.
  2033. """
  2034. return node in self.bases
  2035. def local_attr(self, name, context: InferenceContext | None = None):
  2036. """Get the list of assign nodes associated to the given name.
  2037. Assignments are looked for in both this class and in parents.
  2038. :returns: The list of assignments to the given name.
  2039. :rtype: list(NodeNG)
  2040. :raises AttributeInferenceError: If no attribute with this name
  2041. can be found in this class or parent classes.
  2042. """
  2043. result = []
  2044. if name in self.locals:
  2045. result = self.locals[name]
  2046. else:
  2047. class_node = next(self.local_attr_ancestors(name, context), None)
  2048. if class_node:
  2049. result = class_node.locals[name]
  2050. result = [n for n in result if not isinstance(n, node_classes.DelAttr)]
  2051. if result:
  2052. return result
  2053. raise AttributeInferenceError(target=self, attribute=name, context=context)
  2054. def instance_attr(self, name, context: InferenceContext | None = None):
  2055. """Get the list of nodes associated to the given attribute name.
  2056. Assignments are looked for in both this class and in parents.
  2057. :returns: The list of assignments to the given name.
  2058. :rtype: list(NodeNG)
  2059. :raises AttributeInferenceError: If no attribute with this name
  2060. can be found in this class or parent classes.
  2061. """
  2062. # Return a copy, so we don't modify self.instance_attrs,
  2063. # which could lead to infinite loop.
  2064. values = list(self.instance_attrs.get(name, []))
  2065. # get all values from parents
  2066. for class_node in self.instance_attr_ancestors(name, context):
  2067. values += class_node.instance_attrs[name]
  2068. values = [n for n in values if not isinstance(n, node_classes.DelAttr)]
  2069. if values:
  2070. return values
  2071. raise AttributeInferenceError(target=self, attribute=name, context=context)
  2072. def instantiate_class(self) -> bases.Instance:
  2073. """Get an :class:`Instance` of the :class:`ClassDef` node.
  2074. :returns: An :class:`Instance` of the :class:`ClassDef` node
  2075. """
  2076. try:
  2077. if any(cls.name in EXCEPTION_BASE_CLASSES for cls in self.mro()):
  2078. # Subclasses of exceptions can be exception instances
  2079. return objects.ExceptionInstance(self)
  2080. except MroError:
  2081. pass
  2082. return bases.Instance(self)
  2083. def getattr(
  2084. self,
  2085. name: str,
  2086. context: InferenceContext | None = None,
  2087. class_context: bool = True,
  2088. ) -> list[SuccessfulInferenceResult]:
  2089. """Get an attribute from this class, using Python's attribute semantic.
  2090. This method doesn't look in the :attr:`instance_attrs` dictionary
  2091. since it is done by an :class:`Instance` proxy at inference time.
  2092. It may return an :class:`Uninferable` object if
  2093. the attribute has not been
  2094. found, but a ``__getattr__`` or ``__getattribute__`` method is defined.
  2095. If ``class_context`` is given, then it is considered that the
  2096. attribute is accessed from a class context,
  2097. e.g. ClassDef.attribute, otherwise it might have been accessed
  2098. from an instance as well. If ``class_context`` is used in that
  2099. case, then a lookup in the implicit metaclass and the explicit
  2100. metaclass will be done.
  2101. :param name: The attribute to look for.
  2102. :param class_context: Whether the attribute can be accessed statically.
  2103. :returns: The attribute.
  2104. :raises AttributeInferenceError: If the attribute cannot be inferred.
  2105. """
  2106. if not name:
  2107. raise AttributeInferenceError(target=self, attribute=name, context=context)
  2108. # don't modify the list in self.locals!
  2109. values: list[SuccessfulInferenceResult] = list(self.locals.get(name, []))
  2110. for classnode in self.ancestors(recurs=True, context=context):
  2111. values += classnode.locals.get(name, [])
  2112. if name in self.special_attributes and class_context and not values:
  2113. result = [self.special_attributes.lookup(name)]
  2114. if name == "__bases__":
  2115. # Need special treatment, since they are mutable
  2116. # and we need to return all the values.
  2117. result += values
  2118. return result
  2119. if class_context:
  2120. values += self._metaclass_lookup_attribute(name, context)
  2121. # Remove AnnAssigns without value, which are not attributes in the purest sense.
  2122. for value in values.copy():
  2123. if isinstance(value, node_classes.AssignName):
  2124. stmt = value.statement(future=True)
  2125. if isinstance(stmt, node_classes.AnnAssign) and stmt.value is None:
  2126. values.pop(values.index(value))
  2127. if not values:
  2128. raise AttributeInferenceError(target=self, attribute=name, context=context)
  2129. return values
  2130. @lru_cache(maxsize=1024) # noqa
  2131. def _metaclass_lookup_attribute(self, name, context):
  2132. """Search the given name in the implicit and the explicit metaclass."""
  2133. attrs = set()
  2134. implicit_meta = self.implicit_metaclass()
  2135. context = copy_context(context)
  2136. metaclass = self.metaclass(context=context)
  2137. for cls in (implicit_meta, metaclass):
  2138. if cls and cls != self and isinstance(cls, ClassDef):
  2139. cls_attributes = self._get_attribute_from_metaclass(cls, name, context)
  2140. attrs.update(set(cls_attributes))
  2141. return attrs
  2142. def _get_attribute_from_metaclass(self, cls, name, context):
  2143. try:
  2144. attrs = cls.getattr(name, context=context, class_context=True)
  2145. except AttributeInferenceError:
  2146. return
  2147. for attr in bases._infer_stmts(attrs, context, frame=cls):
  2148. if not isinstance(attr, FunctionDef):
  2149. yield attr
  2150. continue
  2151. if isinstance(attr, objects.Property):
  2152. yield attr
  2153. continue
  2154. if attr.type == "classmethod":
  2155. # If the method is a classmethod, then it will
  2156. # be bound to the metaclass, not to the class
  2157. # from where the attribute is retrieved.
  2158. # get_wrapping_class could return None, so just
  2159. # default to the current class.
  2160. frame = get_wrapping_class(attr) or self
  2161. yield bases.BoundMethod(attr, frame)
  2162. elif attr.type == "staticmethod":
  2163. yield attr
  2164. else:
  2165. yield bases.BoundMethod(attr, self)
  2166. def igetattr(
  2167. self,
  2168. name: str,
  2169. context: InferenceContext | None = None,
  2170. class_context: bool = True,
  2171. ) -> Iterator[InferenceResult]:
  2172. """Infer the possible values of the given variable.
  2173. :param name: The name of the variable to infer.
  2174. :returns: The inferred possible values.
  2175. """
  2176. # set lookup name since this is necessary to infer on import nodes for
  2177. # instance
  2178. context = copy_context(context)
  2179. context.lookupname = name
  2180. metaclass = self.metaclass(context=context)
  2181. try:
  2182. attributes = self.getattr(name, context, class_context=class_context)
  2183. # If we have more than one attribute, make sure that those starting from
  2184. # the second one are from the same scope. This is to account for modifications
  2185. # to the attribute happening *after* the attribute's definition (e.g. AugAssigns on lists)
  2186. if len(attributes) > 1:
  2187. first_attr, attributes = attributes[0], attributes[1:]
  2188. first_scope = first_attr.scope()
  2189. attributes = [first_attr] + [
  2190. attr
  2191. for attr in attributes
  2192. if attr.parent and attr.parent.scope() == first_scope
  2193. ]
  2194. for inferred in bases._infer_stmts(attributes, context, frame=self):
  2195. # yield Uninferable object instead of descriptors when necessary
  2196. if not isinstance(inferred, node_classes.Const) and isinstance(
  2197. inferred, bases.Instance
  2198. ):
  2199. try:
  2200. inferred._proxied.getattr("__get__", context)
  2201. except AttributeInferenceError:
  2202. yield inferred
  2203. else:
  2204. yield util.Uninferable
  2205. elif isinstance(inferred, objects.Property):
  2206. function = inferred.function
  2207. if not class_context:
  2208. # Through an instance so we can solve the property
  2209. yield from function.infer_call_result(
  2210. caller=self, context=context
  2211. )
  2212. # If we're in a class context, we need to determine if the property
  2213. # was defined in the metaclass (a derived class must be a subclass of
  2214. # the metaclass of all its bases), in which case we can resolve the
  2215. # property. If not, i.e. the property is defined in some base class
  2216. # instead, then we return the property object
  2217. elif metaclass and function.parent.scope() is metaclass:
  2218. # Resolve a property as long as it is not accessed through
  2219. # the class itself.
  2220. yield from function.infer_call_result(
  2221. caller=self, context=context
  2222. )
  2223. else:
  2224. yield inferred
  2225. else:
  2226. yield function_to_method(inferred, self)
  2227. except AttributeInferenceError as error:
  2228. if not name.startswith("__") and self.has_dynamic_getattr(context):
  2229. # class handle some dynamic attributes, return a Uninferable object
  2230. yield util.Uninferable
  2231. else:
  2232. raise InferenceError(
  2233. str(error), target=self, attribute=name, context=context
  2234. ) from error
  2235. def has_dynamic_getattr(self, context: InferenceContext | None = None) -> bool:
  2236. """Check if the class has a custom __getattr__ or __getattribute__.
  2237. If any such method is found and it is not from
  2238. builtins, nor from an extension module, then the function
  2239. will return True.
  2240. :returns: Whether the class has a custom __getattr__ or __getattribute__.
  2241. """
  2242. def _valid_getattr(node):
  2243. root = node.root()
  2244. return root.name != "builtins" and getattr(root, "pure_python", None)
  2245. try:
  2246. return _valid_getattr(self.getattr("__getattr__", context)[0])
  2247. except AttributeInferenceError:
  2248. # if self.newstyle: XXX cause an infinite recursion error
  2249. try:
  2250. getattribute = self.getattr("__getattribute__", context)[0]
  2251. return _valid_getattr(getattribute)
  2252. except AttributeInferenceError:
  2253. pass
  2254. return False
  2255. def getitem(self, index, context: InferenceContext | None = None):
  2256. """Return the inference of a subscript.
  2257. This is basically looking up the method in the metaclass and calling it.
  2258. :returns: The inferred value of a subscript to this class.
  2259. :rtype: NodeNG
  2260. :raises AstroidTypeError: If this class does not define a
  2261. ``__getitem__`` method.
  2262. """
  2263. try:
  2264. methods = lookup(self, "__getitem__")
  2265. except AttributeInferenceError as exc:
  2266. if isinstance(self, ClassDef):
  2267. # subscripting a class definition may be
  2268. # achieved thanks to __class_getitem__ method
  2269. # which is a classmethod defined in the class
  2270. # that supports subscript and not in the metaclass
  2271. try:
  2272. methods = self.getattr("__class_getitem__")
  2273. # Here it is assumed that the __class_getitem__ node is
  2274. # a FunctionDef. One possible improvement would be to deal
  2275. # with more generic inference.
  2276. except AttributeInferenceError:
  2277. raise AstroidTypeError(node=self, context=context) from exc
  2278. else:
  2279. raise AstroidTypeError(node=self, context=context) from exc
  2280. method = methods[0]
  2281. # Create a new callcontext for providing index as an argument.
  2282. new_context = bind_context_to_node(context, self)
  2283. new_context.callcontext = CallContext(args=[index], callee=method)
  2284. try:
  2285. return next(method.infer_call_result(self, new_context), util.Uninferable)
  2286. except AttributeError:
  2287. # Starting with python3.9, builtin types list, dict etc...
  2288. # are subscriptable thanks to __class_getitem___ classmethod.
  2289. # However in such case the method is bound to an EmptyNode and
  2290. # EmptyNode doesn't have infer_call_result method yielding to
  2291. # AttributeError
  2292. if (
  2293. isinstance(method, node_classes.EmptyNode)
  2294. and self.pytype() == "builtins.type"
  2295. and PY39_PLUS
  2296. ):
  2297. return self
  2298. raise
  2299. except InferenceError:
  2300. return util.Uninferable
  2301. def methods(self):
  2302. """Iterate over all of the method defined in this class and its parents.
  2303. :returns: The methods defined on the class.
  2304. :rtype: iterable(FunctionDef)
  2305. """
  2306. done = {}
  2307. for astroid in itertools.chain(iter((self,)), self.ancestors()):
  2308. for meth in astroid.mymethods():
  2309. if meth.name in done:
  2310. continue
  2311. done[meth.name] = None
  2312. yield meth
  2313. def mymethods(self):
  2314. """Iterate over all of the method defined in this class only.
  2315. :returns: The methods defined on the class.
  2316. :rtype: iterable(FunctionDef)
  2317. """
  2318. for member in self.values():
  2319. if isinstance(member, FunctionDef):
  2320. yield member
  2321. def implicit_metaclass(self):
  2322. """Get the implicit metaclass of the current class.
  2323. For newstyle classes, this will return an instance of builtins.type.
  2324. For oldstyle classes, it will simply return None, since there's
  2325. no implicit metaclass there.
  2326. :returns: The metaclass.
  2327. :rtype: builtins.type or None
  2328. """
  2329. if self.newstyle:
  2330. return builtin_lookup("type")[1][0]
  2331. return None
  2332. def declared_metaclass(
  2333. self, context: InferenceContext | None = None
  2334. ) -> NodeNG | None:
  2335. """Return the explicit declared metaclass for the current class.
  2336. An explicit declared metaclass is defined
  2337. either by passing the ``metaclass`` keyword argument
  2338. in the class definition line (Python 3) or (Python 2) by
  2339. having a ``__metaclass__`` class attribute, or if there are
  2340. no explicit bases but there is a global ``__metaclass__`` variable.
  2341. :returns: The metaclass of this class,
  2342. or None if one could not be found.
  2343. """
  2344. for base in self.bases:
  2345. try:
  2346. for baseobj in base.infer(context=context):
  2347. if isinstance(baseobj, ClassDef) and baseobj.hide:
  2348. self._metaclass = baseobj._metaclass
  2349. self._metaclass_hack = True
  2350. break
  2351. except InferenceError:
  2352. pass
  2353. if self._metaclass:
  2354. # Expects this from Py3k TreeRebuilder
  2355. try:
  2356. return next(
  2357. node
  2358. for node in self._metaclass.infer(context=context)
  2359. if not isinstance(node, util.UninferableBase)
  2360. )
  2361. except (InferenceError, StopIteration):
  2362. return None
  2363. return None
  2364. def _find_metaclass(
  2365. self, seen: set[ClassDef] | None = None, context: InferenceContext | None = None
  2366. ) -> NodeNG | None:
  2367. if seen is None:
  2368. seen = set()
  2369. seen.add(self)
  2370. klass = self.declared_metaclass(context=context)
  2371. if klass is None:
  2372. for parent in self.ancestors(context=context):
  2373. if parent not in seen:
  2374. klass = parent._find_metaclass(seen)
  2375. if klass is not None:
  2376. break
  2377. return klass
  2378. def metaclass(self, context: InferenceContext | None = None) -> NodeNG | None:
  2379. """Get the metaclass of this class.
  2380. If this class does not define explicitly a metaclass,
  2381. then the first defined metaclass in ancestors will be used
  2382. instead.
  2383. :returns: The metaclass of this class.
  2384. """
  2385. return self._find_metaclass(context=context)
  2386. def has_metaclass_hack(self):
  2387. return self._metaclass_hack
  2388. def _islots(self):
  2389. """Return an iterator with the inferred slots."""
  2390. if "__slots__" not in self.locals:
  2391. return None
  2392. for slots in self.igetattr("__slots__"):
  2393. # check if __slots__ is a valid type
  2394. for meth in ITER_METHODS:
  2395. try:
  2396. slots.getattr(meth)
  2397. break
  2398. except AttributeInferenceError:
  2399. continue
  2400. else:
  2401. continue
  2402. if isinstance(slots, node_classes.Const):
  2403. # a string. Ignore the following checks,
  2404. # but yield the node, only if it has a value
  2405. if slots.value:
  2406. yield slots
  2407. continue
  2408. if not hasattr(slots, "itered"):
  2409. # we can't obtain the values, maybe a .deque?
  2410. continue
  2411. if isinstance(slots, node_classes.Dict):
  2412. values = [item[0] for item in slots.items]
  2413. else:
  2414. values = slots.itered()
  2415. if isinstance(values, util.UninferableBase):
  2416. continue
  2417. if not values:
  2418. # Stop the iteration, because the class
  2419. # has an empty list of slots.
  2420. return values
  2421. for elt in values:
  2422. try:
  2423. for inferred in elt.infer():
  2424. if not isinstance(
  2425. inferred, node_classes.Const
  2426. ) or not isinstance(inferred.value, str):
  2427. continue
  2428. if not inferred.value:
  2429. continue
  2430. yield inferred
  2431. except InferenceError:
  2432. continue
  2433. return None
  2434. def _slots(self):
  2435. if not self.newstyle:
  2436. raise NotImplementedError(
  2437. "The concept of slots is undefined for old-style classes."
  2438. )
  2439. slots = self._islots()
  2440. try:
  2441. first = next(slots)
  2442. except StopIteration as exc:
  2443. # The class doesn't have a __slots__ definition or empty slots.
  2444. if exc.args and exc.args[0] not in ("", None):
  2445. return exc.args[0]
  2446. return None
  2447. return [first] + list(slots)
  2448. # Cached, because inferring them all the time is expensive
  2449. @decorators_mod.cached
  2450. def slots(self):
  2451. """Get all the slots for this node.
  2452. :returns: The names of slots for this class.
  2453. If the class doesn't define any slot, through the ``__slots__``
  2454. variable, then this function will return a None.
  2455. Also, it will return None in the case the slots were not inferred.
  2456. :rtype: list(str) or None
  2457. """
  2458. def grouped_slots(
  2459. mro: list[ClassDef],
  2460. ) -> Iterator[node_classes.NodeNG | None]:
  2461. for cls in mro:
  2462. # Not interested in object, since it can't have slots.
  2463. if cls.qname() == "builtins.object":
  2464. continue
  2465. try:
  2466. cls_slots = cls._slots()
  2467. except NotImplementedError:
  2468. continue
  2469. if cls_slots is not None:
  2470. yield from cls_slots
  2471. else:
  2472. yield None
  2473. if not self.newstyle:
  2474. raise NotImplementedError(
  2475. "The concept of slots is undefined for old-style classes."
  2476. )
  2477. try:
  2478. mro = self.mro()
  2479. except MroError as e:
  2480. raise NotImplementedError(
  2481. "Cannot get slots while parsing mro fails."
  2482. ) from e
  2483. slots = list(grouped_slots(mro))
  2484. if not all(slot is not None for slot in slots):
  2485. return None
  2486. return sorted(set(slots), key=lambda item: item.value)
  2487. def _inferred_bases(self, context: InferenceContext | None = None):
  2488. # Similar with .ancestors, but the difference is when one base is inferred,
  2489. # only the first object is wanted. That's because
  2490. # we aren't interested in superclasses, as in the following
  2491. # example:
  2492. #
  2493. # class SomeSuperClass(object): pass
  2494. # class SomeClass(SomeSuperClass): pass
  2495. # class Test(SomeClass): pass
  2496. #
  2497. # Inferring SomeClass from the Test's bases will give
  2498. # us both SomeClass and SomeSuperClass, but we are interested
  2499. # only in SomeClass.
  2500. if context is None:
  2501. context = InferenceContext()
  2502. if not self.bases and self.qname() != "builtins.object":
  2503. yield builtin_lookup("object")[1][0]
  2504. return
  2505. for stmt in self.bases:
  2506. try:
  2507. # Find the first non-None inferred base value
  2508. baseobj = next(
  2509. b
  2510. for b in stmt.infer(context=context.clone())
  2511. if not (isinstance(b, Const) and b.value is None)
  2512. )
  2513. except (InferenceError, StopIteration):
  2514. continue
  2515. if isinstance(baseobj, bases.Instance):
  2516. baseobj = baseobj._proxied
  2517. if not isinstance(baseobj, ClassDef):
  2518. continue
  2519. if not baseobj.hide:
  2520. yield baseobj
  2521. else:
  2522. yield from baseobj.bases
  2523. def _compute_mro(self, context: InferenceContext | None = None):
  2524. inferred_bases = list(self._inferred_bases(context=context))
  2525. bases_mro = []
  2526. for base in inferred_bases:
  2527. if base is self:
  2528. continue
  2529. try:
  2530. mro = base._compute_mro(context=context)
  2531. bases_mro.append(mro)
  2532. except NotImplementedError:
  2533. # Some classes have in their ancestors both newstyle and
  2534. # old style classes. For these we can't retrieve the .mro,
  2535. # although in Python it's possible, since the class we are
  2536. # currently working is in fact new style.
  2537. # So, we fallback to ancestors here.
  2538. ancestors = list(base.ancestors(context=context))
  2539. bases_mro.append(ancestors)
  2540. unmerged_mro = [[self]] + bases_mro + [inferred_bases]
  2541. unmerged_mro = list(clean_duplicates_mro(unmerged_mro, self, context))
  2542. clean_typing_generic_mro(unmerged_mro)
  2543. return _c3_merge(unmerged_mro, self, context)
  2544. def mro(self, context: InferenceContext | None = None) -> list[ClassDef]:
  2545. """Get the method resolution order, using C3 linearization.
  2546. :returns: The list of ancestors, sorted by the mro.
  2547. :rtype: list(NodeNG)
  2548. :raises DuplicateBasesError: Duplicate bases in the same class base
  2549. :raises InconsistentMroError: A class' MRO is inconsistent
  2550. """
  2551. return self._compute_mro(context=context)
  2552. def bool_value(self, context: InferenceContext | None = None) -> Literal[True]:
  2553. """Determine the boolean value of this node.
  2554. :returns: The boolean value of this node.
  2555. For a :class:`ClassDef` this is always ``True``.
  2556. """
  2557. return True
  2558. def get_children(self):
  2559. if self.decorators is not None:
  2560. yield self.decorators
  2561. yield from self.bases
  2562. if self.keywords is not None:
  2563. yield from self.keywords
  2564. yield from self.body
  2565. @decorators_mod.cached
  2566. def _get_assign_nodes(self):
  2567. children_assign_nodes = (
  2568. child_node._get_assign_nodes() for child_node in self.body
  2569. )
  2570. return list(itertools.chain.from_iterable(children_assign_nodes))
  2571. def frame(self: _T, *, future: Literal[None, True] = None) -> _T:
  2572. """The node's frame node.
  2573. A frame node is a :class:`Module`, :class:`FunctionDef`,
  2574. :class:`ClassDef` or :class:`Lambda`.
  2575. :returns: The node itself.
  2576. """
  2577. return self