libv8 6.7.288.46.1 → 7.3.492.27.0beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (408) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +3 -0
  3. data/CHANGELOG.md +4 -0
  4. data/README.md +2 -0
  5. data/ext/libv8/builder.rb +6 -2
  6. data/lib/libv8/version.rb +1 -1
  7. data/vendor/depot_tools/.gitattributes +1 -0
  8. data/vendor/depot_tools/.gitignore +7 -0
  9. data/vendor/depot_tools/CROS_OWNERS +5 -0
  10. data/vendor/depot_tools/OWNERS +12 -1
  11. data/vendor/depot_tools/PRESUBMIT.py +16 -9
  12. data/vendor/depot_tools/README.md +9 -2
  13. data/vendor/depot_tools/autoninja +14 -6
  14. data/vendor/depot_tools/autoninja.bat +11 -1
  15. data/vendor/depot_tools/autoninja.py +40 -18
  16. data/vendor/depot_tools/bb +12 -0
  17. data/vendor/depot_tools/bb.bat +7 -0
  18. data/vendor/depot_tools/bootstrap/win/manifest.txt +1 -1
  19. data/vendor/depot_tools/bootstrap/win/manifest_bleeding_edge.txt +1 -1
  20. data/vendor/depot_tools/bootstrap/win/win_tools.py +2 -1
  21. data/vendor/depot_tools/buildbucket.py +57 -4
  22. data/vendor/depot_tools/cipd +157 -44
  23. data/vendor/depot_tools/cipd.bat +51 -14
  24. data/vendor/depot_tools/cipd.ps1 +104 -42
  25. data/vendor/depot_tools/cipd_client_version +1 -1
  26. data/vendor/depot_tools/cipd_client_version.digests +21 -0
  27. data/vendor/depot_tools/cipd_manifest.txt +19 -6
  28. data/vendor/depot_tools/cipd_manifest.versions +318 -0
  29. data/vendor/depot_tools/clang_format.py +4 -4
  30. data/vendor/depot_tools/cpplint.py +44 -199
  31. data/vendor/depot_tools/dart_format.py +2 -2
  32. data/vendor/depot_tools/detect_host_arch.py +8 -3
  33. data/vendor/depot_tools/download_from_google_storage.py +47 -39
  34. data/vendor/depot_tools/fetch.py +30 -18
  35. data/vendor/depot_tools/fetch_configs/android_internal.py +34 -0
  36. data/vendor/depot_tools/fetch_configs/chromium.py +18 -1
  37. data/vendor/depot_tools/fetch_configs/config_util.py +4 -2
  38. data/vendor/depot_tools/fetch_configs/inspector_protocol.py +40 -0
  39. data/vendor/depot_tools/fetch_configs/node-ci.py +41 -0
  40. data/vendor/depot_tools/fix_encoding.py +3 -3
  41. data/vendor/depot_tools/gclient +1 -1
  42. data/vendor/depot_tools/gclient.py +415 -198
  43. data/vendor/depot_tools/gclient_eval.py +220 -171
  44. data/vendor/depot_tools/gclient_paths.py +142 -0
  45. data/vendor/depot_tools/gclient_scm.py +200 -51
  46. data/vendor/depot_tools/gclient_utils.py +88 -191
  47. data/vendor/depot_tools/gerrit_client.py +13 -0
  48. data/vendor/depot_tools/gerrit_util.py +158 -23
  49. data/vendor/depot_tools/git-nav-upstream +1 -1
  50. data/vendor/depot_tools/git_cache.py +77 -24
  51. data/vendor/depot_tools/git_cl.py +705 -1099
  52. data/vendor/depot_tools/git_common.py +9 -6
  53. data/vendor/depot_tools/git_map_branches.py +19 -2
  54. data/vendor/depot_tools/git_nav_downstream.py +3 -4
  55. data/vendor/depot_tools/git_rebase_update.py +14 -0
  56. data/vendor/depot_tools/git_reparent_branch.py +8 -2
  57. data/vendor/depot_tools/gn.py +38 -3
  58. data/vendor/depot_tools/gsutil.py +8 -3
  59. data/vendor/depot_tools/gsutil.py.bat +15 -0
  60. data/vendor/depot_tools/gsutil.vpython +16 -0
  61. data/vendor/depot_tools/infra/config/OWNERS +0 -1
  62. data/vendor/depot_tools/infra/config/recipes.cfg +3 -2
  63. data/vendor/depot_tools/lucicfg +12 -0
  64. data/vendor/depot_tools/lucicfg.bat +7 -0
  65. data/vendor/depot_tools/man/html/git-map-branches.html +34 -2
  66. data/vendor/depot_tools/man/html/git-new-branch.html +40 -32
  67. data/vendor/depot_tools/man/man1/git-map-branches.1 +24 -5
  68. data/vendor/depot_tools/man/man1/git-new-branch.1 +35 -27
  69. data/vendor/depot_tools/man/src/git-map-branches.demo.1.sh +1 -0
  70. data/vendor/depot_tools/man/src/git-map-branches.txt +10 -0
  71. data/vendor/depot_tools/man/src/git-new-branch.demo.1.sh +9 -4
  72. data/vendor/depot_tools/man/src/git-new-branch.txt +1 -1
  73. data/vendor/depot_tools/metrics.README.md +98 -0
  74. data/vendor/depot_tools/metrics.py +296 -0
  75. data/vendor/depot_tools/metrics_utils.py +303 -0
  76. data/vendor/depot_tools/my_activity.py +91 -29
  77. data/vendor/depot_tools/ninja +1 -1
  78. data/vendor/depot_tools/ninjalog.README.md +64 -0
  79. data/vendor/depot_tools/ninjalog_uploader.py +232 -0
  80. data/vendor/depot_tools/ninjalog_uploader_wrapper.py +116 -0
  81. data/vendor/depot_tools/owners.py +30 -13
  82. data/vendor/depot_tools/owners_finder.py +5 -2
  83. data/vendor/depot_tools/presubmit_canned_checks.py +188 -29
  84. data/vendor/depot_tools/presubmit_support.py +18 -41
  85. data/vendor/depot_tools/pylintrc +23 -19
  86. data/vendor/depot_tools/recipes/OWNERS +2 -0
  87. data/vendor/depot_tools/recipes/README.recipes.md +344 -151
  88. data/vendor/depot_tools/recipes/recipe_modules/bot_update/OWNERS +2 -0
  89. data/vendor/depot_tools/recipes/recipe_modules/bot_update/__init__.py +2 -16
  90. data/vendor/depot_tools/recipes/recipe_modules/bot_update/api.py +141 -99
  91. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic.json +5 -8
  92. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_luci.json +5 -8
  93. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/basic_with_branch_heads.json +6 -98
  94. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/clobber.json +4 -9
  95. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/deprecated_got_revision_mapping.json +45 -5
  96. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_rebase_patch_ref.json +4 -9
  97. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/gerrit_no_reset.json +4 -9
  98. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{tryjob.json → input_commit_with_id_without_repo.json} +6 -11
  99. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{tryjob_empty_revision.json → multiple_patch_refs.json} +8 -9
  100. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/no_apply_patch_on_gclient.json +19 -29
  101. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/{trychange.json → refs.json} +4 -9
  102. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/reset_root_solution_revision.json +4 -9
  103. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail.json +51 -6
  104. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch.json +50 -6
  105. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_fail_patch_download.json +51 -6
  106. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle.json +17 -25
  107. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_branch_heads.json +17 -25
  108. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_feature_branch.json +18 -26
  109. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8_feature_branch.json +18 -26
  110. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_webrtc.json +26 -28
  111. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8.json +45 -5
  112. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_v8_head_by_default.json +17 -25
  113. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/unrecognized_commit_repo.json +13 -0
  114. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name.json +13 -152
  115. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_tags.json +4 -9
  116. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.py +185 -202
  117. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/bot_update.py +52 -157
  118. data/vendor/depot_tools/recipes/recipe_modules/bot_update/test_api.py +5 -14
  119. data/vendor/depot_tools/recipes/recipe_modules/bot_update/tests/ensure_checkout.py +34 -0
  120. data/vendor/depot_tools/recipes/recipe_modules/cipd/api.py +14 -2
  121. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic.json +4 -5
  122. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/basic_pkg.json +4 -5
  123. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-failed.json +7 -5
  124. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/describe-many-instances.json +4 -5
  125. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/mac64.json +4 -5
  126. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_file.json +9 -3
  127. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_mode.json +9 -3
  128. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/pkg_bad_verfile.json +9 -3
  129. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/full.expected/win64.json +4 -5
  130. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk arch.json +2 -3
  131. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/junk bits.json +2 -3
  132. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_32.json +2 -3
  133. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_arm_64.json +2 -3
  134. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_32.json +2 -3
  135. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_intel_64.json +2 -3
  136. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/linux_mips_64.json +2 -3
  137. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/mac_intel_64.json +2 -3
  138. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_32.json +2 -3
  139. data/vendor/depot_tools/recipes/recipe_modules/cipd/examples/platform_suffix.expected/win_intel_64.json +2 -3
  140. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/api.py +13 -8
  141. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic.json +18 -12
  142. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/basic_luci.json +18 -12
  143. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.expected/win.json +18 -12
  144. data/vendor/depot_tools/recipes/recipe_modules/depot_tools/examples/full.py +3 -0
  145. data/vendor/depot_tools/recipes/recipe_modules/gclient/__init__.py +1 -0
  146. data/vendor/depot_tools/recipes/recipe_modules/gclient/api.py +58 -46
  147. data/vendor/depot_tools/recipes/recipe_modules/gclient/config.py +65 -22
  148. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/basic.json +20 -21
  149. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/buildbot.json +20 -21
  150. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/revision.json +20 -21
  151. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.expected/tryserver.json +20 -21
  152. data/vendor/depot_tools/recipes/recipe_modules/gclient/examples/full.py +5 -2
  153. data/vendor/depot_tools/recipes/recipe_modules/gclient/tests/patch_project.py +62 -14
  154. data/vendor/depot_tools/recipes/recipe_modules/gerrit/api.py +24 -38
  155. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.expected/basic.json +56 -50
  156. data/vendor/depot_tools/recipes/recipe_modules/gerrit/examples/full.py +15 -9
  157. data/vendor/depot_tools/recipes/recipe_modules/git/__init__.py +4 -1
  158. data/vendor/depot_tools/recipes/recipe_modules/git/api.py +34 -22
  159. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic.json +5 -6
  160. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_branch.json +5 -6
  161. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_file_name.json +5 -6
  162. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_hash.json +5 -6
  163. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_luci.json +222 -0
  164. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_ref.json +5 -6
  165. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_submodule_update_force.json +5 -6
  166. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/basic_tags.json +224 -0
  167. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/can_fail_build.json +10 -6
  168. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cannot_fail_build.json +5 -7
  169. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/cat-file_test.json +5 -6
  170. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_delta.json +5 -6
  171. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_failed.json +5 -7
  172. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output.json +5 -6
  173. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/count-objects_with_bad_output_fails_build.json +10 -5
  174. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/curl_trace_file.json +5 -6
  175. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/git-cache-checkout.json +8 -9
  176. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/platform_win.json +5 -6
  177. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/rebase_failed.json +12 -8
  178. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/remote_not_origin.json +5 -6
  179. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.expected/set_got_revision.json +5 -6
  180. data/vendor/depot_tools/recipes/recipe_modules/git/examples/full.py +27 -11
  181. data/vendor/depot_tools/recipes/recipe_modules/git_cl/api.py +1 -1
  182. data/vendor/depot_tools/recipes/recipe_modules/git_cl/examples/full.expected/basic.json +12 -13
  183. data/vendor/depot_tools/recipes/recipe_modules/gitiles/__init__.py +5 -0
  184. data/vendor/depot_tools/recipes/recipe_modules/gitiles/api.py +120 -5
  185. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.expected/basic.json +45 -3
  186. data/vendor/depot_tools/recipes/recipe_modules/gitiles/examples/full.py +25 -0
  187. data/vendor/depot_tools/recipes/recipe_modules/gitiles/resources/gerrit_client.py +56 -4
  188. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.expected/basic.json +6 -0
  189. data/vendor/depot_tools/recipes/recipe_modules/gitiles/tests/parse_repo_url.py +49 -0
  190. data/vendor/depot_tools/recipes/recipe_modules/gsutil/api.py +24 -13
  191. data/vendor/depot_tools/recipes/recipe_modules/gsutil/examples/full.expected/basic.json +13 -14
  192. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/basic.json +2 -3
  193. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_linux.json +2 -3
  194. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_mac.json +2 -3
  195. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_buildbot_win.json +2 -3
  196. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_linux.json +2 -3
  197. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_mac.json +2 -3
  198. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_generic_win.json +2 -3
  199. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_linux.json +2 -3
  200. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_mac.json +2 -3
  201. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/examples/full.expected/paths_kitchen_win.json +2 -3
  202. data/vendor/depot_tools/recipes/recipe_modules/infra_paths/path_config.py +1 -2
  203. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/__init__.py +35 -0
  204. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/api.py +116 -0
  205. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/linux.json +22 -0
  206. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/mac.json +82 -0
  207. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.expected/win.json +22 -0
  208. data/vendor/depot_tools/recipes/recipe_modules/osx_sdk/examples/full.py +23 -0
  209. data/vendor/depot_tools/recipes/recipe_modules/presubmit/__init__.py +1 -0
  210. data/vendor/depot_tools/recipes/recipe_modules/presubmit/api.py +2 -7
  211. data/vendor/depot_tools/recipes/recipe_modules/presubmit/examples/full.expected/basic.json +7 -6
  212. data/vendor/depot_tools/recipes/recipe_modules/tryserver/__init__.py +1 -0
  213. data/vendor/depot_tools/recipes/recipe_modules/tryserver/api.py +117 -8
  214. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/basic_tags.json +4 -5
  215. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/set_failure_hash_with_no_steps.json +7 -4
  216. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch.json +98 -7
  217. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_gerrit_patch_and_target_ref.json +147 -0
  218. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch.json +8 -5
  219. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_git_patch_luci.json +8 -5
  220. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch.json +9 -6
  221. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.expected/with_wrong_patch_new.json +9 -6
  222. data/vendor/depot_tools/recipes/recipe_modules/tryserver/examples/full.py +27 -2
  223. data/vendor/depot_tools/recipes/recipe_modules/tryserver/test_api.py +14 -0
  224. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/__init__.py +25 -0
  225. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/api.py +137 -0
  226. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/linux.json +22 -0
  227. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/mac.json +22 -0
  228. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.expected/win.json +107 -0
  229. data/vendor/depot_tools/recipes/recipe_modules/windows_sdk/examples/full.py +26 -0
  230. data/vendor/depot_tools/recipes/recipes.py +37 -27
  231. data/vendor/depot_tools/recipes/recipes/fetch_end_to_end_test.expected/basic.json +7 -10
  232. data/vendor/depot_tools/repo +34 -8
  233. data/vendor/depot_tools/roll_dep.py +52 -49
  234. data/vendor/depot_tools/scm.py +38 -23
  235. data/vendor/depot_tools/setup_color.py +4 -2
  236. data/vendor/depot_tools/split_cl.py +32 -4
  237. data/vendor/depot_tools/subprocess2.py +22 -4
  238. data/vendor/depot_tools/third_party/httplib2/README.chromium +2 -2
  239. data/vendor/depot_tools/third_party/httplib2/__init__.py +242 -158
  240. data/vendor/depot_tools/third_party/httplib2/cacerts.txt +57 -44
  241. data/vendor/depot_tools/third_party/httplib2/socks.py +15 -5
  242. data/vendor/depot_tools/third_party/logilab/README.chromium +2 -4
  243. data/vendor/depot_tools/third_party/logilab/astroid/README.chromium +2 -1
  244. data/vendor/depot_tools/third_party/logilab/astroid/__init__.py +10 -5
  245. data/vendor/depot_tools/third_party/logilab/astroid/__pkginfo__.py +5 -5
  246. data/vendor/depot_tools/third_party/logilab/astroid/arguments.py +233 -0
  247. data/vendor/depot_tools/third_party/logilab/astroid/as_string.py +82 -33
  248. data/vendor/depot_tools/third_party/logilab/astroid/bases.py +137 -153
  249. data/vendor/depot_tools/third_party/logilab/astroid/brain/{builtin_inference.py → brain_builtin_inference.py} +117 -26
  250. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_dateutil.py +15 -0
  251. data/vendor/depot_tools/third_party/logilab/astroid/brain/{py2gi.py → brain_gi.py} +48 -8
  252. data/vendor/depot_tools/third_party/logilab/astroid/brain/{py2mechanize.py → brain_mechanize.py} +0 -0
  253. data/vendor/depot_tools/third_party/logilab/astroid/brain/{pynose.py → brain_nose.py} +4 -1
  254. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_numpy.py +62 -0
  255. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_pytest.py +76 -0
  256. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_qt.py +44 -0
  257. data/vendor/depot_tools/third_party/logilab/astroid/brain/{pysix_moves.py → brain_six.py} +28 -1
  258. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_ssl.py +65 -0
  259. data/vendor/depot_tools/third_party/logilab/astroid/brain/brain_stdlib.py +473 -0
  260. data/vendor/depot_tools/third_party/logilab/astroid/builder.py +104 -81
  261. data/vendor/depot_tools/third_party/logilab/astroid/context.py +81 -0
  262. data/vendor/depot_tools/third_party/logilab/astroid/decorators.py +75 -0
  263. data/vendor/depot_tools/third_party/logilab/astroid/exceptions.py +20 -0
  264. data/vendor/depot_tools/third_party/logilab/astroid/inference.py +137 -183
  265. data/vendor/depot_tools/third_party/logilab/astroid/manager.py +45 -169
  266. data/vendor/depot_tools/third_party/logilab/astroid/mixins.py +37 -14
  267. data/vendor/depot_tools/third_party/logilab/astroid/modutils.py +112 -41
  268. data/vendor/depot_tools/third_party/logilab/astroid/node_classes.py +243 -156
  269. data/vendor/depot_tools/third_party/logilab/astroid/nodes.py +35 -22
  270. data/vendor/depot_tools/third_party/logilab/astroid/objects.py +186 -0
  271. data/vendor/depot_tools/third_party/logilab/astroid/protocols.py +157 -102
  272. data/vendor/depot_tools/third_party/logilab/astroid/raw_building.py +32 -8
  273. data/vendor/depot_tools/third_party/logilab/astroid/rebuilder.py +372 -309
  274. data/vendor/depot_tools/third_party/logilab/astroid/scoped_nodes.py +652 -420
  275. data/vendor/depot_tools/third_party/logilab/astroid/test_utils.py +4 -21
  276. data/vendor/depot_tools/third_party/logilab/astroid/transforms.py +96 -0
  277. data/vendor/depot_tools/third_party/logilab/astroid/util.py +89 -0
  278. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/LICENSE +19 -0
  279. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/README.chromium +11 -0
  280. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/__init__.py +20 -0
  281. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/cext.c +1421 -0
  282. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/compat.py +9 -0
  283. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/simple.py +246 -0
  284. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/slots.py +414 -0
  285. data/vendor/depot_tools/third_party/logilab/lazy_object_proxy/utils.py +13 -0
  286. data/vendor/depot_tools/third_party/logilab/wrapt/LICENSE +24 -0
  287. data/vendor/depot_tools/third_party/logilab/wrapt/README.chromium +11 -0
  288. data/vendor/depot_tools/third_party/logilab/wrapt/__init__.py +19 -0
  289. data/vendor/depot_tools/third_party/logilab/wrapt/_wrappers.c +2729 -0
  290. data/vendor/depot_tools/third_party/logilab/wrapt/arguments.py +96 -0
  291. data/vendor/depot_tools/third_party/logilab/wrapt/decorators.py +512 -0
  292. data/vendor/depot_tools/third_party/logilab/wrapt/importer.py +228 -0
  293. data/vendor/depot_tools/third_party/logilab/wrapt/wrappers.py +901 -0
  294. data/vendor/depot_tools/third_party/pylint/README.chromium +2 -25
  295. data/vendor/depot_tools/third_party/pylint/__pkginfo__.py +13 -3
  296. data/vendor/depot_tools/third_party/pylint/checkers/__init__.py +1 -2
  297. data/vendor/depot_tools/third_party/pylint/checkers/async.py +82 -0
  298. data/vendor/depot_tools/third_party/pylint/checkers/base.py +893 -119
  299. data/vendor/depot_tools/third_party/pylint/checkers/classes.py +342 -204
  300. data/vendor/depot_tools/third_party/pylint/checkers/design_analysis.py +51 -34
  301. data/vendor/depot_tools/third_party/pylint/checkers/exceptions.py +84 -47
  302. data/vendor/depot_tools/third_party/pylint/checkers/format.py +55 -30
  303. data/vendor/depot_tools/third_party/pylint/checkers/imports.py +314 -73
  304. data/vendor/depot_tools/third_party/pylint/checkers/logging.py +10 -8
  305. data/vendor/depot_tools/third_party/pylint/checkers/misc.py +2 -1
  306. data/vendor/depot_tools/third_party/pylint/checkers/newstyle.py +45 -48
  307. data/vendor/depot_tools/third_party/pylint/checkers/python3.py +31 -21
  308. data/vendor/depot_tools/third_party/pylint/checkers/raw_metrics.py +3 -3
  309. data/vendor/depot_tools/third_party/pylint/checkers/similar.py +4 -5
  310. data/vendor/depot_tools/third_party/pylint/checkers/spelling.py +24 -10
  311. data/vendor/depot_tools/third_party/pylint/checkers/stdlib.py +120 -56
  312. data/vendor/depot_tools/third_party/pylint/checkers/strings.py +38 -35
  313. data/vendor/depot_tools/third_party/pylint/checkers/typecheck.py +485 -138
  314. data/vendor/depot_tools/third_party/pylint/checkers/utils.py +319 -142
  315. data/vendor/depot_tools/third_party/pylint/checkers/variables.py +329 -207
  316. data/vendor/depot_tools/third_party/pylint/config.py +739 -76
  317. data/vendor/depot_tools/third_party/pylint/epylint.py +9 -5
  318. data/vendor/depot_tools/third_party/pylint/extensions/__init__.py +0 -0
  319. data/vendor/depot_tools/third_party/pylint/extensions/check_docs.py +311 -0
  320. data/vendor/depot_tools/third_party/pylint/extensions/check_elif.py +62 -0
  321. data/vendor/depot_tools/third_party/{logilab/common → pylint}/graph.py +30 -133
  322. data/vendor/depot_tools/third_party/pylint/gui.py +2 -2
  323. data/vendor/depot_tools/third_party/pylint/interfaces.py +21 -3
  324. data/vendor/depot_tools/third_party/pylint/lint.py +123 -140
  325. data/vendor/depot_tools/third_party/pylint/pyreverse/diadefslib.py +10 -13
  326. data/vendor/depot_tools/third_party/pylint/pyreverse/diagrams.py +15 -4
  327. data/vendor/depot_tools/third_party/pylint/pyreverse/inspector.py +372 -0
  328. data/vendor/depot_tools/third_party/pylint/pyreverse/main.py +30 -7
  329. data/vendor/depot_tools/third_party/pylint/pyreverse/utils.py +80 -2
  330. data/vendor/depot_tools/third_party/{logilab/common → pylint/pyreverse}/vcgutils.py +19 -37
  331. data/vendor/depot_tools/third_party/pylint/pyreverse/writer.py +3 -4
  332. data/vendor/depot_tools/third_party/pylint/reporters/__init__.py +34 -18
  333. data/vendor/depot_tools/third_party/pylint/reporters/guireporter.py +1 -1
  334. data/vendor/depot_tools/third_party/pylint/reporters/html.py +10 -3
  335. data/vendor/depot_tools/third_party/pylint/reporters/json.py +10 -4
  336. data/vendor/depot_tools/third_party/pylint/reporters/text.py +94 -3
  337. data/vendor/depot_tools/third_party/pylint/reporters/ureports/__init__.py +106 -0
  338. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/html_writer.py +17 -57
  339. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/nodes.py +52 -74
  340. data/vendor/depot_tools/third_party/{logilab/common → pylint/reporters}/ureports/text_writer.py +14 -60
  341. data/vendor/depot_tools/third_party/pylint/testutils.py +22 -20
  342. data/vendor/depot_tools/third_party/pylint/utils.py +268 -44
  343. data/vendor/depot_tools/third_party/repo/progress.py +42 -0
  344. data/vendor/depot_tools/update_depot_tools +1 -1
  345. data/vendor/depot_tools/upload_metrics.py +25 -0
  346. data/vendor/depot_tools/win_toolchain/get_toolchain_if_necessary.py +45 -15
  347. data/vendor/depot_tools/win_toolchain/package_from_installed.py +71 -24
  348. data/vendor/depot_tools/yapf +1 -1
  349. data/vendor/depot_tools/yapf.bat +1 -1
  350. metadata +92 -77
  351. data/vendor/depot_tools/git-crsync +0 -3
  352. data/vendor/depot_tools/infra/config/cq.cfg +0 -32
  353. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/apply_gerrit_ref.json +0 -29
  354. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/apply_gerrit_ref_custom.json +0 -29
  355. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/buildbot.json +0 -105
  356. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/shallow.json +0 -195
  357. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_angle_deprecated.json +0 -248
  358. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/tryjob_gerrit_v8.json +0 -248
  359. data/vendor/depot_tools/recipes/recipe_modules/bot_update/examples/full.expected/with_manifest_name_no_patch.json +0 -105
  360. data/vendor/depot_tools/recipes/recipe_modules/bot_update/resources/apply_gerrit.py +0 -33
  361. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2pytest.py +0 -31
  362. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2qt4.py +0 -22
  363. data/vendor/depot_tools/third_party/logilab/astroid/brain/py2stdlib.py +0 -334
  364. data/vendor/depot_tools/third_party/logilab/astroid/inspector.py +0 -273
  365. data/vendor/depot_tools/third_party/logilab/astroid/utils.py +0 -239
  366. data/vendor/depot_tools/third_party/logilab/common/LICENSE.txt +0 -339
  367. data/vendor/depot_tools/third_party/logilab/common/README.chromium +0 -11
  368. data/vendor/depot_tools/third_party/logilab/common/__init__.py +0 -175
  369. data/vendor/depot_tools/third_party/logilab/common/__pkginfo__.py +0 -57
  370. data/vendor/depot_tools/third_party/logilab/common/cache.py +0 -114
  371. data/vendor/depot_tools/third_party/logilab/common/changelog.py +0 -238
  372. data/vendor/depot_tools/third_party/logilab/common/clcommands.py +0 -334
  373. data/vendor/depot_tools/third_party/logilab/common/cli.py +0 -211
  374. data/vendor/depot_tools/third_party/logilab/common/compat.py +0 -78
  375. data/vendor/depot_tools/third_party/logilab/common/configuration.py +0 -1105
  376. data/vendor/depot_tools/third_party/logilab/common/contexts.py +0 -5
  377. data/vendor/depot_tools/third_party/logilab/common/corbautils.py +0 -117
  378. data/vendor/depot_tools/third_party/logilab/common/daemon.py +0 -101
  379. data/vendor/depot_tools/third_party/logilab/common/date.py +0 -335
  380. data/vendor/depot_tools/third_party/logilab/common/dbf.py +0 -231
  381. data/vendor/depot_tools/third_party/logilab/common/debugger.py +0 -214
  382. data/vendor/depot_tools/third_party/logilab/common/decorators.py +0 -281
  383. data/vendor/depot_tools/third_party/logilab/common/deprecation.py +0 -189
  384. data/vendor/depot_tools/third_party/logilab/common/fileutils.py +0 -404
  385. data/vendor/depot_tools/third_party/logilab/common/interface.py +0 -71
  386. data/vendor/depot_tools/third_party/logilab/common/logging_ext.py +0 -195
  387. data/vendor/depot_tools/third_party/logilab/common/modutils.py +0 -702
  388. data/vendor/depot_tools/third_party/logilab/common/optik_ext.py +0 -392
  389. data/vendor/depot_tools/third_party/logilab/common/optparser.py +0 -92
  390. data/vendor/depot_tools/third_party/logilab/common/proc.py +0 -277
  391. data/vendor/depot_tools/third_party/logilab/common/pyro_ext.py +0 -180
  392. data/vendor/depot_tools/third_party/logilab/common/pytest.py +0 -1199
  393. data/vendor/depot_tools/third_party/logilab/common/registry.py +0 -1119
  394. data/vendor/depot_tools/third_party/logilab/common/shellutils.py +0 -462
  395. data/vendor/depot_tools/third_party/logilab/common/sphinx_ext.py +0 -87
  396. data/vendor/depot_tools/third_party/logilab/common/sphinxutils.py +0 -122
  397. data/vendor/depot_tools/third_party/logilab/common/table.py +0 -929
  398. data/vendor/depot_tools/third_party/logilab/common/tasksqueue.py +0 -101
  399. data/vendor/depot_tools/third_party/logilab/common/testlib.py +0 -1392
  400. data/vendor/depot_tools/third_party/logilab/common/textutils.py +0 -537
  401. data/vendor/depot_tools/third_party/logilab/common/tree.py +0 -369
  402. data/vendor/depot_tools/third_party/logilab/common/umessage.py +0 -194
  403. data/vendor/depot_tools/third_party/logilab/common/ureports/__init__.py +0 -172
  404. data/vendor/depot_tools/third_party/logilab/common/ureports/docbook_writer.py +0 -140
  405. data/vendor/depot_tools/third_party/logilab/common/urllib2ext.py +0 -89
  406. data/vendor/depot_tools/third_party/logilab/common/visitor.py +0 -109
  407. data/vendor/depot_tools/third_party/logilab/common/xmlrpcutils.py +0 -131
  408. data/vendor/depot_tools/third_party/logilab/common/xmlutils.py +0 -61
@@ -15,26 +15,23 @@
15
15
  # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
16
  """Checkers for various standard library functions."""
17
17
 
18
- import six
19
18
  import sys
20
19
 
20
+ import six
21
+
21
22
  import astroid
22
23
  from astroid.bases import Instance
23
-
24
24
  from pylint.interfaces import IAstroidChecker
25
25
  from pylint.checkers import BaseChecker
26
26
  from pylint.checkers import utils
27
27
 
28
28
 
29
- TYPECHECK_COMPARISON_OPERATORS = frozenset(('is', 'is not', '==', '!=', 'in', 'not in'))
30
- LITERAL_NODE_TYPES = (astroid.Const, astroid.Dict, astroid.List, astroid.Set)
31
-
29
+ OPEN_FILES = {'open', 'file'}
30
+ UNITTEST_CASE = 'unittest.case'
32
31
  if sys.version_info >= (3, 0):
33
32
  OPEN_MODULE = '_io'
34
- TYPE_QNAME = 'builtins.type'
35
33
  else:
36
34
  OPEN_MODULE = '__builtin__'
37
- TYPE_QNAME = '__builtin__.type'
38
35
 
39
36
 
40
37
  def _check_mode_str(mode):
@@ -79,15 +76,6 @@ def _check_mode_str(mode):
79
76
  return True
80
77
 
81
78
 
82
- def _is_one_arg_pos_call(call):
83
- """Is this a call with exactly 1 argument,
84
- where that argument is positional?
85
- """
86
- return (isinstance(call, astroid.CallFunc)
87
- and len(call.args) == 1
88
- and not isinstance(call.args[0], astroid.Keyword))
89
-
90
-
91
79
  class StdlibChecker(BaseChecker):
92
80
  __implements__ = (IAstroidChecker,)
93
81
  name = 'stdlib'
@@ -112,25 +100,98 @@ class StdlibChecker(BaseChecker):
112
100
  'a condition. If a constant is passed as parameter, that '
113
101
  'condition will be always true. In this case a warning '
114
102
  'should be emitted.'),
115
- 'W1504': ('Using type() instead of isinstance() for a typecheck.',
116
- 'unidiomatic-typecheck',
117
- 'The idiomatic way to perform an explicit typecheck in '
118
- 'Python is to use isinstance(x, Y) rather than '
119
- 'type(x) == Y, type(x) is Y. Though there are unusual '
120
- 'situations where these give different results.')
103
+ 'W1505': ('Using deprecated method %s()',
104
+ 'deprecated-method',
105
+ 'The method is marked as deprecated and will be removed in '
106
+ 'a future version of Python. Consider looking for an '
107
+ 'alternative in the documentation.'),
121
108
  }
122
109
 
123
- @utils.check_messages('bad-open-mode', 'redundant-unittest-assert')
124
- def visit_callfunc(self, node):
110
+ deprecated = {
111
+ 0: [
112
+ 'cgi.parse_qs', 'cgi.parse_qsl',
113
+ 'ctypes.c_buffer',
114
+ 'distutils.command.register.register.check_metadata',
115
+ 'distutils.command.sdist.sdist.check_metadata',
116
+ 'tkinter.Misc.tk_menuBar',
117
+ 'tkinter.Menu.tk_bindForTraversal',
118
+ ],
119
+ 2: {
120
+ (2, 6): [
121
+ 'commands.getstatus',
122
+ 'os.popen2',
123
+ 'os.popen3',
124
+ 'os.popen4',
125
+ 'macostools.touched',
126
+ ],
127
+ (2, 7): [
128
+ 'unittest.case.TestCase.assertEquals',
129
+ 'unittest.case.TestCase.assertNotEquals',
130
+ 'unittest.case.TestCase.assertAlmostEquals',
131
+ 'unittest.case.TestCase.assertNotAlmostEquals',
132
+ 'unittest.case.TestCase.assert_',
133
+ 'xml.etree.ElementTree.Element.getchildren',
134
+ 'xml.etree.ElementTree.Element.getiterator',
135
+ 'xml.etree.ElementTree.XMLParser.getiterator',
136
+ 'xml.etree.ElementTree.XMLParser.doctype',
137
+ ],
138
+ },
139
+ 3: {
140
+ (3, 0): [
141
+ 'inspect.getargspec',
142
+ 'unittest.case.TestCase._deprecate.deprecated_func',
143
+ ],
144
+ (3, 1): [
145
+ 'base64.encodestring', 'base64.decodestring',
146
+ 'ntpath.splitunc',
147
+ ],
148
+ (3, 2): [
149
+ 'cgi.escape',
150
+ 'configparser.RawConfigParser.readfp',
151
+ 'xml.etree.ElementTree.Element.getchildren',
152
+ 'xml.etree.ElementTree.Element.getiterator',
153
+ 'xml.etree.ElementTree.XMLParser.getiterator',
154
+ 'xml.etree.ElementTree.XMLParser.doctype',
155
+ ],
156
+ (3, 3): [
157
+ 'inspect.getmoduleinfo', 'inspect.getmodulename',
158
+ 'logging.warn', 'logging.Logger.warn',
159
+ 'logging.LoggerAdapter.warn',
160
+ 'nntplib._NNTPBase.xpath',
161
+ 'platform.popen',
162
+ ],
163
+ (3, 4): [
164
+ 'asyncio.tasks.async',
165
+ 'importlib.find_loader',
166
+ 'plistlib.readPlist', 'plistlib.writePlist',
167
+ 'plistlib.readPlistFromBytes',
168
+ 'plistlib.writePlistToBytes',
169
+ 'xml.etree.ElementTree.iterparse',
170
+ ],
171
+ (3, 5): [
172
+ 'fractions.gcd',
173
+ 'inspect.getfullargspec', 'inspect.getargvalues',
174
+ 'inspect.formatargspec', 'inspect.formatargvalues',
175
+ 'inspect.getcallargs',
176
+ 'platform.linux_distribution', 'platform.dist',
177
+ ],
178
+ },
179
+ }
180
+
181
+ @utils.check_messages('bad-open-mode', 'redundant-unittest-assert',
182
+ 'deprecated-method')
183
+ def visit_call(self, node):
125
184
  """Visit a CallFunc node."""
126
- if hasattr(node, 'func'):
127
- infer = utils.safe_infer(node.func)
128
- if infer:
129
- if infer.root().name == OPEN_MODULE:
130
- if getattr(node.func, 'name', None) in ('open', 'file'):
185
+ try:
186
+ for inferred in node.func.infer():
187
+ if inferred.root().name == OPEN_MODULE:
188
+ if getattr(node.func, 'name', None) in OPEN_FILES:
131
189
  self._check_open_mode(node)
132
- if infer.root().name == 'unittest.case':
133
- self._check_redundant_assert(node, infer)
190
+ if inferred.root().name == UNITTEST_CASE:
191
+ self._check_redundant_assert(node, inferred)
192
+ self._check_deprecated_method(node, inferred)
193
+ except astroid.InferenceError:
194
+ return
134
195
 
135
196
  @utils.check_messages('boolean-datetime')
136
197
  def visit_unaryop(self, node):
@@ -150,13 +211,34 @@ class StdlibChecker(BaseChecker):
150
211
  for value in node.values:
151
212
  self._check_datetime(value)
152
213
 
153
- @utils.check_messages('unidiomatic-typecheck')
154
- def visit_compare(self, node):
155
- operator, right = node.ops[0]
156
- if operator in TYPECHECK_COMPARISON_OPERATORS:
157
- left = node.left
158
- if _is_one_arg_pos_call(left):
159
- self._check_type_x_is_y(node, left, operator, right)
214
+ def _check_deprecated_method(self, node, inferred):
215
+ py_vers = sys.version_info[0]
216
+
217
+ if isinstance(node.func, astroid.Attribute):
218
+ func_name = node.func.attrname
219
+ elif isinstance(node.func, astroid.Name):
220
+ func_name = node.func.name
221
+ else:
222
+ # Not interested in other nodes.
223
+ return
224
+
225
+ # Reject nodes which aren't of interest to us.
226
+ acceptable_nodes = (astroid.BoundMethod,
227
+ astroid.UnboundMethod,
228
+ astroid.FunctionDef)
229
+ if not isinstance(inferred, acceptable_nodes):
230
+ return
231
+
232
+ qname = inferred.qname()
233
+ if qname in self.deprecated[0]:
234
+ self.add_message('deprecated-method', node=node,
235
+ args=(func_name, ))
236
+ else:
237
+ for since_vers, func_list in self.deprecated[py_vers].items():
238
+ if since_vers <= sys.version_info and qname in func_list:
239
+ self.add_message('deprecated-method', node=node,
240
+ args=(func_name, ))
241
+ break
160
242
 
161
243
  def _check_redundant_assert(self, node, infer):
162
244
  if (isinstance(infer, astroid.BoundMethod) and
@@ -192,24 +274,6 @@ class StdlibChecker(BaseChecker):
192
274
  self.add_message('bad-open-mode', node=node,
193
275
  args=mode_arg.value)
194
276
 
195
- def _check_type_x_is_y(self, node, left, operator, right):
196
- """Check for expressions like type(x) == Y."""
197
- left_func = utils.safe_infer(left.func)
198
- if not (isinstance(left_func, astroid.Class)
199
- and left_func.qname() == TYPE_QNAME):
200
- return
201
-
202
- if operator in ('is', 'is not') and _is_one_arg_pos_call(right):
203
- right_func = utils.safe_infer(right.func)
204
- if (isinstance(right_func, astroid.Class)
205
- and right_func.qname() == TYPE_QNAME):
206
- # type(x) == type(a)
207
- right_arg = utils.safe_infer(right.args[0])
208
- if not isinstance(right_arg, LITERAL_NODE_TYPES):
209
- # not e.g. type(x) == type([])
210
- return
211
- self.add_message('unidiomatic-typecheck', node=node)
212
-
213
277
 
214
278
  def register(linter):
215
279
  """required method to auto register this checker """
@@ -23,15 +23,14 @@ import tokenize
23
23
  import string
24
24
  import numbers
25
25
 
26
- import astroid
26
+ import six
27
27
 
28
+ import astroid
28
29
  from pylint.interfaces import ITokenChecker, IAstroidChecker, IRawChecker
29
30
  from pylint.checkers import BaseChecker, BaseTokenChecker
30
31
  from pylint.checkers import utils
31
32
  from pylint.checkers.utils import check_messages
32
33
 
33
- import six
34
-
35
34
 
36
35
  _PY3K = sys.version_info[:2] >= (3, 0)
37
36
  _PY27 = sys.version_info[:2] == (2, 7)
@@ -62,7 +61,7 @@ MSGS = {
62
61
  'W1301': ("Unused key %r in format string dictionary",
63
62
  "unused-format-string-key",
64
63
  "Used when a format string that uses named conversion specifiers \
65
- is used with a dictionary that conWtains keys not required by the \
64
+ is used with a dictionary that contains keys not required by the \
66
65
  format string."),
67
66
  'E1304': ("Missing key %r in format string dictionary",
68
67
  "missing-format-string-key",
@@ -77,7 +76,10 @@ MSGS = {
77
76
  "too-few-format-args",
78
77
  "Used when a format string that uses unnamed conversion \
79
78
  specifiers is given too few arguments"),
80
-
79
+ 'E1310': ("Suspicious argument in %s.%s call",
80
+ "bad-str-strip-call",
81
+ "The argument to a str.{l,r,}strip call contains a"
82
+ " duplicate character, "),
81
83
  'W1302': ("Invalid format string",
82
84
  "bad-format-string",
83
85
  "Used when a PEP 3101 format string is invalid.",
@@ -114,12 +116,12 @@ MSGS = {
114
116
  {'minversion': (2, 7)})
115
117
  }
116
118
 
117
- OTHER_NODES = (astroid.Const, astroid.List, astroid.Backquote,
118
- astroid.Lambda, astroid.Function,
119
- astroid.ListComp, astroid.SetComp, astroid.GenExpr)
119
+ OTHER_NODES = (astroid.Const, astroid.List, astroid.Repr,
120
+ astroid.Lambda, astroid.FunctionDef,
121
+ astroid.ListComp, astroid.SetComp, astroid.GeneratorExp)
120
122
 
121
123
  if _PY3K:
122
- import _string
124
+ import _string # pylint: disable=wrong-import-position, wrong-import-order
123
125
 
124
126
  def split_format_field_names(format_string):
125
127
  return _string.formatter_field_name_split(format_string)
@@ -157,9 +159,18 @@ def collect_string_fields(format_string):
157
159
  if nested:
158
160
  for field in collect_string_fields(nested):
159
161
  yield field
160
- except ValueError:
161
- # probably the format string is invalid
162
- # should we check the argument of the ValueError?
162
+ except ValueError as exc:
163
+ # Probably the format string is invalid.
164
+ if exc.args[0].startswith("cannot switch from manual"):
165
+ # On Jython, parsing a string with both manual
166
+ # and automatic positions will fail with a ValueError,
167
+ # while on CPython it will simply return the fields,
168
+ # the validation being done in the interpreter (?).
169
+ # We're just returning two mixed fields in order
170
+ # to trigger the format-combined-specification check.
171
+ yield ""
172
+ yield "1"
173
+ return
163
174
  raise utils.IncompleteFormatString(format_string)
164
175
 
165
176
  def parse_format_method_string(format_string):
@@ -189,19 +200,18 @@ def parse_format_method_string(format_string):
189
200
  return keys, num_args, len(manual_pos_arg)
190
201
 
191
202
  def get_args(callfunc):
192
- """ Get the arguments from the given `CallFunc` node.
203
+ """Get the arguments from the given `CallFunc` node.
204
+
193
205
  Return a tuple, where the first element is the
194
206
  number of positional arguments and the second element
195
207
  is the keyword arguments in a dict.
196
208
  """
197
- positional = 0
198
- named = {}
199
-
200
- for arg in callfunc.args:
201
- if isinstance(arg, astroid.Keyword):
202
- named[arg.arg] = utils.safe_infer(arg.value)
203
- else:
204
- positional += 1
209
+ if callfunc.keywords:
210
+ named = {arg.arg: utils.safe_infer(arg.value)
211
+ for arg in callfunc.keywords}
212
+ else:
213
+ named = {}
214
+ positional = len(callfunc.args)
205
215
  return positional, named
206
216
 
207
217
  def get_access_path(key, parts):
@@ -312,18 +322,8 @@ class StringFormatChecker(BaseChecker):
312
322
  self.add_message('too-few-format-args', node=node)
313
323
 
314
324
 
315
- class StringMethodsChecker(BaseChecker):
316
- __implements__ = (IAstroidChecker,)
317
- name = 'string'
318
- msgs = {
319
- 'E1310': ("Suspicious argument in %s.%s call",
320
- "bad-str-strip-call",
321
- "The argument to a str.{l,r,}strip call contains a"
322
- " duplicate character, "),
323
- }
324
-
325
325
  @check_messages(*(MSGS.keys()))
326
- def visit_callfunc(self, node):
326
+ def visit_call(self, node):
327
327
  func = utils.safe_infer(node.func)
328
328
  if (isinstance(func, astroid.BoundMethod)
329
329
  and isinstance(func.bound, astroid.Instance)
@@ -352,7 +352,7 @@ class StringMethodsChecker(BaseChecker):
352
352
  #
353
353
  # fmt = 'some string {}'.format
354
354
  # fmt('arg')
355
- if (isinstance(node.func, astroid.Getattr)
355
+ if (isinstance(node.func, astroid.Attribute)
356
356
  and not isinstance(node.func.expr, astroid.Const)):
357
357
  return
358
358
  try:
@@ -361,8 +361,10 @@ class StringMethodsChecker(BaseChecker):
361
361
  return
362
362
  if not isinstance(strnode, astroid.Const):
363
363
  return
364
+ if not isinstance(strnode.value, six.string_types):
365
+ return
366
+
364
367
  if node.starargs or node.kwargs:
365
- # TODO: Don't complicate the logic, skip these for now.
366
368
  return
367
369
  try:
368
370
  positional, named = get_args(node)
@@ -482,6 +484,8 @@ class StringMethodsChecker(BaseChecker):
482
484
  previous = previous.getitem(specifier)
483
485
  except (IndexError, TypeError):
484
486
  warn_error = True
487
+ except astroid.InferenceError:
488
+ break
485
489
  else:
486
490
  try:
487
491
  # Lookup __getitem__ in the current node,
@@ -611,5 +615,4 @@ class StringConstantChecker(BaseTokenChecker):
611
615
  def register(linter):
612
616
  """required method to auto register this checker """
613
617
  linter.register_checker(StringFormatChecker(linter))
614
- linter.register_checker(StringMethodsChecker(linter))
615
618
  linter.register_checker(StringConstantChecker(linter))
@@ -16,18 +16,79 @@
16
16
  """try to find more bugs in the code using astroid inference capabilities
17
17
  """
18
18
 
19
+ import collections
20
+ import fnmatch
19
21
  import re
20
22
  import shlex
23
+ import sys
24
+
25
+ import six
21
26
 
22
27
  import astroid
23
- from astroid import InferenceError, NotFoundError, YES, Instance
24
- from astroid.bases import BUILTINS
28
+ import astroid.context
29
+ import astroid.arguments
30
+ from astroid import exceptions
31
+ from astroid import objects
32
+ from astroid import bases
25
33
 
26
34
  from pylint.interfaces import IAstroidChecker, INFERENCE, INFERENCE_FAILURE
27
35
  from pylint.checkers import BaseChecker
28
36
  from pylint.checkers.utils import (
29
- safe_infer, is_super,
30
- check_messages, decorated_with_property)
37
+ is_super, check_messages, decorated_with_property,
38
+ decorated_with, node_ignores_exception,
39
+ is_iterable, is_mapping, supports_membership_test,
40
+ is_comprehension, is_inside_abstract_class,
41
+ supports_subscript,
42
+ safe_infer,
43
+ has_known_bases)
44
+ from pylint import utils
45
+
46
+
47
+ _ZOPE_DEPRECATED = (
48
+ "This option is deprecated. Use generated-members instead."
49
+ )
50
+ BUILTINS = six.moves.builtins.__name__
51
+ STR_FORMAT = "%s.str.format" % BUILTINS
52
+
53
+
54
+ def _unflatten(iterable):
55
+ for index, elem in enumerate(iterable):
56
+ if (isinstance(elem, collections.Sequence) and
57
+ not isinstance(elem, six.string_types)):
58
+ for elem in _unflatten(elem):
59
+ yield elem
60
+ elif elem and not index:
61
+ # We're interested only in the first element.
62
+ yield elem
63
+
64
+
65
+ def _is_owner_ignored(owner, name, ignored_classes, ignored_modules):
66
+ """Check if the given owner should be ignored
67
+
68
+ This will verify if the owner's module is in *ignored_modules*
69
+ or the owner's module fully qualified name is in *ignored_modules*
70
+ or if the *ignored_modules* contains a pattern which catches
71
+ the fully qualified name of the module.
72
+
73
+ Also, similar checks are done for the owner itself, if its name
74
+ matches any name from the *ignored_classes* or if its qualified
75
+ name can be found in *ignored_classes*.
76
+ """
77
+ ignored_modules = set(ignored_modules)
78
+ module_name = owner.root().name
79
+ module_qname = owner.root().qname()
80
+ if any(module_name in ignored_modules or
81
+ module_qname in ignored_modules or
82
+ fnmatch.fnmatch(module_qname, ignore) for ignore in ignored_modules):
83
+ return True
84
+
85
+ ignored_classes = set(ignored_classes)
86
+ if hasattr(owner, 'qname'):
87
+ qname = owner.qname()
88
+ else:
89
+ qname = ''
90
+ return any(name == ignore or qname == ignore for ignore in ignored_classes)
91
+
31
92
 
32
93
  MSGS = {
33
94
  'E1101': ('%s %r has no %r member',
@@ -42,11 +103,6 @@ MSGS = {
42
103
  'assignment-from-no-return',
43
104
  'Used when an assignment is done on a function call but the \
44
105
  inferred function doesn\'t return anything.'),
45
- 'W1111': ('Assigning to function call which only returns None',
46
- 'assignment-from-none',
47
- 'Used when an assignment is done on a function call but the \
48
- inferred function returns nothing but None.'),
49
-
50
106
  'E1120': ('No value for argument %s in %s call',
51
107
  'no-value-for-parameter',
52
108
  'Used when a function call passes too few arguments.'),
@@ -77,12 +133,81 @@ MSGS = {
77
133
  'invalid-slice-index',
78
134
  'Used when a slice index is not an integer, None, or an object \
79
135
  with an __index__ method.'),
136
+ 'E1128': ('Assigning to function call which only returns None',
137
+ 'assignment-from-none',
138
+ 'Used when an assignment is done on a function call but the '
139
+ 'inferred function returns nothing but None.',
140
+ {'old_names': [('W1111', 'assignment-from-none')]}),
141
+ 'E1129': ("Context manager '%s' doesn't implement __enter__ and __exit__.",
142
+ 'not-context-manager',
143
+ 'Used when an instance in a with statement doesn\'t implement '
144
+ 'the context manager protocol(__enter__/__exit__).'),
145
+ 'E1130': ('%s',
146
+ 'invalid-unary-operand-type',
147
+ 'Emitted when an unary operand is used on an object which does not '
148
+ 'support this type of operation'),
149
+ 'E1131': ('%s',
150
+ 'unsupported-binary-operation',
151
+ 'Emitted when a binary arithmetic operation between two '
152
+ 'operands is not supported.'),
153
+ 'E1132': ('Got multiple values for keyword argument %r in function call',
154
+ 'repeated-keyword',
155
+ 'Emitted when a function call got multiple values for a keyword.'),
156
+ 'E1135': ("Value '%s' doesn't support membership test",
157
+ 'unsupported-membership-test',
158
+ 'Emitted when an instance in membership test expression doesn\'t'
159
+ 'implement membership protocol (__contains__/__iter__/__getitem__)'),
160
+ 'E1136': ("Value '%s' is unsubscriptable",
161
+ 'unsubscriptable-object',
162
+ "Emitted when a subscripted value doesn't support subscription"
163
+ "(i.e. doesn't define __getitem__ method)"),
80
164
  }
81
165
 
82
166
  # builtin sequence types in Python 2 and 3.
83
167
  SEQUENCE_TYPES = set(['str', 'unicode', 'list', 'tuple', 'bytearray',
84
168
  'xrange', 'range', 'bytes', 'memoryview'])
85
169
 
170
+
171
+ def _emit_no_member(node, owner, owner_name, ignored_mixins):
172
+ """Try to see if no-member should be emitted for the given owner.
173
+
174
+ The following cases are ignored:
175
+
176
+ * the owner is a function and it has decorators.
177
+ * the owner is an instance and it has __getattr__, __getattribute__ implemented
178
+ * the module is explicitly ignored from no-member checks
179
+ * the owner is a class and the name can be found in its metaclass.
180
+ * The access node is protected by an except handler, which handles
181
+ AttributeError, Exception or bare except.
182
+ """
183
+ if node_ignores_exception(node, AttributeError):
184
+ return False
185
+ # skip None anyway
186
+ if isinstance(owner, astroid.Const) and owner.value is None:
187
+ return False
188
+ if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
189
+ return False
190
+ if ignored_mixins and owner_name[-5:].lower() == 'mixin':
191
+ return False
192
+ if isinstance(owner, astroid.FunctionDef) and owner.decorators:
193
+ return False
194
+ if isinstance(owner, astroid.Instance):
195
+ if owner.has_dynamic_getattr() or not has_known_bases(owner):
196
+ return False
197
+ if isinstance(owner, objects.Super):
198
+ # Verify if we are dealing with an invalid Super object.
199
+ # If it is invalid, then there's no point in checking that
200
+ # it has the required attribute. Also, don't fail if the
201
+ # MRO is invalid.
202
+ try:
203
+ owner.super_mro()
204
+ except (exceptions.MroError, exceptions.SuperError):
205
+ return False
206
+ if not all(map(has_known_bases, owner.type.mro())):
207
+ return False
208
+ return True
209
+
210
+
86
211
  def _determine_callable(callable_obj):
87
212
  # Ordering is important, since BoundMethod is a subclass of UnboundMethod,
88
213
  # and Function inherits Lambda.
@@ -91,31 +216,36 @@ def _determine_callable(callable_obj):
91
216
  return callable_obj, 1, callable_obj.type
92
217
  elif isinstance(callable_obj, astroid.UnboundMethod):
93
218
  return callable_obj, 0, 'unbound method'
94
- elif isinstance(callable_obj, astroid.Function):
219
+ elif isinstance(callable_obj, astroid.FunctionDef):
95
220
  return callable_obj, 0, callable_obj.type
96
221
  elif isinstance(callable_obj, astroid.Lambda):
97
222
  return callable_obj, 0, 'lambda'
98
- elif isinstance(callable_obj, astroid.Class):
223
+ elif isinstance(callable_obj, astroid.ClassDef):
99
224
  # Class instantiation, lookup __new__ instead.
100
225
  # If we only find object.__new__, we can safely check __init__
101
- # instead.
226
+ # instead. If __new__ belongs to builtins, then we look
227
+ # again for __init__ in the locals, since we won't have
228
+ # argument information for the builtin __new__ function.
102
229
  try:
103
230
  # Use the last definition of __new__.
104
231
  new = callable_obj.local_attr('__new__')[-1]
105
- except astroid.NotFoundError:
232
+ except exceptions.NotFoundError:
106
233
  new = None
107
234
 
108
- if not new or new.parent.scope().name == 'object':
235
+ from_object = new and new.parent.scope().name == 'object'
236
+ from_builtins = new and new.root().name in sys.builtin_module_names
237
+
238
+ if not new or from_object or from_builtins:
109
239
  try:
110
240
  # Use the last definition of __init__.
111
241
  callable_obj = callable_obj.local_attr('__init__')[-1]
112
- except astroid.NotFoundError:
242
+ except exceptions.NotFoundError:
113
243
  # do nothing, covered by no-init.
114
244
  raise ValueError
115
245
  else:
116
246
  callable_obj = new
117
247
 
118
- if not isinstance(callable_obj, astroid.Function):
248
+ if not isinstance(callable_obj, astroid.FunctionDef):
119
249
  raise ValueError
120
250
  # both have an extra implicit 'cls'/'self' argument.
121
251
  return callable_obj, 1, 'constructor'
@@ -144,93 +274,87 @@ class should be ignored. A mixin class is detected if its name ends with \
144
274
  {'default': (),
145
275
  'type': 'csv',
146
276
  'metavar': '<module names>',
147
- 'help': 'List of module names for which member attributes \
148
- should not be checked (useful for modules/projects where namespaces are \
149
- manipulated during runtime and thus existing member attributes cannot be \
150
- deduced by static analysis'},
277
+ 'help': 'List of module names for which member attributes '
278
+ 'should not be checked (useful for modules/projects '
279
+ 'where namespaces are manipulated during runtime and '
280
+ 'thus existing member attributes cannot be '
281
+ 'deduced by static analysis. It supports qualified '
282
+ 'module names, as well as Unix pattern matching.'}
151
283
  ),
152
284
  ('ignored-classes',
153
- {'default' : ('SQLObject',),
285
+ {'default' : (),
154
286
  'type' : 'csv',
155
287
  'metavar' : '<members names>',
156
- 'help' : 'List of classes names for which member attributes \
157
- should not be checked (useful for classes with attributes dynamically set).'}
288
+ 'help' : 'List of classes names for which member attributes '
289
+ 'should not be checked (useful for classes with '
290
+ 'attributes dynamically set). This supports '
291
+ 'can work with qualified names.'}
158
292
  ),
159
293
 
160
- ('zope',
161
- {'default' : False, 'type' : 'yn', 'metavar': '<y_or_n>',
162
- 'help' : 'When zope mode is activated, add a predefined set \
163
- of Zope acquired attributes to generated-members.'}
164
- ),
294
+ ('zope', utils.deprecated_option(opt_type='yn',
295
+ help_msg=_ZOPE_DEPRECATED)),
296
+
165
297
  ('generated-members',
166
- {'default' : ('REQUEST', 'acl_users', 'aq_parent'),
298
+ {'default' : (),
167
299
  'type' : 'string',
168
300
  'metavar' : '<members names>',
169
301
  'help' : 'List of members which are set dynamically and \
170
- missed by pylint inference system, and so shouldn\'t trigger E0201 when \
302
+ missed by pylint inference system, and so shouldn\'t trigger E1101 when \
171
303
  accessed. Python regular expressions are accepted.'}
172
304
  ),
173
305
  )
174
306
 
175
307
  def open(self):
176
308
  # do this in open since config not fully initialized in __init__
177
- self.generated_members = list(self.config.generated_members)
178
- if self.config.zope:
179
- self.generated_members.extend(('REQUEST', 'acl_users', 'aq_parent'))
309
+ # generated_members may contain regular expressions
310
+ # (surrounded by quote `"` and followed by a comma `,`)
311
+ # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' =>
312
+ # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}')
313
+ if isinstance(self.config.generated_members, six.string_types):
314
+ gen = shlex.shlex(self.config.generated_members)
315
+ gen.whitespace += ','
316
+ gen.wordchars += '[]-+'
317
+ self.config.generated_members = tuple(tok.strip('"') for tok in gen)
180
318
 
181
- def visit_assattr(self, node):
182
- if isinstance(node.ass_type(), astroid.AugAssign):
183
- self.visit_getattr(node)
319
+ def visit_assignattr(self, node):
320
+ if isinstance(node.assign_type(), astroid.AugAssign):
321
+ self.visit_attribute(node)
184
322
 
185
323
  def visit_delattr(self, node):
186
- self.visit_getattr(node)
324
+ self.visit_attribute(node)
187
325
 
188
326
  @check_messages('no-member')
189
- def visit_getattr(self, node):
327
+ def visit_attribute(self, node):
190
328
  """check that the accessed attribute exists
191
329
 
192
- to avoid to much false positives for now, we'll consider the code as
330
+ to avoid too much false positives for now, we'll consider the code as
193
331
  correct if a single of the inferred nodes has the accessed attribute.
194
332
 
195
333
  function/method, super call and metaclasses are ignored
196
334
  """
197
- # generated_members may containt regular expressions
198
- # (surrounded by quote `"` and followed by a comma `,`)
199
- # REQUEST,aq_parent,"[a-zA-Z]+_set{1,2}"' =>
200
- # ('REQUEST', 'aq_parent', '[a-zA-Z]+_set{1,2}')
201
- if isinstance(self.config.generated_members, str):
202
- gen = shlex.shlex(self.config.generated_members)
203
- gen.whitespace += ','
204
- gen.wordchars += '[]-+'
205
- self.config.generated_members = tuple(tok.strip('"') for tok in gen)
206
335
  for pattern in self.config.generated_members:
207
336
  # attribute is marked as generated, stop here
208
337
  if re.match(pattern, node.attrname):
209
338
  return
339
+
210
340
  try:
211
341
  infered = list(node.expr.infer())
212
- except InferenceError:
342
+ except exceptions.InferenceError:
213
343
  return
214
344
  # list of (node, nodename) which are missing the attribute
215
345
  missingattr = set()
216
- ignoremim = self.config.ignore_mixin_members
217
346
  inference_failure = False
218
347
  for owner in infered:
219
348
  # skip yes object
220
- if owner is YES:
349
+ if owner is astroid.YES:
221
350
  inference_failure = True
222
351
  continue
223
- # skip None anyway
224
- if isinstance(owner, astroid.Const) and owner.value is None:
225
- continue
226
- # XXX "super" / metaclass call
227
- if is_super(owner) or getattr(owner, 'type', None) == 'metaclass':
228
- continue
229
- name = getattr(owner, 'name', 'None')
230
- if name in self.config.ignored_classes:
231
- continue
232
- if ignoremim and name[-5:].lower() == 'mixin':
352
+
353
+ name = getattr(owner, 'name', None)
354
+ if _is_owner_ignored(owner, name, self.config.ignored_classes,
355
+ self.config.ignored_modules):
233
356
  continue
357
+
234
358
  try:
235
359
  if not [n for n in owner.getattr(node.attrname)
236
360
  if not isinstance(n.statement(), astroid.AugAssign)]:
@@ -239,28 +363,17 @@ accessed. Python regular expressions are accepted.'}
239
363
  except AttributeError:
240
364
  # XXX method / function
241
365
  continue
242
- except NotFoundError:
243
- if isinstance(owner, astroid.Function) and owner.decorators:
366
+ except exceptions.NotFoundError:
367
+ # This can't be moved before the actual .getattr call,
368
+ # because there can be more values inferred and we are
369
+ # stopping after the first one which has the attribute in question.
370
+ # The problem is that if the first one has the attribute,
371
+ # but we continue to the next values which doesn't have the
372
+ # attribute, then we'll have a false positive.
373
+ # So call this only after the call has been made.
374
+ if not _emit_no_member(node, owner, name,
375
+ self.config.ignore_mixin_members):
244
376
  continue
245
- if isinstance(owner, Instance) and owner.has_dynamic_getattr():
246
- continue
247
- # explicit skipping of module member access
248
- if owner.root().name in self.config.ignored_modules:
249
- continue
250
- if isinstance(owner, astroid.Class):
251
- # Look up in the metaclass only if the owner is itself
252
- # a class.
253
- # TODO: getattr doesn't return by default members
254
- # from the metaclass, because handling various cases
255
- # of methods accessible from the metaclass itself
256
- # and/or subclasses only is too complicated for little to
257
- # no benefit.
258
- metaclass = owner.metaclass()
259
- try:
260
- if metaclass and metaclass.getattr(node.attrname):
261
- continue
262
- except NotFoundError:
263
- pass
264
377
  missingattr.add((owner, name))
265
378
  continue
266
379
  # stop on the first found
@@ -270,7 +383,7 @@ accessed. Python regular expressions are accepted.'}
270
383
  # message for infered nodes
271
384
  done = set()
272
385
  for owner, name in missingattr:
273
- if isinstance(owner, Instance):
386
+ if isinstance(owner, astroid.Instance):
274
387
  actual = owner._proxied
275
388
  else:
276
389
  actual = owner
@@ -288,18 +401,18 @@ accessed. Python regular expressions are accepted.'}
288
401
  """check that if assigning to a function call, the function is
289
402
  possibly returning something valuable
290
403
  """
291
- if not isinstance(node.value, astroid.CallFunc):
404
+ if not isinstance(node.value, astroid.Call):
292
405
  return
293
406
  function_node = safe_infer(node.value.func)
294
407
  # skip class, generator and incomplete function definition
295
- if not (isinstance(function_node, astroid.Function) and
408
+ if not (isinstance(function_node, astroid.FunctionDef) and
296
409
  function_node.root().fully_defined()):
297
410
  return
298
411
  if function_node.is_generator() \
299
412
  or function_node.is_abstract(pass_is_abstract=False):
300
413
  return
301
414
  returns = list(function_node.nodes_of_class(astroid.Return,
302
- skip_klass=astroid.Function))
415
+ skip_klass=astroid.FunctionDef))
303
416
  if len(returns) == 0:
304
417
  self.add_message('assignment-from-no-return', node=node)
305
418
  else:
@@ -316,7 +429,7 @@ accessed. Python regular expressions are accepted.'}
316
429
  Check that the given uninferable CallFunc node does not
317
430
  call an actual function.
318
431
  """
319
- if not isinstance(node.func, astroid.Getattr):
432
+ if not isinstance(node.func, astroid.Attribute):
320
433
  return
321
434
 
322
435
  # Look for properties. First, obtain
@@ -335,13 +448,13 @@ accessed. Python regular expressions are accepted.'}
335
448
 
336
449
  try:
337
450
  attrs = klass._proxied.getattr(node.func.attrname)
338
- except astroid.NotFoundError:
451
+ except exceptions.NotFoundError:
339
452
  return
340
453
 
341
454
  for attr in attrs:
342
455
  if attr is astroid.YES:
343
456
  continue
344
- if not isinstance(attr, astroid.Function):
457
+ if not isinstance(attr, astroid.FunctionDef):
345
458
  continue
346
459
 
347
460
  # Decorated, see if it is decorated with a property.
@@ -355,21 +468,45 @@ accessed. Python regular expressions are accepted.'}
355
468
  args=node.func.as_string())
356
469
  break
357
470
 
471
+ @staticmethod
472
+ def _no_context_variadic(node):
473
+ """Verify if the given call node has variadic nodes without context
474
+
475
+ This is a workaround for handling cases of nested call functions
476
+ which don't have the specific call context at hand.
477
+ Variadic arguments (variable positional arguments and variable
478
+ keyword arguments) are inferred, inherently wrong, by astroid
479
+ as a Tuple, respectively a Dict with empty elements.
480
+ This can lead pylint to believe that a function call receives
481
+ too few arguments.
482
+ """
483
+ for arg in node.args:
484
+ if not isinstance(arg, astroid.Starred):
485
+ continue
486
+
487
+ inferred = safe_infer(arg.value)
488
+ if isinstance(inferred, astroid.Tuple):
489
+ length = len(inferred.elts)
490
+ elif isinstance(inferred, astroid.Dict):
491
+ length = len(inferred.items)
492
+ else:
493
+ return False
494
+ if not length and isinstance(inferred.statement(), astroid.FunctionDef):
495
+ return True
496
+ return False
497
+
358
498
  @check_messages(*(list(MSGS.keys())))
359
- def visit_callfunc(self, node):
499
+ def visit_call(self, node):
360
500
  """check that called functions/methods are inferred to callable objects,
361
501
  and that the arguments passed to the function match the parameters in
362
502
  the inferred function's definition
363
503
  """
364
504
  # Build the set of keyword arguments, checking for duplicate keywords,
365
505
  # and count the positional arguments.
366
- keyword_args = set()
367
- num_positional_args = 0
368
- for arg in node.args:
369
- if isinstance(arg, astroid.Keyword):
370
- keyword_args.add(arg.arg)
371
- else:
372
- num_positional_args += 1
506
+ call_site = astroid.arguments.CallSite.from_call(node)
507
+ num_positional_args = len(call_site.positional_arguments)
508
+ keyword_args = list(call_site.keyword_arguments.keys())
509
+ no_context_variadic = self._no_context_variadic(node)
373
510
 
374
511
  called = safe_infer(node.func)
375
512
  # only function, generator and object defining __call__ are allowed
@@ -385,14 +522,24 @@ accessed. Python regular expressions are accepted.'}
385
522
  # Any error occurred during determining the function type, most of
386
523
  # those errors are handled by different warnings.
387
524
  return
525
+
388
526
  num_positional_args += implicit_args
389
527
  if called.args.args is None:
390
528
  # Built-in functions have no argument information.
391
529
  return
392
530
 
393
531
  if len(called.argnames()) != len(set(called.argnames())):
394
- # Duplicate parameter name (see E9801). We can't really make sense
395
- # of the function call in this case, so just return.
532
+ # Duplicate parameter name (see duplicate-argument). We can't really
533
+ # make sense of the function call in this case, so just return.
534
+ return
535
+
536
+ # Warn about duplicated keyword arguments, such as `f=24, **{'f': 24}`
537
+ for keyword in call_site.duplicated_keywords:
538
+ self.add_message('repeated-keyword',
539
+ node=node, args=(keyword, ))
540
+
541
+ if call_site.has_invalid_arguments() or call_site.has_invalid_keywords():
542
+ # Can't make sense of this.
396
543
  return
397
544
 
398
545
  # Analyze the list of formal parameters.
@@ -405,13 +552,10 @@ accessed. Python regular expressions are accepted.'}
405
552
  # Don't store any parameter names within the tuple, since those
406
553
  # are not assignable from keyword arguments.
407
554
  else:
408
- if isinstance(arg, astroid.Keyword):
409
- name = arg.arg
410
- else:
411
- assert isinstance(arg, astroid.AssName)
412
- # This occurs with:
413
- # def f( (a), (b) ): pass
414
- name = arg.name
555
+ assert isinstance(arg, astroid.AssignName)
556
+ # This occurs with:
557
+ # def f( (a), (b) ): pass
558
+ name = arg.name
415
559
  parameter_name_to_index[name] = i
416
560
  if i >= num_mandatory_parameters:
417
561
  defval = called.args.defaults[i - num_mandatory_parameters]
@@ -424,7 +568,7 @@ accessed. Python regular expressions are accepted.'}
424
568
  if isinstance(arg, astroid.Keyword):
425
569
  name = arg.arg
426
570
  else:
427
- assert isinstance(arg, astroid.AssName)
571
+ assert isinstance(arg, astroid.AssignName)
428
572
  name = arg.name
429
573
  kwparams[name] = [called.args.kw_defaults[i], False]
430
574
 
@@ -450,8 +594,15 @@ accessed. Python regular expressions are accepted.'}
450
594
  i = parameter_name_to_index[keyword]
451
595
  if parameters[i][1]:
452
596
  # Duplicate definition of function parameter.
453
- self.add_message('redundant-keyword-arg',
454
- node=node, args=(keyword, callable_name))
597
+
598
+ # Might be too hardcoded, but this can actually
599
+ # happen when using str.format and `self` is passed
600
+ # by keyword argument, as in `.format(self=self)`.
601
+ # It's perfectly valid to so, so we're just skipping
602
+ # it if that's the case.
603
+ if not (keyword == 'self' and called.qname() == STR_FORMAT):
604
+ self.add_message('redundant-keyword-arg',
605
+ node=node, args=(keyword, callable_name))
455
606
  else:
456
607
  parameters[i][1] = True
457
608
  elif keyword in kwparams:
@@ -469,24 +620,8 @@ accessed. Python regular expressions are accepted.'}
469
620
  self.add_message('unexpected-keyword-arg', node=node,
470
621
  args=(keyword, callable_name))
471
622
 
472
- # 3. Match the *args, if any. Note that Python actually processes
473
- # *args _before_ any keyword arguments, but we wait until after
474
- # looking at the keyword arguments so as to make a more conservative
475
- # guess at how many values are in the *args sequence.
476
- if node.starargs is not None:
477
- for i in range(num_positional_args, len(parameters)):
478
- [(name, defval), assigned] = parameters[i]
479
- # Assume that *args provides just enough values for all
480
- # non-default parameters after the last parameter assigned by
481
- # the positional arguments but before the first parameter
482
- # assigned by the keyword arguments. This is the best we can
483
- # get without generating any false positives.
484
- if (defval is not None) or assigned:
485
- break
486
- parameters[i][1] = True
487
-
488
- # 4. Match the **kwargs, if any.
489
- if node.kwargs is not None:
623
+ # 3. Match the **kwargs, if any.
624
+ if node.kwargs:
490
625
  for i, [(name, defval), assigned] in enumerate(parameters):
491
626
  # Assume that *kwargs provides values for all remaining
492
627
  # unassigned named parameters.
@@ -504,8 +639,10 @@ accessed. Python regular expressions are accepted.'}
504
639
  display_name = '<tuple>'
505
640
  else:
506
641
  display_name = repr(name)
507
- self.add_message('no-value-for-parameter', node=node,
508
- args=(display_name, callable_name))
642
+ # TODO(cpopa): this should be removed after PyCQA/astroid/issues/177
643
+ if not no_context_variadic:
644
+ self.add_message('no-value-for-parameter', node=node,
645
+ args=(display_name, callable_name))
509
646
 
510
647
  for name in kwparams:
511
648
  defval, assigned = kwparams[name]
@@ -523,13 +660,11 @@ accessed. Python regular expressions are accepted.'}
523
660
  def visit_index(self, node):
524
661
  if not node.parent or not hasattr(node.parent, "value"):
525
662
  return
526
-
527
663
  # Look for index operations where the parent is a sequence type.
528
664
  # If the types can be determined, only allow indices to be int,
529
665
  # slice or instances with __index__.
530
-
531
666
  parent_type = safe_infer(node.parent.value)
532
- if not isinstance(parent_type, (astroid.Class, astroid.Instance)):
667
+ if not isinstance(parent_type, (astroid.ClassDef, astroid.Instance)):
533
668
  return
534
669
 
535
670
  # Determine what method on the parent this index will use
@@ -552,10 +687,9 @@ accessed. Python regular expressions are accepted.'}
552
687
  if methods is astroid.YES:
553
688
  return
554
689
  itemmethod = methods[0]
555
- except (astroid.NotFoundError, IndexError):
690
+ except (exceptions.NotFoundError, IndexError):
556
691
  return
557
-
558
- if not isinstance(itemmethod, astroid.Function):
692
+ if not isinstance(itemmethod, astroid.FunctionDef):
559
693
  return
560
694
  if itemmethod.root().name != BUILTINS:
561
695
  return
@@ -573,7 +707,6 @@ accessed. Python regular expressions are accepted.'}
573
707
  index_type = safe_infer(node)
574
708
  if index_type is None or index_type is astroid.YES:
575
709
  return
576
-
577
710
  # Constants must be of type int
578
711
  if isinstance(index_type, astroid.Const):
579
712
  if isinstance(index_type.value, int):
@@ -585,8 +718,13 @@ accessed. Python regular expressions are accepted.'}
585
718
  try:
586
719
  index_type.getattr('__index__')
587
720
  return
588
- except astroid.NotFoundError:
721
+ except exceptions.NotFoundError:
589
722
  pass
723
+ elif isinstance(index_type, astroid.Slice):
724
+ # Delegate to visit_slice. A slice can be present
725
+ # here after inferring the index node, which could
726
+ # be a `slice(...)` call for instance.
727
+ return self.visit_slice(index_type)
590
728
 
591
729
  # Anything else is an error
592
730
  self.add_message('invalid-sequence-index', node=node)
@@ -616,12 +754,221 @@ accessed. Python regular expressions are accepted.'}
616
754
  try:
617
755
  index_type.getattr('__index__')
618
756
  return
619
- except astroid.NotFoundError:
757
+ except exceptions.NotFoundError:
620
758
  pass
621
759
 
622
760
  # Anything else is an error
623
761
  self.add_message('invalid-slice-index', node=node)
624
762
 
763
+ @check_messages('not-context-manager')
764
+ def visit_with(self, node):
765
+ for ctx_mgr, _ in node.items:
766
+ context = astroid.context.InferenceContext()
767
+ infered = safe_infer(ctx_mgr, context=context)
768
+ if infered is None or infered is astroid.YES:
769
+ continue
770
+
771
+ if isinstance(infered, bases.Generator):
772
+ # Check if we are dealing with a function decorated
773
+ # with contextlib.contextmanager.
774
+ if decorated_with(infered.parent, ['contextlib.contextmanager']):
775
+ continue
776
+ # If the parent of the generator is not the context manager itself,
777
+ # that means that it could have been returned from another
778
+ # function which was the real context manager.
779
+ # The following approach is more of a hack rather than a real
780
+ # solution: walk all the inferred statements for the
781
+ # given *ctx_mgr* and if you find one function scope
782
+ # which is decorated, consider it to be the real
783
+ # manager and give up, otherwise emit not-context-manager.
784
+ # See the test file for not_context_manager for a couple
785
+ # of self explaining tests.
786
+ for path in six.moves.filter(None, _unflatten(context.path)):
787
+ scope = path.scope()
788
+ if not isinstance(scope, astroid.FunctionDef):
789
+ continue
790
+ if decorated_with(scope, ['contextlib.contextmanager']):
791
+ break
792
+ else:
793
+ self.add_message('not-context-manager',
794
+ node=node, args=(infered.name, ))
795
+ else:
796
+ try:
797
+ infered.getattr('__enter__')
798
+ infered.getattr('__exit__')
799
+ except exceptions.NotFoundError:
800
+ if isinstance(infered, astroid.Instance):
801
+ # If we do not know the bases of this class,
802
+ # just skip it.
803
+ if not has_known_bases(infered):
804
+ continue
805
+ # Just ignore mixin classes.
806
+ if self.config.ignore_mixin_members:
807
+ if infered.name[-5:].lower() == 'mixin':
808
+ continue
809
+
810
+ self.add_message('not-context-manager',
811
+ node=node, args=(infered.name, ))
812
+
813
+ # Disabled until we'll have a more capable astroid.
814
+ @check_messages('invalid-unary-operand-type')
815
+ def _visit_unaryop(self, node):
816
+ """Detect TypeErrors for unary operands."""
817
+
818
+ for error in node.type_errors():
819
+ # Let the error customize its output.
820
+ self.add_message('invalid-unary-operand-type',
821
+ args=str(error), node=node)
822
+
823
+ @check_messages('unsupported-binary-operation')
824
+ def _visit_binop(self, node):
825
+ """Detect TypeErrors for binary arithmetic operands."""
826
+ self._check_binop_errors(node)
827
+
828
+ @check_messages('unsupported-binary-operation')
829
+ def _visit_augassign(self, node):
830
+ """Detect TypeErrors for augmented binary arithmetic operands."""
831
+ self._check_binop_errors(node)
832
+
833
+ def _check_binop_errors(self, node):
834
+ for error in node.type_errors():
835
+ # Let the error customize its output.
836
+ self.add_message('unsupported-binary-operation',
837
+ args=str(error), node=node)
838
+
839
+ def _check_membership_test(self, node):
840
+ if is_inside_abstract_class(node):
841
+ return
842
+ if is_comprehension(node):
843
+ return
844
+ infered = safe_infer(node)
845
+ if infered is None or infered is astroid.YES:
846
+ return
847
+ if not supports_membership_test(infered):
848
+ self.add_message('unsupported-membership-test',
849
+ args=node.as_string(),
850
+ node=node)
851
+
852
+ @check_messages('unsupported-membership-test')
853
+ def visit_compare(self, node):
854
+ if len(node.ops) != 1:
855
+ return
856
+ operator, right = node.ops[0]
857
+ if operator in ['in', 'not in']:
858
+ self._check_membership_test(right)
859
+
860
+ @check_messages('unsubscriptable-object')
861
+ def visit_subscript(self, node):
862
+ if isinstance(node.value, (astroid.ListComp, astroid.DictComp)):
863
+ return
864
+ if isinstance(node.value, astroid.SetComp):
865
+ self.add_message('unsubscriptable-object',
866
+ args=node.value.as_string(),
867
+ node=node.value)
868
+ return
869
+
870
+ infered = safe_infer(node.value)
871
+ if infered is None or infered is astroid.YES:
872
+ return
873
+
874
+ if is_inside_abstract_class(node):
875
+ return
876
+
877
+ if not supports_subscript(infered):
878
+ self.add_message('unsubscriptable-object',
879
+ args=node.value.as_string(),
880
+ node=node.value)
881
+
882
+
883
+
884
+ class IterableChecker(BaseChecker):
885
+ """
886
+ Checks for non-iterables used in an iterable context.
887
+ Contexts include:
888
+ - for-statement
889
+ - starargs in function call
890
+ - `yield from`-statement
891
+ - list, dict and set comprehensions
892
+ - generator expressions
893
+ Also checks for non-mappings in function call kwargs.
894
+ """
895
+
896
+ __implements__ = (IAstroidChecker,)
897
+ name = 'iterable_check'
898
+
899
+ msgs = {'E1133': ('Non-iterable value %s is used in an iterating context',
900
+ 'not-an-iterable',
901
+ 'Used when a non-iterable value is used in place where'
902
+ 'iterable is expected'),
903
+ 'E1134': ('Non-mapping value %s is used in a mapping context',
904
+ 'not-a-mapping',
905
+ 'Used when a non-mapping value is used in place where'
906
+ 'mapping is expected'),
907
+ }
908
+
909
+ def _check_iterable(self, node):
910
+ if is_inside_abstract_class(node):
911
+ return
912
+ if is_comprehension(node):
913
+ return
914
+ infered = safe_infer(node)
915
+ if infered is None or infered is astroid.YES:
916
+ return
917
+ if not is_iterable(infered):
918
+ self.add_message('not-an-iterable',
919
+ args=node.as_string(),
920
+ node=node)
921
+
922
+ def _check_mapping(self, node):
923
+ if is_inside_abstract_class(node):
924
+ return
925
+ if isinstance(node, astroid.DictComp):
926
+ return
927
+ infered = safe_infer(node)
928
+ if infered is None or infered is astroid.YES:
929
+ return
930
+ if not is_mapping(infered):
931
+ self.add_message('not-a-mapping',
932
+ args=node.as_string(),
933
+ node=node)
934
+
935
+ @check_messages('not-an-iterable')
936
+ def visit_for(self, node):
937
+ self._check_iterable(node.iter)
938
+
939
+ @check_messages('not-an-iterable')
940
+ def visit_yieldfrom(self, node):
941
+ self._check_iterable(node.value)
942
+
943
+ @check_messages('not-an-iterable', 'not-a-mapping')
944
+ def visit_call(self, node):
945
+ for stararg in node.starargs:
946
+ self._check_iterable(stararg.value)
947
+ for kwarg in node.kwargs:
948
+ self._check_mapping(kwarg.value)
949
+
950
+ @check_messages('not-an-iterable')
951
+ def visit_listcomp(self, node):
952
+ for gen in node.generators:
953
+ self._check_iterable(gen.iter)
954
+
955
+ @check_messages('not-an-iterable')
956
+ def visit_dictcomp(self, node):
957
+ for gen in node.generators:
958
+ self._check_iterable(gen.iter)
959
+
960
+ @check_messages('not-an-iterable')
961
+ def visit_setcomp(self, node):
962
+ for gen in node.generators:
963
+ self._check_iterable(gen.iter)
964
+
965
+ @check_messages('not-an-iterable')
966
+ def visit_generatorexp(self, node):
967
+ for gen in node.generators:
968
+ self._check_iterable(gen.iter)
969
+
970
+
625
971
  def register(linter):
626
972
  """required method to auto register this checker """
627
973
  linter.register_checker(TypeChecker(linter))
974
+ linter.register_checker(IterableChecker(linter))