checker.py 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198
  1. """
  2. Main module.
  3. Implement the central Checker class.
  4. Also, it models the Bindings and Scopes.
  5. """
  6. import __future__
  7. import builtins
  8. import ast
  9. import collections
  10. import contextlib
  11. import doctest
  12. import functools
  13. import os
  14. import re
  15. import string
  16. import sys
  17. import warnings
  18. from pyflakes import messages
  19. PYPY = hasattr(sys, 'pypy_version_info')
  20. builtin_vars = dir(builtins)
  21. parse_format_string = string.Formatter().parse
  22. def getAlternatives(n):
  23. if isinstance(n, ast.If):
  24. return [n.body]
  25. elif isinstance(n, ast.Try):
  26. return [n.body + n.orelse] + [[hdl] for hdl in n.handlers]
  27. elif sys.version_info >= (3, 10) and isinstance(n, ast.Match):
  28. return [mc.body for mc in n.cases]
  29. FOR_TYPES = (ast.For, ast.AsyncFor)
  30. def _is_singleton(node): # type: (ast.AST) -> bool
  31. return (
  32. isinstance(node, ast.Constant) and
  33. isinstance(node.value, (bool, type(Ellipsis), type(None)))
  34. )
  35. def _is_tuple_constant(node): # type: (ast.AST) -> bool
  36. return (
  37. isinstance(node, ast.Tuple) and
  38. all(_is_constant(elt) for elt in node.elts)
  39. )
  40. def _is_constant(node):
  41. return isinstance(node, ast.Constant) or _is_tuple_constant(node)
  42. def _is_const_non_singleton(node): # type: (ast.AST) -> bool
  43. return _is_constant(node) and not _is_singleton(node)
  44. def _is_name_or_attr(node, name): # type: (ast.AST, str) -> bool
  45. return (
  46. (isinstance(node, ast.Name) and node.id == name) or
  47. (isinstance(node, ast.Attribute) and node.attr == name)
  48. )
  49. MAPPING_KEY_RE = re.compile(r'\(([^()]*)\)')
  50. CONVERSION_FLAG_RE = re.compile('[#0+ -]*')
  51. WIDTH_RE = re.compile(r'(?:\*|\d*)')
  52. PRECISION_RE = re.compile(r'(?:\.(?:\*|\d*))?')
  53. LENGTH_RE = re.compile('[hlL]?')
  54. # https://docs.python.org/3/library/stdtypes.html#old-string-formatting
  55. VALID_CONVERSIONS = frozenset('diouxXeEfFgGcrsa%')
  56. def _must_match(regex, string, pos):
  57. match = regex.match(string, pos)
  58. assert match is not None
  59. return match
  60. def parse_percent_format(s):
  61. """Parses the string component of a `'...' % ...` format call
  62. Copied from https://github.com/asottile/pyupgrade at v1.20.1
  63. """
  64. def _parse_inner():
  65. string_start = 0
  66. string_end = 0
  67. in_fmt = False
  68. i = 0
  69. while i < len(s):
  70. if not in_fmt:
  71. try:
  72. i = s.index('%', i)
  73. except ValueError: # no more % fields!
  74. yield s[string_start:], None
  75. return
  76. else:
  77. string_end = i
  78. i += 1
  79. in_fmt = True
  80. else:
  81. key_match = MAPPING_KEY_RE.match(s, i)
  82. if key_match:
  83. key = key_match.group(1)
  84. i = key_match.end()
  85. else:
  86. key = None
  87. conversion_flag_match = _must_match(CONVERSION_FLAG_RE, s, i)
  88. conversion_flag = conversion_flag_match.group() or None
  89. i = conversion_flag_match.end()
  90. width_match = _must_match(WIDTH_RE, s, i)
  91. width = width_match.group() or None
  92. i = width_match.end()
  93. precision_match = _must_match(PRECISION_RE, s, i)
  94. precision = precision_match.group() or None
  95. i = precision_match.end()
  96. # length modifier is ignored
  97. i = _must_match(LENGTH_RE, s, i).end()
  98. try:
  99. conversion = s[i]
  100. except IndexError:
  101. raise ValueError('end-of-string while parsing format')
  102. i += 1
  103. fmt = (key, conversion_flag, width, precision, conversion)
  104. yield s[string_start:string_end], fmt
  105. in_fmt = False
  106. string_start = i
  107. if in_fmt:
  108. raise ValueError('end-of-string while parsing format')
  109. return tuple(_parse_inner())
  110. class _FieldsOrder(dict):
  111. """Fix order of AST node fields."""
  112. def _get_fields(self, node_class):
  113. # handle iter before target, and generators before element
  114. fields = node_class._fields
  115. if 'iter' in fields:
  116. key_first = 'iter'.find
  117. elif 'generators' in fields:
  118. key_first = 'generators'.find
  119. else:
  120. key_first = 'value'.find
  121. return tuple(sorted(fields, key=key_first, reverse=True))
  122. def __missing__(self, node_class):
  123. self[node_class] = fields = self._get_fields(node_class)
  124. return fields
  125. def counter(items):
  126. """
  127. Simplest required implementation of collections.Counter. Required as 2.6
  128. does not have Counter in collections.
  129. """
  130. results = {}
  131. for item in items:
  132. results[item] = results.get(item, 0) + 1
  133. return results
  134. def iter_child_nodes(node, omit=None, _fields_order=_FieldsOrder()):
  135. """
  136. Yield all direct child nodes of *node*, that is, all fields that
  137. are nodes and all items of fields that are lists of nodes.
  138. :param node: AST node to be iterated upon
  139. :param omit: String or tuple of strings denoting the
  140. attributes of the node to be omitted from
  141. further parsing
  142. :param _fields_order: Order of AST node fields
  143. """
  144. for name in _fields_order[node.__class__]:
  145. if omit and name in omit:
  146. continue
  147. field = getattr(node, name, None)
  148. if isinstance(field, ast.AST):
  149. yield field
  150. elif isinstance(field, list):
  151. for item in field:
  152. if isinstance(item, ast.AST):
  153. yield item
  154. def convert_to_value(item):
  155. if isinstance(item, ast.Constant):
  156. return item.value
  157. elif isinstance(item, ast.Tuple):
  158. return tuple(convert_to_value(i) for i in item.elts)
  159. elif isinstance(item, ast.Name):
  160. return VariableKey(item=item)
  161. else:
  162. return UnhandledKeyType()
  163. def is_notimplemented_name_node(node):
  164. return isinstance(node, ast.Name) and getNodeName(node) == 'NotImplemented'
  165. class Binding:
  166. """
  167. Represents the binding of a value to a name.
  168. The checker uses this to keep track of which names have been bound and
  169. which names have not. See L{Assignment} for a special type of binding that
  170. is checked with stricter rules.
  171. @ivar used: pair of (L{Scope}, node) indicating the scope and
  172. the node that this binding was last used.
  173. """
  174. def __init__(self, name, source):
  175. self.name = name
  176. self.source = source
  177. self.used = False
  178. def __str__(self):
  179. return self.name
  180. def __repr__(self):
  181. return '<{} object {!r} from line {!r} at 0x{:x}>'.format(
  182. self.__class__.__name__,
  183. self.name,
  184. self.source.lineno,
  185. id(self),
  186. )
  187. def redefines(self, other):
  188. return isinstance(other, Definition) and self.name == other.name
  189. class Definition(Binding):
  190. """
  191. A binding that defines a function or a class.
  192. """
  193. def redefines(self, other):
  194. return (
  195. super().redefines(other) or
  196. (isinstance(other, Assignment) and self.name == other.name)
  197. )
  198. class Builtin(Definition):
  199. """A definition created for all Python builtins."""
  200. def __init__(self, name):
  201. super().__init__(name, None)
  202. def __repr__(self):
  203. return '<{} object {!r} at 0x{:x}>'.format(
  204. self.__class__.__name__,
  205. self.name,
  206. id(self)
  207. )
  208. class UnhandledKeyType:
  209. """
  210. A dictionary key of a type that we cannot or do not check for duplicates.
  211. """
  212. class VariableKey:
  213. """
  214. A dictionary key which is a variable.
  215. @ivar item: The variable AST object.
  216. """
  217. def __init__(self, item):
  218. self.name = item.id
  219. def __eq__(self, compare):
  220. return (
  221. compare.__class__ == self.__class__ and
  222. compare.name == self.name
  223. )
  224. def __hash__(self):
  225. return hash(self.name)
  226. class Importation(Definition):
  227. """
  228. A binding created by an import statement.
  229. @ivar fullName: The complete name given to the import statement,
  230. possibly including multiple dotted components.
  231. @type fullName: C{str}
  232. """
  233. def __init__(self, name, source, full_name=None):
  234. self.fullName = full_name or name
  235. self.redefined = []
  236. super().__init__(name, source)
  237. def redefines(self, other):
  238. if isinstance(other, SubmoduleImportation):
  239. # See note in SubmoduleImportation about RedefinedWhileUnused
  240. return self.fullName == other.fullName
  241. return isinstance(other, Definition) and self.name == other.name
  242. def _has_alias(self):
  243. """Return whether importation needs an as clause."""
  244. return not self.fullName.split('.')[-1] == self.name
  245. @property
  246. def source_statement(self):
  247. """Generate a source statement equivalent to the import."""
  248. if self._has_alias():
  249. return f'import {self.fullName} as {self.name}'
  250. else:
  251. return 'import %s' % self.fullName
  252. def __str__(self):
  253. """Return import full name with alias."""
  254. if self._has_alias():
  255. return self.fullName + ' as ' + self.name
  256. else:
  257. return self.fullName
  258. class SubmoduleImportation(Importation):
  259. """
  260. A binding created by a submodule import statement.
  261. A submodule import is a special case where the root module is implicitly
  262. imported, without an 'as' clause, and the submodule is also imported.
  263. Python does not restrict which attributes of the root module may be used.
  264. This class is only used when the submodule import is without an 'as' clause.
  265. pyflakes handles this case by registering the root module name in the scope,
  266. allowing any attribute of the root module to be accessed.
  267. RedefinedWhileUnused is suppressed in `redefines` unless the submodule
  268. name is also the same, to avoid false positives.
  269. """
  270. def __init__(self, name, source):
  271. # A dot should only appear in the name when it is a submodule import
  272. assert '.' in name and (not source or isinstance(source, ast.Import))
  273. package_name = name.split('.')[0]
  274. super().__init__(package_name, source)
  275. self.fullName = name
  276. def redefines(self, other):
  277. if isinstance(other, Importation):
  278. return self.fullName == other.fullName
  279. return super().redefines(other)
  280. def __str__(self):
  281. return self.fullName
  282. @property
  283. def source_statement(self):
  284. return 'import ' + self.fullName
  285. class ImportationFrom(Importation):
  286. def __init__(self, name, source, module, real_name=None):
  287. self.module = module
  288. self.real_name = real_name or name
  289. if module.endswith('.'):
  290. full_name = module + self.real_name
  291. else:
  292. full_name = module + '.' + self.real_name
  293. super().__init__(name, source, full_name)
  294. def __str__(self):
  295. """Return import full name with alias."""
  296. if self.real_name != self.name:
  297. return self.fullName + ' as ' + self.name
  298. else:
  299. return self.fullName
  300. @property
  301. def source_statement(self):
  302. if self.real_name != self.name:
  303. return f'from {self.module} import {self.real_name} as {self.name}'
  304. else:
  305. return f'from {self.module} import {self.name}'
  306. class StarImportation(Importation):
  307. """A binding created by a 'from x import *' statement."""
  308. def __init__(self, name, source):
  309. super().__init__('*', source)
  310. # Each star importation needs a unique name, and
  311. # may not be the module name otherwise it will be deemed imported
  312. self.name = name + '.*'
  313. self.fullName = name
  314. @property
  315. def source_statement(self):
  316. return 'from ' + self.fullName + ' import *'
  317. def __str__(self):
  318. # When the module ends with a ., avoid the ambiguous '..*'
  319. if self.fullName.endswith('.'):
  320. return self.source_statement
  321. else:
  322. return self.name
  323. class FutureImportation(ImportationFrom):
  324. """
  325. A binding created by a from `__future__` import statement.
  326. `__future__` imports are implicitly used.
  327. """
  328. def __init__(self, name, source, scope):
  329. super().__init__(name, source, '__future__')
  330. self.used = (scope, source)
  331. class Argument(Binding):
  332. """
  333. Represents binding a name as an argument.
  334. """
  335. class Assignment(Binding):
  336. """
  337. Represents binding a name with an explicit assignment.
  338. The checker will raise warnings for any Assignment that isn't used. Also,
  339. the checker does not consider assignments in tuple/list unpacking to be
  340. Assignments, rather it treats them as simple Bindings.
  341. """
  342. class NamedExprAssignment(Assignment):
  343. """
  344. Represents binding a name with an assignment expression.
  345. """
  346. class Annotation(Binding):
  347. """
  348. Represents binding a name to a type without an associated value.
  349. As long as this name is not assigned a value in another binding, it is considered
  350. undefined for most purposes. One notable exception is using the name as a type
  351. annotation.
  352. """
  353. def redefines(self, other):
  354. """An Annotation doesn't define any name, so it cannot redefine one."""
  355. return False
  356. class FunctionDefinition(Definition):
  357. pass
  358. class ClassDefinition(Definition):
  359. pass
  360. class ExportBinding(Binding):
  361. """
  362. A binding created by an C{__all__} assignment. If the names in the list
  363. can be determined statically, they will be treated as names for export and
  364. additional checking applied to them.
  365. The only recognized C{__all__} assignment via list/tuple concatenation is in the
  366. following format:
  367. __all__ = ['a'] + ['b'] + ['c']
  368. Names which are imported and not otherwise used but appear in the value of
  369. C{__all__} will not have an unused import warning reported for them.
  370. """
  371. def __init__(self, name, source, scope):
  372. if '__all__' in scope and isinstance(source, ast.AugAssign):
  373. self.names = list(scope['__all__'].names)
  374. else:
  375. self.names = []
  376. def _add_to_names(container):
  377. for node in container.elts:
  378. if isinstance(node, ast.Constant) and isinstance(node.value, str):
  379. self.names.append(node.value)
  380. if isinstance(source.value, (ast.List, ast.Tuple)):
  381. _add_to_names(source.value)
  382. # If concatenating lists or tuples
  383. elif isinstance(source.value, ast.BinOp):
  384. currentValue = source.value
  385. while isinstance(currentValue.right, (ast.List, ast.Tuple)):
  386. left = currentValue.left
  387. right = currentValue.right
  388. _add_to_names(right)
  389. # If more lists are being added
  390. if isinstance(left, ast.BinOp):
  391. currentValue = left
  392. # If just two lists are being added
  393. elif isinstance(left, (ast.List, ast.Tuple)):
  394. _add_to_names(left)
  395. # All lists accounted for - done
  396. break
  397. # If not list concatenation
  398. else:
  399. break
  400. super().__init__(name, source)
  401. class Scope(dict):
  402. importStarred = False # set to True when import * is found
  403. def __repr__(self):
  404. scope_cls = self.__class__.__name__
  405. return f'<{scope_cls} at 0x{id(self):x} {dict.__repr__(self)}>'
  406. class ClassScope(Scope):
  407. pass
  408. class FunctionScope(Scope):
  409. """
  410. I represent a name scope for a function.
  411. @ivar globals: Names declared 'global' in this function.
  412. """
  413. usesLocals = False
  414. alwaysUsed = {'__tracebackhide__', '__traceback_info__',
  415. '__traceback_supplement__'}
  416. def __init__(self):
  417. super().__init__()
  418. # Simplify: manage the special locals as globals
  419. self.globals = self.alwaysUsed.copy()
  420. self.returnValue = None # First non-empty return
  421. def unused_assignments(self):
  422. """
  423. Return a generator for the assignments which have not been used.
  424. """
  425. for name, binding in self.items():
  426. if (not binding.used and
  427. name != '_' and # see issue #202
  428. name not in self.globals and
  429. not self.usesLocals and
  430. isinstance(binding, Assignment)):
  431. yield name, binding
  432. def unused_annotations(self):
  433. """
  434. Return a generator for the annotations which have not been used.
  435. """
  436. for name, binding in self.items():
  437. if not binding.used and isinstance(binding, Annotation):
  438. yield name, binding
  439. class TypeScope(Scope):
  440. pass
  441. class GeneratorScope(Scope):
  442. pass
  443. class ModuleScope(Scope):
  444. """Scope for a module."""
  445. _futures_allowed = True
  446. _annotations_future_enabled = False
  447. class DoctestScope(ModuleScope):
  448. """Scope for a doctest."""
  449. class DetectClassScopedMagic:
  450. names = dir()
  451. # Globally defined names which are not attributes of the builtins module, or
  452. # are only present on some platforms.
  453. _MAGIC_GLOBALS = ['__file__', '__builtins__', '__annotations__', 'WindowsError']
  454. def getNodeName(node):
  455. # Returns node.id, or node.name, or None
  456. if hasattr(node, 'id'): # One of the many nodes with an id
  457. return node.id
  458. if hasattr(node, 'name'): # an ExceptHandler node
  459. return node.name
  460. if hasattr(node, 'rest'): # a MatchMapping node
  461. return node.rest
  462. TYPING_MODULES = frozenset(('typing', 'typing_extensions'))
  463. def _is_typing_helper(node, is_name_match_fn, scope_stack):
  464. """
  465. Internal helper to determine whether or not something is a member of a
  466. typing module. This is used as part of working out whether we are within a
  467. type annotation context.
  468. Note: you probably don't want to use this function directly. Instead see the
  469. utils below which wrap it (`_is_typing` and `_is_any_typing_member`).
  470. """
  471. def _bare_name_is_attr(name):
  472. for scope in reversed(scope_stack):
  473. if name in scope:
  474. return (
  475. isinstance(scope[name], ImportationFrom) and
  476. scope[name].module in TYPING_MODULES and
  477. is_name_match_fn(scope[name].real_name)
  478. )
  479. return False
  480. def _module_scope_is_typing(name):
  481. for scope in reversed(scope_stack):
  482. if name in scope:
  483. return (
  484. isinstance(scope[name], Importation) and
  485. scope[name].fullName in TYPING_MODULES
  486. )
  487. return False
  488. return (
  489. (
  490. isinstance(node, ast.Name) and
  491. _bare_name_is_attr(node.id)
  492. ) or (
  493. isinstance(node, ast.Attribute) and
  494. isinstance(node.value, ast.Name) and
  495. _module_scope_is_typing(node.value.id) and
  496. is_name_match_fn(node.attr)
  497. )
  498. )
  499. def _is_typing(node, typing_attr, scope_stack):
  500. """
  501. Determine whether `node` represents the member of a typing module specified
  502. by `typing_attr`.
  503. This is used as part of working out whether we are within a type annotation
  504. context.
  505. """
  506. return _is_typing_helper(node, lambda x: x == typing_attr, scope_stack)
  507. def _is_any_typing_member(node, scope_stack):
  508. """
  509. Determine whether `node` represents any member of a typing module.
  510. This is used as part of working out whether we are within a type annotation
  511. context.
  512. """
  513. return _is_typing_helper(node, lambda x: True, scope_stack)
  514. def is_typing_overload(value, scope_stack):
  515. return (
  516. isinstance(value.source, (ast.FunctionDef, ast.AsyncFunctionDef)) and
  517. any(
  518. _is_typing(dec, 'overload', scope_stack)
  519. for dec in value.source.decorator_list
  520. )
  521. )
  522. class AnnotationState:
  523. NONE = 0
  524. STRING = 1
  525. BARE = 2
  526. def in_annotation(func):
  527. @functools.wraps(func)
  528. def in_annotation_func(self, *args, **kwargs):
  529. with self._enter_annotation():
  530. return func(self, *args, **kwargs)
  531. return in_annotation_func
  532. def in_string_annotation(func):
  533. @functools.wraps(func)
  534. def in_annotation_func(self, *args, **kwargs):
  535. with self._enter_annotation(AnnotationState.STRING):
  536. return func(self, *args, **kwargs)
  537. return in_annotation_func
  538. class Checker:
  539. """I check the cleanliness and sanity of Python code."""
  540. _ast_node_scope = {
  541. ast.Module: ModuleScope,
  542. ast.ClassDef: ClassScope,
  543. ast.FunctionDef: FunctionScope,
  544. ast.AsyncFunctionDef: FunctionScope,
  545. ast.Lambda: FunctionScope,
  546. ast.ListComp: GeneratorScope,
  547. ast.SetComp: GeneratorScope,
  548. ast.GeneratorExp: GeneratorScope,
  549. ast.DictComp: GeneratorScope,
  550. }
  551. nodeDepth = 0
  552. offset = None
  553. _in_annotation = AnnotationState.NONE
  554. builtIns = set(builtin_vars).union(_MAGIC_GLOBALS)
  555. _customBuiltIns = os.environ.get('PYFLAKES_BUILTINS')
  556. if _customBuiltIns:
  557. builtIns.update(_customBuiltIns.split(','))
  558. del _customBuiltIns
  559. def __init__(self, tree, filename='(none)', builtins=None,
  560. withDoctest='PYFLAKES_DOCTEST' in os.environ, file_tokens=()):
  561. self._nodeHandlers = {}
  562. self._deferred = collections.deque()
  563. self.deadScopes = []
  564. self.messages = []
  565. self.filename = filename
  566. if builtins:
  567. self.builtIns = self.builtIns.union(builtins)
  568. self.withDoctest = withDoctest
  569. self.exceptHandlers = [()]
  570. self.root = tree
  571. self.scopeStack = []
  572. try:
  573. scope_tp = Checker._ast_node_scope[type(tree)]
  574. except KeyError:
  575. raise RuntimeError('No scope implemented for the node %r' % tree)
  576. with self.in_scope(scope_tp):
  577. for builtin in self.builtIns:
  578. self.addBinding(None, Builtin(builtin))
  579. self.handleChildren(tree)
  580. self._run_deferred()
  581. self.checkDeadScopes()
  582. if file_tokens:
  583. warnings.warn(
  584. '`file_tokens` will be removed in a future version',
  585. stacklevel=2,
  586. )
  587. def deferFunction(self, callable):
  588. """
  589. Schedule a function handler to be called just before completion.
  590. This is used for handling function bodies, which must be deferred
  591. because code later in the file might modify the global scope. When
  592. `callable` is called, the scope at the time this is called will be
  593. restored, however it will contain any new bindings added to it.
  594. """
  595. self._deferred.append((callable, self.scopeStack[:], self.offset))
  596. def _run_deferred(self):
  597. orig = (self.scopeStack, self.offset)
  598. while self._deferred:
  599. handler, scope, offset = self._deferred.popleft()
  600. self.scopeStack, self.offset = scope, offset
  601. handler()
  602. self.scopeStack, self.offset = orig
  603. def _in_doctest(self):
  604. return (len(self.scopeStack) >= 2 and
  605. isinstance(self.scopeStack[1], DoctestScope))
  606. @property
  607. def futuresAllowed(self):
  608. if not all(isinstance(scope, ModuleScope)
  609. for scope in self.scopeStack):
  610. return False
  611. return self.scope._futures_allowed
  612. @futuresAllowed.setter
  613. def futuresAllowed(self, value):
  614. assert value is False
  615. if isinstance(self.scope, ModuleScope):
  616. self.scope._futures_allowed = False
  617. @property
  618. def annotationsFutureEnabled(self):
  619. scope = self.scopeStack[0]
  620. if not isinstance(scope, ModuleScope):
  621. return False
  622. return scope._annotations_future_enabled
  623. @annotationsFutureEnabled.setter
  624. def annotationsFutureEnabled(self, value):
  625. assert value is True
  626. assert isinstance(self.scope, ModuleScope)
  627. self.scope._annotations_future_enabled = True
  628. @property
  629. def scope(self):
  630. return self.scopeStack[-1]
  631. @contextlib.contextmanager
  632. def in_scope(self, cls):
  633. self.scopeStack.append(cls())
  634. try:
  635. yield
  636. finally:
  637. self.deadScopes.append(self.scopeStack.pop())
  638. def checkDeadScopes(self):
  639. """
  640. Look at scopes which have been fully examined and report names in them
  641. which were imported but unused.
  642. """
  643. for scope in self.deadScopes:
  644. # imports in classes are public members
  645. if isinstance(scope, ClassScope):
  646. continue
  647. if isinstance(scope, FunctionScope):
  648. for name, binding in scope.unused_assignments():
  649. self.report(messages.UnusedVariable, binding.source, name)
  650. for name, binding in scope.unused_annotations():
  651. self.report(messages.UnusedAnnotation, binding.source, name)
  652. all_binding = scope.get('__all__')
  653. if all_binding and not isinstance(all_binding, ExportBinding):
  654. all_binding = None
  655. if all_binding:
  656. all_names = set(all_binding.names)
  657. undefined = [
  658. name for name in all_binding.names
  659. if name not in scope
  660. ]
  661. else:
  662. all_names = undefined = []
  663. if undefined:
  664. if not scope.importStarred and \
  665. os.path.basename(self.filename) != '__init__.py':
  666. # Look for possible mistakes in the export list
  667. for name in undefined:
  668. self.report(messages.UndefinedExport,
  669. scope['__all__'].source, name)
  670. # mark all import '*' as used by the undefined in __all__
  671. if scope.importStarred:
  672. from_list = []
  673. for binding in scope.values():
  674. if isinstance(binding, StarImportation):
  675. binding.used = all_binding
  676. from_list.append(binding.fullName)
  677. # report * usage, with a list of possible sources
  678. from_list = ', '.join(sorted(from_list))
  679. for name in undefined:
  680. self.report(messages.ImportStarUsage,
  681. scope['__all__'].source, name, from_list)
  682. # Look for imported names that aren't used.
  683. for value in scope.values():
  684. if isinstance(value, Importation):
  685. used = value.used or value.name in all_names
  686. if not used:
  687. messg = messages.UnusedImport
  688. self.report(messg, value.source, str(value))
  689. for node in value.redefined:
  690. if isinstance(self.getParent(node), FOR_TYPES):
  691. messg = messages.ImportShadowedByLoopVar
  692. elif used:
  693. continue
  694. else:
  695. messg = messages.RedefinedWhileUnused
  696. self.report(messg, node, value.name, value.source)
  697. def report(self, messageClass, *args, **kwargs):
  698. self.messages.append(messageClass(self.filename, *args, **kwargs))
  699. def getParent(self, node):
  700. # Lookup the first parent which is not Tuple, List or Starred
  701. while True:
  702. node = node._pyflakes_parent
  703. if not hasattr(node, 'elts') and not hasattr(node, 'ctx'):
  704. return node
  705. def getCommonAncestor(self, lnode, rnode, stop):
  706. if (
  707. stop in (lnode, rnode) or
  708. not (
  709. hasattr(lnode, '_pyflakes_parent') and
  710. hasattr(rnode, '_pyflakes_parent')
  711. )
  712. ):
  713. return None
  714. if lnode is rnode:
  715. return lnode
  716. if (lnode._pyflakes_depth > rnode._pyflakes_depth):
  717. return self.getCommonAncestor(lnode._pyflakes_parent, rnode, stop)
  718. if (lnode._pyflakes_depth < rnode._pyflakes_depth):
  719. return self.getCommonAncestor(lnode, rnode._pyflakes_parent, stop)
  720. return self.getCommonAncestor(
  721. lnode._pyflakes_parent,
  722. rnode._pyflakes_parent,
  723. stop,
  724. )
  725. def descendantOf(self, node, ancestors, stop):
  726. for a in ancestors:
  727. if self.getCommonAncestor(node, a, stop):
  728. return True
  729. return False
  730. def _getAncestor(self, node, ancestor_type):
  731. parent = node
  732. while True:
  733. if parent is self.root:
  734. return None
  735. parent = self.getParent(parent)
  736. if isinstance(parent, ancestor_type):
  737. return parent
  738. def getScopeNode(self, node):
  739. return self._getAncestor(node, tuple(Checker._ast_node_scope.keys()))
  740. def differentForks(self, lnode, rnode):
  741. """True, if lnode and rnode are located on different forks of IF/TRY"""
  742. ancestor = self.getCommonAncestor(lnode, rnode, self.root)
  743. parts = getAlternatives(ancestor)
  744. if parts:
  745. for items in parts:
  746. if self.descendantOf(lnode, items, ancestor) ^ \
  747. self.descendantOf(rnode, items, ancestor):
  748. return True
  749. return False
  750. def addBinding(self, node, value):
  751. """
  752. Called when a binding is altered.
  753. - `node` is the statement responsible for the change
  754. - `value` is the new value, a Binding instance
  755. """
  756. # assert value.source in (node, node._pyflakes_parent):
  757. for scope in self.scopeStack[::-1]:
  758. if value.name in scope:
  759. break
  760. existing = scope.get(value.name)
  761. if (existing and not isinstance(existing, Builtin) and
  762. not self.differentForks(node, existing.source)):
  763. parent_stmt = self.getParent(value.source)
  764. if isinstance(existing, Importation) and isinstance(parent_stmt, FOR_TYPES):
  765. self.report(messages.ImportShadowedByLoopVar,
  766. node, value.name, existing.source)
  767. elif scope is self.scope:
  768. if (
  769. (not existing.used and value.redefines(existing)) and
  770. (value.name != '_' or isinstance(existing, Importation)) and
  771. not is_typing_overload(existing, self.scopeStack)
  772. ):
  773. self.report(messages.RedefinedWhileUnused,
  774. node, value.name, existing.source)
  775. elif isinstance(existing, Importation) and value.redefines(existing):
  776. existing.redefined.append(node)
  777. if value.name in self.scope:
  778. # then assume the rebound name is used as a global or within a loop
  779. value.used = self.scope[value.name].used
  780. # don't treat annotations as assignments if there is an existing value
  781. # in scope
  782. if value.name not in self.scope or not isinstance(value, Annotation):
  783. cur_scope_pos = -1
  784. # As per PEP 572, use scope in which outermost generator is defined
  785. while (
  786. isinstance(value, NamedExprAssignment) and
  787. isinstance(self.scopeStack[cur_scope_pos], GeneratorScope)
  788. ):
  789. cur_scope_pos -= 1
  790. self.scopeStack[cur_scope_pos][value.name] = value
  791. def _unknown_handler(self, node):
  792. # this environment variable configures whether to error on unknown
  793. # ast types.
  794. #
  795. # this is silent by default but the error is enabled for the pyflakes
  796. # testsuite.
  797. #
  798. # this allows new syntax to be added to python without *requiring*
  799. # changes from the pyflakes side. but will still produce an error
  800. # in the pyflakes testsuite (so more specific handling can be added if
  801. # needed).
  802. if os.environ.get('PYFLAKES_ERROR_UNKNOWN'):
  803. raise NotImplementedError(f'Unexpected type: {type(node)}')
  804. else:
  805. self.handleChildren(node)
  806. def getNodeHandler(self, node_class):
  807. try:
  808. return self._nodeHandlers[node_class]
  809. except KeyError:
  810. nodeType = node_class.__name__.upper()
  811. self._nodeHandlers[node_class] = handler = getattr(
  812. self, nodeType, self._unknown_handler,
  813. )
  814. return handler
  815. def handleNodeLoad(self, node, parent):
  816. name = getNodeName(node)
  817. if not name:
  818. return
  819. # only the following can access class scoped variables (since classes
  820. # aren't really a scope)
  821. # - direct accesses (not within a nested scope)
  822. # - generators
  823. # - type annotations (for generics, etc.)
  824. can_access_class_vars = None
  825. importStarred = None
  826. # try enclosing function scopes and global scope
  827. for scope in self.scopeStack[-1::-1]:
  828. if isinstance(scope, ClassScope):
  829. if name == '__class__':
  830. return
  831. elif can_access_class_vars is False:
  832. # only generators used in a class scope can access the
  833. # names of the class. this is skipped during the first
  834. # iteration
  835. continue
  836. binding = scope.get(name, None)
  837. if isinstance(binding, Annotation) and not self._in_postponed_annotation:
  838. scope[name].used = (self.scope, node)
  839. continue
  840. if name == 'print' and isinstance(binding, Builtin):
  841. if (isinstance(parent, ast.BinOp) and
  842. isinstance(parent.op, ast.RShift)):
  843. self.report(messages.InvalidPrintSyntax, node)
  844. try:
  845. scope[name].used = (self.scope, node)
  846. # if the name of SubImportation is same as
  847. # alias of other Importation and the alias
  848. # is used, SubImportation also should be marked as used.
  849. n = scope[name]
  850. if isinstance(n, Importation) and n._has_alias():
  851. try:
  852. scope[n.fullName].used = (self.scope, node)
  853. except KeyError:
  854. pass
  855. except KeyError:
  856. pass
  857. else:
  858. return
  859. importStarred = importStarred or scope.importStarred
  860. if can_access_class_vars is not False:
  861. can_access_class_vars = isinstance(
  862. scope, (TypeScope, GeneratorScope),
  863. )
  864. if importStarred:
  865. from_list = []
  866. for scope in self.scopeStack[-1::-1]:
  867. for binding in scope.values():
  868. if isinstance(binding, StarImportation):
  869. # mark '*' imports as used for each scope
  870. binding.used = (self.scope, node)
  871. from_list.append(binding.fullName)
  872. # report * usage, with a list of possible sources
  873. from_list = ', '.join(sorted(from_list))
  874. self.report(messages.ImportStarUsage, node, name, from_list)
  875. return
  876. if name == '__path__' and os.path.basename(self.filename) == '__init__.py':
  877. # the special name __path__ is valid only in packages
  878. return
  879. if name in DetectClassScopedMagic.names and isinstance(self.scope, ClassScope):
  880. return
  881. # protected with a NameError handler?
  882. if 'NameError' not in self.exceptHandlers[-1]:
  883. self.report(messages.UndefinedName, node, name)
  884. def handleNodeStore(self, node):
  885. name = getNodeName(node)
  886. if not name:
  887. return
  888. # if the name hasn't already been defined in the current scope
  889. if isinstance(self.scope, FunctionScope) and name not in self.scope:
  890. # for each function or module scope above us
  891. for scope in self.scopeStack[:-1]:
  892. if not isinstance(scope, (FunctionScope, ModuleScope)):
  893. continue
  894. # if the name was defined in that scope, and the name has
  895. # been accessed already in the current scope, and hasn't
  896. # been declared global
  897. used = name in scope and scope[name].used
  898. if used and used[0] is self.scope and name not in self.scope.globals:
  899. # then it's probably a mistake
  900. self.report(messages.UndefinedLocal,
  901. scope[name].used[1], name, scope[name].source)
  902. break
  903. parent_stmt = self.getParent(node)
  904. if isinstance(parent_stmt, ast.AnnAssign) and parent_stmt.value is None:
  905. binding = Annotation(name, node)
  906. elif isinstance(parent_stmt, (FOR_TYPES, ast.comprehension)) or (
  907. parent_stmt != node._pyflakes_parent and
  908. not self.isLiteralTupleUnpacking(parent_stmt)):
  909. binding = Binding(name, node)
  910. elif (
  911. name == '__all__' and
  912. isinstance(self.scope, ModuleScope) and
  913. isinstance(
  914. node._pyflakes_parent,
  915. (ast.Assign, ast.AugAssign, ast.AnnAssign)
  916. )
  917. ):
  918. binding = ExportBinding(name, node._pyflakes_parent, self.scope)
  919. elif isinstance(parent_stmt, ast.NamedExpr):
  920. binding = NamedExprAssignment(name, node)
  921. else:
  922. binding = Assignment(name, node)
  923. self.addBinding(node, binding)
  924. def handleNodeDelete(self, node):
  925. def on_conditional_branch():
  926. """
  927. Return `True` if node is part of a conditional body.
  928. """
  929. current = getattr(node, '_pyflakes_parent', None)
  930. while current:
  931. if isinstance(current, (ast.If, ast.While, ast.IfExp)):
  932. return True
  933. current = getattr(current, '_pyflakes_parent', None)
  934. return False
  935. name = getNodeName(node)
  936. if not name:
  937. return
  938. if on_conditional_branch():
  939. # We cannot predict if this conditional branch is going to
  940. # be executed.
  941. return
  942. if isinstance(self.scope, FunctionScope) and name in self.scope.globals:
  943. self.scope.globals.remove(name)
  944. else:
  945. try:
  946. del self.scope[name]
  947. except KeyError:
  948. self.report(messages.UndefinedName, node, name)
  949. @contextlib.contextmanager
  950. def _enter_annotation(self, ann_type=AnnotationState.BARE):
  951. orig, self._in_annotation = self._in_annotation, ann_type
  952. try:
  953. yield
  954. finally:
  955. self._in_annotation = orig
  956. @property
  957. def _in_postponed_annotation(self):
  958. return (
  959. self._in_annotation == AnnotationState.STRING or
  960. self.annotationsFutureEnabled
  961. )
  962. def handleChildren(self, tree, omit=None):
  963. for node in iter_child_nodes(tree, omit=omit):
  964. self.handleNode(node, tree)
  965. def isLiteralTupleUnpacking(self, node):
  966. if isinstance(node, ast.Assign):
  967. for child in node.targets + [node.value]:
  968. if not hasattr(child, 'elts'):
  969. return False
  970. return True
  971. def isDocstring(self, node):
  972. """
  973. Determine if the given node is a docstring, as long as it is at the
  974. correct place in the node tree.
  975. """
  976. return (
  977. isinstance(node, ast.Expr) and
  978. isinstance(node.value, ast.Constant) and
  979. isinstance(node.value.value, str)
  980. )
  981. def getDocstring(self, node):
  982. if (
  983. isinstance(node, ast.Expr) and
  984. isinstance(node.value, ast.Constant) and
  985. isinstance(node.value.value, str)
  986. ):
  987. return node.value.value, node.lineno - 1
  988. else:
  989. return None, None
  990. def handleNode(self, node, parent):
  991. if node is None:
  992. return
  993. if self.offset and getattr(node, 'lineno', None) is not None:
  994. node.lineno += self.offset[0]
  995. node.col_offset += self.offset[1]
  996. if (
  997. self.futuresAllowed and
  998. self.nodeDepth == 0 and
  999. not isinstance(node, ast.ImportFrom) and
  1000. not self.isDocstring(node)
  1001. ):
  1002. self.futuresAllowed = False
  1003. self.nodeDepth += 1
  1004. node._pyflakes_depth = self.nodeDepth
  1005. node._pyflakes_parent = parent
  1006. try:
  1007. handler = self.getNodeHandler(node.__class__)
  1008. handler(node)
  1009. finally:
  1010. self.nodeDepth -= 1
  1011. _getDoctestExamples = doctest.DocTestParser().get_examples
  1012. def handleDoctests(self, node):
  1013. try:
  1014. (docstring, node_lineno) = self.getDocstring(node.body[0])
  1015. examples = docstring and self._getDoctestExamples(docstring)
  1016. except (ValueError, IndexError):
  1017. # e.g. line 6 of the docstring for <string> has inconsistent
  1018. # leading whitespace: ...
  1019. return
  1020. if not examples:
  1021. return
  1022. # Place doctest in module scope
  1023. saved_stack = self.scopeStack
  1024. self.scopeStack = [self.scopeStack[0]]
  1025. node_offset = self.offset or (0, 0)
  1026. with self.in_scope(DoctestScope):
  1027. if '_' not in self.scopeStack[0]:
  1028. self.addBinding(None, Builtin('_'))
  1029. for example in examples:
  1030. try:
  1031. tree = ast.parse(example.source, "<doctest>")
  1032. except SyntaxError as e:
  1033. position = (node_lineno + example.lineno + e.lineno,
  1034. example.indent + 4 + (e.offset or 0))
  1035. self.report(messages.DoctestSyntaxError, node, position)
  1036. else:
  1037. self.offset = (node_offset[0] + node_lineno + example.lineno,
  1038. node_offset[1] + example.indent + 4)
  1039. self.handleChildren(tree)
  1040. self.offset = node_offset
  1041. self.scopeStack = saved_stack
  1042. @in_string_annotation
  1043. def handleStringAnnotation(self, s, node, ref_lineno, ref_col_offset, err):
  1044. try:
  1045. tree = ast.parse(s)
  1046. except SyntaxError:
  1047. self.report(err, node, s)
  1048. return
  1049. body = tree.body
  1050. if len(body) != 1 or not isinstance(body[0], ast.Expr):
  1051. self.report(err, node, s)
  1052. return
  1053. parsed_annotation = tree.body[0].value
  1054. for descendant in ast.walk(parsed_annotation):
  1055. if (
  1056. 'lineno' in descendant._attributes and
  1057. 'col_offset' in descendant._attributes
  1058. ):
  1059. descendant.lineno = ref_lineno
  1060. descendant.col_offset = ref_col_offset
  1061. self.handleNode(parsed_annotation, node)
  1062. def handle_annotation_always_deferred(self, annotation, parent):
  1063. fn = in_annotation(Checker.handleNode)
  1064. self.deferFunction(lambda: fn(self, annotation, parent))
  1065. @in_annotation
  1066. def handleAnnotation(self, annotation, node):
  1067. if (
  1068. isinstance(annotation, ast.Constant) and
  1069. isinstance(annotation.value, str)
  1070. ):
  1071. # Defer handling forward annotation.
  1072. self.deferFunction(functools.partial(
  1073. self.handleStringAnnotation,
  1074. annotation.value,
  1075. node,
  1076. annotation.lineno,
  1077. annotation.col_offset,
  1078. messages.ForwardAnnotationSyntaxError,
  1079. ))
  1080. elif self.annotationsFutureEnabled:
  1081. self.handle_annotation_always_deferred(annotation, node)
  1082. else:
  1083. self.handleNode(annotation, node)
  1084. def ignore(self, node):
  1085. pass
  1086. # "stmt" type nodes
  1087. DELETE = FOR = ASYNCFOR = WHILE = WITH = WITHITEM = ASYNCWITH = \
  1088. EXPR = ASSIGN = handleChildren
  1089. PASS = ignore
  1090. # "expr" type nodes
  1091. BOOLOP = UNARYOP = SET = ATTRIBUTE = STARRED = NAMECONSTANT = \
  1092. NAMEDEXPR = handleChildren
  1093. def SUBSCRIPT(self, node):
  1094. if _is_name_or_attr(node.value, 'Literal'):
  1095. with self._enter_annotation(AnnotationState.NONE):
  1096. self.handleChildren(node)
  1097. elif _is_name_or_attr(node.value, 'Annotated'):
  1098. self.handleNode(node.value, node)
  1099. # py39+
  1100. if isinstance(node.slice, ast.Tuple):
  1101. slice_tuple = node.slice
  1102. # <py39
  1103. elif (
  1104. isinstance(node.slice, ast.Index) and
  1105. isinstance(node.slice.value, ast.Tuple)
  1106. ):
  1107. slice_tuple = node.slice.value
  1108. else:
  1109. slice_tuple = None
  1110. # not a multi-arg `Annotated`
  1111. if slice_tuple is None or len(slice_tuple.elts) < 2:
  1112. self.handleNode(node.slice, node)
  1113. else:
  1114. # the first argument is the type
  1115. self.handleNode(slice_tuple.elts[0], node)
  1116. # the rest of the arguments are not
  1117. with self._enter_annotation(AnnotationState.NONE):
  1118. for arg in slice_tuple.elts[1:]:
  1119. self.handleNode(arg, node)
  1120. self.handleNode(node.ctx, node)
  1121. else:
  1122. if _is_any_typing_member(node.value, self.scopeStack):
  1123. with self._enter_annotation():
  1124. self.handleChildren(node)
  1125. else:
  1126. self.handleChildren(node)
  1127. def _handle_string_dot_format(self, node):
  1128. try:
  1129. placeholders = tuple(parse_format_string(node.func.value.value))
  1130. except ValueError as e:
  1131. self.report(messages.StringDotFormatInvalidFormat, node, e)
  1132. return
  1133. auto = None
  1134. next_auto = 0
  1135. placeholder_positional = set()
  1136. placeholder_named = set()
  1137. def _add_key(fmtkey):
  1138. """Returns True if there is an error which should early-exit"""
  1139. nonlocal auto, next_auto
  1140. if fmtkey is None: # end of string or `{` / `}` escapes
  1141. return False
  1142. # attributes / indices are allowed in `.format(...)`
  1143. fmtkey, _, _ = fmtkey.partition('.')
  1144. fmtkey, _, _ = fmtkey.partition('[')
  1145. try:
  1146. fmtkey = int(fmtkey)
  1147. except ValueError:
  1148. pass
  1149. else: # fmtkey was an integer
  1150. if auto is True:
  1151. self.report(messages.StringDotFormatMixingAutomatic, node)
  1152. return True
  1153. else:
  1154. auto = False
  1155. if fmtkey == '':
  1156. if auto is False:
  1157. self.report(messages.StringDotFormatMixingAutomatic, node)
  1158. return True
  1159. else:
  1160. auto = True
  1161. fmtkey = next_auto
  1162. next_auto += 1
  1163. if isinstance(fmtkey, int):
  1164. placeholder_positional.add(fmtkey)
  1165. else:
  1166. placeholder_named.add(fmtkey)
  1167. return False
  1168. for _, fmtkey, spec, _ in placeholders:
  1169. if _add_key(fmtkey):
  1170. return
  1171. # spec can also contain format specifiers
  1172. if spec is not None:
  1173. try:
  1174. spec_placeholders = tuple(parse_format_string(spec))
  1175. except ValueError as e:
  1176. self.report(messages.StringDotFormatInvalidFormat, node, e)
  1177. return
  1178. for _, spec_fmtkey, spec_spec, _ in spec_placeholders:
  1179. # can't recurse again
  1180. if spec_spec is not None and '{' in spec_spec:
  1181. self.report(
  1182. messages.StringDotFormatInvalidFormat,
  1183. node,
  1184. 'Max string recursion exceeded',
  1185. )
  1186. return
  1187. if _add_key(spec_fmtkey):
  1188. return
  1189. # bail early if there is *args or **kwargs
  1190. if (
  1191. # *args
  1192. any(isinstance(arg, ast.Starred) for arg in node.args) or
  1193. # **kwargs
  1194. any(kwd.arg is None for kwd in node.keywords)
  1195. ):
  1196. return
  1197. substitution_positional = set(range(len(node.args)))
  1198. substitution_named = {kwd.arg for kwd in node.keywords}
  1199. extra_positional = substitution_positional - placeholder_positional
  1200. extra_named = substitution_named - placeholder_named
  1201. missing_arguments = (
  1202. (placeholder_positional | placeholder_named) -
  1203. (substitution_positional | substitution_named)
  1204. )
  1205. if extra_positional:
  1206. self.report(
  1207. messages.StringDotFormatExtraPositionalArguments,
  1208. node,
  1209. ', '.join(sorted(str(x) for x in extra_positional)),
  1210. )
  1211. if extra_named:
  1212. self.report(
  1213. messages.StringDotFormatExtraNamedArguments,
  1214. node,
  1215. ', '.join(sorted(extra_named)),
  1216. )
  1217. if missing_arguments:
  1218. self.report(
  1219. messages.StringDotFormatMissingArgument,
  1220. node,
  1221. ', '.join(sorted(str(x) for x in missing_arguments)),
  1222. )
  1223. def CALL(self, node):
  1224. if (
  1225. isinstance(node.func, ast.Attribute) and
  1226. isinstance(node.func.value, ast.Constant) and
  1227. isinstance(node.func.value.value, str) and
  1228. node.func.attr == 'format'
  1229. ):
  1230. self._handle_string_dot_format(node)
  1231. omit = []
  1232. annotated = []
  1233. not_annotated = []
  1234. if (
  1235. _is_typing(node.func, 'cast', self.scopeStack) and
  1236. len(node.args) >= 1
  1237. ):
  1238. with self._enter_annotation():
  1239. self.handleNode(node.args[0], node)
  1240. elif _is_typing(node.func, 'TypeVar', self.scopeStack):
  1241. # TypeVar("T", "int", "str")
  1242. omit += ["args"]
  1243. annotated += [arg for arg in node.args[1:]]
  1244. # TypeVar("T", bound="str")
  1245. omit += ["keywords"]
  1246. annotated += [k.value for k in node.keywords if k.arg == "bound"]
  1247. not_annotated += [
  1248. (k, ["value"] if k.arg == "bound" else None)
  1249. for k in node.keywords
  1250. ]
  1251. elif _is_typing(node.func, "TypedDict", self.scopeStack):
  1252. # TypedDict("a", {"a": int})
  1253. if len(node.args) > 1 and isinstance(node.args[1], ast.Dict):
  1254. omit += ["args"]
  1255. annotated += node.args[1].values
  1256. not_annotated += [
  1257. (arg, ["values"] if i == 1 else None)
  1258. for i, arg in enumerate(node.args)
  1259. ]
  1260. # TypedDict("a", a=int)
  1261. omit += ["keywords"]
  1262. annotated += [k.value for k in node.keywords]
  1263. not_annotated += [(k, ["value"]) for k in node.keywords]
  1264. elif _is_typing(node.func, "NamedTuple", self.scopeStack):
  1265. # NamedTuple("a", [("a", int)])
  1266. if (
  1267. len(node.args) > 1 and
  1268. isinstance(node.args[1], (ast.Tuple, ast.List)) and
  1269. all(isinstance(x, (ast.Tuple, ast.List)) and
  1270. len(x.elts) == 2 for x in node.args[1].elts)
  1271. ):
  1272. omit += ["args"]
  1273. annotated += [elt.elts[1] for elt in node.args[1].elts]
  1274. not_annotated += [(elt.elts[0], None) for elt in node.args[1].elts]
  1275. not_annotated += [
  1276. (arg, ["elts"] if i == 1 else None)
  1277. for i, arg in enumerate(node.args)
  1278. ]
  1279. not_annotated += [(elt, "elts") for elt in node.args[1].elts]
  1280. # NamedTuple("a", a=int)
  1281. omit += ["keywords"]
  1282. annotated += [k.value for k in node.keywords]
  1283. not_annotated += [(k, ["value"]) for k in node.keywords]
  1284. if omit:
  1285. with self._enter_annotation(AnnotationState.NONE):
  1286. for na_node, na_omit in not_annotated:
  1287. self.handleChildren(na_node, omit=na_omit)
  1288. self.handleChildren(node, omit=omit)
  1289. with self._enter_annotation():
  1290. for annotated_node in annotated:
  1291. self.handleNode(annotated_node, node)
  1292. else:
  1293. self.handleChildren(node)
  1294. def _handle_percent_format(self, node):
  1295. try:
  1296. placeholders = parse_percent_format(node.left.value)
  1297. except ValueError:
  1298. self.report(
  1299. messages.PercentFormatInvalidFormat,
  1300. node,
  1301. 'incomplete format',
  1302. )
  1303. return
  1304. named = set()
  1305. positional_count = 0
  1306. positional = None
  1307. for _, placeholder in placeholders:
  1308. if placeholder is None:
  1309. continue
  1310. name, _, width, precision, conversion = placeholder
  1311. if conversion == '%':
  1312. continue
  1313. if conversion not in VALID_CONVERSIONS:
  1314. self.report(
  1315. messages.PercentFormatUnsupportedFormatCharacter,
  1316. node,
  1317. conversion,
  1318. )
  1319. if positional is None and conversion:
  1320. positional = name is None
  1321. for part in (width, precision):
  1322. if part is not None and '*' in part:
  1323. if not positional:
  1324. self.report(
  1325. messages.PercentFormatStarRequiresSequence,
  1326. node,
  1327. )
  1328. else:
  1329. positional_count += 1
  1330. if positional and name is not None:
  1331. self.report(
  1332. messages.PercentFormatMixedPositionalAndNamed,
  1333. node,
  1334. )
  1335. return
  1336. elif not positional and name is None:
  1337. self.report(
  1338. messages.PercentFormatMixedPositionalAndNamed,
  1339. node,
  1340. )
  1341. return
  1342. if positional:
  1343. positional_count += 1
  1344. else:
  1345. named.add(name)
  1346. if (
  1347. isinstance(node.right, (ast.List, ast.Tuple)) and
  1348. # does not have any *splats (py35+ feature)
  1349. not any(
  1350. isinstance(elt, ast.Starred)
  1351. for elt in node.right.elts
  1352. )
  1353. ):
  1354. substitution_count = len(node.right.elts)
  1355. if positional and positional_count != substitution_count:
  1356. self.report(
  1357. messages.PercentFormatPositionalCountMismatch,
  1358. node,
  1359. positional_count,
  1360. substitution_count,
  1361. )
  1362. elif not positional:
  1363. self.report(messages.PercentFormatExpectedMapping, node)
  1364. if (
  1365. isinstance(node.right, ast.Dict) and
  1366. all(
  1367. isinstance(k, ast.Constant) and isinstance(k.value, str)
  1368. for k in node.right.keys
  1369. )
  1370. ):
  1371. if positional and positional_count > 1:
  1372. self.report(messages.PercentFormatExpectedSequence, node)
  1373. return
  1374. substitution_keys = {k.value for k in node.right.keys}
  1375. extra_keys = substitution_keys - named
  1376. missing_keys = named - substitution_keys
  1377. if not positional and extra_keys:
  1378. self.report(
  1379. messages.PercentFormatExtraNamedArguments,
  1380. node,
  1381. ', '.join(sorted(extra_keys)),
  1382. )
  1383. if not positional and missing_keys:
  1384. self.report(
  1385. messages.PercentFormatMissingArgument,
  1386. node,
  1387. ', '.join(sorted(missing_keys)),
  1388. )
  1389. def BINOP(self, node):
  1390. if (
  1391. isinstance(node.op, ast.Mod) and
  1392. isinstance(node.left, ast.Constant) and
  1393. isinstance(node.left.value, str)
  1394. ):
  1395. self._handle_percent_format(node)
  1396. self.handleChildren(node)
  1397. def CONSTANT(self, node):
  1398. if isinstance(node.value, str) and self._in_annotation:
  1399. fn = functools.partial(
  1400. self.handleStringAnnotation,
  1401. node.value,
  1402. node,
  1403. node.lineno,
  1404. node.col_offset,
  1405. messages.ForwardAnnotationSyntaxError,
  1406. )
  1407. self.deferFunction(fn)
  1408. # "slice" type nodes
  1409. SLICE = EXTSLICE = INDEX = handleChildren
  1410. # expression contexts are node instances too, though being constants
  1411. LOAD = STORE = DEL = AUGLOAD = AUGSTORE = PARAM = ignore
  1412. # same for operators
  1413. AND = OR = ADD = SUB = MULT = DIV = MOD = POW = LSHIFT = RSHIFT = \
  1414. BITOR = BITXOR = BITAND = FLOORDIV = INVERT = NOT = UADD = USUB = \
  1415. EQ = NOTEQ = LT = LTE = GT = GTE = IS = ISNOT = IN = NOTIN = \
  1416. MATMULT = ignore
  1417. def RAISE(self, node):
  1418. self.handleChildren(node)
  1419. arg = node.exc
  1420. if isinstance(arg, ast.Call):
  1421. if is_notimplemented_name_node(arg.func):
  1422. # Handle "raise NotImplemented(...)"
  1423. self.report(messages.RaiseNotImplemented, node)
  1424. elif is_notimplemented_name_node(arg):
  1425. # Handle "raise NotImplemented"
  1426. self.report(messages.RaiseNotImplemented, node)
  1427. # additional node types
  1428. COMPREHENSION = KEYWORD = FORMATTEDVALUE = handleChildren
  1429. _in_fstring = False
  1430. def JOINEDSTR(self, node):
  1431. if (
  1432. # the conversion / etc. flags are parsed as f-strings without
  1433. # placeholders
  1434. not self._in_fstring and
  1435. not any(isinstance(x, ast.FormattedValue) for x in node.values)
  1436. ):
  1437. self.report(messages.FStringMissingPlaceholders, node)
  1438. self._in_fstring, orig = True, self._in_fstring
  1439. try:
  1440. self.handleChildren(node)
  1441. finally:
  1442. self._in_fstring = orig
  1443. def DICT(self, node):
  1444. # Complain if there are duplicate keys with different values
  1445. # If they have the same value it's not going to cause potentially
  1446. # unexpected behaviour so we'll not complain.
  1447. keys = [
  1448. convert_to_value(key) for key in node.keys
  1449. ]
  1450. key_counts = counter(keys)
  1451. duplicate_keys = [
  1452. key for key, count in key_counts.items()
  1453. if count > 1
  1454. ]
  1455. for key in duplicate_keys:
  1456. key_indices = [i for i, i_key in enumerate(keys) if i_key == key]
  1457. values = counter(
  1458. convert_to_value(node.values[index])
  1459. for index in key_indices
  1460. )
  1461. if any(count == 1 for value, count in values.items()):
  1462. for key_index in key_indices:
  1463. key_node = node.keys[key_index]
  1464. if isinstance(key, VariableKey):
  1465. self.report(messages.MultiValueRepeatedKeyVariable,
  1466. key_node,
  1467. key.name)
  1468. else:
  1469. self.report(
  1470. messages.MultiValueRepeatedKeyLiteral,
  1471. key_node,
  1472. key,
  1473. )
  1474. self.handleChildren(node)
  1475. def IF(self, node):
  1476. if isinstance(node.test, ast.Tuple) and node.test.elts != []:
  1477. self.report(messages.IfTuple, node)
  1478. self.handleChildren(node)
  1479. IFEXP = IF
  1480. def ASSERT(self, node):
  1481. if isinstance(node.test, ast.Tuple) and node.test.elts != []:
  1482. self.report(messages.AssertTuple, node)
  1483. self.handleChildren(node)
  1484. def GLOBAL(self, node):
  1485. """
  1486. Keep track of globals declarations.
  1487. """
  1488. global_scope_index = 1 if self._in_doctest() else 0
  1489. global_scope = self.scopeStack[global_scope_index]
  1490. # Ignore 'global' statement in global scope.
  1491. if self.scope is not global_scope:
  1492. # One 'global' statement can bind multiple (comma-delimited) names.
  1493. for node_name in node.names:
  1494. node_value = Assignment(node_name, node)
  1495. # Remove UndefinedName messages already reported for this name.
  1496. # TODO: if the global is not used in this scope, it does not
  1497. # become a globally defined name. See test_unused_global.
  1498. self.messages = [
  1499. m for m in self.messages if not
  1500. isinstance(m, messages.UndefinedName) or
  1501. m.message_args[0] != node_name]
  1502. # Bind name to global scope if it doesn't exist already.
  1503. global_scope.setdefault(node_name, node_value)
  1504. # Bind name to non-global scopes, but as already "used".
  1505. node_value.used = (global_scope, node)
  1506. for scope in self.scopeStack[global_scope_index + 1:]:
  1507. scope[node_name] = node_value
  1508. NONLOCAL = GLOBAL
  1509. def GENERATOREXP(self, node):
  1510. with self.in_scope(GeneratorScope):
  1511. self.handleChildren(node)
  1512. LISTCOMP = DICTCOMP = SETCOMP = GENERATOREXP
  1513. def NAME(self, node):
  1514. """
  1515. Handle occurrence of Name (which can be a load/store/delete access.)
  1516. """
  1517. # Locate the name in locals / function / globals scopes.
  1518. if isinstance(node.ctx, ast.Load):
  1519. self.handleNodeLoad(node, self.getParent(node))
  1520. if (node.id == 'locals' and isinstance(self.scope, FunctionScope) and
  1521. isinstance(node._pyflakes_parent, ast.Call)):
  1522. # we are doing locals() call in current scope
  1523. self.scope.usesLocals = True
  1524. elif isinstance(node.ctx, ast.Store):
  1525. self.handleNodeStore(node)
  1526. elif isinstance(node.ctx, ast.Del):
  1527. self.handleNodeDelete(node)
  1528. else:
  1529. # Unknown context
  1530. raise RuntimeError(f"Got impossible expression context: {node.ctx!r}")
  1531. def CONTINUE(self, node):
  1532. # Walk the tree up until we see a loop (OK), a function or class
  1533. # definition (not OK), for 'continue', a finally block (not OK), or
  1534. # the top module scope (not OK)
  1535. n = node
  1536. while hasattr(n, '_pyflakes_parent'):
  1537. n, n_child = n._pyflakes_parent, n
  1538. if isinstance(n, (ast.While, ast.For, ast.AsyncFor)):
  1539. # Doesn't apply unless it's in the loop itself
  1540. if n_child not in n.orelse:
  1541. return
  1542. if isinstance(n, (ast.FunctionDef, ast.ClassDef)):
  1543. break
  1544. if isinstance(node, ast.Continue):
  1545. self.report(messages.ContinueOutsideLoop, node)
  1546. else: # ast.Break
  1547. self.report(messages.BreakOutsideLoop, node)
  1548. BREAK = CONTINUE
  1549. def RETURN(self, node):
  1550. if isinstance(self.scope, (ClassScope, ModuleScope)):
  1551. self.report(messages.ReturnOutsideFunction, node)
  1552. return
  1553. if (
  1554. node.value and
  1555. hasattr(self.scope, 'returnValue') and
  1556. not self.scope.returnValue
  1557. ):
  1558. self.scope.returnValue = node.value
  1559. self.handleNode(node.value, node)
  1560. def YIELD(self, node):
  1561. if isinstance(self.scope, (ClassScope, ModuleScope)):
  1562. self.report(messages.YieldOutsideFunction, node)
  1563. return
  1564. self.handleNode(node.value, node)
  1565. AWAIT = YIELDFROM = YIELD
  1566. def FUNCTIONDEF(self, node):
  1567. for deco in node.decorator_list:
  1568. self.handleNode(deco, node)
  1569. with self._type_param_scope(node):
  1570. self.LAMBDA(node)
  1571. self.addBinding(node, FunctionDefinition(node.name, node))
  1572. # doctest does not process doctest within a doctest,
  1573. # or in nested functions.
  1574. if (self.withDoctest and
  1575. not self._in_doctest() and
  1576. not isinstance(self.scope, FunctionScope)):
  1577. self.deferFunction(lambda: self.handleDoctests(node))
  1578. ASYNCFUNCTIONDEF = FUNCTIONDEF
  1579. def LAMBDA(self, node):
  1580. args = []
  1581. annotations = []
  1582. for arg in node.args.posonlyargs:
  1583. args.append(arg.arg)
  1584. annotations.append(arg.annotation)
  1585. for arg in node.args.args + node.args.kwonlyargs:
  1586. args.append(arg.arg)
  1587. annotations.append(arg.annotation)
  1588. defaults = node.args.defaults + node.args.kw_defaults
  1589. has_annotations = not isinstance(node, ast.Lambda)
  1590. for arg_name in ('vararg', 'kwarg'):
  1591. wildcard = getattr(node.args, arg_name)
  1592. if not wildcard:
  1593. continue
  1594. args.append(wildcard.arg)
  1595. if has_annotations:
  1596. annotations.append(wildcard.annotation)
  1597. if has_annotations:
  1598. annotations.append(node.returns)
  1599. if len(set(args)) < len(args):
  1600. for (idx, arg) in enumerate(args):
  1601. if arg in args[:idx]:
  1602. self.report(messages.DuplicateArgument, node, arg)
  1603. for annotation in annotations:
  1604. self.handleAnnotation(annotation, node)
  1605. for default in defaults:
  1606. self.handleNode(default, node)
  1607. def runFunction():
  1608. with self.in_scope(FunctionScope):
  1609. self.handleChildren(
  1610. node,
  1611. omit=('decorator_list', 'returns', 'type_params'),
  1612. )
  1613. self.deferFunction(runFunction)
  1614. def ARGUMENTS(self, node):
  1615. self.handleChildren(node, omit=('defaults', 'kw_defaults'))
  1616. def ARG(self, node):
  1617. self.addBinding(node, Argument(node.arg, self.getScopeNode(node)))
  1618. def CLASSDEF(self, node):
  1619. """
  1620. Check names used in a class definition, including its decorators, base
  1621. classes, and the body of its definition. Additionally, add its name to
  1622. the current scope.
  1623. """
  1624. for deco in node.decorator_list:
  1625. self.handleNode(deco, node)
  1626. with self._type_param_scope(node):
  1627. for baseNode in node.bases:
  1628. self.handleNode(baseNode, node)
  1629. for keywordNode in node.keywords:
  1630. self.handleNode(keywordNode, node)
  1631. with self.in_scope(ClassScope):
  1632. # doctest does not process doctest within a doctest
  1633. # classes within classes are processed.
  1634. if (self.withDoctest and
  1635. not self._in_doctest() and
  1636. not isinstance(self.scope, FunctionScope)):
  1637. self.deferFunction(lambda: self.handleDoctests(node))
  1638. for stmt in node.body:
  1639. self.handleNode(stmt, node)
  1640. self.addBinding(node, ClassDefinition(node.name, node))
  1641. def AUGASSIGN(self, node):
  1642. self.handleNodeLoad(node.target, node)
  1643. self.handleNode(node.value, node)
  1644. self.handleNode(node.target, node)
  1645. def TUPLE(self, node):
  1646. if isinstance(node.ctx, ast.Store):
  1647. # Python 3 advanced tuple unpacking: a, *b, c = d.
  1648. # Only one starred expression is allowed, and no more than 1<<8
  1649. # assignments are allowed before a stared expression. There is
  1650. # also a limit of 1<<24 expressions after the starred expression,
  1651. # which is impossible to test due to memory restrictions, but we
  1652. # add it here anyway
  1653. has_starred = False
  1654. star_loc = -1
  1655. for i, n in enumerate(node.elts):
  1656. if isinstance(n, ast.Starred):
  1657. if has_starred:
  1658. self.report(messages.TwoStarredExpressions, node)
  1659. # The SyntaxError doesn't distinguish two from more
  1660. # than two.
  1661. break
  1662. has_starred = True
  1663. star_loc = i
  1664. if star_loc >= 1 << 8 or len(node.elts) - star_loc - 1 >= 1 << 24:
  1665. self.report(messages.TooManyExpressionsInStarredAssignment, node)
  1666. self.handleChildren(node)
  1667. LIST = TUPLE
  1668. def IMPORT(self, node):
  1669. for alias in node.names:
  1670. if '.' in alias.name and not alias.asname:
  1671. importation = SubmoduleImportation(alias.name, node)
  1672. else:
  1673. name = alias.asname or alias.name
  1674. importation = Importation(name, node, alias.name)
  1675. self.addBinding(node, importation)
  1676. def IMPORTFROM(self, node):
  1677. if node.module == '__future__':
  1678. if not self.futuresAllowed:
  1679. self.report(messages.LateFutureImport, node)
  1680. else:
  1681. self.futuresAllowed = False
  1682. module = ('.' * node.level) + (node.module or '')
  1683. for alias in node.names:
  1684. name = alias.asname or alias.name
  1685. if node.module == '__future__':
  1686. importation = FutureImportation(name, node, self.scope)
  1687. if alias.name not in __future__.all_feature_names:
  1688. self.report(messages.FutureFeatureNotDefined,
  1689. node, alias.name)
  1690. if alias.name == 'annotations':
  1691. self.annotationsFutureEnabled = True
  1692. elif alias.name == '*':
  1693. if not isinstance(self.scope, ModuleScope):
  1694. self.report(messages.ImportStarNotPermitted,
  1695. node, module)
  1696. continue
  1697. self.scope.importStarred = True
  1698. self.report(messages.ImportStarUsed, node, module)
  1699. importation = StarImportation(module, node)
  1700. else:
  1701. importation = ImportationFrom(name, node,
  1702. module, alias.name)
  1703. self.addBinding(node, importation)
  1704. def TRY(self, node):
  1705. handler_names = []
  1706. # List the exception handlers
  1707. for i, handler in enumerate(node.handlers):
  1708. if isinstance(handler.type, ast.Tuple):
  1709. for exc_type in handler.type.elts:
  1710. handler_names.append(getNodeName(exc_type))
  1711. elif handler.type:
  1712. handler_names.append(getNodeName(handler.type))
  1713. if handler.type is None and i < len(node.handlers) - 1:
  1714. self.report(messages.DefaultExceptNotLast, handler)
  1715. # Memorize the except handlers and process the body
  1716. self.exceptHandlers.append(handler_names)
  1717. for child in node.body:
  1718. self.handleNode(child, node)
  1719. self.exceptHandlers.pop()
  1720. # Process the other nodes: "except:", "else:", "finally:"
  1721. self.handleChildren(node, omit='body')
  1722. TRYSTAR = TRY
  1723. def EXCEPTHANDLER(self, node):
  1724. if node.name is None:
  1725. self.handleChildren(node)
  1726. return
  1727. # If the name already exists in the scope, modify state of existing
  1728. # binding.
  1729. if node.name in self.scope:
  1730. self.handleNodeStore(node)
  1731. # 3.x: the name of the exception, which is not a Name node, but a
  1732. # simple string, creates a local that is only bound within the scope of
  1733. # the except: block. As such, temporarily remove the existing binding
  1734. # to more accurately determine if the name is used in the except:
  1735. # block.
  1736. try:
  1737. prev_definition = self.scope.pop(node.name)
  1738. except KeyError:
  1739. prev_definition = None
  1740. self.handleNodeStore(node)
  1741. self.handleChildren(node)
  1742. # See discussion on https://github.com/PyCQA/pyflakes/pull/59
  1743. # We're removing the local name since it's being unbound after leaving
  1744. # the except: block and it's always unbound if the except: block is
  1745. # never entered. This will cause an "undefined name" error raised if
  1746. # the checked code tries to use the name afterwards.
  1747. #
  1748. # Unless it's been removed already. Then do nothing.
  1749. try:
  1750. binding = self.scope.pop(node.name)
  1751. except KeyError:
  1752. pass
  1753. else:
  1754. if not binding.used:
  1755. self.report(messages.UnusedVariable, node, node.name)
  1756. # Restore.
  1757. if prev_definition:
  1758. self.scope[node.name] = prev_definition
  1759. def ANNASSIGN(self, node):
  1760. self.handleAnnotation(node.annotation, node)
  1761. # If the assignment has value, handle the *value* now.
  1762. if node.value:
  1763. # If the annotation is `TypeAlias`, handle the *value* as an annotation.
  1764. if _is_typing(node.annotation, 'TypeAlias', self.scopeStack):
  1765. self.handleAnnotation(node.value, node)
  1766. else:
  1767. self.handleNode(node.value, node)
  1768. self.handleNode(node.target, node)
  1769. def COMPARE(self, node):
  1770. left = node.left
  1771. for op, right in zip(node.ops, node.comparators):
  1772. if (
  1773. isinstance(op, (ast.Is, ast.IsNot)) and (
  1774. _is_const_non_singleton(left) or
  1775. _is_const_non_singleton(right)
  1776. )
  1777. ):
  1778. self.report(messages.IsLiteral, node)
  1779. left = right
  1780. self.handleChildren(node)
  1781. MATCH = MATCH_CASE = MATCHCLASS = MATCHOR = MATCHSEQUENCE = handleChildren
  1782. MATCHSINGLETON = MATCHVALUE = handleChildren
  1783. def _match_target(self, node):
  1784. self.handleNodeStore(node)
  1785. self.handleChildren(node)
  1786. MATCHAS = MATCHMAPPING = MATCHSTAR = _match_target
  1787. @contextlib.contextmanager
  1788. def _type_param_scope(self, node):
  1789. with contextlib.ExitStack() as ctx:
  1790. if sys.version_info >= (3, 12):
  1791. ctx.enter_context(self.in_scope(TypeScope))
  1792. for param in node.type_params:
  1793. self.handleNode(param, node)
  1794. yield
  1795. def TYPEVAR(self, node):
  1796. self.handleNodeStore(node)
  1797. self.handle_annotation_always_deferred(node.bound, node)
  1798. def TYPEALIAS(self, node):
  1799. self.handleNode(node.name, node)
  1800. with self._type_param_scope(node):
  1801. self.handle_annotation_always_deferred(node.value, node)