libv8 7.8.279.23.0beta1 → 8.4.255.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (719) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.travis.yml +11 -14
  4. data/CHANGELOG.md +7 -1
  5. data/README.md +10 -11
  6. data/Rakefile +30 -36
  7. data/ext/libv8/builder.rb +2 -1
  8. data/lib/libv8/version.rb +1 -1
  9. data/libv8.gemspec +1 -3
  10. data/vendor/depot_tools/{cipd.ps1 → .cipd_impl.ps1} +0 -0
  11. data/vendor/depot_tools/.gitattributes +1 -1
  12. data/vendor/depot_tools/.gitignore +3 -1
  13. data/vendor/depot_tools/.style.yapf +3 -1
  14. data/vendor/depot_tools/.vpython +55 -0
  15. data/vendor/depot_tools/.vpython3 +23 -0
  16. data/vendor/depot_tools/CROS_OWNERS +3 -1
  17. data/vendor/depot_tools/GOMA_OWNERS +9 -0
  18. data/vendor/depot_tools/LUCI_OWNERS +5 -0
  19. data/vendor/depot_tools/OWNERS +21 -6
  20. data/vendor/depot_tools/PRESUBMIT.py +35 -18
  21. data/vendor/depot_tools/README.git-cl.md +0 -14
  22. data/vendor/depot_tools/README.md +1 -1
  23. data/vendor/depot_tools/WATCHLISTS +2 -2
  24. data/vendor/depot_tools/auth.py +60 -772
  25. data/vendor/depot_tools/autoninja +12 -6
  26. data/vendor/depot_tools/autoninja.bat +6 -6
  27. data/vendor/depot_tools/autoninja.py +64 -27
  28. data/vendor/depot_tools/bb +1 -1
  29. data/vendor/depot_tools/bootstrap/{win/README.md → README.md} +28 -14
  30. data/vendor/depot_tools/bootstrap/{win/win_tools.py → bootstrap.py} +60 -43
  31. data/vendor/depot_tools/bootstrap/{win/git-bash.template.sh → git-bash.template.sh} +1 -1
  32. data/vendor/depot_tools/bootstrap/{win/git.template.bat → git.template.bat} +0 -0
  33. data/vendor/depot_tools/bootstrap/manifest.txt +27 -0
  34. data/vendor/depot_tools/bootstrap/manifest_bleeding_edge.txt +27 -0
  35. data/vendor/depot_tools/bootstrap/{win/profile.d.python.sh → profile.d.python.sh} +0 -0
  36. data/vendor/depot_tools/bootstrap/{win/python27.bleeding_edge.bat → python27.bat} +0 -0
  37. data/vendor/depot_tools/bootstrap/{win/python27.new.bat → python3.bat} +3 -3
  38. data/vendor/depot_tools/bootstrap/{win/win_tools.bat → win_tools.bat} +21 -16
  39. data/vendor/depot_tools/bootstrap_python3 +35 -0
  40. data/vendor/depot_tools/cbuildbot +1 -1
  41. data/vendor/depot_tools/chrome_set_ver +1 -1
  42. data/vendor/depot_tools/cipd +43 -39
  43. data/vendor/depot_tools/cipd.bat +2 -2
  44. data/vendor/depot_tools/cipd_client_version +1 -1
  45. data/vendor/depot_tools/cipd_client_version.digests +15 -14
  46. data/vendor/depot_tools/cipd_manifest.txt +31 -8
  47. data/vendor/depot_tools/cipd_manifest.versions +278 -158
  48. data/vendor/depot_tools/cit.py +9 -7
  49. data/vendor/depot_tools/clang_format.py +4 -1
  50. data/vendor/depot_tools/clang_format_merge_driver.py +10 -8
  51. data/vendor/depot_tools/compile_single_file.py +7 -2
  52. data/vendor/depot_tools/cpplint.py +51 -45
  53. data/vendor/depot_tools/cros +87 -0
  54. data/vendor/depot_tools/cros_sdk +1 -1
  55. data/vendor/depot_tools/crosjobs +13 -0
  56. data/vendor/depot_tools/detect_host_arch.py +0 -1
  57. data/vendor/depot_tools/dirmd +12 -0
  58. data/vendor/depot_tools/dirmd.bat +7 -0
  59. data/vendor/depot_tools/download_from_google_storage.py +47 -27
  60. data/vendor/depot_tools/ensure_bootstrap +14 -0
  61. data/vendor/depot_tools/fetch +14 -1
  62. data/vendor/depot_tools/fetch.bat +14 -1
  63. data/vendor/depot_tools/fetch.py +5 -7
  64. data/vendor/depot_tools/fetch_configs/chromium.py +6 -4
  65. data/vendor/depot_tools/fetch_configs/devtools-frontend.py +44 -0
  66. data/vendor/depot_tools/fetch_configs/ios_internal.py +10 -19
  67. data/vendor/depot_tools/fix_encoding.py +19 -5
  68. data/vendor/depot_tools/gclient +28 -12
  69. data/vendor/depot_tools/gclient-new-workdir.py +2 -0
  70. data/vendor/depot_tools/gclient.bat +18 -1
  71. data/vendor/depot_tools/gclient.py +156 -118
  72. data/vendor/depot_tools/gclient_eval.py +119 -107
  73. data/vendor/depot_tools/gclient_paths.py +67 -57
  74. data/vendor/depot_tools/gclient_scm.py +180 -169
  75. data/vendor/depot_tools/gclient_utils.py +177 -124
  76. data/vendor/depot_tools/gerrit_client.py +21 -13
  77. data/vendor/depot_tools/gerrit_util.py +188 -228
  78. data/vendor/depot_tools/git-cache +1 -1
  79. data/vendor/depot_tools/git-cl +1 -1
  80. data/vendor/depot_tools/git-drover +1 -1
  81. data/vendor/depot_tools/git-find-releases +1 -1
  82. data/vendor/depot_tools/git-footers +1 -1
  83. data/vendor/depot_tools/git-freeze +1 -1
  84. data/vendor/depot_tools/git-hyper-blame +1 -1
  85. data/vendor/depot_tools/git-map +1 -1
  86. data/vendor/depot_tools/git-map-branches +1 -1
  87. data/vendor/depot_tools/git-mark-merge-base +1 -1
  88. data/vendor/depot_tools/git-nav-downstream +1 -1
  89. data/vendor/depot_tools/git-new-branch +1 -1
  90. data/vendor/depot_tools/git-number +1 -1
  91. data/vendor/depot_tools/git-rebase-update +1 -1
  92. data/vendor/depot_tools/git-rename-branch +1 -1
  93. data/vendor/depot_tools/git-reparent-branch +1 -1
  94. data/vendor/depot_tools/git-retry +1 -1
  95. data/vendor/depot_tools/git-squash-branch +1 -1
  96. data/vendor/depot_tools/git-thaw +1 -1
  97. data/vendor/depot_tools/git-upstream-diff +1 -1
  98. data/vendor/depot_tools/git_cache.py +195 -281
  99. data/vendor/depot_tools/git_cl.py +1506 -2075
  100. data/vendor/depot_tools/git_cl_completion.sh +16 -2
  101. data/vendor/depot_tools/git_common.py +77 -32
  102. data/vendor/depot_tools/git_drover.py +17 -8
  103. data/vendor/depot_tools/git_find_releases.py +11 -9
  104. data/vendor/depot_tools/git_footers.py +13 -9
  105. data/vendor/depot_tools/git_freezer.py +3 -1
  106. data/vendor/depot_tools/git_hyper_blame.py +25 -32
  107. data/vendor/depot_tools/git_map.py +115 -93
  108. data/vendor/depot_tools/git_map_branches.py +11 -10
  109. data/vendor/depot_tools/git_mark_merge_base.py +8 -6
  110. data/vendor/depot_tools/git_nav_downstream.py +9 -6
  111. data/vendor/depot_tools/git_new_branch.py +39 -33
  112. data/vendor/depot_tools/git_number.py +28 -17
  113. data/vendor/depot_tools/git_rebase_update.py +50 -49
  114. data/vendor/depot_tools/git_rename_branch.py +2 -2
  115. data/vendor/depot_tools/git_reparent_branch.py +8 -6
  116. data/vendor/depot_tools/git_upstream_diff.py +4 -2
  117. data/vendor/depot_tools/gn.py +6 -4
  118. data/vendor/depot_tools/goma_auth +12 -0
  119. data/vendor/depot_tools/goma_auth.bat +8 -0
  120. data/vendor/depot_tools/goma_ctl +12 -0
  121. data/vendor/depot_tools/goma_ctl.bat +8 -0
  122. data/vendor/depot_tools/gsutil.py +5 -2
  123. data/vendor/depot_tools/gsutil.py.bat +8 -0
  124. data/vendor/depot_tools/gsutil.vpython +3 -1
  125. data/vendor/depot_tools/infra/config/OWNERS +2 -2
  126. data/vendor/depot_tools/infra/config/recipes.cfg +3 -2
  127. data/vendor/depot_tools/led +1 -1
  128. data/vendor/depot_tools/lockfile.py +116 -0
  129. data/vendor/depot_tools/luci-auth +1 -1
  130. data/vendor/depot_tools/lucicfg +1 -1
  131. data/vendor/depot_tools/mac_toolchain +1 -1
  132. data/vendor/depot_tools/man/html/depot_tools.html +1 -1
  133. data/vendor/depot_tools/man/html/depot_tools_tutorial.html +31 -25
  134. data/vendor/depot_tools/man/html/git-cl.html +1 -1
  135. data/vendor/depot_tools/man/html/git-drover.html +18 -18
  136. data/vendor/depot_tools/man/html/git-footers.html +1 -1
  137. data/vendor/depot_tools/man/html/git-freeze.html +3 -3
  138. data/vendor/depot_tools/man/html/git-hyper-blame.html +1 -1
  139. data/vendor/depot_tools/man/html/git-map-branches.html +2 -2
  140. data/vendor/depot_tools/man/html/git-map.html +1 -1
  141. data/vendor/depot_tools/man/html/git-mark-merge-base.html +1 -1
  142. data/vendor/depot_tools/man/html/git-nav-downstream.html +3 -3
  143. data/vendor/depot_tools/man/html/git-nav-upstream.html +12 -6
  144. data/vendor/depot_tools/man/html/git-new-branch.html +1 -1
  145. data/vendor/depot_tools/man/html/git-rebase-update.html +20 -1
  146. data/vendor/depot_tools/man/html/git-rename-branch.html +1 -1
  147. data/vendor/depot_tools/man/html/git-reparent-branch.html +1 -1
  148. data/vendor/depot_tools/man/html/git-retry.html +1 -1
  149. data/vendor/depot_tools/man/html/git-squash-branch.html +1 -1
  150. data/vendor/depot_tools/man/html/git-thaw.html +1 -1
  151. data/vendor/depot_tools/man/html/git-upstream-diff.html +10 -6
  152. data/vendor/depot_tools/man/man1/git-cl.1 +4 -4
  153. data/vendor/depot_tools/man/man1/git-drover.1 +21 -21
  154. data/vendor/depot_tools/man/man1/git-footers.1 +4 -4
  155. data/vendor/depot_tools/man/man1/git-freeze.1 +6 -6
  156. data/vendor/depot_tools/man/man1/git-hyper-blame.1 +4 -4
  157. data/vendor/depot_tools/man/man1/git-map-branches.1 +4 -4
  158. data/vendor/depot_tools/man/man1/git-map.1 +4 -4
  159. data/vendor/depot_tools/man/man1/git-mark-merge-base.1 +4 -4
  160. data/vendor/depot_tools/man/man1/git-nav-downstream.1 +6 -6
  161. data/vendor/depot_tools/man/man1/git-nav-upstream.1 +15 -9
  162. data/vendor/depot_tools/man/man1/git-new-branch.1 +3 -3
  163. data/vendor/depot_tools/man/man1/git-rebase-update.1 +14 -4
  164. data/vendor/depot_tools/man/man1/git-rename-branch.1 +4 -4
  165. data/vendor/depot_tools/man/man1/git-reparent-branch.1 +4 -4
  166. data/vendor/depot_tools/man/man1/git-retry.1 +4 -4
  167. data/vendor/depot_tools/man/man1/git-squash-branch.1 +4 -4
  168. data/vendor/depot_tools/man/man1/git-thaw.1 +4 -4
  169. data/vendor/depot_tools/man/man1/git-upstream-diff.1 +7 -13
  170. data/vendor/depot_tools/man/man7/depot_tools.7 +4 -4
  171. data/vendor/depot_tools/man/man7/depot_tools_tutorial.7 +31 -25
  172. data/vendor/depot_tools/man/src/common_demo_functions.sh +2 -2
  173. data/vendor/depot_tools/man/src/depot_tools_tutorial.txt +3 -3
  174. data/vendor/depot_tools/man/src/filter_demo_output.py +3 -1
  175. data/vendor/depot_tools/man/src/git-new-branch.txt +2 -1
  176. data/vendor/depot_tools/man/src/git-rebase-update.txt +8 -1
  177. data/vendor/depot_tools/metrics.README.md +5 -2
  178. data/vendor/depot_tools/metrics.py +4 -4
  179. data/vendor/depot_tools/metrics_utils.py +3 -3
  180. data/vendor/depot_tools/my_activity.py +85 -251
  181. data/vendor/depot_tools/ninja +1 -0
  182. data/vendor/depot_tools/ninja-mac +0 -0
  183. data/vendor/depot_tools/ninjalog_uploader.py +146 -145
  184. data/vendor/depot_tools/ninjalog_uploader_wrapper.py +69 -60
  185. data/vendor/depot_tools/owners.py +57 -21
  186. data/vendor/depot_tools/owners_finder.py +28 -14
  187. data/vendor/depot_tools/post_build_ninja_summary.py +76 -48
  188. data/vendor/depot_tools/presubmit_canned_checks.py +293 -106
  189. data/vendor/depot_tools/presubmit_support.py +527 -333
  190. data/vendor/depot_tools/prpc +1 -1
  191. data/vendor/depot_tools/pylint +2 -12
  192. data/vendor/depot_tools/pylint-1.5 +78 -0
  193. data/vendor/depot_tools/pylint-1.6 +78 -0
  194. data/vendor/depot_tools/pylint-1.7 +78 -0
  195. data/vendor/depot_tools/pylint-1.8 +78 -0
  196. data/vendor/depot_tools/pylint-1.9 +78 -0
  197. data/vendor/depot_tools/{depot-tools-auth.bat → pylint.bat} +2 -2
  198. data/vendor/depot_tools/pylint_main.py +45 -0
  199. data/vendor/depot_tools/pylintrc +14 -1
  200. data/vendor/depot_tools/python-bin/python3 +7 -0
  201. data/vendor/depot_tools/python_runner.sh +13 -8
  202. data/vendor/depot_tools/rdb +12 -0
  203. data/vendor/depot_tools/rdb.bat +7 -0
  204. data/vendor/depot_tools/recipes/OWNERS +0 -1
  205. data/vendor/depot_tools/recipes/README.recipes.md +215 -151
  206. data/vendor/depot_tools/recipes/recipe_modules/OWNERS +1 -1
  207. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +17 -17
  208. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +65 -32
  209. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +12 -4
  210. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +11 -3
  211. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +12 -4
  212. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +22 -8
  213. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +27 -9
  214. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +22 -8
  215. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +22 -8
  216. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/input_commit_with_id_without_repo.json +22 -8
  217. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/multiple_patch_refs.json +22 -8
  218. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +27 -9
  219. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_HEAD.json +12 -4
  220. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_branch_head.json +10 -4
  221. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_a_specific_commit.json +12 -4
  222. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_cp_checkout_master.json +10 -4
  223. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/refs.json +22 -8
  224. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +22 -8
  225. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/resolve_chromium_fixed_version.json +117 -0
  226. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +16 -10
  227. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +34 -10
  228. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +16 -10
  229. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +27 -9
  230. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +27 -9
  231. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +27 -9
  232. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +27 -9
  233. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +27 -9
  234. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +27 -9
  235. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +27 -9
  236. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +0 -5
  237. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +22 -8
  238. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +7 -23
  239. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +187 -114
  240. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +2 -2
  241. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/do_not_retry_patch_failures_in_cq.py +42 -0
  242. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/ensure_checkout.py +1 -0
  243. data/vendor/depot_tools/recipes/recipe_modules/cipd/__init__.py +0 -1
  244. data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +2 -2
  245. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +0 -1
  246. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +0 -1
  247. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +2 -4
  248. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +0 -1
  249. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +0 -1
  250. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +26 -6
  251. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +23 -5
  252. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +23 -5
  253. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +0 -1
  254. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +0 -1
  255. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +0 -1
  256. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +0 -1
  257. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +0 -1
  258. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +0 -1
  259. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +0 -1
  260. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +0 -1
  261. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +0 -1
  262. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +0 -1
  263. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +0 -1
  264. data/vendor/depot_tools/recipes/recipe_modules/cipd/test_api.py +1 -1
  265. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +4 -1
  266. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +4 -2
  267. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +3 -1
  268. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +4 -2
  269. data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +2 -1
  270. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +82 -13
  271. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +21 -9
  272. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +3 -4
  273. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +3 -6
  274. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +3 -4
  275. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +7 -7
  276. data/vendor/depot_tools/recipes/recipe_modules/gclient/resources/diff_deps.py +16 -0
  277. data/vendor/depot_tools/recipes/recipe_modules/gclient/test_api.py +4 -0
  278. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/basic.json +55 -0
  279. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/dont have revision yet.json +84 -0
  280. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/no change, exception.json +83 -0
  281. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.expected/windows.json +55 -0
  282. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/diff_deps.py +88 -0
  283. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/patch_project.py +9 -21
  284. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/sync_failure.py +24 -0
  285. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +2 -1
  286. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +7 -12
  287. data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +0 -2
  288. data/vendor/depot_tools/recipes/recipe_modules/git/api.py +9 -17
  289. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +2 -8
  290. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +2 -8
  291. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +2 -8
  292. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +2 -8
  293. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +2 -8
  294. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +2 -8
  295. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +2 -8
  296. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +3 -13
  297. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +2 -8
  298. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +4 -12
  299. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +2 -10
  300. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +1 -7
  301. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +1 -7
  302. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +0 -8
  303. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +3 -10
  304. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +3 -11
  305. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +2 -8
  306. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +3 -13
  307. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +2 -8
  308. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +2 -8
  309. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +0 -5
  310. data/vendor/depot_tools/recipes/recipe_modules/git_cl/__init__.py +1 -1
  311. data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +7 -13
  312. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +21 -16
  313. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.py +1 -2
  314. data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +1 -1
  315. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +0 -1
  316. data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +2 -2
  317. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +0 -1
  318. data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +23 -8
  319. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +52 -1
  320. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.py +15 -0
  321. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +1 -0
  322. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +32 -8
  323. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/ancient_version.json +83 -0
  324. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/automatic_version.json +83 -0
  325. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/explicit_version.json +83 -0
  326. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/linux.json +0 -1
  327. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +5 -4
  328. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +0 -1
  329. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +21 -2
  330. data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +20 -0
  331. data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +235 -3
  332. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +13 -5
  333. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.py +5 -1
  334. data/vendor/depot_tools/recipes/recipe_modules/presubmit/properties.proto +14 -0
  335. data/vendor/depot_tools/recipes/recipe_modules/presubmit/test_api.py +19 -0
  336. data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/execute.py +247 -0
  337. data/vendor/depot_tools/recipes/recipe_modules/presubmit/tests/prepare.py +49 -0
  338. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +33 -45
  339. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +0 -1
  340. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +64 -21
  341. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +64 -21
  342. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +1 -22
  343. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +1 -22
  344. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +5 -32
  345. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_fetch_ref_timeout.py +29 -0
  346. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.expected/basic.json +5 -0
  347. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_owner.py +22 -0
  348. data/vendor/depot_tools/recipes/recipe_modules/tryserver/tests/gerrit_change_target_ref.py +32 -0
  349. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +0 -1
  350. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +0 -1
  351. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +2 -1
  352. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +1 -6
  353. data/vendor/depot_tools/recipes/recipes.py +49 -28
  354. data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +11 -6
  355. data/vendor/depot_tools/repo +698 -540
  356. data/vendor/depot_tools/roll-dep +14 -1
  357. data/vendor/depot_tools/roll-dep.bat +10 -1
  358. data/vendor/depot_tools/roll_dep.py +15 -10
  359. data/vendor/depot_tools/scm.py +94 -74
  360. data/vendor/depot_tools/setup_color.py +36 -2
  361. data/vendor/depot_tools/split_cl.py +44 -32
  362. data/vendor/depot_tools/subcommand.py +6 -6
  363. data/vendor/depot_tools/subprocess2.py +38 -322
  364. data/vendor/depot_tools/third_party/colorama/LICENSE.txt +0 -1
  365. data/vendor/depot_tools/third_party/colorama/README.chromium +4 -5
  366. data/vendor/depot_tools/third_party/colorama/README.rst +346 -0
  367. data/vendor/depot_tools/third_party/colorama/__init__.py +3 -4
  368. data/vendor/depot_tools/third_party/colorama/ansi.py +82 -30
  369. data/vendor/depot_tools/third_party/colorama/ansitowin32.py +105 -37
  370. data/vendor/depot_tools/third_party/colorama/initialise.py +39 -15
  371. data/vendor/depot_tools/third_party/colorama/win32.py +46 -28
  372. data/vendor/depot_tools/third_party/colorama/winterm.py +80 -31
  373. data/vendor/depot_tools/update_depot_tools +18 -8
  374. data/vendor/depot_tools/update_depot_tools.bat +19 -15
  375. data/vendor/depot_tools/upload_metrics.py +7 -6
  376. data/vendor/depot_tools/upload_to_google_storage.py +22 -15
  377. data/vendor/depot_tools/vpython +4 -4
  378. data/vendor/depot_tools/vpython.bat +1 -1
  379. data/vendor/depot_tools/vpython3 +55 -0
  380. data/vendor/depot_tools/vpython3.bat +12 -0
  381. data/vendor/depot_tools/watchlists.py +14 -11
  382. data/vendor/depot_tools/weekly +4 -2
  383. data/vendor/depot_tools/win32imports.py +61 -0
  384. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +49 -41
  385. data/vendor/depot_tools/win_toolchain/package_from_installed.py +142 -149
  386. data/vendor/depot_tools/wtf +5 -3
  387. data/vendor/depot_tools/yapf +5 -1
  388. metadata +66 -345
  389. data/vendor/depot_tools/README.testing +0 -23
  390. data/vendor/depot_tools/annotated_gclient.py +0 -89
  391. data/vendor/depot_tools/appengine_mapper.py +0 -23
  392. data/vendor/depot_tools/bootstrap/win/manifest.txt +0 -20
  393. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +0 -20
  394. data/vendor/depot_tools/bootstrap/win/pylint.new.bat +0 -7
  395. data/vendor/depot_tools/buildbucket.py +0 -186
  396. data/vendor/depot_tools/checkout.py +0 -431
  397. data/vendor/depot_tools/cros +0 -1
  398. data/vendor/depot_tools/dart_format.py +0 -58
  399. data/vendor/depot_tools/depot-tools-auth +0 -8
  400. data/vendor/depot_tools/depot-tools-auth.py +0 -102
  401. data/vendor/depot_tools/my_reviews.py +0 -396
  402. data/vendor/depot_tools/patch.py +0 -548
  403. data/vendor/depot_tools/pylint.py +0 -30
  404. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name.json +0 -48
  405. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +0 -239
  406. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_luci.json +0 -222
  407. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/__init__.py +0 -4
  408. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/api.py +0 -29
  409. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/basic.json +0 -15
  410. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_linux.json +0 -15
  411. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_mac.json +0 -15
  412. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_win.json +0 -15
  413. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_linux.json +0 -15
  414. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_mac.json +0 -15
  415. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_win.json +0 -15
  416. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_linux.json +0 -15
  417. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_mac.json +0 -15
  418. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_win.json +0 -15
  419. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.py +0 -33
  420. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/path_config.py +0 -66
  421. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/set_failure_hash_with_no_steps.json +0 -11
  422. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch.json +0 -45
  423. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch_luci.json +0 -45
  424. data/vendor/depot_tools/rietveld.py +0 -779
  425. data/vendor/depot_tools/roll-dep-svn +0 -8
  426. data/vendor/depot_tools/roll-dep-svn.bat +0 -12
  427. data/vendor/depot_tools/roll_dep_svn.py +0 -430
  428. data/vendor/depot_tools/support/chromite_wrapper +0 -96
  429. data/vendor/depot_tools/third_party/boto/LICENSE +0 -18
  430. data/vendor/depot_tools/third_party/boto/README.chromium +0 -43
  431. data/vendor/depot_tools/third_party/boto/README.rst +0 -163
  432. data/vendor/depot_tools/third_party/boto/__init__.py +0 -793
  433. data/vendor/depot_tools/third_party/boto/auth.py +0 -682
  434. data/vendor/depot_tools/third_party/boto/auth_handler.py +0 -58
  435. data/vendor/depot_tools/third_party/boto/cacerts/__init__.py +0 -22
  436. data/vendor/depot_tools/third_party/boto/cacerts/cacerts.txt +0 -2183
  437. data/vendor/depot_tools/third_party/boto/compat.py +0 -28
  438. data/vendor/depot_tools/third_party/boto/connection.py +0 -1081
  439. data/vendor/depot_tools/third_party/boto/contrib/__init__.py +0 -22
  440. data/vendor/depot_tools/third_party/boto/contrib/ymlmessage.py +0 -52
  441. data/vendor/depot_tools/third_party/boto/core/README +0 -58
  442. data/vendor/depot_tools/third_party/boto/core/__init__.py +0 -23
  443. data/vendor/depot_tools/third_party/boto/core/auth.py +0 -78
  444. data/vendor/depot_tools/third_party/boto/core/credentials.py +0 -154
  445. data/vendor/depot_tools/third_party/boto/core/dictresponse.py +0 -178
  446. data/vendor/depot_tools/third_party/boto/core/service.py +0 -67
  447. data/vendor/depot_tools/third_party/boto/datapipeline/__init__.py +0 -0
  448. data/vendor/depot_tools/third_party/boto/datapipeline/exceptions.py +0 -42
  449. data/vendor/depot_tools/third_party/boto/datapipeline/layer1.py +0 -546
  450. data/vendor/depot_tools/third_party/boto/ecs/__init__.py +0 -90
  451. data/vendor/depot_tools/third_party/boto/ecs/item.py +0 -153
  452. data/vendor/depot_tools/third_party/boto/exception.py +0 -476
  453. data/vendor/depot_tools/third_party/boto/file/README +0 -49
  454. data/vendor/depot_tools/third_party/boto/file/__init__.py +0 -28
  455. data/vendor/depot_tools/third_party/boto/file/bucket.py +0 -112
  456. data/vendor/depot_tools/third_party/boto/file/connection.py +0 -33
  457. data/vendor/depot_tools/third_party/boto/file/key.py +0 -199
  458. data/vendor/depot_tools/third_party/boto/file/simpleresultset.py +0 -30
  459. data/vendor/depot_tools/third_party/boto/fps/__init__.py +0 -21
  460. data/vendor/depot_tools/third_party/boto/fps/connection.py +0 -369
  461. data/vendor/depot_tools/third_party/boto/fps/exception.py +0 -344
  462. data/vendor/depot_tools/third_party/boto/fps/response.py +0 -175
  463. data/vendor/depot_tools/third_party/boto/gs/__init__.py +0 -22
  464. data/vendor/depot_tools/third_party/boto/gs/acl.py +0 -304
  465. data/vendor/depot_tools/third_party/boto/gs/bucket.py +0 -870
  466. data/vendor/depot_tools/third_party/boto/gs/bucketlistresultset.py +0 -64
  467. data/vendor/depot_tools/third_party/boto/gs/connection.py +0 -103
  468. data/vendor/depot_tools/third_party/boto/gs/cors.py +0 -169
  469. data/vendor/depot_tools/third_party/boto/gs/key.py +0 -704
  470. data/vendor/depot_tools/third_party/boto/gs/resumable_upload_handler.py +0 -659
  471. data/vendor/depot_tools/third_party/boto/gs/user.py +0 -54
  472. data/vendor/depot_tools/third_party/boto/handler.py +0 -44
  473. data/vendor/depot_tools/third_party/boto/https_connection.py +0 -124
  474. data/vendor/depot_tools/third_party/boto/jsonresponse.py +0 -163
  475. data/vendor/depot_tools/third_party/boto/manage/__init__.py +0 -23
  476. data/vendor/depot_tools/third_party/boto/manage/cmdshell.py +0 -241
  477. data/vendor/depot_tools/third_party/boto/manage/propget.py +0 -64
  478. data/vendor/depot_tools/third_party/boto/manage/server.py +0 -556
  479. data/vendor/depot_tools/third_party/boto/manage/task.py +0 -175
  480. data/vendor/depot_tools/third_party/boto/manage/test_manage.py +0 -34
  481. data/vendor/depot_tools/third_party/boto/manage/volume.py +0 -420
  482. data/vendor/depot_tools/third_party/boto/mashups/__init__.py +0 -23
  483. data/vendor/depot_tools/third_party/boto/mashups/interactive.py +0 -97
  484. data/vendor/depot_tools/third_party/boto/mashups/iobject.py +0 -115
  485. data/vendor/depot_tools/third_party/boto/mashups/order.py +0 -211
  486. data/vendor/depot_tools/third_party/boto/mashups/server.py +0 -395
  487. data/vendor/depot_tools/third_party/boto/plugin.py +0 -90
  488. data/vendor/depot_tools/third_party/boto/provider.py +0 -337
  489. data/vendor/depot_tools/third_party/boto/pyami/__init__.py +0 -22
  490. data/vendor/depot_tools/third_party/boto/pyami/bootstrap.py +0 -134
  491. data/vendor/depot_tools/third_party/boto/pyami/config.py +0 -229
  492. data/vendor/depot_tools/third_party/boto/pyami/copybot.cfg +0 -60
  493. data/vendor/depot_tools/third_party/boto/pyami/copybot.py +0 -97
  494. data/vendor/depot_tools/third_party/boto/pyami/helloworld.py +0 -28
  495. data/vendor/depot_tools/third_party/boto/pyami/launch_ami.py +0 -178
  496. data/vendor/depot_tools/third_party/boto/pyami/scriptbase.py +0 -44
  497. data/vendor/depot_tools/third_party/boto/pyami/startup.py +0 -60
  498. data/vendor/depot_tools/third_party/boto/regioninfo.py +0 -63
  499. data/vendor/depot_tools/third_party/boto/resultset.py +0 -169
  500. data/vendor/depot_tools/third_party/boto/roboto/__init__.py +0 -1
  501. data/vendor/depot_tools/third_party/boto/roboto/awsqueryrequest.py +0 -504
  502. data/vendor/depot_tools/third_party/boto/roboto/awsqueryservice.py +0 -121
  503. data/vendor/depot_tools/third_party/boto/roboto/param.py +0 -147
  504. data/vendor/depot_tools/third_party/boto/s3/__init__.py +0 -84
  505. data/vendor/depot_tools/third_party/boto/s3/acl.py +0 -164
  506. data/vendor/depot_tools/third_party/boto/s3/bucket.py +0 -1634
  507. data/vendor/depot_tools/third_party/boto/s3/bucketlistresultset.py +0 -139
  508. data/vendor/depot_tools/third_party/boto/s3/bucketlogging.py +0 -83
  509. data/vendor/depot_tools/third_party/boto/s3/connection.py +0 -540
  510. data/vendor/depot_tools/third_party/boto/s3/cors.py +0 -210
  511. data/vendor/depot_tools/third_party/boto/s3/deletemarker.py +0 -55
  512. data/vendor/depot_tools/third_party/boto/s3/key.py +0 -1712
  513. data/vendor/depot_tools/third_party/boto/s3/keyfile.py +0 -134
  514. data/vendor/depot_tools/third_party/boto/s3/lifecycle.py +0 -231
  515. data/vendor/depot_tools/third_party/boto/s3/multidelete.py +0 -138
  516. data/vendor/depot_tools/third_party/boto/s3/multipart.py +0 -315
  517. data/vendor/depot_tools/third_party/boto/s3/prefix.py +0 -42
  518. data/vendor/depot_tools/third_party/boto/s3/resumable_download_handler.py +0 -339
  519. data/vendor/depot_tools/third_party/boto/s3/tagging.py +0 -71
  520. data/vendor/depot_tools/third_party/boto/s3/user.py +0 -49
  521. data/vendor/depot_tools/third_party/boto/s3/website.py +0 -237
  522. data/vendor/depot_tools/third_party/boto/services/__init__.py +0 -23
  523. data/vendor/depot_tools/third_party/boto/services/bs.py +0 -179
  524. data/vendor/depot_tools/third_party/boto/services/message.py +0 -58
  525. data/vendor/depot_tools/third_party/boto/services/result.py +0 -136
  526. data/vendor/depot_tools/third_party/boto/services/service.py +0 -161
  527. data/vendor/depot_tools/third_party/boto/services/servicedef.py +0 -91
  528. data/vendor/depot_tools/third_party/boto/services/sonofmmm.cfg +0 -43
  529. data/vendor/depot_tools/third_party/boto/services/sonofmmm.py +0 -81
  530. data/vendor/depot_tools/third_party/boto/services/submit.py +0 -88
  531. data/vendor/depot_tools/third_party/boto/ses/__init__.py +0 -54
  532. data/vendor/depot_tools/third_party/boto/ses/connection.py +0 -521
  533. data/vendor/depot_tools/third_party/boto/ses/exceptions.py +0 -77
  534. data/vendor/depot_tools/third_party/boto/storage_uri.py +0 -835
  535. data/vendor/depot_tools/third_party/boto/sts/__init__.py +0 -55
  536. data/vendor/depot_tools/third_party/boto/sts/connection.py +0 -207
  537. data/vendor/depot_tools/third_party/boto/sts/credentials.py +0 -215
  538. data/vendor/depot_tools/third_party/boto/utils.py +0 -927
  539. data/vendor/depot_tools/third_party/colorama/README.txt +0 -304
  540. data/vendor/depot_tools/third_party/fancy_urllib/README +0 -22
  541. data/vendor/depot_tools/third_party/fancy_urllib/__init__.py +0 -460
  542. data/vendor/depot_tools/third_party/logilab/README.chromium +0 -6
  543. data/vendor/depot_tools/third_party/logilab/__init__.py +0 -0
  544. data/vendor/depot_tools/third_party/logilab/astroid/LICENSE.txt +0 -340
  545. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +0 -11
  546. data/vendor/depot_tools/third_party/logilab/astroid/__init__.py +0 -136
  547. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +0 -42
  548. data/vendor/depot_tools/third_party/logilab/astroid/arguments.py +0 -233
  549. data/vendor/depot_tools/third_party/logilab/astroid/as_string.py +0 -548
  550. data/vendor/depot_tools/third_party/logilab/astroid/astpeephole.py +0 -86
  551. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +0 -636
  552. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_builtin_inference.py +0 -336
  553. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_dateutil.py +0 -15
  554. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_gi.py +0 -195
  555. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_mechanize.py +0 -18
  556. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_nose.py +0 -82
  557. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_numpy.py +0 -62
  558. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_pytest.py +0 -76
  559. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_qt.py +0 -44
  560. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_six.py +0 -288
  561. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_ssl.py +0 -65
  562. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_stdlib.py +0 -473
  563. data/vendor/depot_tools/third_party/logilab/astroid/builder.py +0 -263
  564. data/vendor/depot_tools/third_party/logilab/astroid/context.py +0 -81
  565. data/vendor/depot_tools/third_party/logilab/astroid/decorators.py +0 -75
  566. data/vendor/depot_tools/third_party/logilab/astroid/exceptions.py +0 -71
  567. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +0 -359
  568. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +0 -267
  569. data/vendor/depot_tools/third_party/logilab/astroid/mixins.py +0 -147
  570. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +0 -741
  571. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +0 -1053
  572. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +0 -87
  573. data/vendor/depot_tools/third_party/logilab/astroid/objects.py +0 -186
  574. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +0 -470
  575. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +0 -390
  576. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +0 -989
  577. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +0 -1716
  578. data/vendor/depot_tools/third_party/logilab/astroid/test_utils.py +0 -201
  579. data/vendor/depot_tools/third_party/logilab/astroid/transforms.py +0 -96
  580. data/vendor/depot_tools/third_party/logilab/astroid/util.py +0 -89
  581. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/LICENSE +0 -19
  582. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/README.chromium +0 -11
  583. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/__init__.py +0 -20
  584. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/cext.c +0 -1421
  585. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/compat.py +0 -9
  586. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/simple.py +0 -246
  587. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/slots.py +0 -414
  588. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/utils.py +0 -13
  589. data/vendor/depot_tools/third_party/logilab/wrapt/LICENSE +0 -24
  590. data/vendor/depot_tools/third_party/logilab/wrapt/README.chromium +0 -11
  591. data/vendor/depot_tools/third_party/logilab/wrapt/__init__.py +0 -19
  592. data/vendor/depot_tools/third_party/logilab/wrapt/_wrappers.c +0 -2729
  593. data/vendor/depot_tools/third_party/logilab/wrapt/arguments.py +0 -96
  594. data/vendor/depot_tools/third_party/logilab/wrapt/decorators.py +0 -512
  595. data/vendor/depot_tools/third_party/logilab/wrapt/importer.py +0 -228
  596. data/vendor/depot_tools/third_party/logilab/wrapt/wrappers.py +0 -901
  597. data/vendor/depot_tools/third_party/mock/LICENSE.txt +0 -26
  598. data/vendor/depot_tools/third_party/mock/README.chromium +0 -24
  599. data/vendor/depot_tools/third_party/mock/__init__.py +0 -2366
  600. data/vendor/depot_tools/third_party/oauth2client/LICENSE +0 -202
  601. data/vendor/depot_tools/third_party/oauth2client/MODIFICATIONS.diff +0 -66
  602. data/vendor/depot_tools/third_party/oauth2client/README.chromium +0 -15
  603. data/vendor/depot_tools/third_party/oauth2client/__init__.py +0 -5
  604. data/vendor/depot_tools/third_party/oauth2client/anyjson.py +0 -32
  605. data/vendor/depot_tools/third_party/oauth2client/appengine.py +0 -963
  606. data/vendor/depot_tools/third_party/oauth2client/client.py +0 -1363
  607. data/vendor/depot_tools/third_party/oauth2client/clientsecrets.py +0 -153
  608. data/vendor/depot_tools/third_party/oauth2client/crypt.py +0 -377
  609. data/vendor/depot_tools/third_party/oauth2client/django_orm.py +0 -134
  610. data/vendor/depot_tools/third_party/oauth2client/file.py +0 -124
  611. data/vendor/depot_tools/third_party/oauth2client/gce.py +0 -90
  612. data/vendor/depot_tools/third_party/oauth2client/keyring_storage.py +0 -109
  613. data/vendor/depot_tools/third_party/oauth2client/locked_file.py +0 -373
  614. data/vendor/depot_tools/third_party/oauth2client/multistore_file.py +0 -465
  615. data/vendor/depot_tools/third_party/oauth2client/old_run.py +0 -160
  616. data/vendor/depot_tools/third_party/oauth2client/tools.py +0 -243
  617. data/vendor/depot_tools/third_party/oauth2client/util.py +0 -196
  618. data/vendor/depot_tools/third_party/oauth2client/xsrfutil.py +0 -113
  619. data/vendor/depot_tools/third_party/protobuf26/README.chromium +0 -23
  620. data/vendor/depot_tools/third_party/protobuf26/__init__.py +0 -0
  621. data/vendor/depot_tools/third_party/protobuf26/compiler/__init__.py +0 -0
  622. data/vendor/depot_tools/third_party/protobuf26/compiler/plugin_pb2.py +0 -184
  623. data/vendor/depot_tools/third_party/protobuf26/descriptor.py +0 -849
  624. data/vendor/depot_tools/third_party/protobuf26/descriptor_database.py +0 -137
  625. data/vendor/depot_tools/third_party/protobuf26/descriptor_pb2.py +0 -1522
  626. data/vendor/depot_tools/third_party/protobuf26/descriptor_pool.py +0 -643
  627. data/vendor/depot_tools/third_party/protobuf26/internal/__init__.py +0 -0
  628. data/vendor/depot_tools/third_party/protobuf26/internal/api_implementation.py +0 -89
  629. data/vendor/depot_tools/third_party/protobuf26/internal/containers.py +0 -269
  630. data/vendor/depot_tools/third_party/protobuf26/internal/cpp_message.py +0 -663
  631. data/vendor/depot_tools/third_party/protobuf26/internal/decoder.py +0 -831
  632. data/vendor/depot_tools/third_party/protobuf26/internal/encoder.py +0 -788
  633. data/vendor/depot_tools/third_party/protobuf26/internal/enum_type_wrapper.py +0 -89
  634. data/vendor/depot_tools/third_party/protobuf26/internal/message_listener.py +0 -78
  635. data/vendor/depot_tools/third_party/protobuf26/internal/python_message.py +0 -1247
  636. data/vendor/depot_tools/third_party/protobuf26/internal/type_checkers.py +0 -328
  637. data/vendor/depot_tools/third_party/protobuf26/internal/wire_format.py +0 -268
  638. data/vendor/depot_tools/third_party/protobuf26/message.py +0 -284
  639. data/vendor/depot_tools/third_party/protobuf26/message_factory.py +0 -155
  640. data/vendor/depot_tools/third_party/protobuf26/reflection.py +0 -205
  641. data/vendor/depot_tools/third_party/protobuf26/service.py +0 -226
  642. data/vendor/depot_tools/third_party/protobuf26/service_reflection.py +0 -284
  643. data/vendor/depot_tools/third_party/protobuf26/symbol_database.py +0 -185
  644. data/vendor/depot_tools/third_party/protobuf26/text_encoding.py +0 -110
  645. data/vendor/depot_tools/third_party/protobuf26/text_format.py +0 -873
  646. data/vendor/depot_tools/third_party/pylint.py +0 -37
  647. data/vendor/depot_tools/third_party/pylint/LICENSE.txt +0 -340
  648. data/vendor/depot_tools/third_party/pylint/README.chromium +0 -30
  649. data/vendor/depot_tools/third_party/pylint/__init__.py +0 -46
  650. data/vendor/depot_tools/third_party/pylint/__main__.py +0 -3
  651. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +0 -80
  652. data/vendor/depot_tools/third_party/pylint/checkers/__init__.py +0 -123
  653. data/vendor/depot_tools/third_party/pylint/checkers/async.py +0 -82
  654. data/vendor/depot_tools/third_party/pylint/checkers/base.py +0 -2010
  655. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +0 -1120
  656. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +0 -348
  657. data/vendor/depot_tools/third_party/pylint/checkers/exceptions.py +0 -369
  658. data/vendor/depot_tools/third_party/pylint/checkers/format.py +0 -993
  659. data/vendor/depot_tools/third_party/pylint/checkers/imports.py +0 -654
  660. data/vendor/depot_tools/third_party/pylint/checkers/logging.py +0 -258
  661. data/vendor/depot_tools/third_party/pylint/checkers/misc.py +0 -105
  662. data/vendor/depot_tools/third_party/pylint/checkers/newstyle.py +0 -169
  663. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +0 -591
  664. data/vendor/depot_tools/third_party/pylint/checkers/raw_metrics.py +0 -129
  665. data/vendor/depot_tools/third_party/pylint/checkers/similar.py +0 -371
  666. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +0 -264
  667. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +0 -280
  668. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +0 -618
  669. data/vendor/depot_tools/third_party/pylint/checkers/typecheck.py +0 -974
  670. data/vendor/depot_tools/third_party/pylint/checkers/utils.py +0 -741
  671. data/vendor/depot_tools/third_party/pylint/checkers/variables.py +0 -1191
  672. data/vendor/depot_tools/third_party/pylint/config.py +0 -820
  673. data/vendor/depot_tools/third_party/pylint/epylint.py +0 -181
  674. data/vendor/depot_tools/third_party/pylint/extensions/__init__.py +0 -0
  675. data/vendor/depot_tools/third_party/pylint/extensions/check_docs.py +0 -311
  676. data/vendor/depot_tools/third_party/pylint/extensions/check_elif.py +0 -62
  677. data/vendor/depot_tools/third_party/pylint/graph.py +0 -179
  678. data/vendor/depot_tools/third_party/pylint/gui.py +0 -531
  679. data/vendor/depot_tools/third_party/pylint/interfaces.py +0 -102
  680. data/vendor/depot_tools/third_party/pylint/lint.py +0 -1381
  681. data/vendor/depot_tools/third_party/pylint/pyreverse/__init__.py +0 -5
  682. data/vendor/depot_tools/third_party/pylint/pyreverse/diadefslib.py +0 -230
  683. data/vendor/depot_tools/third_party/pylint/pyreverse/diagrams.py +0 -258
  684. data/vendor/depot_tools/third_party/pylint/pyreverse/inspector.py +0 -372
  685. data/vendor/depot_tools/third_party/pylint/pyreverse/main.py +0 -147
  686. data/vendor/depot_tools/third_party/pylint/pyreverse/utils.py +0 -210
  687. data/vendor/depot_tools/third_party/pylint/pyreverse/vcgutils.py +0 -198
  688. data/vendor/depot_tools/third_party/pylint/pyreverse/writer.py +0 -198
  689. data/vendor/depot_tools/third_party/pylint/reporters/__init__.py +0 -149
  690. data/vendor/depot_tools/third_party/pylint/reporters/guireporter.py +0 -27
  691. data/vendor/depot_tools/third_party/pylint/reporters/html.py +0 -108
  692. data/vendor/depot_tools/third_party/pylint/reporters/json.py +0 -64
  693. data/vendor/depot_tools/third_party/pylint/reporters/text.py +0 -237
  694. data/vendor/depot_tools/third_party/pylint/reporters/ureports/__init__.py +0 -106
  695. data/vendor/depot_tools/third_party/pylint/reporters/ureports/html_writer.py +0 -93
  696. data/vendor/depot_tools/third_party/pylint/reporters/ureports/nodes.py +0 -181
  697. data/vendor/depot_tools/third_party/pylint/reporters/ureports/text_writer.py +0 -99
  698. data/vendor/depot_tools/third_party/pylint/testutils.py +0 -414
  699. data/vendor/depot_tools/third_party/pylint/utils.py +0 -1148
  700. data/vendor/depot_tools/third_party/pymox/COPYING +0 -202
  701. data/vendor/depot_tools/third_party/pymox/MANIFEST.in +0 -5
  702. data/vendor/depot_tools/third_party/pymox/README +0 -56
  703. data/vendor/depot_tools/third_party/pymox/__init__.py +0 -0
  704. data/vendor/depot_tools/third_party/pymox/mox.py +0 -1643
  705. data/vendor/depot_tools/third_party/pymox/mox_test.py +0 -1708
  706. data/vendor/depot_tools/third_party/pymox/mox_test_helper.py +0 -76
  707. data/vendor/depot_tools/third_party/pymox/setup.py +0 -14
  708. data/vendor/depot_tools/third_party/pymox/stubout.py +0 -142
  709. data/vendor/depot_tools/third_party/pymox/stubout_test.py +0 -47
  710. data/vendor/depot_tools/third_party/pymox/stubout_testee.py +0 -2
  711. data/vendor/depot_tools/third_party/simplejson/LICENSE.txt +0 -19
  712. data/vendor/depot_tools/third_party/simplejson/PKG-INFO +0 -29
  713. data/vendor/depot_tools/third_party/simplejson/__init__.py +0 -437
  714. data/vendor/depot_tools/third_party/simplejson/decoder.py +0 -421
  715. data/vendor/depot_tools/third_party/simplejson/encoder.py +0 -501
  716. data/vendor/depot_tools/third_party/simplejson/ordered_dict.py +0 -119
  717. data/vendor/depot_tools/third_party/simplejson/scanner.py +0 -77
  718. data/vendor/depot_tools/third_party/simplejson/tool.py +0 -39
  719. data/vendor/depot_tools/third_party/upload.py +0 -2565
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env python
2
- import pylint
3
- pylint.run_pylint()
@@ -1,80 +0,0 @@
1
- # pylint: disable=W0622,C0103
2
- # Copyright (c) 2003-2014 LOGILAB S.A. (Paris, FRANCE).
3
- # http://www.logilab.fr/ -- mailto:contact@logilab.fr
4
- #
5
- # This program is free software; you can redistribute it and/or modify it under
6
- # the terms of the GNU General Public License as published by the Free Software
7
- # Foundation; either version 2 of the License, or (at your option) any later
8
- # version.
9
- #
10
- # This program is distributed in the hope that it will be useful, but WITHOUT
11
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
- # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details
13
- #
14
- # You should have received a copy of the GNU General Public License along with
15
- # this program; if not, write to the Free Software Foundation, Inc.,
16
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
- """pylint packaging information"""
18
- from __future__ import absolute_import
19
-
20
- import sys
21
- from os.path import join
22
-
23
-
24
- modname = distname = 'pylint'
25
-
26
- numversion = (1, 5, 6)
27
- version = '.'.join([str(num) for num in numversion])
28
-
29
- install_requires = [
30
- 'astroid>=1.4.5,<1.5.0',
31
- 'six',
32
- ]
33
-
34
- if sys.platform == 'win32':
35
- install_requires.append('colorama')
36
-
37
-
38
- license = 'GPL'
39
- description = "python code static checker"
40
- web = 'http://www.pylint.org'
41
- mailinglist = "mailto://code-quality@python.org"
42
- author = 'Logilab'
43
- author_email = 'python-projects@lists.logilab.org'
44
-
45
- classifiers = ['Development Status :: 4 - Beta',
46
- 'Environment :: Console',
47
- 'Intended Audience :: Developers',
48
- 'License :: OSI Approved :: GNU General Public License (GPL)',
49
- 'Operating System :: OS Independent',
50
- 'Programming Language :: Python',
51
- 'Programming Language :: Python :: 2',
52
- 'Programming Language :: Python :: 3',
53
- 'Topic :: Software Development :: Debuggers',
54
- 'Topic :: Software Development :: Quality Assurance',
55
- 'Topic :: Software Development :: Testing'
56
- ]
57
-
58
-
59
- long_desc = """\
60
- Pylint is a Python source code analyzer which looks for programming
61
- errors, helps enforcing a coding standard and sniffs for some code
62
- smells (as defined in Martin Fowler's Refactoring book)
63
- .
64
- Pylint can be seen as another PyChecker since nearly all tests you
65
- can do with PyChecker can also be done with Pylint. However, Pylint
66
- offers some more features, like checking length of lines of code,
67
- checking if variable names are well-formed according to your coding
68
- standard, or checking if declared interfaces are truly implemented,
69
- and much more.
70
- .
71
- Additionally, it is possible to write plugins to add your own checks.
72
- .
73
- Pylint is shipped with "pylint-gui", "pyreverse" (UML diagram generator)
74
- and "symilar" (an independent similarities checker)."""
75
-
76
- scripts = [join('bin', filename)
77
- for filename in ('pylint', 'pylint-gui', "symilar", "epylint",
78
- "pyreverse")]
79
-
80
- include_dirs = [join('pylint', 'test')]
@@ -1,123 +0,0 @@
1
- # Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE).
2
- # http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- #
4
- # This program is free software; you can redistribute it and/or modify it under
5
- # the terms of the GNU General Public License as published by the Free Software
6
- # Foundation; either version 2 of the License, or (at your option) any later
7
- # version.
8
- #
9
- # This program is distributed in the hope that it will be useful, but WITHOUT
10
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
- # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
- #
13
- # You should have received a copy of the GNU General Public License along with
14
- # this program; if not, write to the Free Software Foundation, Inc.,
15
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
- """utilities methods and classes for checkers
17
-
18
- Base id of standard checkers (used in msg and report ids):
19
- 01: base
20
- 02: classes
21
- 03: format
22
- 04: import
23
- 05: misc
24
- 06: variables
25
- 07: exceptions
26
- 08: similar
27
- 09: design_analysis
28
- 10: newstyle
29
- 11: typecheck
30
- 12: logging
31
- 13: string_format
32
- 14: string_constant
33
- 15: stdlib
34
- 16: python3
35
- 17-50: not yet used: reserved for future internal checkers.
36
- 51-99: perhaps used: reserved for external checkers
37
-
38
- The raw_metrics checker has no number associated since it doesn't emit any
39
- messages nor reports. XXX not true, emit a 07 report !
40
-
41
- """
42
-
43
- import sys
44
- import tokenize
45
- import warnings
46
-
47
- from pylint.config import OptionsProviderMixIn
48
- from pylint.reporters import diff_string
49
- from pylint.utils import register_plugins
50
- from pylint.interfaces import UNDEFINED
51
-
52
-
53
- def table_lines_from_stats(stats, old_stats, columns):
54
- """get values listed in <columns> from <stats> and <old_stats>,
55
- and return a formated list of values, designed to be given to a
56
- ureport.Table object
57
- """
58
- lines = []
59
- for m_type in columns:
60
- new = stats[m_type]
61
- format = str # pylint: disable=redefined-builtin
62
- if isinstance(new, float):
63
- format = lambda num: '%.3f' % num
64
- old = old_stats.get(m_type)
65
- if old is not None:
66
- diff_str = diff_string(old, new)
67
- old = format(old)
68
- else:
69
- old, diff_str = 'NC', 'NC'
70
- lines += (m_type.replace('_', ' '), format(new), old, diff_str)
71
- return lines
72
-
73
-
74
- class BaseChecker(OptionsProviderMixIn):
75
- """base class for checkers"""
76
- # checker name (you may reuse an existing one)
77
- name = None
78
- # options level (0 will be displaying in --help, 1 in --long-help)
79
- level = 1
80
- # ordered list of options to control the ckecker behaviour
81
- options = ()
82
- # messages issued by this checker
83
- msgs = {}
84
- # reports issued by this checker
85
- reports = ()
86
- # mark this checker as enabled or not.
87
- enabled = True
88
-
89
- def __init__(self, linter=None):
90
- """checker instances should have the linter as argument
91
-
92
- linter is an object implementing ILinter
93
- """
94
- self.name = self.name.lower()
95
- OptionsProviderMixIn.__init__(self)
96
- self.linter = linter
97
-
98
- def add_message(self, msg_id, line=None, node=None, args=None, confidence=UNDEFINED):
99
- """add a message of a given type"""
100
- self.linter.add_message(msg_id, line, node, args, confidence)
101
-
102
- # dummy methods implementing the IChecker interface
103
-
104
- def open(self):
105
- """called before visiting project (i.e set of modules)"""
106
-
107
- def close(self):
108
- """called after visiting project (i.e set of modules)"""
109
-
110
-
111
- class BaseTokenChecker(BaseChecker):
112
- """Base class for checkers that want to have access to the token stream."""
113
-
114
- def process_tokens(self, tokens):
115
- """Should be overridden by subclasses."""
116
- raise NotImplementedError()
117
-
118
-
119
- def initialize(linter):
120
- """initialize linter with checkers in this package """
121
- register_plugins(linter, __path__[0])
122
-
123
- __all__ = ('BaseChecker', 'initialize')
@@ -1,82 +0,0 @@
1
- # Copyright (c) 2003-2015 LOGILAB S.A. (Paris, FRANCE).
2
- # http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- #
4
- # This program is free software; you can redistribute it and/or modify it under
5
- # the terms of the GNU General Public License as published by the Free Software
6
- # Foundation; either version 2 of the License, or (at your option) any later
7
- # version.
8
- #
9
- # This program is distributed in the hope that it will be useful, but WITHOUT
10
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
- # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
- #
13
- # You should have received a copy of the GNU General Public License along with
14
- # this program; if not, write to the Free Software Foundation, Inc.,
15
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
- """Checker for anything related to the async protocol (PEP 492)."""
17
-
18
- import astroid
19
- from astroid import exceptions
20
-
21
- from pylint import checkers
22
- from pylint.checkers import utils as checker_utils
23
- from pylint import interfaces
24
- from pylint import utils
25
-
26
-
27
- class AsyncChecker(checkers.BaseChecker):
28
- __implements__ = interfaces.IAstroidChecker
29
- name = 'async'
30
- msgs = {
31
- 'E1700': ('Yield inside async function',
32
- 'yield-inside-async-function',
33
- 'Used when an `yield` or `yield from` statement is '
34
- 'found inside an async function.',
35
- {'minversion': (3, 5)}),
36
- 'E1701': ("Async context manager '%s' doesn't implement __aenter__ and __aexit__.",
37
- 'not-async-context-manager',
38
- 'Used when an async context manager is used with an object '
39
- 'that does not implement the async context management protocol.',
40
- {'minversion': (3, 5)}),
41
- }
42
-
43
- def open(self):
44
- self._ignore_mixin_members = utils.get_global_option(self, 'ignore-mixin-members')
45
-
46
- @checker_utils.check_messages('yield-inside-async-function')
47
- def visit_asyncfunctiondef(self, node):
48
- for child in node.nodes_of_class(astroid.Yield):
49
- if child.scope() is node:
50
- self.add_message('yield-inside-async-function', node=child)
51
-
52
- @checker_utils.check_messages('not-async-context-manager')
53
- def visit_asyncwith(self, node):
54
- for ctx_mgr, _ in node.items:
55
- infered = checker_utils.safe_infer(ctx_mgr)
56
- if infered is None or infered is astroid.YES:
57
- continue
58
-
59
- if isinstance(infered, astroid.Instance):
60
- try:
61
- infered.getattr('__aenter__')
62
- infered.getattr('__aexit__')
63
- except exceptions.NotFoundError:
64
- if isinstance(infered, astroid.Instance):
65
- # If we do not know the bases of this class,
66
- # just skip it.
67
- if not checker_utils.has_known_bases(infered):
68
- continue
69
- # Just ignore mixin classes.
70
- if self._ignore_mixin_members:
71
- if infered.name[-5:].lower() == 'mixin':
72
- continue
73
- else:
74
- continue
75
-
76
- self.add_message('not-async-context-manager',
77
- node=node, args=(infered.name, ))
78
-
79
-
80
- def register(linter):
81
- """required method to auto register this checker"""
82
- linter.register_checker(AsyncChecker(linter))
@@ -1,2010 +0,0 @@
1
- # Copyright (c) 2003-2013 LOGILAB S.A. (Paris, FRANCE).
2
- # http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- # Copyright (c) 2009-2010 Arista Networks, Inc.
4
- #
5
- # This program is free software; you can redistribute it and/or modify it under
6
- # the terms of the GNU General Public License as published by the Free Software
7
- # Foundation; either version 2 of the License, or (at your option) any later
8
- # version.
9
- #
10
- # This program is distributed in the hope that it will be useful, but WITHOUT
11
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
- # FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
- #
14
- # You should have received a copy of the GNU General Public License along with
15
- # this program; if not, write to the Free Software Foundation, Inc.,
16
- # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
- """basic checker for Python code"""
18
-
19
- import collections
20
- import itertools
21
- import sys
22
- import re
23
-
24
- import six
25
- from six.moves import zip # pylint: disable=redefined-builtin
26
-
27
- import astroid
28
- import astroid.bases
29
- import astroid.scoped_nodes
30
- from astroid import are_exclusive, InferenceError
31
-
32
- from pylint.interfaces import (IAstroidChecker, ITokenChecker, INFERENCE,
33
- INFERENCE_FAILURE, HIGH)
34
- from pylint.utils import EmptyReport, deprecated_option
35
- from pylint.reporters import diff_string
36
- from pylint.checkers import BaseChecker, BaseTokenChecker
37
- from pylint.checkers.utils import (
38
- check_messages,
39
- clobber_in_except,
40
- is_builtin_object,
41
- is_inside_except,
42
- overrides_a_method,
43
- get_argument_from_call,
44
- node_frame_class,
45
- NoSuchArgumentError,
46
- error_of_type,
47
- unimplemented_abstract_methods,
48
- has_known_bases,
49
- safe_infer
50
- )
51
- from pylint.reporters.ureports.nodes import Table
52
-
53
-
54
- # regex for class/function/variable/constant name
55
- CLASS_NAME_RGX = re.compile('[A-Z_][a-zA-Z0-9]+$')
56
- MOD_NAME_RGX = re.compile('(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$')
57
- CONST_NAME_RGX = re.compile('(([A-Z_][A-Z0-9_]*)|(__.*__))$')
58
- COMP_VAR_RGX = re.compile('[A-Za-z_][A-Za-z0-9_]*$')
59
- DEFAULT_NAME_RGX = re.compile('[a-z_][a-z0-9_]{2,30}$')
60
- CLASS_ATTRIBUTE_RGX = re.compile(r'([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$')
61
- # do not require a doc string on private/system methods
62
- NO_REQUIRED_DOC_RGX = re.compile('^_')
63
- REVERSED_PROTOCOL_METHOD = '__reversed__'
64
- SEQUENCE_PROTOCOL_METHODS = ('__getitem__', '__len__')
65
- REVERSED_METHODS = (SEQUENCE_PROTOCOL_METHODS,
66
- (REVERSED_PROTOCOL_METHOD, ))
67
- TYPECHECK_COMPARISON_OPERATORS = frozenset(('is', 'is not', '==',
68
- '!=', 'in', 'not in'))
69
- LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set)
70
- UNITTEST_CASE = 'unittest.case'
71
- BUILTINS = six.moves.builtins.__name__
72
- TYPE_QNAME = "%s.type" % BUILTINS
73
- PY33 = sys.version_info >= (3, 3)
74
- PY3K = sys.version_info >= (3, 0)
75
- PY35 = sys.version_info >= (3, 5)
76
- BAD_FUNCTIONS = ['map', 'filter']
77
- if sys.version_info < (3, 0):
78
- BAD_FUNCTIONS.append('input')
79
-
80
- # Some hints regarding the use of bad builtins.
81
- BUILTIN_HINTS = {
82
- 'map': 'Using a list comprehension can be clearer.',
83
- }
84
- BUILTIN_HINTS['filter'] = BUILTIN_HINTS['map']
85
-
86
- # Name categories that are always consistent with all naming conventions.
87
- EXEMPT_NAME_CATEGORIES = set(('exempt', 'ignore'))
88
-
89
- # A mapping from builtin-qname -> symbol, to be used when generating messages
90
- # about dangerous default values as arguments
91
- DEFAULT_ARGUMENT_SYMBOLS = dict(
92
- zip(['.'.join([BUILTINS, x]) for x in ('set', 'dict', 'list')],
93
- ['set()', '{}', '[]'])
94
- )
95
- REVERSED_COMPS = {'<': '>', '<=': '>=', '>': '<', '>=': '<='}
96
-
97
- del re
98
-
99
- def _redefines_import(node):
100
- """ Detect that the given node (AssName) is inside an
101
- exception handler and redefines an import from the tryexcept body.
102
- Returns True if the node redefines an import, False otherwise.
103
- """
104
- current = node
105
- while current and not isinstance(current.parent, astroid.ExceptHandler):
106
- current = current.parent
107
- if not current or not error_of_type(current.parent, ImportError):
108
- return False
109
- try_block = current.parent.parent
110
- for import_node in try_block.nodes_of_class((astroid.ImportFrom, astroid.Import)):
111
- for name, alias in import_node.names:
112
- if alias:
113
- if alias == node.name:
114
- return True
115
- elif name == node.name:
116
- return True
117
- return False
118
-
119
- def in_loop(node):
120
- """return True if the node is inside a kind of for loop"""
121
- parent = node.parent
122
- while parent is not None:
123
- if isinstance(parent, (astroid.For, astroid.ListComp, astroid.SetComp,
124
- astroid.DictComp, astroid.GeneratorExp)):
125
- return True
126
- parent = parent.parent
127
- return False
128
-
129
- def in_nested_list(nested_list, obj):
130
- """return true if the object is an element of <nested_list> or of a nested
131
- list
132
- """
133
- for elmt in nested_list:
134
- if isinstance(elmt, (list, tuple)):
135
- if in_nested_list(elmt, obj):
136
- return True
137
- elif elmt == obj:
138
- return True
139
- return False
140
-
141
- def _loop_exits_early(loop):
142
- """Returns true if a loop has a break statement in its body."""
143
- loop_nodes = (astroid.For, astroid.While)
144
- # Loop over body explicitly to avoid matching break statements
145
- # in orelse.
146
- for child in loop.body:
147
- if isinstance(child, loop_nodes):
148
- # break statement may be in orelse of child loop.
149
- # pylint: disable=superfluous-parens
150
- for orelse in (child.orelse or ()):
151
- for _ in orelse.nodes_of_class(astroid.Break, skip_klass=loop_nodes):
152
- return True
153
- continue
154
- for _ in child.nodes_of_class(astroid.Break, skip_klass=loop_nodes):
155
- return True
156
- return False
157
-
158
- def _is_multi_naming_match(match, node_type, confidence):
159
- return (match is not None and
160
- match.lastgroup is not None and
161
- match.lastgroup not in EXEMPT_NAME_CATEGORIES
162
- and (node_type != 'method' or confidence != INFERENCE_FAILURE))
163
-
164
-
165
- if sys.version_info < (3, 0):
166
- PROPERTY_CLASSES = set(('__builtin__.property', 'abc.abstractproperty'))
167
- else:
168
- PROPERTY_CLASSES = set(('builtins.property', 'abc.abstractproperty'))
169
-
170
-
171
- def _determine_function_name_type(node):
172
- """Determine the name type whose regex the a function's name should match.
173
-
174
- :param node: A function node.
175
- :returns: One of ('function', 'method', 'attr')
176
- """
177
- if not node.is_method():
178
- return 'function'
179
- if node.decorators:
180
- decorators = node.decorators.nodes
181
- else:
182
- decorators = []
183
- for decorator in decorators:
184
- # If the function is a property (decorated with @property
185
- # or @abc.abstractproperty), the name type is 'attr'.
186
- if (isinstance(decorator, astroid.Name) or
187
- (isinstance(decorator, astroid.Attribute) and
188
- decorator.attrname == 'abstractproperty')):
189
- infered = safe_infer(decorator)
190
- if infered and infered.qname() in PROPERTY_CLASSES:
191
- return 'attr'
192
- # If the function is decorated using the prop_method.{setter,getter}
193
- # form, treat it like an attribute as well.
194
- elif (isinstance(decorator, astroid.Attribute) and
195
- decorator.attrname in ('setter', 'deleter')):
196
- return 'attr'
197
- return 'method'
198
-
199
-
200
- def _is_none(node):
201
- return (node is None or
202
- (isinstance(node, astroid.Const) and node.value is None) or
203
- (isinstance(node, astroid.Name) and node.name == 'None')
204
- )
205
-
206
-
207
- def _has_abstract_methods(node):
208
- """
209
- Determine if the given `node` has abstract methods.
210
-
211
- The methods should be made abstract by decorating them
212
- with `abc` decorators.
213
- """
214
- return len(unimplemented_abstract_methods(node)) > 0
215
-
216
-
217
- def report_by_type_stats(sect, stats, old_stats):
218
- """make a report of
219
-
220
- * percentage of different types documented
221
- * percentage of different types with a bad name
222
- """
223
- # percentage of different types documented and/or with a bad name
224
- nice_stats = {}
225
- for node_type in ('module', 'class', 'method', 'function'):
226
- try:
227
- total = stats[node_type]
228
- except KeyError:
229
- raise EmptyReport()
230
- nice_stats[node_type] = {}
231
- if total != 0:
232
- try:
233
- documented = total - stats['undocumented_'+node_type]
234
- percent = (documented * 100.) / total
235
- nice_stats[node_type]['percent_documented'] = '%.2f' % percent
236
- except KeyError:
237
- nice_stats[node_type]['percent_documented'] = 'NC'
238
- try:
239
- percent = (stats['badname_'+node_type] * 100.) / total
240
- nice_stats[node_type]['percent_badname'] = '%.2f' % percent
241
- except KeyError:
242
- nice_stats[node_type]['percent_badname'] = 'NC'
243
- lines = ('type', 'number', 'old number', 'difference',
244
- '%documented', '%badname')
245
- for node_type in ('module', 'class', 'method', 'function'):
246
- new = stats[node_type]
247
- old = old_stats.get(node_type, None)
248
- if old is not None:
249
- diff_str = diff_string(old, new)
250
- else:
251
- old, diff_str = 'NC', 'NC'
252
- lines += (node_type, str(new), str(old), diff_str,
253
- nice_stats[node_type].get('percent_documented', '0'),
254
- nice_stats[node_type].get('percent_badname', '0'))
255
- sect.append(Table(children=lines, cols=6, rheaders=1))
256
-
257
- def redefined_by_decorator(node):
258
- """return True if the object is a method redefined via decorator.
259
-
260
- For example:
261
- @property
262
- def x(self): return self._x
263
- @x.setter
264
- def x(self, value): self._x = value
265
- """
266
- if node.decorators:
267
- for decorator in node.decorators.nodes:
268
- if (isinstance(decorator, astroid.Attribute) and
269
- getattr(decorator.expr, 'name', None) == node.name):
270
- return True
271
- return False
272
-
273
-
274
- def _node_type(node):
275
- """Return the inferred type for `node`
276
-
277
- If there is more than one possible type, or if inferred type is YES or None,
278
- return None
279
- """
280
- # check there is only one possible type for the assign node. Else we
281
- # don't handle it for now
282
- types = set()
283
- try:
284
- for var_type in node.infer():
285
- if var_type == astroid.YES or _is_none(var_type):
286
- continue
287
- types.add(var_type)
288
- if len(types) > 1:
289
- return
290
- except InferenceError:
291
- return
292
- return types.pop() if types else None
293
-
294
-
295
- class _BasicChecker(BaseChecker):
296
- __implements__ = IAstroidChecker
297
- name = 'basic'
298
-
299
- class BasicErrorChecker(_BasicChecker):
300
- msgs = {
301
- 'E0100': ('__init__ method is a generator',
302
- 'init-is-generator',
303
- 'Used when the special class method __init__ is turned into a '
304
- 'generator by a yield in its body.'),
305
- 'E0101': ('Explicit return in __init__',
306
- 'return-in-init',
307
- 'Used when the special class method __init__ has an explicit '
308
- 'return value.'),
309
- 'E0102': ('%s already defined line %s',
310
- 'function-redefined',
311
- 'Used when a function / class / method is redefined.'),
312
- 'E0103': ('%r not properly in loop',
313
- 'not-in-loop',
314
- 'Used when break or continue keywords are used outside a loop.'),
315
- 'E0104': ('Return outside function',
316
- 'return-outside-function',
317
- 'Used when a "return" statement is found outside a function or '
318
- 'method.'),
319
- 'E0105': ('Yield outside function',
320
- 'yield-outside-function',
321
- 'Used when a "yield" statement is found outside a function or '
322
- 'method.'),
323
- 'E0106': ('Return with argument inside generator',
324
- 'return-arg-in-generator',
325
- 'Used when a "return" statement with an argument is found '
326
- 'outside in a generator function or method (e.g. with some '
327
- '"yield" statements).',
328
- {'maxversion': (3, 3)}),
329
- 'E0107': ("Use of the non-existent %s operator",
330
- 'nonexistent-operator',
331
- "Used when you attempt to use the C-style pre-increment or"
332
- "pre-decrement operator -- and ++, which doesn't exist in Python."),
333
- 'E0108': ('Duplicate argument name %s in function definition',
334
- 'duplicate-argument-name',
335
- 'Duplicate argument names in function definitions are syntax'
336
- ' errors.'),
337
- 'E0110': ('Abstract class %r with abstract methods instantiated',
338
- 'abstract-class-instantiated',
339
- 'Used when an abstract class with `abc.ABCMeta` as metaclass '
340
- 'has abstract methods and is instantiated.'),
341
- 'W0120': ('Else clause on loop without a break statement',
342
- 'useless-else-on-loop',
343
- 'Loops should only have an else clause if they can exit early '
344
- 'with a break statement, otherwise the statements under else '
345
- 'should be on the same scope as the loop itself.'),
346
- 'E0112': ('More than one starred expression in assignment',
347
- 'too-many-star-expressions',
348
- 'Emitted when there are more than one starred '
349
- 'expressions (`*x`) in an assignment. This is a SyntaxError.',
350
- {'minversion': (3, 0)}),
351
- 'E0113': ('Starred assignment target must be in a list or tuple',
352
- 'invalid-star-assignment-target',
353
- 'Emitted when a star expression is used as a starred '
354
- 'assignment target.',
355
- {'minversion': (3, 0)}),
356
- 'E0114': ('Can use starred expression only in assignment target',
357
- 'star-needs-assignment-target',
358
- 'Emitted when a star expression is not used in an '
359
- 'assignment target.',
360
- {'minversion': (3, 0)}),
361
- 'E0115': ('Name %r is nonlocal and global',
362
- 'nonlocal-and-global',
363
- 'Emitted when a name is both nonlocal and global.',
364
- {'minversion': (3, 0)}),
365
- 'E0116': ("'continue' not supported inside 'finally' clause",
366
- 'continue-in-finally',
367
- 'Emitted when the `continue` keyword is found '
368
- 'inside a finally clause, which is a SyntaxError.'),
369
- 'E0117': ("nonlocal name %s found without binding",
370
- 'nonlocal-without-binding',
371
- 'Emitted when a nonlocal variable does not have an attached '
372
- 'name somewhere in the parent scopes',
373
- {'minversion': (3, 0)}),
374
- }
375
-
376
- @check_messages('function-redefined')
377
- def visit_classdef(self, node):
378
- self._check_redefinition('class', node)
379
-
380
- @check_messages('too-many-star-expressions',
381
- 'invalid-star-assignment-target')
382
- def visit_assign(self, node):
383
- starred = list(node.targets[0].nodes_of_class(astroid.Starred))
384
- if len(starred) > 1:
385
- self.add_message('too-many-star-expressions', node=node)
386
-
387
- # Check *a = b
388
- if isinstance(node.targets[0], astroid.Starred):
389
- self.add_message('invalid-star-assignment-target', node=node)
390
-
391
- @check_messages('star-needs-assignment-target')
392
- def visit_starred(self, node):
393
- """Check that a Starred expression is used in an assignment target."""
394
- if isinstance(node.parent, astroid.Call):
395
- # f(*args) is converted to Call(args=[Starred]), so ignore
396
- # them for this check.
397
- return
398
- if PY35 and isinstance(node.parent,
399
- (astroid.List, astroid.Tuple,
400
- astroid.Set, astroid.Dict)):
401
- # PEP 448 unpacking.
402
- return
403
-
404
- stmt = node.statement()
405
- if not isinstance(stmt, astroid.Assign):
406
- return
407
-
408
- if stmt.value is node or stmt.value.parent_of(node):
409
- self.add_message('star-needs-assignment-target', node=node)
410
-
411
- @check_messages('init-is-generator', 'return-in-init',
412
- 'function-redefined', 'return-arg-in-generator',
413
- 'duplicate-argument-name', 'nonlocal-and-global')
414
- def visit_functiondef(self, node):
415
- self._check_nonlocal_and_global(node)
416
- if not redefined_by_decorator(node):
417
- self._check_redefinition(node.is_method() and 'method' or 'function', node)
418
- # checks for max returns, branch, return in __init__
419
- returns = node.nodes_of_class(astroid.Return,
420
- skip_klass=(astroid.FunctionDef,
421
- astroid.ClassDef))
422
- if node.is_method() and node.name == '__init__':
423
- if node.is_generator():
424
- self.add_message('init-is-generator', node=node)
425
- else:
426
- values = [r.value for r in returns]
427
- # Are we returning anything but None from constructors
428
- if [v for v in values if not _is_none(v)]:
429
- self.add_message('return-in-init', node=node)
430
- elif node.is_generator():
431
- # make sure we don't mix non-None returns and yields
432
- if not PY33:
433
- for retnode in returns:
434
- if isinstance(retnode.value, astroid.Const) and \
435
- retnode.value.value is not None:
436
- self.add_message('return-arg-in-generator', node=node,
437
- line=retnode.fromlineno)
438
- # Check for duplicate names
439
- args = set()
440
- for name in node.argnames():
441
- if name in args:
442
- self.add_message('duplicate-argument-name', node=node, args=(name,))
443
- else:
444
- args.add(name)
445
-
446
- visit_asyncfunctiondef = visit_functiondef
447
-
448
- def _check_nonlocal_and_global(self, node):
449
- """Check that a name is both nonlocal and global."""
450
- def same_scope(current):
451
- return current.scope() is node
452
-
453
- from_iter = itertools.chain.from_iterable
454
- nonlocals = set(from_iter(
455
- child.names for child in node.nodes_of_class(astroid.Nonlocal)
456
- if same_scope(child)))
457
- global_vars = set(from_iter(
458
- child.names for child in node.nodes_of_class(astroid.Global)
459
- if same_scope(child)))
460
- for name in nonlocals.intersection(global_vars):
461
- self.add_message('nonlocal-and-global',
462
- args=(name, ), node=node)
463
-
464
- @check_messages('return-outside-function')
465
- def visit_return(self, node):
466
- if not isinstance(node.frame(), astroid.FunctionDef):
467
- self.add_message('return-outside-function', node=node)
468
-
469
- @check_messages('yield-outside-function')
470
- def visit_yield(self, node):
471
- self._check_yield_outside_func(node)
472
-
473
- @check_messages('yield-outside-function')
474
- def visit_yieldfrom(self, node):
475
- self._check_yield_outside_func(node)
476
-
477
- @check_messages('not-in-loop', 'continue-in-finally')
478
- def visit_continue(self, node):
479
- self._check_in_loop(node, 'continue')
480
-
481
- @check_messages('not-in-loop')
482
- def visit_break(self, node):
483
- self._check_in_loop(node, 'break')
484
-
485
- @check_messages('useless-else-on-loop')
486
- def visit_for(self, node):
487
- self._check_else_on_loop(node)
488
-
489
- @check_messages('useless-else-on-loop')
490
- def visit_while(self, node):
491
- self._check_else_on_loop(node)
492
-
493
- @check_messages('nonexistent-operator')
494
- def visit_unaryop(self, node):
495
- """check use of the non-existent ++ and -- operator operator"""
496
- if ((node.op in '+-') and
497
- isinstance(node.operand, astroid.UnaryOp) and
498
- (node.operand.op == node.op)):
499
- self.add_message('nonexistent-operator', node=node, args=node.op*2)
500
-
501
- def _check_nonlocal_without_binding(self, node, name):
502
- current_scope = node.scope()
503
- while True:
504
- if current_scope.parent is None:
505
- break
506
-
507
- if not isinstance(current_scope, astroid.FunctionDef):
508
- self.add_message('nonlocal-without-binding', args=(name, ),
509
- node=node)
510
- return
511
- else:
512
- if name not in current_scope.locals:
513
- current_scope = current_scope.parent.scope()
514
- continue
515
- else:
516
- # Okay, found it.
517
- return
518
-
519
- self.add_message('nonlocal-without-binding', args=(name, ), node=node)
520
-
521
- @check_messages('nonlocal-without-binding')
522
- def visit_nonlocal(self, node):
523
- for name in node.names:
524
- self._check_nonlocal_without_binding(node, name)
525
-
526
- @check_messages('abstract-class-instantiated')
527
- def visit_call(self, node):
528
- """ Check instantiating abstract class with
529
- abc.ABCMeta as metaclass.
530
- """
531
- try:
532
- infered = next(node.func.infer())
533
- except astroid.InferenceError:
534
- return
535
-
536
- if not isinstance(infered, astroid.ClassDef):
537
- return
538
-
539
- klass = node_frame_class(node)
540
- if klass is infered:
541
- # Don't emit the warning if the class is instantiated
542
- # in its own body or if the call is not an instance
543
- # creation. If the class is instantiated into its own
544
- # body, we're expecting that it knows what it is doing.
545
- return
546
-
547
- # __init__ was called
548
- metaclass = infered.metaclass()
549
- abstract_methods = _has_abstract_methods(infered)
550
- if metaclass is None:
551
- # Python 3.4 has `abc.ABC`, which won't be detected
552
- # by ClassNode.metaclass()
553
- for ancestor in infered.ancestors():
554
- if ancestor.qname() == 'abc.ABC' and abstract_methods:
555
- self.add_message('abstract-class-instantiated',
556
- args=(infered.name, ),
557
- node=node)
558
- break
559
- return
560
- if metaclass.qname() == 'abc.ABCMeta' and abstract_methods:
561
- self.add_message('abstract-class-instantiated',
562
- args=(infered.name, ),
563
- node=node)
564
-
565
- def _check_yield_outside_func(self, node):
566
- if not isinstance(node.frame(), (astroid.FunctionDef, astroid.Lambda)):
567
- self.add_message('yield-outside-function', node=node)
568
-
569
- def _check_else_on_loop(self, node):
570
- """Check that any loop with an else clause has a break statement."""
571
- if node.orelse and not _loop_exits_early(node):
572
- self.add_message('useless-else-on-loop', node=node,
573
- # This is not optimal, but the line previous
574
- # to the first statement in the else clause
575
- # will usually be the one that contains the else:.
576
- line=node.orelse[0].lineno - 1)
577
-
578
- def _check_in_loop(self, node, node_name):
579
- """check that a node is inside a for or while loop"""
580
- _node = node.parent
581
- while _node:
582
- if isinstance(_node, (astroid.For, astroid.While)):
583
- if node not in _node.orelse:
584
- return
585
-
586
- if isinstance(_node, (astroid.ClassDef, astroid.FunctionDef)):
587
- break
588
- if (isinstance(_node, astroid.TryFinally)
589
- and node in _node.finalbody
590
- and isinstance(node, astroid.Continue)):
591
- self.add_message('continue-in-finally', node=node)
592
-
593
- _node = _node.parent
594
-
595
- self.add_message('not-in-loop', node=node, args=node_name)
596
-
597
- def _check_redefinition(self, redeftype, node):
598
- """check for redefinition of a function / method / class name"""
599
- defined_self = node.parent.frame()[node.name]
600
- if defined_self is not node and not are_exclusive(node, defined_self):
601
- self.add_message('function-redefined', node=node,
602
- args=(redeftype, defined_self.fromlineno))
603
-
604
-
605
-
606
- class BasicChecker(_BasicChecker):
607
- """checks for :
608
- * doc strings
609
- * number of arguments, local variables, branches, returns and statements in
610
- functions, methods
611
- * required module attributes
612
- * dangerous default values as arguments
613
- * redefinition of function / method / class
614
- * uses of the global statement
615
- """
616
-
617
- __implements__ = IAstroidChecker
618
-
619
- name = 'basic'
620
- msgs = {
621
- 'W0101': ('Unreachable code',
622
- 'unreachable',
623
- 'Used when there is some code behind a "return" or "raise" '
624
- 'statement, which will never be accessed.'),
625
- 'W0102': ('Dangerous default value %s as argument',
626
- 'dangerous-default-value',
627
- 'Used when a mutable value as list or dictionary is detected in '
628
- 'a default value for an argument.'),
629
- 'W0104': ('Statement seems to have no effect',
630
- 'pointless-statement',
631
- 'Used when a statement doesn\'t have (or at least seems to) '
632
- 'any effect.'),
633
- 'W0105': ('String statement has no effect',
634
- 'pointless-string-statement',
635
- 'Used when a string is used as a statement (which of course '
636
- 'has no effect). This is a particular case of W0104 with its '
637
- 'own message so you can easily disable it if you\'re using '
638
- 'those strings as documentation, instead of comments.'),
639
- 'W0106': ('Expression "%s" is assigned to nothing',
640
- 'expression-not-assigned',
641
- 'Used when an expression that is not a function call is assigned '
642
- 'to nothing. Probably something else was intended.'),
643
- 'W0108': ('Lambda may not be necessary',
644
- 'unnecessary-lambda',
645
- 'Used when the body of a lambda expression is a function call '
646
- 'on the same argument list as the lambda itself; such lambda '
647
- 'expressions are in all but a few cases replaceable with the '
648
- 'function being called in the body of the lambda.'),
649
- 'W0109': ("Duplicate key %r in dictionary",
650
- 'duplicate-key',
651
- 'Used when a dictionary expression binds the same key multiple '
652
- 'times.'),
653
- 'W0122': ('Use of exec',
654
- 'exec-used',
655
- 'Used when you use the "exec" statement (function for Python '
656
- '3), to discourage its usage. That doesn\'t '
657
- 'mean you can not use it !'),
658
- 'W0123': ('Use of eval',
659
- 'eval-used',
660
- 'Used when you use the "eval" function, to discourage its '
661
- 'usage. Consider using `ast.literal_eval` for safely evaluating '
662
- 'strings containing Python expressions '
663
- 'from untrusted sources. '),
664
- 'W0141': ('Used builtin function %s',
665
- 'bad-builtin',
666
- 'Used when a black listed builtin function is used (see the '
667
- 'bad-function option). Usual black listed functions are the ones '
668
- 'like map, or filter , where Python offers now some cleaner '
669
- 'alternative like list comprehension.'),
670
- 'W0150': ("%s statement in finally block may swallow exception",
671
- 'lost-exception',
672
- 'Used when a break or a return statement is found inside the '
673
- 'finally clause of a try...finally block: the exceptions raised '
674
- 'in the try clause will be silently swallowed instead of being '
675
- 're-raised.'),
676
- 'W0199': ('Assert called on a 2-uple. Did you mean \'assert x,y\'?',
677
- 'assert-on-tuple',
678
- 'A call of assert on a tuple will always evaluate to true if '
679
- 'the tuple is not empty, and will always evaluate to false if '
680
- 'it is.'),
681
- 'W0124': ('Following "as" with another context manager looks like a tuple.',
682
- 'confusing-with-statement',
683
- 'Emitted when a `with` statement component returns multiple values '
684
- 'and uses name binding with `as` only for a part of those values, '
685
- 'as in with ctx() as a, b. This can be misleading, since it\'s not '
686
- 'clear if the context manager returns a tuple or if the node without '
687
- 'a name binding is another context manager.'),
688
- 'W0125': ('Using a conditional statement with a constant value',
689
- 'using-constant-test',
690
- 'Emitted when a conditional statement (If or ternary if) '
691
- 'uses a constant value for its test. This might not be what '
692
- 'the user intended to do.'),
693
- 'E0111': ('The first reversed() argument is not a sequence',
694
- 'bad-reversed-sequence',
695
- 'Used when the first argument to reversed() builtin '
696
- 'isn\'t a sequence (does not implement __reversed__, '
697
- 'nor __getitem__ and __len__'),
698
-
699
- }
700
-
701
- options = (('required-attributes',
702
- deprecated_option(opt_type='csv',
703
- help_msg="Required attributes for module. "
704
- "This option is obsolete.")),
705
-
706
- ('bad-functions',
707
- {'default' : BAD_FUNCTIONS,
708
- 'type' :'csv', 'metavar' : '<builtin function names>',
709
- 'help' : 'List of builtins function names that should not be '
710
- 'used, separated by a comma'}
711
- ),
712
- )
713
- reports = (('RP0101', 'Statistics by type', report_by_type_stats),)
714
-
715
- def __init__(self, linter):
716
- _BasicChecker.__init__(self, linter)
717
- self.stats = None
718
- self._tryfinallys = None
719
-
720
- def open(self):
721
- """initialize visit variables and statistics
722
- """
723
- self._tryfinallys = []
724
- self.stats = self.linter.add_stats(module=0, function=0,
725
- method=0, class_=0)
726
-
727
- @check_messages('using-constant-test')
728
- def visit_if(self, node):
729
- self._check_using_constant_test(node, node.test)
730
-
731
- @check_messages('using-constant-test')
732
- def visit_ifexp(self, node):
733
- self._check_using_constant_test(node, node.test)
734
-
735
- @check_messages('using-constant-test')
736
- def visit_comprehension(self, node):
737
- if node.ifs:
738
- for if_test in node.ifs:
739
- self._check_using_constant_test(node, if_test)
740
-
741
- def _check_using_constant_test(self, node, test):
742
- const_nodes = (
743
- astroid.Module,
744
- astroid.scoped_nodes.GeneratorExp,
745
- astroid.Lambda, astroid.FunctionDef, astroid.ClassDef,
746
- astroid.bases.Generator, astroid.UnboundMethod,
747
- astroid.BoundMethod, astroid.Module)
748
- structs = (astroid.Dict, astroid.Tuple, astroid.Set)
749
-
750
- # These nodes are excepted, since they are not constant
751
- # values, requiring a computation to happen. The only type
752
- # of node in this list which doesn't have this property is
753
- # Getattr, which is excepted because the conditional statement
754
- # can be used to verify that the attribute was set inside a class,
755
- # which is definitely a valid use case.
756
- except_nodes = (astroid.Attribute, astroid.Call,
757
- astroid.BinOp, astroid.BoolOp, astroid.UnaryOp,
758
- astroid.Subscript)
759
- inferred = None
760
- emit = isinstance(test, (astroid.Const, ) + structs + const_nodes)
761
- if not isinstance(test, except_nodes):
762
- inferred = safe_infer(test)
763
-
764
- if emit or isinstance(inferred, const_nodes):
765
- self.add_message('using-constant-test', node=node)
766
-
767
- def visit_module(self, _):
768
- """check module name, docstring and required arguments
769
- """
770
- self.stats['module'] += 1
771
-
772
- def visit_classdef(self, node): # pylint: disable=unused-argument
773
- """check module name, docstring and redefinition
774
- increment branch counter
775
- """
776
- self.stats['class'] += 1
777
-
778
- @check_messages('pointless-statement', 'pointless-string-statement',
779
- 'expression-not-assigned')
780
- def visit_expr(self, node):
781
- """check for various kind of statements without effect"""
782
- expr = node.value
783
- if isinstance(expr, astroid.Const) and isinstance(expr.value,
784
- six.string_types):
785
- # treat string statement in a separated message
786
- # Handle PEP-257 attribute docstrings.
787
- # An attribute docstring is defined as being a string right after
788
- # an assignment at the module level, class level or __init__ level.
789
- scope = expr.scope()
790
- if isinstance(scope, (astroid.ClassDef, astroid.Module, astroid.FunctionDef)):
791
- if isinstance(scope, astroid.FunctionDef) and scope.name != '__init__':
792
- pass
793
- else:
794
- sibling = expr.previous_sibling()
795
- if (sibling is not None and sibling.scope() is scope and
796
- isinstance(sibling, astroid.Assign)):
797
- return
798
- self.add_message('pointless-string-statement', node=node)
799
- return
800
- # ignore if this is :
801
- # * a direct function call
802
- # * the unique child of a try/except body
803
- # * a yield (which are wrapped by a discard node in _ast XXX)
804
- # warn W0106 if we have any underlying function call (we can't predict
805
- # side effects), else pointless-statement
806
- if (isinstance(expr, (astroid.Yield, astroid.Await, astroid.Call)) or
807
- (isinstance(node.parent, astroid.TryExcept) and
808
- node.parent.body == [node])):
809
- return
810
- if any(expr.nodes_of_class(astroid.Call)):
811
- self.add_message('expression-not-assigned', node=node,
812
- args=expr.as_string())
813
- else:
814
- self.add_message('pointless-statement', node=node)
815
-
816
- @staticmethod
817
- def _filter_vararg(node, call_args):
818
- # Return the arguments for the given call which are
819
- # not passed as vararg.
820
- for arg in call_args:
821
- if isinstance(arg, astroid.Starred):
822
- if (isinstance(arg.value, astroid.Name)
823
- and arg.value.name != node.args.vararg):
824
- yield arg
825
- else:
826
- yield arg
827
-
828
- @staticmethod
829
- def _has_variadic_argument(args, variadic_name):
830
- if not args:
831
- return True
832
- for arg in args:
833
- if isinstance(arg.value, astroid.Name):
834
- if arg.value.name != variadic_name:
835
- return True
836
- else:
837
- return True
838
- return False
839
-
840
- @check_messages('unnecessary-lambda')
841
- def visit_lambda(self, node):
842
- """check whether or not the lambda is suspicious
843
- """
844
- # if the body of the lambda is a call expression with the same
845
- # argument list as the lambda itself, then the lambda is
846
- # possibly unnecessary and at least suspicious.
847
- if node.args.defaults:
848
- # If the arguments of the lambda include defaults, then a
849
- # judgment cannot be made because there is no way to check
850
- # that the defaults defined by the lambda are the same as
851
- # the defaults defined by the function called in the body
852
- # of the lambda.
853
- return
854
- call = node.body
855
- if not isinstance(call, astroid.Call):
856
- # The body of the lambda must be a function call expression
857
- # for the lambda to be unnecessary.
858
- return
859
- if (isinstance(node.body.func, astroid.Attribute) and
860
- isinstance(node.body.func.expr, astroid.Call)):
861
- # Chained call, the intermediate call might
862
- # return something else (but we don't check that, yet).
863
- return
864
-
865
- ordinary_args = list(node.args.args)
866
- new_call_args = list(self._filter_vararg(node, call.args))
867
- if node.args.kwarg:
868
- if self._has_variadic_argument(call.kwargs, node.args.kwarg):
869
- return
870
- elif call.kwargs or call.keywords:
871
- return
872
-
873
- if node.args.vararg:
874
- if self._has_variadic_argument(call.starargs, node.args.vararg):
875
- return
876
- elif call.starargs:
877
- return
878
-
879
- # The "ordinary" arguments must be in a correspondence such that:
880
- # ordinary_args[i].name == call.args[i].name.
881
- if len(ordinary_args) != len(new_call_args):
882
- return
883
- for arg, passed_arg in zip(ordinary_args, new_call_args):
884
- if not isinstance(passed_arg, astroid.Name):
885
- return
886
- if arg.name != passed_arg.name:
887
- return
888
-
889
- self.add_message('unnecessary-lambda', line=node.fromlineno,
890
- node=node)
891
-
892
- @check_messages('dangerous-default-value')
893
- def visit_functiondef(self, node):
894
- """check function name, docstring, arguments, redefinition,
895
- variable names, max locals
896
- """
897
- self.stats[node.is_method() and 'method' or 'function'] += 1
898
- self._check_dangerous_default(node)
899
-
900
- visit_asyncfunctiondef = visit_functiondef
901
-
902
- def _check_dangerous_default(self, node):
903
- # check for dangerous default values as arguments
904
- is_iterable = lambda n: isinstance(n, (astroid.List,
905
- astroid.Set,
906
- astroid.Dict))
907
- for default in node.args.defaults:
908
- try:
909
- value = next(default.infer())
910
- except astroid.InferenceError:
911
- continue
912
-
913
- if (isinstance(value, astroid.Instance) and
914
- value.qname() in DEFAULT_ARGUMENT_SYMBOLS):
915
-
916
- if value is default:
917
- msg = DEFAULT_ARGUMENT_SYMBOLS[value.qname()]
918
- elif isinstance(value, astroid.Instance) or is_iterable(value):
919
- # We are here in the following situation(s):
920
- # * a dict/set/list/tuple call which wasn't inferred
921
- # to a syntax node ({}, () etc.). This can happen
922
- # when the arguments are invalid or unknown to
923
- # the inference.
924
- # * a variable from somewhere else, which turns out to be a list
925
- # or a dict.
926
- if is_iterable(default):
927
- msg = value.pytype()
928
- elif isinstance(default, astroid.Call):
929
- msg = '%s() (%s)' % (value.name, value.qname())
930
- else:
931
- msg = '%s (%s)' % (default.as_string(), value.qname())
932
- else:
933
- # this argument is a name
934
- msg = '%s (%s)' % (default.as_string(),
935
- DEFAULT_ARGUMENT_SYMBOLS[value.qname()])
936
- self.add_message('dangerous-default-value',
937
- node=node,
938
- args=(msg, ))
939
-
940
- @check_messages('unreachable', 'lost-exception')
941
- def visit_return(self, node):
942
- """1 - check is the node has a right sibling (if so, that's some
943
- unreachable code)
944
- 2 - check is the node is inside the finally clause of a try...finally
945
- block
946
- """
947
- self._check_unreachable(node)
948
- # Is it inside final body of a try...finally bloc ?
949
- self._check_not_in_finally(node, 'return', (astroid.FunctionDef,))
950
-
951
- @check_messages('unreachable')
952
- def visit_continue(self, node):
953
- """check is the node has a right sibling (if so, that's some unreachable
954
- code)
955
- """
956
- self._check_unreachable(node)
957
-
958
- @check_messages('unreachable', 'lost-exception')
959
- def visit_break(self, node):
960
- """1 - check is the node has a right sibling (if so, that's some
961
- unreachable code)
962
- 2 - check is the node is inside the finally clause of a try...finally
963
- block
964
- """
965
- # 1 - Is it right sibling ?
966
- self._check_unreachable(node)
967
- # 2 - Is it inside final body of a try...finally bloc ?
968
- self._check_not_in_finally(node, 'break', (astroid.For, astroid.While,))
969
-
970
- @check_messages('unreachable')
971
- def visit_raise(self, node):
972
- """check if the node has a right sibling (if so, that's some unreachable
973
- code)
974
- """
975
- self._check_unreachable(node)
976
-
977
- @check_messages('exec-used')
978
- def visit_exec(self, node):
979
- """just print a warning on exec statements"""
980
- self.add_message('exec-used', node=node)
981
-
982
- @check_messages('bad-builtin', 'eval-used',
983
- 'exec-used', 'bad-reversed-sequence')
984
- def visit_call(self, node):
985
- """visit a CallFunc node -> check if this is not a blacklisted builtin
986
- call and check for * or ** use
987
- """
988
- if isinstance(node.func, astroid.Name):
989
- name = node.func.name
990
- # ignore the name if it's not a builtin (i.e. not defined in the
991
- # locals nor globals scope)
992
- if not (name in node.frame() or
993
- name in node.root()):
994
- if name == 'exec':
995
- self.add_message('exec-used', node=node)
996
- elif name == 'reversed':
997
- self._check_reversed(node)
998
- elif name == 'eval':
999
- self.add_message('eval-used', node=node)
1000
- if name in self.config.bad_functions:
1001
- hint = BUILTIN_HINTS.get(name)
1002
- if hint:
1003
- args = "%r. %s" % (name, hint)
1004
- else:
1005
- args = repr(name)
1006
- self.add_message('bad-builtin', node=node, args=args)
1007
-
1008
- @check_messages('assert-on-tuple')
1009
- def visit_assert(self, node):
1010
- """check the use of an assert statement on a tuple."""
1011
- if node.fail is None and isinstance(node.test, astroid.Tuple) and \
1012
- len(node.test.elts) == 2:
1013
- self.add_message('assert-on-tuple', node=node)
1014
-
1015
- @check_messages('duplicate-key')
1016
- def visit_dict(self, node):
1017
- """check duplicate key in dictionary"""
1018
- keys = set()
1019
- for k, _ in node.items:
1020
- if isinstance(k, astroid.Const):
1021
- key = k.value
1022
- if key in keys:
1023
- self.add_message('duplicate-key', node=node, args=key)
1024
- keys.add(key)
1025
-
1026
- def visit_tryfinally(self, node):
1027
- """update try...finally flag"""
1028
- self._tryfinallys.append(node)
1029
-
1030
- def leave_tryfinally(self, node): # pylint: disable=unused-argument
1031
- """update try...finally flag"""
1032
- self._tryfinallys.pop()
1033
-
1034
- def _check_unreachable(self, node):
1035
- """check unreachable code"""
1036
- unreach_stmt = node.next_sibling()
1037
- if unreach_stmt is not None:
1038
- self.add_message('unreachable', node=unreach_stmt)
1039
-
1040
- def _check_not_in_finally(self, node, node_name, breaker_classes=()):
1041
- """check that a node is not inside a finally clause of a
1042
- try...finally statement.
1043
- If we found before a try...finally bloc a parent which its type is
1044
- in breaker_classes, we skip the whole check."""
1045
- # if self._tryfinallys is empty, we're not a in try...finally bloc
1046
- if not self._tryfinallys:
1047
- return
1048
- # the node could be a grand-grand...-children of the try...finally
1049
- _parent = node.parent
1050
- _node = node
1051
- while _parent and not isinstance(_parent, breaker_classes):
1052
- if hasattr(_parent, 'finalbody') and _node in _parent.finalbody:
1053
- self.add_message('lost-exception', node=node, args=node_name)
1054
- return
1055
- _node = _parent
1056
- _parent = _node.parent
1057
-
1058
- def _check_reversed(self, node):
1059
- """ check that the argument to `reversed` is a sequence """
1060
- try:
1061
- argument = safe_infer(get_argument_from_call(node, position=0))
1062
- except NoSuchArgumentError:
1063
- pass
1064
- else:
1065
- if argument is astroid.YES:
1066
- return
1067
- if argument is None:
1068
- # Nothing was infered.
1069
- # Try to see if we have iter().
1070
- if isinstance(node.args[0], astroid.Call):
1071
- try:
1072
- func = next(node.args[0].func.infer())
1073
- except InferenceError:
1074
- return
1075
- if (getattr(func, 'name', None) == 'iter' and
1076
- is_builtin_object(func)):
1077
- self.add_message('bad-reversed-sequence', node=node)
1078
- return
1079
-
1080
- if isinstance(argument, astroid.Instance):
1081
- if (argument._proxied.name == 'dict' and
1082
- is_builtin_object(argument._proxied)):
1083
- self.add_message('bad-reversed-sequence', node=node)
1084
- return
1085
- elif any(ancestor.name == 'dict' and is_builtin_object(ancestor)
1086
- for ancestor in argument._proxied.ancestors()):
1087
- # Mappings aren't accepted by reversed(), unless
1088
- # they provide explicitly a __reversed__ method.
1089
- try:
1090
- argument.locals[REVERSED_PROTOCOL_METHOD]
1091
- except KeyError:
1092
- self.add_message('bad-reversed-sequence', node=node)
1093
- return
1094
-
1095
- for methods in REVERSED_METHODS:
1096
- for meth in methods:
1097
- try:
1098
- argument.getattr(meth)
1099
- except astroid.NotFoundError:
1100
- break
1101
- else:
1102
- break
1103
- else:
1104
- self.add_message('bad-reversed-sequence', node=node)
1105
- elif not isinstance(argument, (astroid.List, astroid.Tuple)):
1106
- # everything else is not a proper sequence for reversed()
1107
- self.add_message('bad-reversed-sequence', node=node)
1108
-
1109
- @check_messages('confusing-with-statement')
1110
- def visit_with(self, node):
1111
- if not PY3K:
1112
- # in Python 2 a "with" statement with multiple managers coresponds
1113
- # to multiple nested AST "With" nodes
1114
- pairs = []
1115
- parent_node = node.parent
1116
- if isinstance(parent_node, astroid.With):
1117
- # we only care about the direct parent, since this method
1118
- # gets called for each with node anyway
1119
- pairs.extend(parent_node.items)
1120
- pairs.extend(node.items)
1121
- else:
1122
- # in PY3K a "with" statement with multiple managers coresponds
1123
- # to one AST "With" node with multiple items
1124
- pairs = node.items
1125
- if pairs:
1126
- for prev_pair, pair in zip(pairs, pairs[1:]):
1127
- if (isinstance(prev_pair[1], astroid.AssignName) and
1128
- (pair[1] is None and not isinstance(pair[0], astroid.Call))):
1129
- # don't emit a message if the second is a function call
1130
- # there's no way that can be mistaken for a name assignment
1131
- if PY3K or node.lineno == node.parent.lineno:
1132
- # if the line number doesn't match
1133
- # we assume it's a nested "with"
1134
- self.add_message('confusing-with-statement', node=node)
1135
-
1136
-
1137
- _NAME_TYPES = {
1138
- 'module': (MOD_NAME_RGX, 'module'),
1139
- 'const': (CONST_NAME_RGX, 'constant'),
1140
- 'class': (CLASS_NAME_RGX, 'class'),
1141
- 'function': (DEFAULT_NAME_RGX, 'function'),
1142
- 'method': (DEFAULT_NAME_RGX, 'method'),
1143
- 'attr': (DEFAULT_NAME_RGX, 'attribute'),
1144
- 'argument': (DEFAULT_NAME_RGX, 'argument'),
1145
- 'variable': (DEFAULT_NAME_RGX, 'variable'),
1146
- 'class_attribute': (CLASS_ATTRIBUTE_RGX, 'class attribute'),
1147
- 'inlinevar': (COMP_VAR_RGX, 'inline iteration'),
1148
- }
1149
-
1150
- def _create_naming_options():
1151
- name_options = []
1152
- for name_type, (rgx, human_readable_name) in six.iteritems(_NAME_TYPES):
1153
- name_type = name_type.replace('_', '-')
1154
- name_options.append((
1155
- '%s-rgx' % (name_type,),
1156
- {'default': rgx, 'type': 'regexp', 'metavar': '<regexp>',
1157
- 'help': 'Regular expression matching correct %s names' % (human_readable_name,)}))
1158
- name_options.append((
1159
- '%s-name-hint' % (name_type,),
1160
- {'default': rgx.pattern, 'type': 'string', 'metavar': '<string>',
1161
- 'help': 'Naming hint for %s names' % (human_readable_name,)}))
1162
- return tuple(name_options)
1163
-
1164
- class NameChecker(_BasicChecker):
1165
- msgs = {
1166
- 'C0102': ('Black listed name "%s"',
1167
- 'blacklisted-name',
1168
- 'Used when the name is listed in the black list (unauthorized '
1169
- 'names).'),
1170
- 'C0103': ('Invalid %s name "%s"%s',
1171
- 'invalid-name',
1172
- 'Used when the name doesn\'t match the regular expression '
1173
- 'associated to its type (constant, variable, class...).'),
1174
- }
1175
-
1176
- options = (('good-names',
1177
- {'default' : ('i', 'j', 'k', 'ex', 'Run', '_'),
1178
- 'type' :'csv', 'metavar' : '<names>',
1179
- 'help' : 'Good variable names which should always be accepted,'
1180
- ' separated by a comma'}
1181
- ),
1182
- ('bad-names',
1183
- {'default' : ('foo', 'bar', 'baz', 'toto', 'tutu', 'tata'),
1184
- 'type' :'csv', 'metavar' : '<names>',
1185
- 'help' : 'Bad variable names which should always be refused, '
1186
- 'separated by a comma'}
1187
- ),
1188
- ('name-group',
1189
- {'default' : (),
1190
- 'type' :'csv', 'metavar' : '<name1:name2>',
1191
- 'help' : ('Colon-delimited sets of names that determine each'
1192
- ' other\'s naming style when the name regexes'
1193
- ' allow several styles.')}
1194
- ),
1195
- ('include-naming-hint',
1196
- {'default': False, 'type' : 'yn', 'metavar' : '<y_or_n>',
1197
- 'help': 'Include a hint for the correct naming format with invalid-name'}
1198
- ),
1199
- ) + _create_naming_options()
1200
-
1201
-
1202
- def __init__(self, linter):
1203
- _BasicChecker.__init__(self, linter)
1204
- self._name_category = {}
1205
- self._name_group = {}
1206
- self._bad_names = {}
1207
-
1208
- def open(self):
1209
- self.stats = self.linter.add_stats(badname_module=0,
1210
- badname_class=0, badname_function=0,
1211
- badname_method=0, badname_attr=0,
1212
- badname_const=0,
1213
- badname_variable=0,
1214
- badname_inlinevar=0,
1215
- badname_argument=0,
1216
- badname_class_attribute=0)
1217
- for group in self.config.name_group:
1218
- for name_type in group.split(':'):
1219
- self._name_group[name_type] = 'group_%s' % (group,)
1220
-
1221
- @check_messages('blacklisted-name', 'invalid-name')
1222
- def visit_module(self, node):
1223
- self._check_name('module', node.name.split('.')[-1], node)
1224
- self._bad_names = {}
1225
-
1226
- def leave_module(self, node): # pylint: disable=unused-argument
1227
- for all_groups in six.itervalues(self._bad_names):
1228
- if len(all_groups) < 2:
1229
- continue
1230
- groups = collections.defaultdict(list)
1231
- min_warnings = sys.maxsize
1232
- for group in six.itervalues(all_groups):
1233
- groups[len(group)].append(group)
1234
- min_warnings = min(len(group), min_warnings)
1235
- if len(groups[min_warnings]) > 1:
1236
- by_line = sorted(groups[min_warnings],
1237
- key=lambda group: min(warning[0].lineno for warning in group))
1238
- warnings = itertools.chain(*by_line[1:])
1239
- else:
1240
- warnings = groups[min_warnings][0]
1241
- for args in warnings:
1242
- self._raise_name_warning(*args)
1243
-
1244
- @check_messages('blacklisted-name', 'invalid-name')
1245
- def visit_classdef(self, node):
1246
- self._check_name('class', node.name, node)
1247
- for attr, anodes in six.iteritems(node.instance_attrs):
1248
- if not any(node.instance_attr_ancestors(attr)):
1249
- self._check_name('attr', attr, anodes[0])
1250
-
1251
- @check_messages('blacklisted-name', 'invalid-name')
1252
- def visit_functiondef(self, node):
1253
- # Do not emit any warnings if the method is just an implementation
1254
- # of a base class method.
1255
- confidence = HIGH
1256
- if node.is_method():
1257
- if overrides_a_method(node.parent.frame(), node.name):
1258
- return
1259
- confidence = (INFERENCE if has_known_bases(node.parent.frame())
1260
- else INFERENCE_FAILURE)
1261
-
1262
- self._check_name(_determine_function_name_type(node),
1263
- node.name, node, confidence)
1264
- # Check argument names
1265
- args = node.args.args
1266
- if args is not None:
1267
- self._recursive_check_names(args, node)
1268
-
1269
- visit_asyncfunctiondef = visit_functiondef
1270
-
1271
- @check_messages('blacklisted-name', 'invalid-name')
1272
- def visit_global(self, node):
1273
- for name in node.names:
1274
- self._check_name('const', name, node)
1275
-
1276
- @check_messages('blacklisted-name', 'invalid-name')
1277
- def visit_assignname(self, node):
1278
- """check module level assigned names"""
1279
- frame = node.frame()
1280
- ass_type = node.assign_type()
1281
- if isinstance(ass_type, astroid.Comprehension):
1282
- self._check_name('inlinevar', node.name, node)
1283
- elif isinstance(frame, astroid.Module):
1284
- if isinstance(ass_type, astroid.Assign) and not in_loop(ass_type):
1285
- if isinstance(safe_infer(ass_type.value), astroid.ClassDef):
1286
- self._check_name('class', node.name, node)
1287
- else:
1288
- if not _redefines_import(node):
1289
- # Don't emit if the name redefines an import
1290
- # in an ImportError except handler.
1291
- self._check_name('const', node.name, node)
1292
- elif isinstance(ass_type, astroid.ExceptHandler):
1293
- self._check_name('variable', node.name, node)
1294
- elif isinstance(frame, astroid.FunctionDef):
1295
- # global introduced variable aren't in the function locals
1296
- if node.name in frame and node.name not in frame.argnames():
1297
- if not _redefines_import(node):
1298
- self._check_name('variable', node.name, node)
1299
- elif isinstance(frame, astroid.ClassDef):
1300
- if not list(frame.local_attr_ancestors(node.name)):
1301
- self._check_name('class_attribute', node.name, node)
1302
-
1303
- def _recursive_check_names(self, args, node):
1304
- """check names in a possibly recursive list <arg>"""
1305
- for arg in args:
1306
- if isinstance(arg, astroid.AssignName):
1307
- self._check_name('argument', arg.name, node)
1308
- else:
1309
- self._recursive_check_names(arg.elts, node)
1310
-
1311
- def _find_name_group(self, node_type):
1312
- return self._name_group.get(node_type, node_type)
1313
-
1314
- def _raise_name_warning(self, node, node_type, name, confidence):
1315
- type_label = _NAME_TYPES[node_type][1]
1316
- hint = ''
1317
- if self.config.include_naming_hint:
1318
- hint = ' (hint: %s)' % (getattr(self.config, node_type + '_name_hint'))
1319
- self.add_message('invalid-name', node=node, args=(type_label, name, hint),
1320
- confidence=confidence)
1321
- self.stats['badname_' + node_type] += 1
1322
-
1323
- def _check_name(self, node_type, name, node, confidence=HIGH):
1324
- """check for a name using the type's regexp"""
1325
- if is_inside_except(node):
1326
- clobbering, _ = clobber_in_except(node)
1327
- if clobbering:
1328
- return
1329
- if name in self.config.good_names:
1330
- return
1331
- if name in self.config.bad_names:
1332
- self.stats['badname_' + node_type] += 1
1333
- self.add_message('blacklisted-name', node=node, args=name)
1334
- return
1335
- regexp = getattr(self.config, node_type + '_rgx')
1336
- match = regexp.match(name)
1337
-
1338
- if _is_multi_naming_match(match, node_type, confidence):
1339
- name_group = self._find_name_group(node_type)
1340
- bad_name_group = self._bad_names.setdefault(name_group, {})
1341
- warnings = bad_name_group.setdefault(match.lastgroup, [])
1342
- warnings.append((node, node_type, name, confidence))
1343
-
1344
- if match is None:
1345
- self._raise_name_warning(node, node_type, name, confidence)
1346
-
1347
-
1348
- class DocStringChecker(_BasicChecker):
1349
- msgs = {
1350
- 'C0111': ('Missing %s docstring', # W0131
1351
- 'missing-docstring',
1352
- 'Used when a module, function, class or method has no docstring.'
1353
- 'Some special methods like __init__ doesn\'t necessary require a '
1354
- 'docstring.'),
1355
- 'C0112': ('Empty %s docstring', # W0132
1356
- 'empty-docstring',
1357
- 'Used when a module, function, class or method has an empty '
1358
- 'docstring (it would be too easy ;).'),
1359
- }
1360
- options = (('no-docstring-rgx',
1361
- {'default' : NO_REQUIRED_DOC_RGX,
1362
- 'type' : 'regexp', 'metavar' : '<regexp>',
1363
- 'help' : 'Regular expression which should only match '
1364
- 'function or class names that do not require a '
1365
- 'docstring.'}
1366
- ),
1367
- ('docstring-min-length',
1368
- {'default' : -1,
1369
- 'type' : 'int', 'metavar' : '<int>',
1370
- 'help': ('Minimum line length for functions/classes that'
1371
- ' require docstrings, shorter ones are exempt.')}
1372
- ),
1373
- )
1374
-
1375
-
1376
- def open(self):
1377
- self.stats = self.linter.add_stats(undocumented_module=0,
1378
- undocumented_function=0,
1379
- undocumented_method=0,
1380
- undocumented_class=0)
1381
- @check_messages('missing-docstring', 'empty-docstring')
1382
- def visit_module(self, node):
1383
- self._check_docstring('module', node)
1384
-
1385
- @check_messages('missing-docstring', 'empty-docstring')
1386
- def visit_classdef(self, node):
1387
- if self.config.no_docstring_rgx.match(node.name) is None:
1388
- self._check_docstring('class', node)
1389
-
1390
- @staticmethod
1391
- def _is_setter_or_deleter(node):
1392
- names = {'setter', 'deleter'}
1393
- for decorator in node.decorators.nodes:
1394
- if (isinstance(decorator, astroid.Attribute)
1395
- and decorator.attrname in names):
1396
- return True
1397
- return False
1398
-
1399
- @check_messages('missing-docstring', 'empty-docstring')
1400
- def visit_functiondef(self, node):
1401
- if self.config.no_docstring_rgx.match(node.name) is None:
1402
- ftype = node.is_method() and 'method' or 'function'
1403
- if node.decorators and self._is_setter_or_deleter(node):
1404
- return
1405
-
1406
- if isinstance(node.parent.frame(), astroid.ClassDef):
1407
- overridden = False
1408
- confidence = (INFERENCE if has_known_bases(node.parent.frame())
1409
- else INFERENCE_FAILURE)
1410
- # check if node is from a method overridden by its ancestor
1411
- for ancestor in node.parent.frame().ancestors():
1412
- if node.name in ancestor and \
1413
- isinstance(ancestor[node.name], astroid.FunctionDef):
1414
- overridden = True
1415
- break
1416
- self._check_docstring(ftype, node,
1417
- report_missing=not overridden,
1418
- confidence=confidence)
1419
- else:
1420
- self._check_docstring(ftype, node)
1421
-
1422
- visit_asyncfunctiondef = visit_functiondef
1423
-
1424
- def _check_docstring(self, node_type, node, report_missing=True,
1425
- confidence=HIGH):
1426
- """check the node has a non empty docstring"""
1427
- docstring = node.doc
1428
- if docstring is None:
1429
- if not report_missing:
1430
- return
1431
- if node.body:
1432
- lines = node.body[-1].lineno - node.body[0].lineno + 1
1433
- else:
1434
- lines = 0
1435
-
1436
- if node_type == 'module' and not lines:
1437
- # If the module has no body, there's no reason
1438
- # to require a docstring.
1439
- return
1440
- max_lines = self.config.docstring_min_length
1441
-
1442
- if node_type != 'module' and max_lines > -1 and lines < max_lines:
1443
- return
1444
- self.stats['undocumented_'+node_type] += 1
1445
- if (node.body and isinstance(node.body[0], astroid.Expr) and
1446
- isinstance(node.body[0].value, astroid.Call)):
1447
- # Most likely a string with a format call. Let's see.
1448
- func = safe_infer(node.body[0].value.func)
1449
- if (isinstance(func, astroid.BoundMethod)
1450
- and isinstance(func.bound, astroid.Instance)):
1451
- # Strings in Python 3, others in Python 2.
1452
- if PY3K and func.bound.name == 'str':
1453
- return
1454
- elif func.bound.name in ('str', 'unicode', 'bytes'):
1455
- return
1456
- self.add_message('missing-docstring', node=node, args=(node_type,),
1457
- confidence=confidence)
1458
- elif not docstring.strip():
1459
- self.stats['undocumented_'+node_type] += 1
1460
- self.add_message('empty-docstring', node=node, args=(node_type,),
1461
- confidence=confidence)
1462
-
1463
-
1464
- class PassChecker(_BasicChecker):
1465
- """check if the pass statement is really necessary"""
1466
- msgs = {'W0107': ('Unnecessary pass statement',
1467
- 'unnecessary-pass',
1468
- 'Used when a "pass" statement that can be avoided is '
1469
- 'encountered.'),
1470
- }
1471
- @check_messages('unnecessary-pass')
1472
- def visit_pass(self, node):
1473
- if len(node.parent.child_sequence(node)) > 1:
1474
- self.add_message('unnecessary-pass', node=node)
1475
-
1476
-
1477
- class LambdaForComprehensionChecker(_BasicChecker):
1478
- """check for using a lambda where a comprehension would do.
1479
-
1480
- See <http://www.artima.com/weblogs/viewpost.jsp?thread=98196>
1481
- where GvR says comprehensions would be clearer.
1482
- """
1483
-
1484
- msgs = {'W0110': ('map/filter on lambda could be replaced by comprehension',
1485
- 'deprecated-lambda',
1486
- 'Used when a lambda is the first argument to "map" or '
1487
- '"filter". It could be clearer as a list '
1488
- 'comprehension or generator expression.',
1489
- {'maxversion': (3, 0)}),
1490
- }
1491
-
1492
- @check_messages('deprecated-lambda')
1493
- def visit_call(self, node):
1494
- """visit a CallFunc node, check if map or filter are called with a
1495
- lambda
1496
- """
1497
- if not node.args:
1498
- return
1499
- if not isinstance(node.args[0], astroid.Lambda):
1500
- return
1501
- infered = safe_infer(node.func)
1502
- if (is_builtin_object(infered)
1503
- and infered.name in ['map', 'filter']):
1504
- self.add_message('deprecated-lambda', node=node)
1505
-
1506
-
1507
- class RecommandationChecker(_BasicChecker):
1508
- msgs = {'C0200': ('Consider using enumerate instead of iterating with range and len',
1509
- 'consider-using-enumerate',
1510
- 'Emitted when code that iterates with range and len is '
1511
- 'encountered. Such code can be simplified by using the '
1512
- 'enumerate builtin.'),
1513
- }
1514
-
1515
- @staticmethod
1516
- def _is_builtin(node, function):
1517
- inferred = safe_infer(node)
1518
- if not inferred:
1519
- return False
1520
- return is_builtin_object(inferred) and inferred.name == function
1521
-
1522
- @check_messages('consider-using-enumerate')
1523
- def visit_for(self, node):
1524
- """Emit a convention whenever range and len are used for indexing."""
1525
- # Verify that we have a `range(len(...))` call and that the object
1526
- # which is iterated is used as a subscript in the body of the for.
1527
-
1528
- # Is it a proper range call?
1529
- if not isinstance(node.iter, astroid.Call):
1530
- return
1531
- if not self._is_builtin(node.iter.func, 'range'):
1532
- return
1533
- if len(node.iter.args) != 1:
1534
- return
1535
-
1536
- # Is it a proper len call?
1537
- if not isinstance(node.iter.args[0], astroid.Call):
1538
- return
1539
- second_func = node.iter.args[0].func
1540
- if not self._is_builtin(second_func, 'len'):
1541
- return
1542
- len_args = node.iter.args[0].args
1543
- if not len_args or len(len_args) != 1:
1544
- return
1545
- iterating_object = len_args[0]
1546
- if not isinstance(iterating_object, astroid.Name):
1547
- return
1548
-
1549
- # Verify that the body of the for loop uses a subscript
1550
- # with the object that was iterated. This uses some heuristics
1551
- # in order to make sure that the same object is used in the
1552
- # for body.
1553
- for child in node.body:
1554
- for subscript in child.nodes_of_class(astroid.Subscript):
1555
- if not isinstance(subscript.value, astroid.Name):
1556
- continue
1557
- if not isinstance(subscript.slice, astroid.Index):
1558
- continue
1559
- if not isinstance(subscript.slice.value, astroid.Name):
1560
- continue
1561
- if subscript.slice.value.name != node.target.name:
1562
- continue
1563
- if iterating_object.name != subscript.value.name:
1564
- continue
1565
- if subscript.value.scope() != node.scope():
1566
- # Ignore this subscript if it's not in the same
1567
- # scope. This means that in the body of the for
1568
- # loop, another scope was created, where the same
1569
- # name for the iterating object was used.
1570
- continue
1571
- self.add_message('consider-using-enumerate', node=node)
1572
- return
1573
-
1574
-
1575
- def _is_one_arg_pos_call(call):
1576
- """Is this a call with exactly 1 argument,
1577
- where that argument is positional?
1578
- """
1579
- return (isinstance(call, astroid.Call)
1580
- and len(call.args) == 1 and not call.keywords)
1581
-
1582
-
1583
- class ComparisonChecker(_BasicChecker):
1584
- """Checks for comparisons
1585
-
1586
- - singleton comparison: 'expr == True', 'expr == False' and 'expr == None'
1587
- - yoda condition: 'const "comp" right' where comp can be '==', '!=', '<',
1588
- '<=', '>' or '>=', and right can be a variable, an attribute, a method or
1589
- a function
1590
- """
1591
- msgs = {'C0121': ('Comparison to %s should be %s',
1592
- 'singleton-comparison',
1593
- 'Used when an expression is compared to singleton '
1594
- 'values like True, False or None.'),
1595
- 'C0122': ('Comparison should be %s',
1596
- 'misplaced-comparison-constant',
1597
- 'Used when the constant is placed on the left side'
1598
- 'of a comparison. It is usually clearer in intent to '
1599
- 'place it in the right hand side of the comparison.'),
1600
- 'C0123': ('Using type() instead of isinstance() for a typecheck.',
1601
- 'unidiomatic-typecheck',
1602
- 'The idiomatic way to perform an explicit typecheck in '
1603
- 'Python is to use isinstance(x, Y) rather than '
1604
- 'type(x) == Y, type(x) is Y. Though there are unusual '
1605
- 'situations where these give different results.',
1606
- {'old_names': [('W0154', 'unidiomatic-typecheck')]}),
1607
- }
1608
-
1609
- def _check_singleton_comparison(self, singleton, root_node):
1610
- if singleton.value is True:
1611
- suggestion = "just 'expr' or 'expr is True'"
1612
- self.add_message('singleton-comparison',
1613
- node=root_node,
1614
- args=(True, suggestion))
1615
- elif singleton.value is False:
1616
- suggestion = "'not expr' or 'expr is False'"
1617
- self.add_message('singleton-comparison',
1618
- node=root_node,
1619
- args=(False, suggestion))
1620
- elif singleton.value is None:
1621
- self.add_message('singleton-comparison',
1622
- node=root_node,
1623
- args=(None, "'expr is None'"))
1624
-
1625
- def _check_misplaced_constant(self, node, left, right, operator):
1626
- if isinstance(right, astroid.Const):
1627
- return
1628
- operator = REVERSED_COMPS.get(operator, operator)
1629
- suggestion = '%s %s %r' % (right.as_string(), operator, left.value)
1630
- self.add_message('misplaced-comparison-constant', node=node,
1631
- args=(suggestion,))
1632
-
1633
- @check_messages('singleton-comparison', 'misplaced-comparison-constant',
1634
- 'unidiomatic-typecheck')
1635
- def visit_compare(self, node):
1636
- self._check_unidiomatic_typecheck(node)
1637
- # NOTE: this checker only works with binary comparisons like 'x == 42'
1638
- # but not 'x == y == 42'
1639
- if len(node.ops) != 1:
1640
- return
1641
- left = node.left
1642
- operator, right = node.ops[0]
1643
- if (operator in ('<', '<=', '>', '>=', '!=', '==')
1644
- and isinstance(left, astroid.Const)):
1645
- self._check_misplaced_constant(node, left, right, operator)
1646
-
1647
- if operator == '==':
1648
- if isinstance(left, astroid.Const):
1649
- self._check_singleton_comparison(left, node)
1650
- elif isinstance(right, astroid.Const):
1651
- self._check_singleton_comparison(right, node)
1652
-
1653
- def _check_unidiomatic_typecheck(self, node):
1654
- operator, right = node.ops[0]
1655
- if operator in TYPECHECK_COMPARISON_OPERATORS:
1656
- left = node.left
1657
- if _is_one_arg_pos_call(left):
1658
- self._check_type_x_is_y(node, left, operator, right)
1659
-
1660
- def _check_type_x_is_y(self, node, left, operator, right):
1661
- """Check for expressions like type(x) == Y."""
1662
- left_func = safe_infer(left.func)
1663
- if not (isinstance(left_func, astroid.ClassDef)
1664
- and left_func.qname() == TYPE_QNAME):
1665
- return
1666
-
1667
- if operator in ('is', 'is not') and _is_one_arg_pos_call(right):
1668
- right_func = safe_infer(right.func)
1669
- if (isinstance(right_func, astroid.ClassDef)
1670
- and right_func.qname() == TYPE_QNAME):
1671
- # type(x) == type(a)
1672
- right_arg = safe_infer(right.args[0])
1673
- if not isinstance(right_arg, LITERAL_NODE_TYPES):
1674
- # not e.g. type(x) == type([])
1675
- return
1676
- self.add_message('unidiomatic-typecheck', node=node)
1677
-
1678
-
1679
- class ElifChecker(BaseTokenChecker):
1680
- """Checks needing to distinguish "else if" from "elif"
1681
-
1682
- This checker mixes the astroid and the token approaches in order to create
1683
- knowledge about whether a "else if" node is a true "else if" node, or a
1684
- "elif" node.
1685
-
1686
- The following checks depend on this implementation:
1687
- - check for too many nested blocks (if/elif structures aren't considered
1688
- as nested)
1689
- - to be continued
1690
- """
1691
- __implements__ = (ITokenChecker, IAstroidChecker)
1692
- name = 'elif'
1693
- msgs = {'R0101': ('Too many nested blocks (%s/%s)',
1694
- 'too-many-nested-blocks',
1695
- 'Used when a function or a method has too many nested '
1696
- 'blocks. This makes the code less understandable and '
1697
- 'maintainable.'),
1698
- 'R0102': ('The if statement can be replaced with %s',
1699
- 'simplifiable-if-statement',
1700
- 'Used when an if statement can be replaced with '
1701
- '\'bool(test)\'. '),
1702
- }
1703
- options = (('max-nested-blocks',
1704
- {'default' : 5, 'type' : 'int', 'metavar' : '<int>',
1705
- 'help': 'Maximum number of nested blocks for function / '
1706
- 'method body'}
1707
- ),)
1708
-
1709
- def __init__(self, linter=None):
1710
- BaseTokenChecker.__init__(self, linter)
1711
- self._init()
1712
-
1713
- def _init(self):
1714
- self._nested_blocks = []
1715
- self._elifs = []
1716
- self._if_counter = 0
1717
- self._nested_blocks_msg = None
1718
-
1719
- @staticmethod
1720
- def _is_bool_const(node):
1721
- return (isinstance(node.value, astroid.Const)
1722
- and isinstance(node.value.value, bool))
1723
-
1724
- def _is_actual_elif(self, node):
1725
- """Check if the given node is an actual elif
1726
-
1727
- This is a problem we're having with the builtin ast module,
1728
- which splits `elif` branches into a separate if statement.
1729
- Unfortunately we need to know the exact type in certain
1730
- cases.
1731
- """
1732
-
1733
- if isinstance(node.parent, astroid.If):
1734
- orelse = node.parent.orelse
1735
- # current if node must directly follow a "else"
1736
- if orelse and orelse == [node]:
1737
- if self._elifs[self._if_counter]:
1738
- return True
1739
- return False
1740
-
1741
- def _check_simplifiable_if(self, node):
1742
- """Check if the given if node can be simplified.
1743
-
1744
- The if statement can be reduced to a boolean expression
1745
- in some cases. For instance, if there are two branches
1746
- and both of them return a boolean value that depends on
1747
- the result of the statement's test, then this can be reduced
1748
- to `bool(test)` without losing any functionality.
1749
- """
1750
-
1751
- if self._is_actual_elif(node):
1752
- # Not interested in if statements with multiple branches.
1753
- return
1754
- if len(node.orelse) != 1 or len(node.body) != 1:
1755
- return
1756
-
1757
- # Check if both branches can be reduced.
1758
- first_branch = node.body[0]
1759
- else_branch = node.orelse[0]
1760
- if isinstance(first_branch, astroid.Return):
1761
- if not isinstance(else_branch, astroid.Return):
1762
- return
1763
- first_branch_is_bool = self._is_bool_const(first_branch)
1764
- else_branch_is_bool = self._is_bool_const(else_branch)
1765
- reduced_to = "'return bool(test)'"
1766
- elif isinstance(first_branch, astroid.Assign):
1767
- if not isinstance(else_branch, astroid.Assign):
1768
- return
1769
- first_branch_is_bool = self._is_bool_const(first_branch)
1770
- else_branch_is_bool = self._is_bool_const(else_branch)
1771
- reduced_to = "'var = bool(test)'"
1772
- else:
1773
- return
1774
-
1775
- if not first_branch_is_bool or not else_branch_is_bool:
1776
- return
1777
- if not first_branch.value.value:
1778
- # This is a case that can't be easily simplified and
1779
- # if it can be simplified, it will usually result in a
1780
- # code that's harder to understand and comprehend.
1781
- # Let's take for instance `arg and arg <= 3`. This could theoretically be
1782
- # reduced to `not arg or arg > 3`, but the net result is that now the
1783
- # condition is harder to understand, because it requires understanding of
1784
- # an extra clause:
1785
- # * first, there is the negation of truthness with `not arg`
1786
- # * the second clause is `arg > 3`, which occurs when arg has a
1787
- # a truth value, but it implies that `arg > 3` is equivalent
1788
- # with `arg and arg > 3`, which means that the user must
1789
- # think about this assumption when evaluating `arg > 3`.
1790
- # The original form is easier to grasp.
1791
- return
1792
-
1793
- self.add_message('simplifiable-if-statement', node=node,
1794
- args=(reduced_to, ))
1795
-
1796
- def process_tokens(self, tokens):
1797
- # Process tokens and look for 'if' or 'elif'
1798
- for _, token, _, _, _ in tokens:
1799
- if token == 'elif':
1800
- self._elifs.append(True)
1801
- elif token == 'if':
1802
- self._elifs.append(False)
1803
-
1804
- def leave_module(self, _):
1805
- self._init()
1806
-
1807
- @check_messages('too-many-nested-blocks')
1808
- def visit_tryexcept(self, node):
1809
- self._check_nested_blocks(node)
1810
-
1811
- visit_tryfinally = visit_tryexcept
1812
- visit_while = visit_tryexcept
1813
- visit_for = visit_while
1814
-
1815
- def visit_ifexp(self, _):
1816
- self._if_counter += 1
1817
-
1818
- def visit_comprehension(self, node):
1819
- self._if_counter += len(node.ifs)
1820
-
1821
- @check_messages('too-many-nested-blocks', 'simplifiable-if-statement')
1822
- def visit_if(self, node):
1823
- self._check_simplifiable_if(node)
1824
- self._check_nested_blocks(node)
1825
- self._if_counter += 1
1826
-
1827
- @check_messages('too-many-nested-blocks')
1828
- def leave_functiondef(self, _):
1829
- # new scope = reinitialize the stack of nested blocks
1830
- self._nested_blocks = []
1831
- # if there is a waiting message left, send it
1832
- if self._nested_blocks_msg:
1833
- self.add_message('too-many-nested-blocks',
1834
- node=self._nested_blocks_msg[0],
1835
- args=self._nested_blocks_msg[1])
1836
- self._nested_blocks_msg = None
1837
-
1838
- def _check_nested_blocks(self, node):
1839
- """Update and check the number of nested blocks
1840
- """
1841
- # only check block levels inside functions or methods
1842
- if not isinstance(node.scope(), astroid.FunctionDef):
1843
- return
1844
- # messages are triggered on leaving the nested block. Here we save the
1845
- # stack in case the current node isn't nested in the previous one
1846
- nested_blocks = self._nested_blocks[:]
1847
- if node.parent == node.scope():
1848
- self._nested_blocks = [node]
1849
- else:
1850
- # go through ancestors from the most nested to the less
1851
- for ancestor_node in reversed(self._nested_blocks):
1852
- if ancestor_node == node.parent:
1853
- break
1854
- self._nested_blocks.pop()
1855
- # if the node is a elif, this should not be another nesting level
1856
- if isinstance(node, astroid.If) and self._elifs[self._if_counter]:
1857
- if self._nested_blocks:
1858
- self._nested_blocks.pop()
1859
- self._nested_blocks.append(node)
1860
- # send message only once per group of nested blocks
1861
- if len(nested_blocks) > self.config.max_nested_blocks:
1862
- if len(nested_blocks) > len(self._nested_blocks):
1863
- self.add_message('too-many-nested-blocks', node=nested_blocks[0],
1864
- args=(len(nested_blocks),
1865
- self.config.max_nested_blocks))
1866
- self._nested_blocks_msg = None
1867
- else:
1868
- # if time has not come yet to send the message (ie the stack of
1869
- # nested nodes is still increasing), save it in case the
1870
- # current node is the last one of the function
1871
- self._nested_blocks_msg = (self._nested_blocks[0],
1872
- (len(self._nested_blocks),
1873
- self.config.max_nested_blocks))
1874
-
1875
- class NotChecker(_BasicChecker):
1876
- """checks for too many not in comparison expressions
1877
-
1878
- - "not not" should trigger a warning
1879
- - "not" followed by a comparison should trigger a warning
1880
- """
1881
- msgs = {'C0113': ('Consider changing "%s" to "%s"',
1882
- 'unneeded-not',
1883
- 'Used when a boolean expression contains an unneeded '
1884
- 'negation.'),
1885
- }
1886
-
1887
- reverse_op = {'<': '>=', '<=': '>', '>': '<=', '>=': '<', '==': '!=',
1888
- '!=': '==', 'in': 'not in', 'is': 'is not'}
1889
- # sets are not ordered, so for example "not set(LEFT_VALS) <= set(RIGHT_VALS)" is
1890
- # not equivalent to "set(LEFT_VALS) > set(RIGHT_VALS)"
1891
- skipped_nodes = (astroid.Set, )
1892
- # 'builtins' py3, '__builtin__' py2
1893
- skipped_classnames = ['%s.%s' % (six.moves.builtins.__name__, qname)
1894
- for qname in ('set', 'frozenset')]
1895
-
1896
- @check_messages('unneeded-not')
1897
- def visit_unaryop(self, node):
1898
- if node.op != 'not':
1899
- return
1900
- operand = node.operand
1901
-
1902
- if isinstance(operand, astroid.UnaryOp) and operand.op == 'not':
1903
- self.add_message('unneeded-not', node=node,
1904
- args=(node.as_string(),
1905
- operand.operand.as_string()))
1906
- elif isinstance(operand, astroid.Compare):
1907
- left = operand.left
1908
- # ignore multiple comparisons
1909
- if len(operand.ops) > 1:
1910
- return
1911
- operator, right = operand.ops[0]
1912
- if operator not in self.reverse_op:
1913
- return
1914
- # Ignore __ne__ as function of __eq__
1915
- frame = node.frame()
1916
- if frame.name == '__ne__' and operator == '==':
1917
- return
1918
- for _type in (_node_type(left), _node_type(right)):
1919
- if not _type:
1920
- return
1921
- if isinstance(_type, self.skipped_nodes):
1922
- return
1923
- if (isinstance(_type, astroid.Instance) and
1924
- _type.qname() in self.skipped_classnames):
1925
- return
1926
- suggestion = '%s %s %s' % (left.as_string(),
1927
- self.reverse_op[operator],
1928
- right.as_string())
1929
- self.add_message('unneeded-not', node=node,
1930
- args=(node.as_string(), suggestion))
1931
-
1932
-
1933
- class MultipleTypesChecker(BaseChecker):
1934
- """Checks for variable type redefinitions (NoneType excepted)
1935
-
1936
- At a function, method, class or module scope
1937
-
1938
- This rule could be improved:
1939
- - Currently, if an attribute is set to different types in 2 methods of a
1940
- same class, it won't be detected (see functional test)
1941
- - One could improve the support for inference on assignment with tuples,
1942
- ifexpr, etc. Also it would be great to have support for inference on
1943
- str.split()
1944
- """
1945
- __implements__ = IAstroidChecker
1946
-
1947
- name = 'multiple_types'
1948
- msgs = {'R0204': ('Redefinition of %s type from %s to %s',
1949
- 'redefined-variable-type',
1950
- 'Used when the type of a variable changes inside a '
1951
- 'method or a function.'
1952
- ),
1953
- }
1954
-
1955
- def visit_classdef(self, _):
1956
- self._assigns.append({})
1957
-
1958
- @check_messages('redefined-variable-type')
1959
- def leave_classdef(self, _):
1960
- self._check_and_add_messages()
1961
-
1962
- visit_functiondef = visit_classdef
1963
- leave_functiondef = leave_module = leave_classdef
1964
-
1965
- def visit_module(self, _):
1966
- self._assigns = [{}]
1967
-
1968
- def _check_and_add_messages(self):
1969
- assigns = self._assigns.pop()
1970
- for name, args in assigns.items():
1971
- if len(args) <= 1:
1972
- continue
1973
- _, orig_type = args[0]
1974
- # Check if there is a type in the following nodes that would be
1975
- # different from orig_type.
1976
- for redef_node, redef_type in args[1:]:
1977
- if redef_type != orig_type:
1978
- orig_type = orig_type.replace(BUILTINS + ".", '')
1979
- redef_type = redef_type.replace(BUILTINS + ".", '')
1980
- self.add_message('redefined-variable-type', node=redef_node,
1981
- args=(name, orig_type, redef_type))
1982
- break
1983
-
1984
- def visit_assign(self, node):
1985
- # we don't handle multiple assignment nor slice assignment
1986
- target = node.targets[0]
1987
- if isinstance(target, (astroid.Tuple, astroid.Subscript)):
1988
- return
1989
- # ignore NoneType
1990
- if _is_none(node):
1991
- return
1992
- _type = _node_type(node.value)
1993
- if _type:
1994
- self._assigns[-1].setdefault(target.as_string(), []).append(
1995
- (node, _type.pytype()))
1996
-
1997
-
1998
- def register(linter):
1999
- """required method to auto register this checker"""
2000
- linter.register_checker(BasicErrorChecker(linter))
2001
- linter.register_checker(BasicChecker(linter))
2002
- linter.register_checker(NameChecker(linter))
2003
- linter.register_checker(DocStringChecker(linter))
2004
- linter.register_checker(PassChecker(linter))
2005
- linter.register_checker(LambdaForComprehensionChecker(linter))
2006
- linter.register_checker(ComparisonChecker(linter))
2007
- linter.register_checker(NotChecker(linter))
2008
- linter.register_checker(RecommandationChecker(linter))
2009
- linter.register_checker(ElifChecker(linter))
2010
- linter.register_checker(MultipleTypesChecker(linter))