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
@@ -1,1119 +0,0 @@
1
- # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
2
- # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
3
- #
4
- # This file is part of Logilab-common.
5
- #
6
- # Logilab-common is free software: you can redistribute it and/or modify it
7
- # under the terms of the GNU Lesser General Public License as published by the
8
- # Free Software Foundation, either version 2.1 of the License, or (at your
9
- # option) any later version.
10
- #
11
- # Logilab-common is distributed in the hope that it will be useful, but WITHOUT
12
- # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13
- # FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
14
- # details.
15
- #
16
- # You should have received a copy of the GNU Lesser General Public License along
17
- # with Logilab-common. If not, see <http://www.gnu.org/licenses/>.
18
- """This module provides bases for predicates dispatching (the pattern in use
19
- here is similar to what's refered as multi-dispatch or predicate-dispatch in the
20
- literature, though a bit different since the idea is to select across different
21
- implementation 'e.g. classes), not to dispatch a message to a function or
22
- method. It contains the following classes:
23
-
24
- * :class:`RegistryStore`, the top level object which loads implementation
25
- objects and stores them into registries. You'll usually use it to access
26
- registries and their contained objects;
27
-
28
- * :class:`Registry`, the base class which contains objects semantically grouped
29
- (for instance, sharing a same API, hence the 'implementation' name). You'll
30
- use it to select the proper implementation according to a context. Notice you
31
- may use registries on their own without using the store.
32
-
33
- .. Note::
34
-
35
- implementation objects are usually designed to be accessed through the
36
- registry and not by direct instantiation, besides to use it as base classe.
37
-
38
- The selection procedure is delegated to a selector, which is responsible for
39
- scoring the object according to some context. At the end of the selection, if an
40
- implementation has been found, an instance of this class is returned. A selector
41
- is built from one or more predicates combined together using AND, OR, NOT
42
- operators (actually `&`, `|` and `~`). You'll thus find some base classes to
43
- build predicates:
44
-
45
- * :class:`Predicate`, the abstract base predicate class
46
-
47
- * :class:`AndPredicate`, :class:`OrPredicate`, :class:`NotPredicate`, which you
48
- shouldn't have to use directly. You'll use `&`, `|` and '~' operators between
49
- predicates directly
50
-
51
- * :func:`objectify_predicate`
52
-
53
- You'll eventually find one concrete predicate: :class:`yes`
54
-
55
- .. autoclass:: RegistryStore
56
- .. autoclass:: Registry
57
-
58
- Predicates
59
- ----------
60
- .. autoclass:: Predicate
61
- .. autofunc:: objectify_predicate
62
- .. autoclass:: yes
63
-
64
- Debugging
65
- ---------
66
- .. autoclass:: traced_selection
67
-
68
- Exceptions
69
- ----------
70
- .. autoclass:: RegistryException
71
- .. autoclass:: RegistryNotFound
72
- .. autoclass:: ObjectNotFound
73
- .. autoclass:: NoSelectableObject
74
- """
75
-
76
- from __future__ import print_function
77
-
78
- __docformat__ = "restructuredtext en"
79
-
80
- import sys
81
- import types
82
- import weakref
83
- import traceback as tb
84
- from os import listdir, stat
85
- from os.path import join, isdir, exists
86
- from logging import getLogger
87
- from warnings import warn
88
-
89
- from six import string_types, add_metaclass
90
-
91
- from logilab.common.modutils import modpath_from_file
92
- from logilab.common.logging_ext import set_log_methods
93
- from logilab.common.decorators import classproperty
94
-
95
-
96
- class RegistryException(Exception):
97
- """Base class for registry exception."""
98
-
99
- class RegistryNotFound(RegistryException):
100
- """Raised when an unknown registry is requested.
101
-
102
- This is usually a programming/typo error.
103
- """
104
-
105
- class ObjectNotFound(RegistryException):
106
- """Raised when an unregistered object is requested.
107
-
108
- This may be a programming/typo or a misconfiguration error.
109
- """
110
-
111
- class NoSelectableObject(RegistryException):
112
- """Raised when no object is selectable for a given context."""
113
- def __init__(self, args, kwargs, objects):
114
- self.args = args
115
- self.kwargs = kwargs
116
- self.objects = objects
117
-
118
- def __str__(self):
119
- return ('args: %s, kwargs: %s\ncandidates: %s'
120
- % (self.args, self.kwargs.keys(), self.objects))
121
-
122
-
123
- def _modname_from_path(path, extrapath=None):
124
- modpath = modpath_from_file(path, extrapath)
125
- # omit '__init__' from package's name to avoid loading that module
126
- # once for each name when it is imported by some other object
127
- # module. This supposes import in modules are done as::
128
- #
129
- # from package import something
130
- #
131
- # not::
132
- #
133
- # from package.__init__ import something
134
- #
135
- # which seems quite correct.
136
- if modpath[-1] == '__init__':
137
- modpath.pop()
138
- return '.'.join(modpath)
139
-
140
-
141
- def _toload_info(path, extrapath, _toload=None):
142
- """Return a dictionary of <modname>: <modpath> and an ordered list of
143
- (file, module name) to load
144
- """
145
- if _toload is None:
146
- assert isinstance(path, list)
147
- _toload = {}, []
148
- for fileordir in path:
149
- if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
150
- subfiles = [join(fileordir, fname) for fname in listdir(fileordir)]
151
- _toload_info(subfiles, extrapath, _toload)
152
- elif fileordir[-3:] == '.py':
153
- modname = _modname_from_path(fileordir, extrapath)
154
- _toload[0][modname] = fileordir
155
- _toload[1].append((fileordir, modname))
156
- return _toload
157
-
158
-
159
- class RegistrableObject(object):
160
- """This is the base class for registrable objects which are selected
161
- according to a context.
162
-
163
- :attr:`__registry__`
164
- name of the registry for this object (string like 'views',
165
- 'templates'...). You may want to define `__registries__` directly if your
166
- object should be registered in several registries.
167
-
168
- :attr:`__regid__`
169
- object's identifier in the registry (string like 'main',
170
- 'primary', 'folder_box')
171
-
172
- :attr:`__select__`
173
- class'selector
174
-
175
- Moreover, the `__abstract__` attribute may be set to True to indicate that a
176
- class is abstract and should not be registered.
177
-
178
- You don't have to inherit from this class to put it in a registry (having
179
- `__regid__` and `__select__` is enough), though this is needed for classes
180
- that should be automatically registered.
181
- """
182
-
183
- __registry__ = None
184
- __regid__ = None
185
- __select__ = None
186
- __abstract__ = True # see doc snipppets below (in Registry class)
187
-
188
- @classproperty
189
- def __registries__(cls):
190
- if cls.__registry__ is None:
191
- return ()
192
- return (cls.__registry__,)
193
-
194
-
195
- class RegistrableInstance(RegistrableObject):
196
- """Inherit this class if you want instances of the classes to be
197
- automatically registered.
198
- """
199
-
200
- def __new__(cls, *args, **kwargs):
201
- """Add a __module__ attribute telling the module where the instance was
202
- created, for automatic registration.
203
- """
204
- obj = super(RegistrableInstance, cls).__new__(cls)
205
- # XXX subclass must no override __new__
206
- filepath = tb.extract_stack(limit=2)[0][0]
207
- obj.__module__ = _modname_from_path(filepath)
208
- return obj
209
-
210
-
211
- class Registry(dict):
212
- """The registry store a set of implementations associated to identifier:
213
-
214
- * to each identifier are associated a list of implementations
215
-
216
- * to select an implementation of a given identifier, you should use one of the
217
- :meth:`select` or :meth:`select_or_none` method
218
-
219
- * to select a list of implementations for a context, you should use the
220
- :meth:`possible_objects` method
221
-
222
- * dictionary like access to an identifier will return the bare list of
223
- implementations for this identifier.
224
-
225
- To be usable in a registry, the only requirement is to have a `__select__`
226
- attribute.
227
-
228
- At the end of the registration process, the :meth:`__registered__`
229
- method is called on each registered object which have them, given the
230
- registry in which it's registered as argument.
231
-
232
- Registration methods:
233
-
234
- .. automethod: register
235
- .. automethod: unregister
236
-
237
- Selection methods:
238
-
239
- .. automethod: select
240
- .. automethod: select_or_none
241
- .. automethod: possible_objects
242
- .. automethod: object_by_id
243
- """
244
- def __init__(self, debugmode):
245
- super(Registry, self).__init__()
246
- self.debugmode = debugmode
247
-
248
- def __getitem__(self, name):
249
- """return the registry (list of implementation objects) associated to
250
- this name
251
- """
252
- try:
253
- return super(Registry, self).__getitem__(name)
254
- except KeyError:
255
- exc = ObjectNotFound(name)
256
- exc.__traceback__ = sys.exc_info()[-1]
257
- raise exc
258
-
259
- @classmethod
260
- def objid(cls, obj):
261
- """returns a unique identifier for an object stored in the registry"""
262
- return '%s.%s' % (obj.__module__, cls.objname(obj))
263
-
264
- @classmethod
265
- def objname(cls, obj):
266
- """returns a readable name for an object stored in the registry"""
267
- return getattr(obj, '__name__', id(obj))
268
-
269
- def initialization_completed(self):
270
- """call method __registered__() on registered objects when the callback
271
- is defined"""
272
- for objects in self.values():
273
- for objectcls in objects:
274
- registered = getattr(objectcls, '__registered__', None)
275
- if registered:
276
- registered(self)
277
- if self.debugmode:
278
- wrap_predicates(_lltrace)
279
-
280
- def register(self, obj, oid=None, clear=False):
281
- """base method to add an object in the registry"""
282
- assert not '__abstract__' in obj.__dict__, obj
283
- assert obj.__select__, obj
284
- oid = oid or obj.__regid__
285
- assert oid, ('no explicit name supplied to register object %s, '
286
- 'which has no __regid__ set' % obj)
287
- if clear:
288
- objects = self[oid] = []
289
- else:
290
- objects = self.setdefault(oid, [])
291
- assert not obj in objects, 'object %s is already registered' % obj
292
- objects.append(obj)
293
-
294
- def register_and_replace(self, obj, replaced):
295
- """remove <replaced> and register <obj>"""
296
- # XXXFIXME this is a duplication of unregister()
297
- # remove register_and_replace in favor of unregister + register
298
- # or simplify by calling unregister then register here
299
- if not isinstance(replaced, string_types):
300
- replaced = self.objid(replaced)
301
- # prevent from misspelling
302
- assert obj is not replaced, 'replacing an object by itself: %s' % obj
303
- registered_objs = self.get(obj.__regid__, ())
304
- for index, registered in enumerate(registered_objs):
305
- if self.objid(registered) == replaced:
306
- del registered_objs[index]
307
- break
308
- else:
309
- self.warning('trying to replace %s that is not registered with %s',
310
- replaced, obj)
311
- self.register(obj)
312
-
313
- def unregister(self, obj):
314
- """remove object <obj> from this registry"""
315
- objid = self.objid(obj)
316
- oid = obj.__regid__
317
- for registered in self.get(oid, ()):
318
- # use self.objid() to compare objects because vreg will probably
319
- # have its own version of the object, loaded through execfile
320
- if self.objid(registered) == objid:
321
- self[oid].remove(registered)
322
- break
323
- else:
324
- self.warning('can\'t remove %s, no id %s in the registry',
325
- objid, oid)
326
-
327
- def all_objects(self):
328
- """return a list containing all objects in this registry.
329
- """
330
- result = []
331
- for objs in self.values():
332
- result += objs
333
- return result
334
-
335
- # dynamic selection methods ################################################
336
-
337
- def object_by_id(self, oid, *args, **kwargs):
338
- """return object with the `oid` identifier. Only one object is expected
339
- to be found.
340
-
341
- raise :exc:`ObjectNotFound` if there are no object with id `oid` in this
342
- registry
343
-
344
- raise :exc:`AssertionError` if there is more than one object there
345
- """
346
- objects = self[oid]
347
- assert len(objects) == 1, objects
348
- return objects[0](*args, **kwargs)
349
-
350
- def select(self, __oid, *args, **kwargs):
351
- """return the most specific object among those with the given oid
352
- according to the given context.
353
-
354
- raise :exc:`ObjectNotFound` if there are no object with id `oid` in this
355
- registry
356
-
357
- raise :exc:`NoSelectableObject` if no object can be selected
358
- """
359
- obj = self._select_best(self[__oid], *args, **kwargs)
360
- if obj is None:
361
- raise NoSelectableObject(args, kwargs, self[__oid] )
362
- return obj
363
-
364
- def select_or_none(self, __oid, *args, **kwargs):
365
- """return the most specific object among those with the given oid
366
- according to the given context, or None if no object applies.
367
- """
368
- try:
369
- return self._select_best(self[__oid], *args, **kwargs)
370
- except ObjectNotFound:
371
- return None
372
-
373
- def possible_objects(self, *args, **kwargs):
374
- """return an iterator on possible objects in this registry for the given
375
- context
376
- """
377
- for objects in self.values():
378
- obj = self._select_best(objects, *args, **kwargs)
379
- if obj is None:
380
- continue
381
- yield obj
382
-
383
- def _select_best(self, objects, *args, **kwargs):
384
- """return an instance of the most specific object according
385
- to parameters
386
-
387
- return None if not object apply (don't raise `NoSelectableObject` since
388
- it's costly when searching objects using `possible_objects`
389
- (e.g. searching for hooks).
390
- """
391
- score, winners = 0, None
392
- for obj in objects:
393
- objectscore = obj.__select__(obj, *args, **kwargs)
394
- if objectscore > score:
395
- score, winners = objectscore, [obj]
396
- elif objectscore > 0 and objectscore == score:
397
- winners.append(obj)
398
- if winners is None:
399
- return None
400
- if len(winners) > 1:
401
- # log in production environement / test, error while debugging
402
- msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)'
403
- if self.debugmode:
404
- # raise bare exception in debug mode
405
- raise Exception(msg % (winners, args, kwargs.keys()))
406
- self.error(msg, winners, args, kwargs.keys())
407
- # return the result of calling the object
408
- return self.selected(winners[0], args, kwargs)
409
-
410
- def selected(self, winner, args, kwargs):
411
- """override here if for instance you don't want "instanciation"
412
- """
413
- return winner(*args, **kwargs)
414
-
415
- # these are overridden by set_log_methods below
416
- # only defining here to prevent pylint from complaining
417
- info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
418
-
419
-
420
- def obj_registries(cls, registryname=None):
421
- """return a tuple of registry names (see __registries__)"""
422
- if registryname:
423
- return (registryname,)
424
- return cls.__registries__
425
-
426
-
427
- class RegistryStore(dict):
428
- """This class is responsible for loading objects and storing them
429
- in their registry which is created on the fly as needed.
430
-
431
- It handles dynamic registration of objects and provides a
432
- convenient api to access them. To be recognized as an object that
433
- should be stored into one of the store's registry
434
- (:class:`Registry`), an object must provide the following
435
- attributes, used control how they interact with the registry:
436
-
437
- :attr:`__registries__`
438
- list of registry names (string like 'views', 'templates'...) into which
439
- the object should be registered
440
-
441
- :attr:`__regid__`
442
- object identifier in the registry (string like 'main',
443
- 'primary', 'folder_box')
444
-
445
- :attr:`__select__`
446
- the object predicate selectors
447
-
448
- Moreover, the :attr:`__abstract__` attribute may be set to `True`
449
- to indicate that an object is abstract and should not be registered
450
- (such inherited attributes not considered).
451
-
452
- .. Note::
453
-
454
- When using the store to load objects dynamically, you *always* have
455
- to use **super()** to get the methods and attributes of the
456
- superclasses, and not use the class identifier. If not, you'll get into
457
- trouble at reload time.
458
-
459
- For example, instead of writing::
460
-
461
- class Thing(Parent):
462
- __regid__ = 'athing'
463
- __select__ = yes()
464
-
465
- def f(self, arg1):
466
- Parent.f(self, arg1)
467
-
468
- You must write::
469
-
470
- class Thing(Parent):
471
- __regid__ = 'athing'
472
- __select__ = yes()
473
-
474
- def f(self, arg1):
475
- super(Thing, self).f(arg1)
476
-
477
- Controlling object registration
478
- -------------------------------
479
-
480
- Dynamic loading is triggered by calling the
481
- :meth:`register_objects` method, given a list of directories to
482
- inspect for python modules.
483
-
484
- .. automethod: register_objects
485
-
486
- For each module, by default, all compatible objects are registered
487
- automatically. However if some objects come as replacement of
488
- other objects, or have to be included only if some condition is
489
- met, you'll have to define a `registration_callback(vreg)`
490
- function in the module and explicitly register **all objects** in
491
- this module, using the api defined below.
492
-
493
-
494
- .. automethod:: RegistryStore.register_all
495
- .. automethod:: RegistryStore.register_and_replace
496
- .. automethod:: RegistryStore.register
497
- .. automethod:: RegistryStore.unregister
498
-
499
- .. Note::
500
- Once the function `registration_callback(vreg)` is implemented in a
501
- module, all the objects from this module have to be explicitly
502
- registered as it disables the automatic object registration.
503
-
504
-
505
- Examples:
506
-
507
- .. sourcecode:: python
508
-
509
- def registration_callback(store):
510
- # register everything in the module except BabarClass
511
- store.register_all(globals().values(), __name__, (BabarClass,))
512
-
513
- # conditionally register BabarClass
514
- if 'babar_relation' in store.schema:
515
- store.register(BabarClass)
516
-
517
- In this example, we register all application object classes defined in the module
518
- except `BabarClass`. This class is then registered only if the 'babar_relation'
519
- relation type is defined in the instance schema.
520
-
521
- .. sourcecode:: python
522
-
523
- def registration_callback(store):
524
- store.register(Elephant)
525
- # replace Babar by Celeste
526
- store.register_and_replace(Celeste, Babar)
527
-
528
- In this example, we explicitly register classes one by one:
529
-
530
- * the `Elephant` class
531
- * the `Celeste` to replace `Babar`
532
-
533
- If at some point we register a new appobject class in this module, it won't be
534
- registered at all without modification to the `registration_callback`
535
- implementation. The first example will register it though, thanks to the call
536
- to the `register_all` method.
537
-
538
- Controlling registry instantiation
539
- ----------------------------------
540
-
541
- The `REGISTRY_FACTORY` class dictionary allows to specify which class should
542
- be instantiated for a given registry name. The class associated to `None`
543
- key will be the class used when there is no specific class for a name.
544
- """
545
-
546
- def __init__(self, debugmode=False):
547
- super(RegistryStore, self).__init__()
548
- self.debugmode = debugmode
549
-
550
- def reset(self):
551
- """clear all registries managed by this store"""
552
- # don't use self.clear, we want to keep existing subdictionaries
553
- for subdict in self.values():
554
- subdict.clear()
555
- self._lastmodifs = {}
556
-
557
- def __getitem__(self, name):
558
- """return the registry (dictionary of class objects) associated to
559
- this name
560
- """
561
- try:
562
- return super(RegistryStore, self).__getitem__(name)
563
- except KeyError:
564
- exc = RegistryNotFound(name)
565
- exc.__traceback__ = sys.exc_info()[-1]
566
- raise exc
567
-
568
- # methods for explicit (un)registration ###################################
569
-
570
- # default class, when no specific class set
571
- REGISTRY_FACTORY = {None: Registry}
572
-
573
- def registry_class(self, regid):
574
- """return existing registry named regid or use factory to create one and
575
- return it"""
576
- try:
577
- return self.REGISTRY_FACTORY[regid]
578
- except KeyError:
579
- return self.REGISTRY_FACTORY[None]
580
-
581
- def setdefault(self, regid):
582
- try:
583
- return self[regid]
584
- except RegistryNotFound:
585
- self[regid] = self.registry_class(regid)(self.debugmode)
586
- return self[regid]
587
-
588
- def register_all(self, objects, modname, butclasses=()):
589
- """register registrable objects into `objects`.
590
-
591
- Registrable objects are properly configured subclasses of
592
- :class:`RegistrableObject`. Objects which are not defined in the module
593
- `modname` or which are in `butclasses` won't be registered.
594
-
595
- Typical usage is:
596
-
597
- .. sourcecode:: python
598
-
599
- store.register_all(globals().values(), __name__, (ClassIWantToRegisterExplicitly,))
600
-
601
- So you get partially automatic registration, keeping manual registration
602
- for some object (to use
603
- :meth:`~logilab.common.registry.RegistryStore.register_and_replace` for
604
- instance).
605
- """
606
- assert isinstance(modname, string_types), \
607
- 'modname expected to be a module name (ie string), got %r' % modname
608
- for obj in objects:
609
- if self.is_registrable(obj) and obj.__module__ == modname and not obj in butclasses:
610
- if isinstance(obj, type):
611
- self._load_ancestors_then_object(modname, obj, butclasses)
612
- else:
613
- self.register(obj)
614
-
615
- def register(self, obj, registryname=None, oid=None, clear=False):
616
- """register `obj` implementation into `registryname` or
617
- `obj.__registries__` if not specified, with identifier `oid` or
618
- `obj.__regid__` if not specified.
619
-
620
- If `clear` is true, all objects with the same identifier will be
621
- previously unregistered.
622
- """
623
- assert not obj.__dict__.get('__abstract__'), obj
624
- for registryname in obj_registries(obj, registryname):
625
- registry = self.setdefault(registryname)
626
- registry.register(obj, oid=oid, clear=clear)
627
- self.debug("register %s in %s['%s']",
628
- registry.objname(obj), registryname, oid or obj.__regid__)
629
- self._loadedmods.setdefault(obj.__module__, {})[registry.objid(obj)] = obj
630
-
631
- def unregister(self, obj, registryname=None):
632
- """unregister `obj` object from the registry `registryname` or
633
- `obj.__registries__` if not specified.
634
- """
635
- for registryname in obj_registries(obj, registryname):
636
- registry = self[registryname]
637
- registry.unregister(obj)
638
- self.debug("unregister %s from %s['%s']",
639
- registry.objname(obj), registryname, obj.__regid__)
640
-
641
- def register_and_replace(self, obj, replaced, registryname=None):
642
- """register `obj` object into `registryname` or
643
- `obj.__registries__` if not specified. If found, the `replaced` object
644
- will be unregistered first (else a warning will be issued as it is
645
- generally unexpected).
646
- """
647
- for registryname in obj_registries(obj, registryname):
648
- registry = self[registryname]
649
- registry.register_and_replace(obj, replaced)
650
- self.debug("register %s in %s['%s'] instead of %s",
651
- registry.objname(obj), registryname, obj.__regid__,
652
- registry.objname(replaced))
653
-
654
- # initialization methods ###################################################
655
-
656
- def init_registration(self, path, extrapath=None):
657
- """reset registry and walk down path to return list of (path, name)
658
- file modules to be loaded"""
659
- # XXX make this private by renaming it to _init_registration ?
660
- self.reset()
661
- # compute list of all modules that have to be loaded
662
- self._toloadmods, filemods = _toload_info(path, extrapath)
663
- # XXX is _loadedmods still necessary ? It seems like it's useful
664
- # to avoid loading same module twice, especially with the
665
- # _load_ancestors_then_object logic but this needs to be checked
666
- self._loadedmods = {}
667
- return filemods
668
-
669
- def register_objects(self, path, extrapath=None):
670
- """register all objects found walking down <path>"""
671
- # load views from each directory in the instance's path
672
- # XXX inline init_registration ?
673
- filemods = self.init_registration(path, extrapath)
674
- for filepath, modname in filemods:
675
- self.load_file(filepath, modname)
676
- self.initialization_completed()
677
-
678
- def initialization_completed(self):
679
- """call initialization_completed() on all known registries"""
680
- for reg in self.values():
681
- reg.initialization_completed()
682
-
683
- def _mdate(self, filepath):
684
- """ return the modification date of a file path """
685
- try:
686
- return stat(filepath)[-2]
687
- except OSError:
688
- # this typically happens on emacs backup files (.#foo.py)
689
- self.warning('Unable to load %s. It is likely to be a backup file',
690
- filepath)
691
- return None
692
-
693
- def is_reload_needed(self, path):
694
- """return True if something module changed and the registry should be
695
- reloaded
696
- """
697
- lastmodifs = self._lastmodifs
698
- for fileordir in path:
699
- if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
700
- if self.is_reload_needed([join(fileordir, fname)
701
- for fname in listdir(fileordir)]):
702
- return True
703
- elif fileordir[-3:] == '.py':
704
- mdate = self._mdate(fileordir)
705
- if mdate is None:
706
- continue # backup file, see _mdate implementation
707
- elif "flymake" in fileordir:
708
- # flymake + pylint in use, don't consider these they will corrupt the registry
709
- continue
710
- if fileordir not in lastmodifs or lastmodifs[fileordir] < mdate:
711
- self.info('File %s changed since last visit', fileordir)
712
- return True
713
- return False
714
-
715
- def load_file(self, filepath, modname):
716
- """ load registrable objects (if any) from a python file """
717
- from logilab.common.modutils import load_module_from_name
718
- if modname in self._loadedmods:
719
- return
720
- self._loadedmods[modname] = {}
721
- mdate = self._mdate(filepath)
722
- if mdate is None:
723
- return # backup file, see _mdate implementation
724
- elif "flymake" in filepath:
725
- # flymake + pylint in use, don't consider these they will corrupt the registry
726
- return
727
- # set update time before module loading, else we get some reloading
728
- # weirdness in case of syntax error or other error while importing the
729
- # module
730
- self._lastmodifs[filepath] = mdate
731
- # load the module
732
- module = load_module_from_name(modname)
733
- self.load_module(module)
734
-
735
- def load_module(self, module):
736
- """Automatically handle module objects registration.
737
-
738
- Instances are registered as soon as they are hashable and have the
739
- following attributes:
740
-
741
- * __regid__ (a string)
742
- * __select__ (a callable)
743
- * __registries__ (a tuple/list of string)
744
-
745
- For classes this is a bit more complicated :
746
-
747
- - first ensure parent classes are already registered
748
-
749
- - class with __abstract__ == True in their local dictionary are skipped
750
-
751
- - object class needs to have registries and identifier properly set to a
752
- non empty string to be registered.
753
- """
754
- self.info('loading %s from %s', module.__name__, module.__file__)
755
- if hasattr(module, 'registration_callback'):
756
- module.registration_callback(self)
757
- else:
758
- self.register_all(vars(module).values(), module.__name__)
759
-
760
- def _load_ancestors_then_object(self, modname, objectcls, butclasses=()):
761
- """handle class registration according to rules defined in
762
- :meth:`load_module`
763
- """
764
- # backward compat, we used to allow whatever else than classes
765
- if not isinstance(objectcls, type):
766
- if self.is_registrable(objectcls) and objectcls.__module__ == modname:
767
- self.register(objectcls)
768
- return
769
- # imported classes
770
- objmodname = objectcls.__module__
771
- if objmodname != modname:
772
- # The module of the object is not the same as the currently
773
- # worked on module, or this is actually an instance, which
774
- # has no module at all
775
- if objmodname in self._toloadmods:
776
- # if this is still scheduled for loading, let's proceed immediately,
777
- # but using the object module
778
- self.load_file(self._toloadmods[objmodname], objmodname)
779
- return
780
- # ensure object hasn't been already processed
781
- clsid = '%s.%s' % (modname, objectcls.__name__)
782
- if clsid in self._loadedmods[modname]:
783
- return
784
- self._loadedmods[modname][clsid] = objectcls
785
- # ensure ancestors are registered
786
- for parent in objectcls.__bases__:
787
- self._load_ancestors_then_object(modname, parent, butclasses)
788
- # ensure object is registrable
789
- if objectcls in butclasses or not self.is_registrable(objectcls):
790
- return
791
- # backward compat
792
- reg = self.setdefault(obj_registries(objectcls)[0])
793
- if reg.objname(objectcls)[0] == '_':
794
- warn("[lgc 0.59] object whose name start with '_' won't be "
795
- "skipped anymore at some point, use __abstract__ = True "
796
- "instead (%s)" % objectcls, DeprecationWarning)
797
- return
798
- # register, finally
799
- self.register(objectcls)
800
-
801
- @classmethod
802
- def is_registrable(cls, obj):
803
- """ensure `obj` should be registered
804
-
805
- as arbitrary stuff may be registered, do a lot of check and warn about
806
- weird cases (think to dumb proxy objects)
807
- """
808
- if isinstance(obj, type):
809
- if not issubclass(obj, RegistrableObject):
810
- # ducktyping backward compat
811
- if not (getattr(obj, '__registries__', None)
812
- and getattr(obj, '__regid__', None)
813
- and getattr(obj, '__select__', None)):
814
- return False
815
- elif issubclass(obj, RegistrableInstance):
816
- return False
817
- elif not isinstance(obj, RegistrableInstance):
818
- return False
819
- if not obj.__regid__:
820
- return False # no regid
821
- registries = obj.__registries__
822
- if not registries:
823
- return False # no registries
824
- selector = obj.__select__
825
- if not selector:
826
- return False # no selector
827
- if obj.__dict__.get('__abstract__', False):
828
- return False
829
- # then detect potential problems that should be warned
830
- if not isinstance(registries, (tuple, list)):
831
- cls.warning('%s has __registries__ which is not a list or tuple', obj)
832
- return False
833
- if not callable(selector):
834
- cls.warning('%s has not callable __select__', obj)
835
- return False
836
- return True
837
-
838
- # these are overridden by set_log_methods below
839
- # only defining here to prevent pylint from complaining
840
- info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
841
-
842
-
843
- # init logging
844
- set_log_methods(RegistryStore, getLogger('registry.store'))
845
- set_log_methods(Registry, getLogger('registry'))
846
-
847
-
848
- # helpers for debugging selectors
849
- TRACED_OIDS = None
850
-
851
- def _trace_selector(cls, selector, args, ret):
852
- vobj = args[0]
853
- if TRACED_OIDS == 'all' or vobj.__regid__ in TRACED_OIDS:
854
- print('%s -> %s for %s(%s)' % (cls, ret, vobj, vobj.__regid__))
855
-
856
- def _lltrace(selector):
857
- """use this decorator on your predicates so they become traceable with
858
- :class:`traced_selection`
859
- """
860
- def traced(cls, *args, **kwargs):
861
- ret = selector(cls, *args, **kwargs)
862
- if TRACED_OIDS is not None:
863
- _trace_selector(cls, selector, args, ret)
864
- return ret
865
- traced.__name__ = selector.__name__
866
- traced.__doc__ = selector.__doc__
867
- return traced
868
-
869
- class traced_selection(object): # pylint: disable=C0103
870
- """
871
- Typical usage is :
872
-
873
- .. sourcecode:: python
874
-
875
- >>> from logilab.common.registry import traced_selection
876
- >>> with traced_selection():
877
- ... # some code in which you want to debug selectors
878
- ... # for all objects
879
-
880
- This will yield lines like this in the logs::
881
-
882
- selector one_line_rset returned 0 for <class 'elephant.Babar'>
883
-
884
- You can also give to :class:`traced_selection` the identifiers of objects on
885
- which you want to debug selection ('oid1' and 'oid2' in the example above).
886
-
887
- .. sourcecode:: python
888
-
889
- >>> with traced_selection( ('regid1', 'regid2') ):
890
- ... # some code in which you want to debug selectors
891
- ... # for objects with __regid__ 'regid1' and 'regid2'
892
-
893
- A potentially useful point to set up such a tracing function is
894
- the `logilab.common.registry.Registry.select` method body.
895
- """
896
-
897
- def __init__(self, traced='all'):
898
- self.traced = traced
899
-
900
- def __enter__(self):
901
- global TRACED_OIDS
902
- TRACED_OIDS = self.traced
903
-
904
- def __exit__(self, exctype, exc, traceback):
905
- global TRACED_OIDS
906
- TRACED_OIDS = None
907
- return traceback is None
908
-
909
- # selector base classes and operations ########################################
910
-
911
- def objectify_predicate(selector_func):
912
- """Most of the time, a simple score function is enough to build a selector.
913
- The :func:`objectify_predicate` decorator turn it into a proper selector
914
- class::
915
-
916
- @objectify_predicate
917
- def one(cls, req, rset=None, **kwargs):
918
- return 1
919
-
920
- class MyView(View):
921
- __select__ = View.__select__ & one()
922
-
923
- """
924
- return type(selector_func.__name__, (Predicate,),
925
- {'__doc__': selector_func.__doc__,
926
- '__call__': lambda self, *a, **kw: selector_func(*a, **kw)})
927
-
928
-
929
- _PREDICATES = {}
930
-
931
- def wrap_predicates(decorator):
932
- for predicate in _PREDICATES.values():
933
- if not '_decorators' in predicate.__dict__:
934
- predicate._decorators = set()
935
- if decorator in predicate._decorators:
936
- continue
937
- predicate._decorators.add(decorator)
938
- predicate.__call__ = decorator(predicate.__call__)
939
-
940
- class PredicateMetaClass(type):
941
- def __new__(mcs, *args, **kwargs):
942
- # use __new__ so subclasses doesn't have to call Predicate.__init__
943
- inst = type.__new__(mcs, *args, **kwargs)
944
- proxy = weakref.proxy(inst, lambda p: _PREDICATES.pop(id(p)))
945
- _PREDICATES[id(proxy)] = proxy
946
- return inst
947
-
948
-
949
- @add_metaclass(PredicateMetaClass)
950
- class Predicate(object):
951
- """base class for selector classes providing implementation
952
- for operators ``&``, ``|`` and ``~``
953
-
954
- This class is only here to give access to binary operators, the selector
955
- logic itself should be implemented in the :meth:`__call__` method. Notice it
956
- should usually accept any arbitrary arguments (the context), though that may
957
- vary depending on your usage of the registry.
958
-
959
- a selector is called to help choosing the correct object for a
960
- particular context by returning a score (`int`) telling how well
961
- the implementation given as first argument fit to the given context.
962
-
963
- 0 score means that the class doesn't apply.
964
- """
965
-
966
- @property
967
- def func_name(self):
968
- # backward compatibility
969
- return self.__class__.__name__
970
-
971
- def search_selector(self, selector):
972
- """search for the given selector, selector instance or tuple of
973
- selectors in the selectors tree. Return None if not found.
974
- """
975
- if self is selector:
976
- return self
977
- if (isinstance(selector, type) or isinstance(selector, tuple)) and \
978
- isinstance(self, selector):
979
- return self
980
- return None
981
-
982
- def __str__(self):
983
- return self.__class__.__name__
984
-
985
- def __and__(self, other):
986
- return AndPredicate(self, other)
987
- def __rand__(self, other):
988
- return AndPredicate(other, self)
989
- def __iand__(self, other):
990
- return AndPredicate(self, other)
991
- def __or__(self, other):
992
- return OrPredicate(self, other)
993
- def __ror__(self, other):
994
- return OrPredicate(other, self)
995
- def __ior__(self, other):
996
- return OrPredicate(self, other)
997
-
998
- def __invert__(self):
999
- return NotPredicate(self)
1000
-
1001
- # XXX (function | function) or (function & function) not managed yet
1002
-
1003
- def __call__(self, cls, *args, **kwargs):
1004
- return NotImplementedError("selector %s must implement its logic "
1005
- "in its __call__ method" % self.__class__)
1006
-
1007
- def __repr__(self):
1008
- return u'<Predicate %s at %x>' % (self.__class__.__name__, id(self))
1009
-
1010
-
1011
- class MultiPredicate(Predicate):
1012
- """base class for compound selector classes"""
1013
-
1014
- def __init__(self, *selectors):
1015
- self.selectors = self.merge_selectors(selectors)
1016
-
1017
- def __str__(self):
1018
- return '%s(%s)' % (self.__class__.__name__,
1019
- ','.join(str(s) for s in self.selectors))
1020
-
1021
- @classmethod
1022
- def merge_selectors(cls, selectors):
1023
- """deal with selector instanciation when necessary and merge
1024
- multi-selectors if possible:
1025
-
1026
- AndPredicate(AndPredicate(sel1, sel2), AndPredicate(sel3, sel4))
1027
- ==> AndPredicate(sel1, sel2, sel3, sel4)
1028
- """
1029
- merged_selectors = []
1030
- for selector in selectors:
1031
- # XXX do we really want magic-transformations below?
1032
- # if so, wanna warn about them?
1033
- if isinstance(selector, types.FunctionType):
1034
- selector = objectify_predicate(selector)()
1035
- if isinstance(selector, type) and issubclass(selector, Predicate):
1036
- selector = selector()
1037
- assert isinstance(selector, Predicate), selector
1038
- if isinstance(selector, cls):
1039
- merged_selectors += selector.selectors
1040
- else:
1041
- merged_selectors.append(selector)
1042
- return merged_selectors
1043
-
1044
- def search_selector(self, selector):
1045
- """search for the given selector or selector instance (or tuple of
1046
- selectors) in the selectors tree. Return None if not found
1047
- """
1048
- for childselector in self.selectors:
1049
- if childselector is selector:
1050
- return childselector
1051
- found = childselector.search_selector(selector)
1052
- if found is not None:
1053
- return found
1054
- # if not found in children, maybe we are looking for self?
1055
- return super(MultiPredicate, self).search_selector(selector)
1056
-
1057
-
1058
- class AndPredicate(MultiPredicate):
1059
- """and-chained selectors"""
1060
- def __call__(self, cls, *args, **kwargs):
1061
- score = 0
1062
- for selector in self.selectors:
1063
- partscore = selector(cls, *args, **kwargs)
1064
- if not partscore:
1065
- return 0
1066
- score += partscore
1067
- return score
1068
-
1069
-
1070
- class OrPredicate(MultiPredicate):
1071
- """or-chained selectors"""
1072
- def __call__(self, cls, *args, **kwargs):
1073
- for selector in self.selectors:
1074
- partscore = selector(cls, *args, **kwargs)
1075
- if partscore:
1076
- return partscore
1077
- return 0
1078
-
1079
- class NotPredicate(Predicate):
1080
- """negation selector"""
1081
- def __init__(self, selector):
1082
- self.selector = selector
1083
-
1084
- def __call__(self, cls, *args, **kwargs):
1085
- score = self.selector(cls, *args, **kwargs)
1086
- return int(not score)
1087
-
1088
- def __str__(self):
1089
- return 'NOT(%s)' % self.selector
1090
-
1091
-
1092
- class yes(Predicate): # pylint: disable=C0103
1093
- """Return the score given as parameter, with a default score of 0.5 so any
1094
- other selector take precedence.
1095
-
1096
- Usually used for objects which can be selected whatever the context, or
1097
- also sometimes to add arbitrary points to a score.
1098
-
1099
- Take care, `yes(0)` could be named 'no'...
1100
- """
1101
- def __init__(self, score=0.5):
1102
- self.score = score
1103
-
1104
- def __call__(self, *args, **kwargs):
1105
- return self.score
1106
-
1107
-
1108
- # deprecated stuff #############################################################
1109
-
1110
- from logilab.common.deprecation import deprecated
1111
-
1112
- @deprecated('[lgc 0.59] use Registry.objid class method instead')
1113
- def classid(cls):
1114
- return '%s.%s' % (cls.__module__, cls.__name__)
1115
-
1116
- @deprecated('[lgc 0.59] use obj_registries function instead')
1117
- def class_registries(cls, registryname):
1118
- return obj_registries(cls, registryname)
1119
-