exercism-analysis 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (579) hide show
  1. checksums.yaml +7 -0
  2. data/exercism-analysis.gemspec +30 -0
  3. data/lib/exercism-analysis.rb +38 -0
  4. data/lib/exercism-analysis/adapters/adapter.rb +23 -0
  5. data/lib/exercism-analysis/adapters/clojure.rb +13 -0
  6. data/lib/exercism-analysis/adapters/go.rb +19 -0
  7. data/lib/exercism-analysis/adapters/javascript.rb +13 -0
  8. data/lib/exercism-analysis/adapters/python.rb +13 -0
  9. data/lib/exercism-analysis/adapters/ruby.rb +19 -0
  10. data/lib/exercism-analysis/analysis.rb +18 -0
  11. data/lib/exercism-analysis/analyzers/analyzer.rb +54 -0
  12. data/lib/exercism-analysis/analyzers/clojure/kibit.rb +25 -0
  13. data/lib/exercism-analysis/analyzers/go/golint.rb +23 -0
  14. data/lib/exercism-analysis/analyzers/javascript/jslint.rb +24 -0
  15. data/lib/exercism-analysis/analyzers/python/pylint.rb +24 -0
  16. data/lib/exercism-analysis/analyzers/ruby/control_flow.rb +21 -0
  17. data/lib/exercism-analysis/analyzers/ruby/enumerable_condition.rb +21 -0
  18. data/lib/exercism-analysis/analyzers/ruby/for_loop.rb +29 -0
  19. data/lib/exercism-analysis/analyzers/ruby/indentation.rb +21 -0
  20. data/lib/exercism-analysis/analyzers/ruby/iter_mutation.rb +37 -0
  21. data/lib/exercism-analysis/analyzers/ruby/output.rb +20 -0
  22. data/lib/exercism-analysis/analyzers/ruby/range.rb +28 -0
  23. data/lib/exercism-analysis/analyzers/ruby/roodi.rb +19 -0
  24. data/lib/exercism-analysis/analyzers/ruby/send.rb +25 -0
  25. data/lib/exercism-analysis/analyzers/ruby/shebang.rb +23 -0
  26. data/lib/exercism-analysis/analyzers/ruby/tab.rb +38 -0
  27. data/lib/exercism-analysis/processors/call_processor.rb +39 -0
  28. data/lib/exercism-analysis/processors/control_flow_processor.rb +27 -0
  29. data/lib/exercism-analysis/processors/enumerable_condition_processor.rb +31 -0
  30. data/lib/exercism-analysis/processors/for_loop_processor.rb +21 -0
  31. data/lib/exercism-analysis/processors/indentation_processor.rb +69 -0
  32. data/lib/exercism-analysis/processors/iter_mutation_processor.rb +50 -0
  33. data/lib/exercism-analysis/processors/processor.rb +34 -0
  34. data/lib/exercism-analysis/processors/range_processor.rb +23 -0
  35. data/lib/exercism-analysis/processors/send_processor.rb +23 -0
  36. data/lib/exercism-analysis/templates/each_to_map.rb +29 -0
  37. data/lib/exercism-analysis/templates/each_to_select.rb +31 -0
  38. data/lib/exercism-analysis/templates/range_exclusive.rb +19 -0
  39. data/lib/exercism-analysis/templates/template.rb +29 -0
  40. data/vendor/clojure/kibit-runner/LICENSE +214 -0
  41. data/vendor/clojure/kibit-runner/project.clj +10 -0
  42. data/vendor/clojure/kibit-runner/src/kibit_runner/core.clj +17 -0
  43. data/vendor/clojure/kibit-runner/target/kibit-runner-0.1.0-SNAPSHOT-standalone.jar +0 -0
  44. data/vendor/clojure/kibit-runner/target/kibit-runner-0.1.0-SNAPSHOT.jar +0 -0
  45. data/vendor/clojure/kibit-runner/target/stale/extract-native.dependencies +1 -0
  46. data/vendor/go/src/github.com/golang/lint/LICENSE +27 -0
  47. data/vendor/go/src/github.com/golang/lint/README +59 -0
  48. data/vendor/go/src/github.com/golang/lint/golint/golint.go +67 -0
  49. data/vendor/go/src/github.com/golang/lint/lint.go +1061 -0
  50. data/vendor/go/src/runner/golint_runner.go +23 -0
  51. data/vendor/javascript/jshint_runner.js +6 -0
  52. data/vendor/javascript/node_modules/jshint/README.md +47 -0
  53. data/vendor/javascript/node_modules/jshint/bin/apply +6 -0
  54. data/vendor/javascript/node_modules/jshint/bin/build +36 -0
  55. data/vendor/javascript/node_modules/jshint/bin/changelog +36 -0
  56. data/vendor/javascript/node_modules/jshint/bin/jshint +3 -0
  57. data/vendor/javascript/node_modules/jshint/bin/land +34 -0
  58. data/vendor/javascript/node_modules/jshint/data/ascii-identifier-data.js +22 -0
  59. data/vendor/javascript/node_modules/jshint/data/non-ascii-identifier-part-only.js +1570 -0
  60. data/vendor/javascript/node_modules/jshint/data/non-ascii-identifier-start.js +48477 -0
  61. data/vendor/javascript/node_modules/jshint/dist/jshint-rhino.js +60642 -0
  62. data/vendor/javascript/node_modules/jshint/dist/jshint.js +60525 -0
  63. data/vendor/javascript/node_modules/jshint/node_modules/cli/README.md +196 -0
  64. data/vendor/javascript/node_modules/jshint/node_modules/cli/cli.js +1139 -0
  65. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/cat.js +17 -0
  66. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/command.js +16 -0
  67. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/echo.js +54 -0
  68. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/glob.js +6 -0
  69. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/long_desc.js +20 -0
  70. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/progress.js +11 -0
  71. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/sort.js +18 -0
  72. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/spinner.js +9 -0
  73. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/static.coffee +27 -0
  74. data/vendor/javascript/node_modules/jshint/node_modules/cli/examples/static.js +25 -0
  75. data/vendor/javascript/node_modules/jshint/node_modules/cli/index.js +1 -0
  76. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/LICENSE +27 -0
  77. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/README.md +250 -0
  78. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/examples/g.js +9 -0
  79. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/examples/usr-local.js +9 -0
  80. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/glob.js +728 -0
  81. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/LICENSE +16 -0
  82. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/README.md +42 -0
  83. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/inherits.js +1 -0
  84. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/inherits_browser.js +23 -0
  85. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/package.json +51 -0
  86. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/node_modules/inherits/test.js +25 -0
  87. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/package.json +58 -0
  88. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/00-setup.js +176 -0
  89. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/bash-comparison.js +63 -0
  90. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/bash-results.json +351 -0
  91. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/cwd-test.js +55 -0
  92. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/globstar-match.js +19 -0
  93. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/mark.js +118 -0
  94. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/new-glob-optional-options.js +10 -0
  95. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/nocase-nomagic.js +113 -0
  96. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/pause-resume.js +73 -0
  97. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/readme-issue.js +36 -0
  98. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/root-nomount.js +39 -0
  99. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/root.js +46 -0
  100. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/stat.js +32 -0
  101. data/vendor/javascript/node_modules/jshint/node_modules/cli/node_modules/glob/test/zz-cleanup.js +11 -0
  102. data/vendor/javascript/node_modules/jshint/node_modules/cli/package.json +70 -0
  103. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/LICENCE +19 -0
  104. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/README.md +33 -0
  105. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/index.js +86 -0
  106. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/LICENCE +19 -0
  107. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/README.md +45 -0
  108. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/index.js +5 -0
  109. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/package.json +89 -0
  110. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/seed.js +16 -0
  111. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/test/index.js +28 -0
  112. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/node_modules/date-now/test/static/index.html +10 -0
  113. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/package.json +88 -0
  114. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/index.js +67 -0
  115. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/static/index.html +12 -0
  116. data/vendor/javascript/node_modules/jshint/node_modules/console-browserify/test/static/test-adapter.js +53 -0
  117. data/vendor/javascript/node_modules/jshint/node_modules/exit/Gruntfile.js +48 -0
  118. data/vendor/javascript/node_modules/jshint/node_modules/exit/LICENSE-MIT +22 -0
  119. data/vendor/javascript/node_modules/jshint/node_modules/exit/README.md +75 -0
  120. data/vendor/javascript/node_modules/jshint/node_modules/exit/lib/exit.js +41 -0
  121. data/vendor/javascript/node_modules/jshint/node_modules/exit/package.json +69 -0
  122. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/exit_test.js +121 -0
  123. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stderr.txt +10 -0
  124. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stdout-stderr.txt +20 -0
  125. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/10-stdout.txt +10 -0
  126. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stderr.txt +100 -0
  127. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stdout-stderr.txt +200 -0
  128. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/100-stdout.txt +100 -0
  129. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stderr.txt +1000 -0
  130. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stdout-stderr.txt +2000 -0
  131. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/1000-stdout.txt +1000 -0
  132. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/create-files.sh +8 -0
  133. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/log-broken.js +23 -0
  134. data/vendor/javascript/node_modules/jshint/node_modules/exit/test/fixtures/log.js +25 -0
  135. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/LICENSE +18 -0
  136. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/README.md +83 -0
  137. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/CollectingHandler.js +55 -0
  138. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/FeedHandler.js +95 -0
  139. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Parser.js +337 -0
  140. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/ProxyHandler.js +27 -0
  141. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Stream.js +35 -0
  142. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/Tokenizer.js +891 -0
  143. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/WritableStream.js +21 -0
  144. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/lib/index.js +68 -0
  145. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/LICENSE +11 -0
  146. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/index.js +14 -0
  147. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/package.json +40 -0
  148. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domelementtype/readme.md +1 -0
  149. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/LICENSE +11 -0
  150. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/index.js +211 -0
  151. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/package.json +68 -0
  152. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/readme.md +102 -0
  153. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/01-basic.json +57 -0
  154. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/02-single_tag_1.json +21 -0
  155. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/03-single_tag_2.json +21 -0
  156. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/04-unescaped_in_script.json +27 -0
  157. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/05-tags_in_comment.json +18 -0
  158. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/06-comment_in_script.json +18 -0
  159. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/07-unescaped_in_style.json +20 -0
  160. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/08-extra_spaces_in_tag.json +20 -0
  161. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/09-unquoted_attrib.json +20 -0
  162. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/10-singular_attribute.json +15 -0
  163. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/11-text_outside_tags.json +40 -0
  164. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/12-text_only.json +11 -0
  165. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/13-comment_in_text.json +19 -0
  166. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/14-comment_in_text_in_script.json +18 -0
  167. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/15-non-verbose.json +22 -0
  168. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/16-normalize_whitespace.json +47 -0
  169. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/17-xml_namespace.json +18 -0
  170. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/18-enforce_empty_tags.json +16 -0
  171. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/19-ignore_empty_tags.json +20 -0
  172. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/20-template_script_tags.json +20 -0
  173. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/21-conditional_comments.json +15 -0
  174. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/22-lowercase_tags.json +41 -0
  175. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/cases/23-dom-lvl1.json +121 -0
  176. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domhandler/test/tests.js +58 -0
  177. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/LICENSE +11 -0
  178. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/index.js +14 -0
  179. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/helpers.js +141 -0
  180. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/legacy.js +87 -0
  181. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/manipulation.js +77 -0
  182. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/querying.js +94 -0
  183. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/stringify.js +93 -0
  184. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/lib/traversal.js +24 -0
  185. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/package.json +71 -0
  186. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/readme.md +1 -0
  187. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/fixture.js +6 -0
  188. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/tests/helpers.js +89 -0
  189. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/tests/legacy.js +119 -0
  190. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/domutils/test/utils.js +9 -0
  191. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/LICENSE +11 -0
  192. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/index.js +31 -0
  193. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/decode.js +72 -0
  194. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/decode_codepoint.js +26 -0
  195. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/lib/encode.js +48 -0
  196. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/decode.json +1 -0
  197. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/entities.json +1 -0
  198. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/legacy.json +1 -0
  199. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/maps/xml.json +1 -0
  200. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/package.json +79 -0
  201. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/readme.md +31 -0
  202. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/test/mocha.opts +2 -0
  203. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/entities/test/test.js +150 -0
  204. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/LICENSE +18 -0
  205. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/README.md +15 -0
  206. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/duplex.js +1 -0
  207. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/float.patch +923 -0
  208. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_duplex.js +89 -0
  209. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_passthrough.js +46 -0
  210. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_readable.js +944 -0
  211. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_transform.js +209 -0
  212. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/lib/_stream_writable.js +472 -0
  213. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/README.md +3 -0
  214. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/float.patch +604 -0
  215. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/lib/util.js +107 -0
  216. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/package.json +53 -0
  217. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/core-util-is/util.js +106 -0
  218. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/LICENSE +16 -0
  219. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/README.md +42 -0
  220. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/inherits.js +1 -0
  221. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/inherits_browser.js +23 -0
  222. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/package.json +51 -0
  223. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/inherits/test.js +25 -0
  224. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/README.md +54 -0
  225. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/build/build.js +209 -0
  226. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/component.json +19 -0
  227. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/index.js +3 -0
  228. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/isarray/package.json +54 -0
  229. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/LICENSE +20 -0
  230. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/README.md +7 -0
  231. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/index.js +200 -0
  232. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/node_modules/string_decoder/package.json +53 -0
  233. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/package.json +68 -0
  234. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/passthrough.js +1 -0
  235. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/readable.js +7 -0
  236. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/transform.js +1 -0
  237. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/node_modules/readable-stream/writable.js +1 -0
  238. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/package.json +90 -0
  239. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/01-events.js +9 -0
  240. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/02-stream.js +23 -0
  241. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/03-feed.js +19 -0
  242. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Atom_Example.xml +25 -0
  243. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Attributes.html +16 -0
  244. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/Basic.html +1 -0
  245. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/RDF_Example.xml +63 -0
  246. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Documents/RSS_Example.xml +48 -0
  247. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/01-simple.json +44 -0
  248. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/02-template.json +63 -0
  249. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/03-lowercase_tags.json +46 -0
  250. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/04-cdata.json +50 -0
  251. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/05-cdata-special.json +35 -0
  252. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/06-leading-lt.json +16 -0
  253. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/07-self-closing.json +67 -0
  254. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/08-implicit-close-tags.json +59 -0
  255. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/09-attributes.json +68 -0
  256. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/10-crazy-attrib.json +52 -0
  257. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/11-script_in_script.json +54 -0
  258. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/12-long-comment-end.json +20 -0
  259. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/13-long-cdata-end.json +22 -0
  260. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/14-implicit-open-tags.json +27 -0
  261. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/15-lt-whitespace.json +16 -0
  262. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/16-double_attribs.json +45 -0
  263. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/17-numeric_entities.json +16 -0
  264. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/18-legacy_entities.json +16 -0
  265. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/19-named_entities.json +16 -0
  266. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/20-xml_entities.json +16 -0
  267. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/21-entity_in_attribute.json +38 -0
  268. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/22-double_brackets.json +41 -0
  269. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/23-legacy_entity_fail.json +16 -0
  270. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/24-special_special.json +133 -0
  271. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/25-empty_tag_name.json +13 -0
  272. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/26-not-quite-closed.json +35 -0
  273. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/27-entities_in_attributes.json +62 -0
  274. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/28-cdata_in_html.json +9 -0
  275. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/29-comment_edge-cases.json +18 -0
  276. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Events/30-cdata_edge-cases.json +22 -0
  277. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/01-rss.js +34 -0
  278. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/02-atom.js +18 -0
  279. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Feeds/03-rdf.js +20 -0
  280. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/01-basic.json +83 -0
  281. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/02-RSS.json +1093 -0
  282. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/03-Atom.json +644 -0
  283. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/04-RDF.json +1399 -0
  284. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/Stream/05-Attributes.json +354 -0
  285. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/api.js +63 -0
  286. data/vendor/javascript/node_modules/jshint/node_modules/htmlparser2/test/test-helper.js +83 -0
  287. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/LICENSE +23 -0
  288. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/README.md +218 -0
  289. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/minimatch.js +1061 -0
  290. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/CONTRIBUTORS +14 -0
  291. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/LICENSE +23 -0
  292. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/README.md +97 -0
  293. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/lib/lru-cache.js +252 -0
  294. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/package.json +50 -0
  295. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/basic.js +369 -0
  296. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/foreach.js +52 -0
  297. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/lru-cache/test/memory-leak.js +50 -0
  298. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/LICENSE +27 -0
  299. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/README.md +53 -0
  300. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/bench.js +283 -0
  301. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/package.json +58 -0
  302. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/sigmund.js +39 -0
  303. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/node_modules/sigmund/test/basic.js +24 -0
  304. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/package.json +57 -0
  305. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/basic.js +399 -0
  306. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/brace-expand.js +33 -0
  307. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/caching.js +14 -0
  308. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/defaults.js +274 -0
  309. data/vendor/javascript/node_modules/jshint/node_modules/minimatch/test/extglob-ending-with-state-char.js +8 -0
  310. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/LICENSE +26 -0
  311. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/README.md +569 -0
  312. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/bin/shjs +51 -0
  313. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/global.js +3 -0
  314. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/make.js +47 -0
  315. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/package.json +61 -0
  316. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/scripts/generate-docs.js +21 -0
  317. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/scripts/run-tests.js +50 -0
  318. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/shell.js +157 -0
  319. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cat.js +43 -0
  320. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cd.js +19 -0
  321. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/chmod.js +208 -0
  322. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/common.js +203 -0
  323. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/cp.js +201 -0
  324. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/dirs.js +191 -0
  325. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/echo.js +20 -0
  326. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/error.js +10 -0
  327. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/exec.js +181 -0
  328. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/find.js +51 -0
  329. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/grep.js +52 -0
  330. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/ln.js +53 -0
  331. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/ls.js +126 -0
  332. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/mkdir.js +68 -0
  333. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/mv.js +80 -0
  334. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/popd.js +1 -0
  335. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/pushd.js +1 -0
  336. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/pwd.js +11 -0
  337. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/rm.js +145 -0
  338. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/sed.js +43 -0
  339. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/tempdir.js +56 -0
  340. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/test.js +85 -0
  341. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/to.js +29 -0
  342. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/toEnd.js +29 -0
  343. data/vendor/javascript/node_modules/jshint/node_modules/shelljs/src/which.js +83 -0
  344. data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/cli.js +41 -0
  345. data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/package.json +76 -0
  346. data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/readme.md +74 -0
  347. data/vendor/javascript/node_modules/jshint/node_modules/strip-json-comments/strip-json-comments.js +64 -0
  348. data/vendor/javascript/node_modules/jshint/node_modules/underscore/LICENSE +23 -0
  349. data/vendor/javascript/node_modules/jshint/node_modules/underscore/README.md +22 -0
  350. data/vendor/javascript/node_modules/jshint/node_modules/underscore/package.json +66 -0
  351. data/vendor/javascript/node_modules/jshint/node_modules/underscore/underscore-min.js +6 -0
  352. data/vendor/javascript/node_modules/jshint/node_modules/underscore/underscore.js +1343 -0
  353. data/vendor/javascript/node_modules/jshint/package.json +80 -0
  354. data/vendor/javascript/node_modules/jshint/src/cli.js +731 -0
  355. data/vendor/javascript/node_modules/jshint/src/jshint.js +5023 -0
  356. data/vendor/javascript/node_modules/jshint/src/lex.js +1650 -0
  357. data/vendor/javascript/node_modules/jshint/src/messages.js +223 -0
  358. data/vendor/javascript/node_modules/jshint/src/platforms/rhino.js +115 -0
  359. data/vendor/javascript/node_modules/jshint/src/reg.js +38 -0
  360. data/vendor/javascript/node_modules/jshint/src/reporters/checkstyle.js +81 -0
  361. data/vendor/javascript/node_modules/jshint/src/reporters/default.js +34 -0
  362. data/vendor/javascript/node_modules/jshint/src/reporters/jslint_xml.js +57 -0
  363. data/vendor/javascript/node_modules/jshint/src/reporters/non_error.js +52 -0
  364. data/vendor/javascript/node_modules/jshint/src/state.js +28 -0
  365. data/vendor/javascript/node_modules/jshint/src/style.js +143 -0
  366. data/vendor/javascript/node_modules/jshint/src/vars.js +658 -0
  367. data/vendor/python/astroid/COPYING +339 -0
  368. data/vendor/python/astroid/COPYING.LESSER +510 -0
  369. data/vendor/python/astroid/ChangeLog +574 -0
  370. data/vendor/python/astroid/MANIFEST.in +9 -0
  371. data/vendor/python/astroid/README +56 -0
  372. data/vendor/python/astroid/README.Python3 +26 -0
  373. data/vendor/python/astroid/__init__.py +118 -0
  374. data/vendor/python/astroid/__init__.pyc +0 -0
  375. data/vendor/python/astroid/__pkginfo__.py +48 -0
  376. data/vendor/python/astroid/__pkginfo__.pyc +0 -0
  377. data/vendor/python/astroid/announce.txt +23 -0
  378. data/vendor/python/astroid/as_string.py +496 -0
  379. data/vendor/python/astroid/as_string.pyc +0 -0
  380. data/vendor/python/astroid/bases.py +618 -0
  381. data/vendor/python/astroid/bases.pyc +0 -0
  382. data/vendor/python/astroid/brain/py2gi.py +159 -0
  383. data/vendor/python/astroid/brain/py2gi.pyc +0 -0
  384. data/vendor/python/astroid/brain/py2mechanize.py +20 -0
  385. data/vendor/python/astroid/brain/py2mechanize.pyc +0 -0
  386. data/vendor/python/astroid/brain/py2qt4.py +25 -0
  387. data/vendor/python/astroid/brain/py2qt4.pyc +0 -0
  388. data/vendor/python/astroid/brain/py2stdlib.py +252 -0
  389. data/vendor/python/astroid/brain/py2stdlib.pyc +0 -0
  390. data/vendor/python/astroid/builder.py +238 -0
  391. data/vendor/python/astroid/builder.pyc +0 -0
  392. data/vendor/python/astroid/exceptions.py +51 -0
  393. data/vendor/python/astroid/exceptions.pyc +0 -0
  394. data/vendor/python/astroid/inference.py +393 -0
  395. data/vendor/python/astroid/inference.pyc +0 -0
  396. data/vendor/python/astroid/inspector.py +275 -0
  397. data/vendor/python/astroid/manager.py +336 -0
  398. data/vendor/python/astroid/manager.pyc +0 -0
  399. data/vendor/python/astroid/mixins.py +122 -0
  400. data/vendor/python/astroid/mixins.pyc +0 -0
  401. data/vendor/python/astroid/node_classes.py +928 -0
  402. data/vendor/python/astroid/node_classes.pyc +0 -0
  403. data/vendor/python/astroid/nodes.py +73 -0
  404. data/vendor/python/astroid/nodes.pyc +0 -0
  405. data/vendor/python/astroid/protocols.py +322 -0
  406. data/vendor/python/astroid/protocols.pyc +0 -0
  407. data/vendor/python/astroid/raw_building.py +361 -0
  408. data/vendor/python/astroid/raw_building.pyc +0 -0
  409. data/vendor/python/astroid/rebuilder.py +954 -0
  410. data/vendor/python/astroid/rebuilder.pyc +0 -0
  411. data/vendor/python/astroid/scoped_nodes.py +1118 -0
  412. data/vendor/python/astroid/scoped_nodes.pyc +0 -0
  413. data/vendor/python/astroid/setup.py +184 -0
  414. data/vendor/python/astroid/tox.ini +10 -0
  415. data/vendor/python/astroid/utils.py +236 -0
  416. data/vendor/python/astroid/utils.pyc +0 -0
  417. data/vendor/python/logilab/__init__.py +0 -0
  418. data/vendor/python/logilab/__init__.pyc +0 -0
  419. data/vendor/python/logilab/common/COPYING +339 -0
  420. data/vendor/python/logilab/common/COPYING.LESSER +510 -0
  421. data/vendor/python/logilab/common/ChangeLog +1517 -0
  422. data/vendor/python/logilab/common/MANIFEST.in +13 -0
  423. data/vendor/python/logilab/common/README +185 -0
  424. data/vendor/python/logilab/common/README.Python3 +29 -0
  425. data/vendor/python/logilab/common/__init__.py +171 -0
  426. data/vendor/python/logilab/common/__init__.pyc +0 -0
  427. data/vendor/python/logilab/common/__pkginfo__.py +53 -0
  428. data/vendor/python/logilab/common/__pkginfo__.pyc +0 -0
  429. data/vendor/python/logilab/common/announce.txt +25 -0
  430. data/vendor/python/logilab/common/bin/pytest +7 -0
  431. data/vendor/python/logilab/common/bin/pytest.bat +17 -0
  432. data/vendor/python/logilab/common/cache.py +114 -0
  433. data/vendor/python/logilab/common/changelog.py +236 -0
  434. data/vendor/python/logilab/common/changelog.pyc +0 -0
  435. data/vendor/python/logilab/common/clcommands.py +332 -0
  436. data/vendor/python/logilab/common/cli.py +208 -0
  437. data/vendor/python/logilab/common/compat.py +243 -0
  438. data/vendor/python/logilab/common/compat.pyc +0 -0
  439. data/vendor/python/logilab/common/configuration.py +1094 -0
  440. data/vendor/python/logilab/common/configuration.pyc +0 -0
  441. data/vendor/python/logilab/common/contexts.py +5 -0
  442. data/vendor/python/logilab/common/corbautils.py +117 -0
  443. data/vendor/python/logilab/common/daemon.py +100 -0
  444. data/vendor/python/logilab/common/date.py +333 -0
  445. data/vendor/python/logilab/common/dbf.py +229 -0
  446. data/vendor/python/logilab/common/debugger.py +210 -0
  447. data/vendor/python/logilab/common/decorators.py +281 -0
  448. data/vendor/python/logilab/common/decorators.pyc +0 -0
  449. data/vendor/python/logilab/common/deprecation.py +188 -0
  450. data/vendor/python/logilab/common/deprecation.pyc +0 -0
  451. data/vendor/python/logilab/common/fileutils.py +402 -0
  452. data/vendor/python/logilab/common/graph.py +276 -0
  453. data/vendor/python/logilab/common/graph.pyc +0 -0
  454. data/vendor/python/logilab/common/hg.py +130 -0
  455. data/vendor/python/logilab/common/interface.py +71 -0
  456. data/vendor/python/logilab/common/interface.pyc +0 -0
  457. data/vendor/python/logilab/common/logging_ext.py +193 -0
  458. data/vendor/python/logilab/common/modutils.py +695 -0
  459. data/vendor/python/logilab/common/modutils.pyc +0 -0
  460. data/vendor/python/logilab/common/optik_ext.py +391 -0
  461. data/vendor/python/logilab/common/optik_ext.pyc +0 -0
  462. data/vendor/python/logilab/common/optparser.py +90 -0
  463. data/vendor/python/logilab/common/proc.py +277 -0
  464. data/vendor/python/logilab/common/pyro_ext.py +180 -0
  465. data/vendor/python/logilab/common/pytest.py +1177 -0
  466. data/vendor/python/logilab/common/python-logilab-common.spec +184 -0
  467. data/vendor/python/logilab/common/registry.py +1113 -0
  468. data/vendor/python/logilab/common/setup.cfg +3 -0
  469. data/vendor/python/logilab/common/setup.py +189 -0
  470. data/vendor/python/logilab/common/shellutils.py +455 -0
  471. data/vendor/python/logilab/common/sphinx_ext.py +87 -0
  472. data/vendor/python/logilab/common/sphinxutils.py +122 -0
  473. data/vendor/python/logilab/common/table.py +925 -0
  474. data/vendor/python/logilab/common/tasksqueue.py +100 -0
  475. data/vendor/python/logilab/common/textutils.py +534 -0
  476. data/vendor/python/logilab/common/textutils.pyc +0 -0
  477. data/vendor/python/logilab/common/tree.py +369 -0
  478. data/vendor/python/logilab/common/tree.pyc +0 -0
  479. data/vendor/python/logilab/common/umessage.py +190 -0
  480. data/vendor/python/logilab/common/ureports/__init__.py +174 -0
  481. data/vendor/python/logilab/common/ureports/__init__.pyc +0 -0
  482. data/vendor/python/logilab/common/ureports/docbook_writer.py +139 -0
  483. data/vendor/python/logilab/common/ureports/html_writer.py +131 -0
  484. data/vendor/python/logilab/common/ureports/html_writer.pyc +0 -0
  485. data/vendor/python/logilab/common/ureports/nodes.py +201 -0
  486. data/vendor/python/logilab/common/ureports/nodes.pyc +0 -0
  487. data/vendor/python/logilab/common/ureports/text_writer.py +140 -0
  488. data/vendor/python/logilab/common/ureports/text_writer.pyc +0 -0
  489. data/vendor/python/logilab/common/urllib2ext.py +87 -0
  490. data/vendor/python/logilab/common/vcgutils.py +216 -0
  491. data/vendor/python/logilab/common/visitor.py +107 -0
  492. data/vendor/python/logilab/common/visitor.pyc +0 -0
  493. data/vendor/python/logilab/common/xmlrpcutils.py +131 -0
  494. data/vendor/python/logilab/common/xmlutils.py +61 -0
  495. data/vendor/python/pylint/CONTRIBUTORS.txt +38 -0
  496. data/vendor/python/pylint/COPYING +340 -0
  497. data/vendor/python/pylint/ChangeLog +1437 -0
  498. data/vendor/python/pylint/DEPENDS +3 -0
  499. data/vendor/python/pylint/MANIFEST.in +14 -0
  500. data/vendor/python/pylint/README +50 -0
  501. data/vendor/python/pylint/README.Python3 +37 -0
  502. data/vendor/python/pylint/__init__.py +44 -0
  503. data/vendor/python/pylint/__init__.pyc +0 -0
  504. data/vendor/python/pylint/__main__.py +3 -0
  505. data/vendor/python/pylint/__pkginfo__.py +74 -0
  506. data/vendor/python/pylint/__pkginfo__.pyc +0 -0
  507. data/vendor/python/pylint/bin/epylint +3 -0
  508. data/vendor/python/pylint/bin/epylint.bat +5 -0
  509. data/vendor/python/pylint/bin/pylint +3 -0
  510. data/vendor/python/pylint/bin/pylint-gui +3 -0
  511. data/vendor/python/pylint/bin/pylint-gui.bat +5 -0
  512. data/vendor/python/pylint/bin/pylint.bat +5 -0
  513. data/vendor/python/pylint/bin/pyreverse +3 -0
  514. data/vendor/python/pylint/bin/pyreverse.bat +5 -0
  515. data/vendor/python/pylint/bin/symilar +3 -0
  516. data/vendor/python/pylint/bin/symilar.bat +5 -0
  517. data/vendor/python/pylint/checkers/__init__.py +145 -0
  518. data/vendor/python/pylint/checkers/__init__.pyc +0 -0
  519. data/vendor/python/pylint/checkers/base.py +1141 -0
  520. data/vendor/python/pylint/checkers/base.pyc +0 -0
  521. data/vendor/python/pylint/checkers/classes.py +792 -0
  522. data/vendor/python/pylint/checkers/classes.pyc +0 -0
  523. data/vendor/python/pylint/checkers/design_analysis.py +367 -0
  524. data/vendor/python/pylint/checkers/design_analysis.pyc +0 -0
  525. data/vendor/python/pylint/checkers/exceptions.py +306 -0
  526. data/vendor/python/pylint/checkers/exceptions.pyc +0 -0
  527. data/vendor/python/pylint/checkers/format.py +943 -0
  528. data/vendor/python/pylint/checkers/format.pyc +0 -0
  529. data/vendor/python/pylint/checkers/imports.py +394 -0
  530. data/vendor/python/pylint/checkers/imports.pyc +0 -0
  531. data/vendor/python/pylint/checkers/logging.py +213 -0
  532. data/vendor/python/pylint/checkers/logging.pyc +0 -0
  533. data/vendor/python/pylint/checkers/misc.py +90 -0
  534. data/vendor/python/pylint/checkers/misc.pyc +0 -0
  535. data/vendor/python/pylint/checkers/newstyle.py +151 -0
  536. data/vendor/python/pylint/checkers/newstyle.pyc +0 -0
  537. data/vendor/python/pylint/checkers/raw_metrics.py +129 -0
  538. data/vendor/python/pylint/checkers/raw_metrics.pyc +0 -0
  539. data/vendor/python/pylint/checkers/similar.py +365 -0
  540. data/vendor/python/pylint/checkers/similar.pyc +0 -0
  541. data/vendor/python/pylint/checkers/stdlib.py +69 -0
  542. data/vendor/python/pylint/checkers/stdlib.pyc +0 -0
  543. data/vendor/python/pylint/checkers/strings.py +304 -0
  544. data/vendor/python/pylint/checkers/strings.pyc +0 -0
  545. data/vendor/python/pylint/checkers/typecheck.py +451 -0
  546. data/vendor/python/pylint/checkers/typecheck.pyc +0 -0
  547. data/vendor/python/pylint/checkers/utils.py +416 -0
  548. data/vendor/python/pylint/checkers/utils.pyc +0 -0
  549. data/vendor/python/pylint/checkers/variables.py +741 -0
  550. data/vendor/python/pylint/checkers/variables.pyc +0 -0
  551. data/vendor/python/pylint/config.py +156 -0
  552. data/vendor/python/pylint/config.pyc +0 -0
  553. data/vendor/python/pylint/epylint.py +175 -0
  554. data/vendor/python/pylint/gui.py +508 -0
  555. data/vendor/python/pylint/interfaces.py +72 -0
  556. data/vendor/python/pylint/interfaces.pyc +0 -0
  557. data/vendor/python/pylint/lint.py +1106 -0
  558. data/vendor/python/pylint/lint.pyc +0 -0
  559. data/vendor/python/pylint/pyreverse/__init__.py +5 -0
  560. data/vendor/python/pylint/pyreverse/diadefslib.py +233 -0
  561. data/vendor/python/pylint/pyreverse/diagrams.py +247 -0
  562. data/vendor/python/pylint/pyreverse/main.py +124 -0
  563. data/vendor/python/pylint/pyreverse/utils.py +131 -0
  564. data/vendor/python/pylint/pyreverse/writer.py +199 -0
  565. data/vendor/python/pylint/reporters/__init__.py +138 -0
  566. data/vendor/python/pylint/reporters/__init__.pyc +0 -0
  567. data/vendor/python/pylint/reporters/guireporter.py +28 -0
  568. data/vendor/python/pylint/reporters/guireporter.pyc +0 -0
  569. data/vendor/python/pylint/reporters/html.py +70 -0
  570. data/vendor/python/pylint/reporters/html.pyc +0 -0
  571. data/vendor/python/pylint/reporters/text.py +143 -0
  572. data/vendor/python/pylint/reporters/text.pyc +0 -0
  573. data/vendor/python/pylint/setup.cfg +3 -0
  574. data/vendor/python/pylint/setup.py +203 -0
  575. data/vendor/python/pylint/tox.ini +10 -0
  576. data/vendor/python/pylint/utils.py +744 -0
  577. data/vendor/python/pylint/utils.pyc +0 -0
  578. data/vendor/python/pylint_runner.py +22 -0
  579. metadata +675 -0
@@ -0,0 +1,184 @@
1
+ # for el5, force use of python2.6
2
+ %if 0%{?el5}
3
+ %define python python26
4
+ %define __python /usr/bin/python2.6
5
+ %{!?python_scriptarch: %define python_scriptarch %(%{__python} -c "from distutils.sysconfig import get_python_lib; from os.path import join; print join(get_python_lib(1, 1), 'scripts')")}
6
+ %else
7
+ %define python python
8
+ %define __python /usr/bin/python
9
+ %endif
10
+ %{!?_python_sitelib: %define _python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")}
11
+
12
+ Name: %{python}-logilab-common
13
+ Version: 0.61.0
14
+ Release: logilab.1%{?dist}
15
+ Summary: Common libraries for Logilab projects
16
+
17
+ Group: Development/Libraries
18
+ License: LGPLv2.1+
19
+ URL: http://www.logilab.org/projects/logilab-common
20
+ Source0: http://download.logilab.org/pub/common/logilab-common-%{version}.tar.gz
21
+ BuildArch: noarch
22
+ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
23
+
24
+ BuildRequires: python-devel python-setuptools python-unittest2
25
+ Requires: mx
26
+
27
+
28
+ %description
29
+ This package contains several modules providing low level functionality
30
+ shared among some python projects developed by logilab.
31
+
32
+
33
+ %prep
34
+ %setup -q -n logilab-common-%{version}
35
+
36
+
37
+ %build
38
+ %{__python} setup.py build
39
+ %if 0%{?el5}
40
+ # change the python version in shebangs
41
+ find . -name '*.py' -type f -print0 | xargs -0 sed -i '1,3s;^#!.*python.*$;#! /usr/bin/python2.6;'
42
+ %endif
43
+
44
+
45
+ %install
46
+ rm -rf $RPM_BUILD_ROOT
47
+ NO_SETUPTOOLS=1 %{__python} setup.py install -O1 --skip-build --root $RPM_BUILD_ROOT %{?python_scriptarch: --install-scripts=%{python_scriptarch}}
48
+ rm -rf $RPM_BUILD_ROOT%{_python_sitelib}/logilab/common/test
49
+
50
+ %check
51
+ %{__python} setup.py test
52
+
53
+ %clean
54
+ rm -rf $RPM_BUILD_ROOT
55
+
56
+
57
+ %files
58
+ %defattr(-,root,root,-)
59
+ %doc README ChangeLog COPYING
60
+ %{_python_sitelib}/logilab*
61
+ %{_bindir}/*
62
+
63
+
64
+ %changelog
65
+ * Fri Nov 16 2012 Julien Cristau <julien.cristau@logilab.fr> 0.58.2-logilab.1
66
+ - Force python26 on el5
67
+
68
+ * Fri Aug 03 2012 Brian C. Lane <bcl@redhat.com> 0.58.2-1
69
+ - Upstream 0.58.2
70
+
71
+ * Sat Jul 21 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.57.1-3
72
+ - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
73
+
74
+ * Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.57.1-2
75
+ - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
76
+
77
+ * Fri Nov 18 2011 Brian C. Lane <bcl@redhat.com> - 0.57.1-1
78
+ - Upstream 0.57.1
79
+
80
+ * Fri Jul 29 2011 Brian C. Lane <bcl@redhat.com> - 0.56.0-1
81
+ - Upstream 0.56.0
82
+
83
+ * Mon Mar 28 2011 Brian C. Lane <bcl@redhat.com> - 0.55.1-1
84
+ - Upstream 0.55.1
85
+ - Add unit tests to spec
86
+
87
+ * Tue Feb 08 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.53.0-2
88
+ - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
89
+
90
+ * Mon Nov 29 2010 Brian C. Lane <bcl@redhat.com> - 0.53.0-1
91
+ - Upstream 0.53.0
92
+
93
+ * Thu Jul 22 2010 David Malcolm <dmalcolm@redhat.com> - 0.50.3-2
94
+ - Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild
95
+
96
+ * Thu Jul 08 2010 Brian C. Lane <bcl@brdhat.com> - 0.50.3-1
97
+ - Upstream 0.50.3
98
+
99
+ * Fri Mar 26 2010 Brian C. Lane <bcl@redhat.com> - 0.49.0-2
100
+ - Add python-setuptools to BuildRequires
101
+
102
+ * Thu Mar 25 2010 Brian C. Lane <bcl@redhat.com> - 0.49.0-1
103
+ - Upstream 0.49.0
104
+
105
+ * Sun Aug 30 2009 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.45.0-1
106
+ - Upstream 0.45.0 (small enhancements and bugfixes)
107
+
108
+ * Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.41.0-3
109
+ - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
110
+
111
+ * Wed Jun 17 2009 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.41.0-2
112
+ - Upstream 0.41.0
113
+ - Bugfixes and a few minor new features
114
+
115
+ * Thu Feb 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.38.0-2
116
+ - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
117
+
118
+ * Wed Jan 28 2009 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.38.0-1
119
+ - Upstream 0.38.0
120
+
121
+ * Tue Dec 30 2008 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.37.0-1
122
+ - Upstream 0.37.0
123
+
124
+ * Sat Nov 29 2008 Ignacio Vazquez-Abrams <ivazqueznet+rpm@gmail.com> - 0.32.0-2
125
+ - Rebuild for Python 2.6
126
+
127
+ * Mon Jun 30 2008 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.32.0-1
128
+ - Upstream 0.32.0
129
+
130
+ * Sun Feb 17 2008 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.28.0-1
131
+ - Upstream 0.28.0
132
+
133
+ * Thu Jan 17 2008 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.26.1-1
134
+ - Upstream 0.26.1
135
+ - Package egg-info and other files.
136
+
137
+ * Mon Dec 24 2007 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.25.2-1
138
+ - Upstream 0.25.2
139
+
140
+ * Sun Nov 18 2007 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.24.0-1
141
+ - Upstream 0.24.0
142
+ - Adjust license to the new standard
143
+
144
+ * Sun Apr 01 2007 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.21.2-1
145
+ - Upstream 0.21.2
146
+
147
+ * Sun Dec 17 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.21.0-1
148
+ - Upstream 0.21.0
149
+ - Include COPYING with docs
150
+
151
+ * Tue Sep 26 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.19.2-1
152
+ - Upstream 0.19.2
153
+ - Ghostbusting
154
+ - Require mx
155
+
156
+ * Mon May 01 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.15.0-1
157
+ - Version 0.15.0
158
+
159
+ * Sun Mar 12 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.14.1-2
160
+ - Also handle __init__.pyc and __init__.pyo
161
+
162
+ * Sun Mar 12 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.14.1-1
163
+ - Version 0.14.1
164
+
165
+ * Thu Jan 12 2006 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.13.0-1
166
+ - Version 0.13.0
167
+ - astng no longer part of the package
168
+
169
+ * Thu Nov 17 2005 Konstantin Ryabitsev <icon@fedoraproject.org> - 0.12.0-1
170
+ - Version 0.12.0
171
+
172
+ * Mon Jun 13 2005 Konstantin Ryabitsev <icon@linux.duke.edu> - 0.10.0-1
173
+ - Version 0.10.0.
174
+ - Disttagging.
175
+
176
+ * Thu May 05 2005 Konstantin Ryabitsev <icon@linux.duke.edu> - 0.9.3-3
177
+ - Fix paths.
178
+
179
+ * Tue Apr 26 2005 Konstantin Ryabitsev <icon@linux.duke.edu> - 0.9.3-2
180
+ - Ghost .pyo files.
181
+ - Get rid of test, which doesn't do anything.
182
+
183
+ * Fri Apr 22 2005 Konstantin Ryabitsev <icon@linux.duke.edu> - 0.9.3-1
184
+ - Initial packaging.
@@ -0,0 +1,1113 @@
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
+ __docformat__ = "restructuredtext en"
77
+
78
+ import sys
79
+ import types
80
+ import weakref
81
+ import traceback as tb
82
+ from os import listdir, stat
83
+ from os.path import join, isdir, exists
84
+ from logging import getLogger
85
+ from warnings import warn
86
+
87
+ from logilab.common.modutils import modpath_from_file
88
+ from logilab.common.logging_ext import set_log_methods
89
+ from logilab.common.decorators import classproperty
90
+
91
+
92
+ class RegistryException(Exception):
93
+ """Base class for registry exception."""
94
+
95
+ class RegistryNotFound(RegistryException):
96
+ """Raised when an unknown registry is requested.
97
+
98
+ This is usually a programming/typo error.
99
+ """
100
+
101
+ class ObjectNotFound(RegistryException):
102
+ """Raised when an unregistered object is requested.
103
+
104
+ This may be a programming/typo or a misconfiguration error.
105
+ """
106
+
107
+ class NoSelectableObject(RegistryException):
108
+ """Raised when no object is selectable for a given context."""
109
+ def __init__(self, args, kwargs, objects):
110
+ self.args = args
111
+ self.kwargs = kwargs
112
+ self.objects = objects
113
+
114
+ def __str__(self):
115
+ return ('args: %s, kwargs: %s\ncandidates: %s'
116
+ % (self.args, self.kwargs.keys(), self.objects))
117
+
118
+
119
+ def _modname_from_path(path, extrapath=None):
120
+ modpath = modpath_from_file(path, extrapath)
121
+ # omit '__init__' from package's name to avoid loading that module
122
+ # once for each name when it is imported by some other object
123
+ # module. This supposes import in modules are done as::
124
+ #
125
+ # from package import something
126
+ #
127
+ # not::
128
+ #
129
+ # from package.__init__ import something
130
+ #
131
+ # which seems quite correct.
132
+ if modpath[-1] == '__init__':
133
+ modpath.pop()
134
+ return '.'.join(modpath)
135
+
136
+
137
+ def _toload_info(path, extrapath, _toload=None):
138
+ """Return a dictionary of <modname>: <modpath> and an ordered list of
139
+ (file, module name) to load
140
+ """
141
+ if _toload is None:
142
+ assert isinstance(path, list)
143
+ _toload = {}, []
144
+ for fileordir in path:
145
+ if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
146
+ subfiles = [join(fileordir, fname) for fname in listdir(fileordir)]
147
+ _toload_info(subfiles, extrapath, _toload)
148
+ elif fileordir[-3:] == '.py':
149
+ modname = _modname_from_path(fileordir, extrapath)
150
+ _toload[0][modname] = fileordir
151
+ _toload[1].append((fileordir, modname))
152
+ return _toload
153
+
154
+
155
+ class RegistrableObject(object):
156
+ """This is the base class for registrable objects which are selected
157
+ according to a context.
158
+
159
+ :attr:`__registry__`
160
+ name of the registry for this object (string like 'views',
161
+ 'templates'...). You may want to define `__registries__` directly if your
162
+ object should be registered in several registries.
163
+
164
+ :attr:`__regid__`
165
+ object's identifier in the registry (string like 'main',
166
+ 'primary', 'folder_box')
167
+
168
+ :attr:`__select__`
169
+ class'selector
170
+
171
+ Moreover, the `__abstract__` attribute may be set to True to indicate that a
172
+ class is abstract and should not be registered.
173
+
174
+ You don't have to inherit from this class to put it in a registry (having
175
+ `__regid__` and `__select__` is enough), though this is needed for classes
176
+ that should be automatically registered.
177
+ """
178
+
179
+ __registry__ = None
180
+ __regid__ = None
181
+ __select__ = None
182
+ __abstract__ = True # see doc snipppets below (in Registry class)
183
+
184
+ @classproperty
185
+ def __registries__(cls):
186
+ if cls.__registry__ is None:
187
+ return ()
188
+ return (cls.__registry__,)
189
+
190
+
191
+ class RegistrableInstance(RegistrableObject):
192
+ """Inherit this class if you want instances of the classes to be
193
+ automatically registered.
194
+ """
195
+
196
+ def __new__(cls, *args, **kwargs):
197
+ """Add a __module__ attribute telling the module where the instance was
198
+ created, for automatic registration.
199
+ """
200
+ obj = super(RegistrableInstance, cls).__new__(cls)
201
+ # XXX subclass must no override __new__
202
+ filepath = tb.extract_stack(limit=2)[0][0]
203
+ obj.__module__ = _modname_from_path(filepath)
204
+ return obj
205
+
206
+
207
+ class Registry(dict):
208
+ """The registry store a set of implementations associated to identifier:
209
+
210
+ * to each identifier are associated a list of implementations
211
+
212
+ * to select an implementation of a given identifier, you should use one of the
213
+ :meth:`select` or :meth:`select_or_none` method
214
+
215
+ * to select a list of implementations for a context, you should use the
216
+ :meth:`possible_objects` method
217
+
218
+ * dictionary like access to an identifier will return the bare list of
219
+ implementations for this identifier.
220
+
221
+ To be usable in a registry, the only requirement is to have a `__select__`
222
+ attribute.
223
+
224
+ At the end of the registration process, the :meth:`__registered__`
225
+ method is called on each registered object which have them, given the
226
+ registry in which it's registered as argument.
227
+
228
+ Registration methods:
229
+
230
+ .. automethod: register
231
+ .. automethod: unregister
232
+
233
+ Selection methods:
234
+
235
+ .. automethod: select
236
+ .. automethod: select_or_none
237
+ .. automethod: possible_objects
238
+ .. automethod: object_by_id
239
+ """
240
+ def __init__(self, debugmode):
241
+ super(Registry, self).__init__()
242
+ self.debugmode = debugmode
243
+
244
+ def __getitem__(self, name):
245
+ """return the registry (list of implementation objects) associated to
246
+ this name
247
+ """
248
+ try:
249
+ return super(Registry, self).__getitem__(name)
250
+ except KeyError:
251
+ raise ObjectNotFound(name), None, sys.exc_info()[-1]
252
+
253
+ @classmethod
254
+ def objid(cls, obj):
255
+ """returns a unique identifier for an object stored in the registry"""
256
+ return '%s.%s' % (obj.__module__, cls.objname(obj))
257
+
258
+ @classmethod
259
+ def objname(cls, obj):
260
+ """returns a readable name for an object stored in the registry"""
261
+ return getattr(obj, '__name__', id(obj))
262
+
263
+ def initialization_completed(self):
264
+ """call method __registered__() on registered objects when the callback
265
+ is defined"""
266
+ for objects in self.itervalues():
267
+ for objectcls in objects:
268
+ registered = getattr(objectcls, '__registered__', None)
269
+ if registered:
270
+ registered(self)
271
+ if self.debugmode:
272
+ wrap_predicates(_lltrace)
273
+
274
+ def register(self, obj, oid=None, clear=False):
275
+ """base method to add an object in the registry"""
276
+ assert not '__abstract__' in obj.__dict__, obj
277
+ assert obj.__select__, obj
278
+ oid = oid or obj.__regid__
279
+ assert oid, ('no explicit name supplied to register object %s, '
280
+ 'which has no __regid__ set' % obj)
281
+ if clear:
282
+ objects = self[oid] = []
283
+ else:
284
+ objects = self.setdefault(oid, [])
285
+ assert not obj in objects, 'object %s is already registered' % obj
286
+ objects.append(obj)
287
+
288
+ def register_and_replace(self, obj, replaced):
289
+ """remove <replaced> and register <obj>"""
290
+ # XXXFIXME this is a duplication of unregister()
291
+ # remove register_and_replace in favor of unregister + register
292
+ # or simplify by calling unregister then register here
293
+ if not isinstance(replaced, basestring):
294
+ replaced = self.objid(replaced)
295
+ # prevent from misspelling
296
+ assert obj is not replaced, 'replacing an object by itself: %s' % obj
297
+ registered_objs = self.get(obj.__regid__, ())
298
+ for index, registered in enumerate(registered_objs):
299
+ if self.objid(registered) == replaced:
300
+ del registered_objs[index]
301
+ break
302
+ else:
303
+ self.warning('trying to replace %s that is not registered with %s',
304
+ replaced, obj)
305
+ self.register(obj)
306
+
307
+ def unregister(self, obj):
308
+ """remove object <obj> from this registry"""
309
+ objid = self.objid(obj)
310
+ oid = obj.__regid__
311
+ for registered in self.get(oid, ()):
312
+ # use self.objid() to compare objects because vreg will probably
313
+ # have its own version of the object, loaded through execfile
314
+ if self.objid(registered) == objid:
315
+ self[oid].remove(registered)
316
+ break
317
+ else:
318
+ self.warning('can\'t remove %s, no id %s in the registry',
319
+ objid, oid)
320
+
321
+ def all_objects(self):
322
+ """return a list containing all objects in this registry.
323
+ """
324
+ result = []
325
+ for objs in self.values():
326
+ result += objs
327
+ return result
328
+
329
+ # dynamic selection methods ################################################
330
+
331
+ def object_by_id(self, oid, *args, **kwargs):
332
+ """return object with the `oid` identifier. Only one object is expected
333
+ to be found.
334
+
335
+ raise :exc:`ObjectNotFound` if there are no object with id `oid` in this
336
+ registry
337
+
338
+ raise :exc:`AssertionError` if there is more than one object there
339
+ """
340
+ objects = self[oid]
341
+ assert len(objects) == 1, objects
342
+ return objects[0](*args, **kwargs)
343
+
344
+ def select(self, __oid, *args, **kwargs):
345
+ """return the most specific object among those with the given oid
346
+ according to the given context.
347
+
348
+ raise :exc:`ObjectNotFound` if there are no object with id `oid` in this
349
+ registry
350
+
351
+ raise :exc:`NoSelectableObject` if no object can be selected
352
+ """
353
+ obj = self._select_best(self[__oid], *args, **kwargs)
354
+ if obj is None:
355
+ raise NoSelectableObject(args, kwargs, self[__oid] )
356
+ return obj
357
+
358
+ def select_or_none(self, __oid, *args, **kwargs):
359
+ """return the most specific object among those with the given oid
360
+ according to the given context, or None if no object applies.
361
+ """
362
+ try:
363
+ return self._select_best(self[__oid], *args, **kwargs)
364
+ except ObjectNotFound:
365
+ return None
366
+
367
+ def possible_objects(self, *args, **kwargs):
368
+ """return an iterator on possible objects in this registry for the given
369
+ context
370
+ """
371
+ for objects in self.itervalues():
372
+ obj = self._select_best(objects, *args, **kwargs)
373
+ if obj is None:
374
+ continue
375
+ yield obj
376
+
377
+ def _select_best(self, objects, *args, **kwargs):
378
+ """return an instance of the most specific object according
379
+ to parameters
380
+
381
+ return None if not object apply (don't raise `NoSelectableObject` since
382
+ it's costly when searching objects using `possible_objects`
383
+ (e.g. searching for hooks).
384
+ """
385
+ score, winners = 0, None
386
+ for obj in objects:
387
+ objectscore = obj.__select__(obj, *args, **kwargs)
388
+ if objectscore > score:
389
+ score, winners = objectscore, [obj]
390
+ elif objectscore > 0 and objectscore == score:
391
+ winners.append(obj)
392
+ if winners is None:
393
+ return None
394
+ if len(winners) > 1:
395
+ # log in production environement / test, error while debugging
396
+ msg = 'select ambiguity: %s\n(args: %s, kwargs: %s)'
397
+ if self.debugmode:
398
+ # raise bare exception in debug mode
399
+ raise Exception(msg % (winners, args, kwargs.keys()))
400
+ self.error(msg, winners, args, kwargs.keys())
401
+ # return the result of calling the object
402
+ return self.selected(winners[0], args, kwargs)
403
+
404
+ def selected(self, winner, args, kwargs):
405
+ """override here if for instance you don't want "instanciation"
406
+ """
407
+ return winner(*args, **kwargs)
408
+
409
+ # these are overridden by set_log_methods below
410
+ # only defining here to prevent pylint from complaining
411
+ info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
412
+
413
+
414
+ def obj_registries(cls, registryname=None):
415
+ """return a tuple of registry names (see __registries__)"""
416
+ if registryname:
417
+ return (registryname,)
418
+ return cls.__registries__
419
+
420
+
421
+ class RegistryStore(dict):
422
+ """This class is responsible for loading objects and storing them
423
+ in their registry which is created on the fly as needed.
424
+
425
+ It handles dynamic registration of objects and provides a
426
+ convenient api to access them. To be recognized as an object that
427
+ should be stored into one of the store's registry
428
+ (:class:`Registry`), an object must provide the following
429
+ attributes, used control how they interact with the registry:
430
+
431
+ :attr:`__registries__`
432
+ list of registry names (string like 'views', 'templates'...) into which
433
+ the object should be registered
434
+
435
+ :attr:`__regid__`
436
+ object identifier in the registry (string like 'main',
437
+ 'primary', 'folder_box')
438
+
439
+ :attr:`__select__`
440
+ the object predicate selectors
441
+
442
+ Moreover, the :attr:`__abstract__` attribute may be set to `True`
443
+ to indicate that an object is abstract and should not be registered
444
+ (such inherited attributes not considered).
445
+
446
+ .. Note::
447
+
448
+ When using the store to load objects dynamically, you *always* have
449
+ to use **super()** to get the methods and attributes of the
450
+ superclasses, and not use the class identifier. If not, you'll get into
451
+ trouble at reload time.
452
+
453
+ For example, instead of writing::
454
+
455
+ class Thing(Parent):
456
+ __regid__ = 'athing'
457
+ __select__ = yes()
458
+
459
+ def f(self, arg1):
460
+ Parent.f(self, arg1)
461
+
462
+ You must write::
463
+
464
+ class Thing(Parent):
465
+ __regid__ = 'athing'
466
+ __select__ = yes()
467
+
468
+ def f(self, arg1):
469
+ super(Thing, self).f(arg1)
470
+
471
+ Controlling object registration
472
+ -------------------------------
473
+
474
+ Dynamic loading is triggered by calling the
475
+ :meth:`register_objects` method, given a list of directories to
476
+ inspect for python modules.
477
+
478
+ .. automethod: register_objects
479
+
480
+ For each module, by default, all compatible objects are registered
481
+ automatically. However if some objects come as replacement of
482
+ other objects, or have to be included only if some condition is
483
+ met, you'll have to define a `registration_callback(vreg)`
484
+ function in the module and explicitly register **all objects** in
485
+ this module, using the api defined below.
486
+
487
+
488
+ .. automethod:: RegistryStore.register_all
489
+ .. automethod:: RegistryStore.register_and_replace
490
+ .. automethod:: RegistryStore.register
491
+ .. automethod:: RegistryStore.unregister
492
+
493
+ .. Note::
494
+ Once the function `registration_callback(vreg)` is implemented in a
495
+ module, all the objects from this module have to be explicitly
496
+ registered as it disables the automatic object registration.
497
+
498
+
499
+ Examples:
500
+
501
+ .. sourcecode:: python
502
+
503
+ def registration_callback(store):
504
+ # register everything in the module except BabarClass
505
+ store.register_all(globals().values(), __name__, (BabarClass,))
506
+
507
+ # conditionally register BabarClass
508
+ if 'babar_relation' in store.schema:
509
+ store.register(BabarClass)
510
+
511
+ In this example, we register all application object classes defined in the module
512
+ except `BabarClass`. This class is then registered only if the 'babar_relation'
513
+ relation type is defined in the instance schema.
514
+
515
+ .. sourcecode:: python
516
+
517
+ def registration_callback(store):
518
+ store.register(Elephant)
519
+ # replace Babar by Celeste
520
+ store.register_and_replace(Celeste, Babar)
521
+
522
+ In this example, we explicitly register classes one by one:
523
+
524
+ * the `Elephant` class
525
+ * the `Celeste` to replace `Babar`
526
+
527
+ If at some point we register a new appobject class in this module, it won't be
528
+ registered at all without modification to the `registration_callback`
529
+ implementation. The first example will register it though, thanks to the call
530
+ to the `register_all` method.
531
+
532
+ Controlling registry instantiation
533
+ ----------------------------------
534
+
535
+ The `REGISTRY_FACTORY` class dictionary allows to specify which class should
536
+ be instantiated for a given registry name. The class associated to `None`
537
+ key will be the class used when there is no specific class for a name.
538
+ """
539
+
540
+ def __init__(self, debugmode=False):
541
+ super(RegistryStore, self).__init__()
542
+ self.debugmode = debugmode
543
+
544
+ def reset(self):
545
+ """clear all registries managed by this store"""
546
+ # don't use self.clear, we want to keep existing subdictionaries
547
+ for subdict in self.itervalues():
548
+ subdict.clear()
549
+ self._lastmodifs = {}
550
+
551
+ def __getitem__(self, name):
552
+ """return the registry (dictionary of class objects) associated to
553
+ this name
554
+ """
555
+ try:
556
+ return super(RegistryStore, self).__getitem__(name)
557
+ except KeyError:
558
+ raise RegistryNotFound(name), None, sys.exc_info()[-1]
559
+
560
+ # methods for explicit (un)registration ###################################
561
+
562
+ # default class, when no specific class set
563
+ REGISTRY_FACTORY = {None: Registry}
564
+
565
+ def registry_class(self, regid):
566
+ """return existing registry named regid or use factory to create one and
567
+ return it"""
568
+ try:
569
+ return self.REGISTRY_FACTORY[regid]
570
+ except KeyError:
571
+ return self.REGISTRY_FACTORY[None]
572
+
573
+ def setdefault(self, regid):
574
+ try:
575
+ return self[regid]
576
+ except RegistryNotFound:
577
+ self[regid] = self.registry_class(regid)(self.debugmode)
578
+ return self[regid]
579
+
580
+ def register_all(self, objects, modname, butclasses=()):
581
+ """register registrable objects into `objects`.
582
+
583
+ Registrable objects are properly configured subclasses of
584
+ :class:`RegistrableObject`. Objects which are not defined in the module
585
+ `modname` or which are in `butclasses` won't be registered.
586
+
587
+ Typical usage is:
588
+
589
+ .. sourcecode:: python
590
+
591
+ store.register_all(globals().values(), __name__, (ClassIWantToRegisterExplicitly,))
592
+
593
+ So you get partially automatic registration, keeping manual registration
594
+ for some object (to use
595
+ :meth:`~logilab.common.registry.RegistryStore.register_and_replace` for
596
+ instance).
597
+ """
598
+ assert isinstance(modname, basestring), \
599
+ 'modname expected to be a module name (ie string), got %r' % modname
600
+ for obj in objects:
601
+ if self.is_registrable(obj) and obj.__module__ == modname and not obj in butclasses:
602
+ if isinstance(obj, type):
603
+ self._load_ancestors_then_object(modname, obj, butclasses)
604
+ else:
605
+ self.register(obj)
606
+
607
+ def register(self, obj, registryname=None, oid=None, clear=False):
608
+ """register `obj` implementation into `registryname` or
609
+ `obj.__registries__` if not specified, with identifier `oid` or
610
+ `obj.__regid__` if not specified.
611
+
612
+ If `clear` is true, all objects with the same identifier will be
613
+ previously unregistered.
614
+ """
615
+ assert not obj.__dict__.get('__abstract__'), obj
616
+ for registryname in obj_registries(obj, registryname):
617
+ registry = self.setdefault(registryname)
618
+ registry.register(obj, oid=oid, clear=clear)
619
+ self.debug("register %s in %s['%s']",
620
+ registry.objname(obj), registryname, oid or obj.__regid__)
621
+ self._loadedmods.setdefault(obj.__module__, {})[registry.objid(obj)] = obj
622
+
623
+ def unregister(self, obj, registryname=None):
624
+ """unregister `obj` object from the registry `registryname` or
625
+ `obj.__registries__` if not specified.
626
+ """
627
+ for registryname in obj_registries(obj, registryname):
628
+ registry = self[registryname]
629
+ registry.unregister(obj)
630
+ self.debug("unregister %s from %s['%s']",
631
+ registry.objname(obj), registryname, obj.__regid__)
632
+
633
+ def register_and_replace(self, obj, replaced, registryname=None):
634
+ """register `obj` object into `registryname` or
635
+ `obj.__registries__` if not specified. If found, the `replaced` object
636
+ will be unregistered first (else a warning will be issued as it is
637
+ generally unexpected).
638
+ """
639
+ for registryname in obj_registries(obj, registryname):
640
+ registry = self[registryname]
641
+ registry.register_and_replace(obj, replaced)
642
+ self.debug("register %s in %s['%s'] instead of %s",
643
+ registry.objname(obj), registryname, obj.__regid__,
644
+ registry.objname(replaced))
645
+
646
+ # initialization methods ###################################################
647
+
648
+ def init_registration(self, path, extrapath=None):
649
+ """reset registry and walk down path to return list of (path, name)
650
+ file modules to be loaded"""
651
+ # XXX make this private by renaming it to _init_registration ?
652
+ self.reset()
653
+ # compute list of all modules that have to be loaded
654
+ self._toloadmods, filemods = _toload_info(path, extrapath)
655
+ # XXX is _loadedmods still necessary ? It seems like it's useful
656
+ # to avoid loading same module twice, especially with the
657
+ # _load_ancestors_then_object logic but this needs to be checked
658
+ self._loadedmods = {}
659
+ return filemods
660
+
661
+ def register_objects(self, path, extrapath=None):
662
+ """register all objects found walking down <path>"""
663
+ # load views from each directory in the instance's path
664
+ # XXX inline init_registration ?
665
+ filemods = self.init_registration(path, extrapath)
666
+ for filepath, modname in filemods:
667
+ self.load_file(filepath, modname)
668
+ self.initialization_completed()
669
+
670
+ def initialization_completed(self):
671
+ """call initialization_completed() on all known registries"""
672
+ for reg in self.itervalues():
673
+ reg.initialization_completed()
674
+
675
+ def _mdate(self, filepath):
676
+ """ return the modification date of a file path """
677
+ try:
678
+ return stat(filepath)[-2]
679
+ except OSError:
680
+ # this typically happens on emacs backup files (.#foo.py)
681
+ self.warning('Unable to load %s. It is likely to be a backup file',
682
+ filepath)
683
+ return None
684
+
685
+ def is_reload_needed(self, path):
686
+ """return True if something module changed and the registry should be
687
+ reloaded
688
+ """
689
+ lastmodifs = self._lastmodifs
690
+ for fileordir in path:
691
+ if isdir(fileordir) and exists(join(fileordir, '__init__.py')):
692
+ if self.is_reload_needed([join(fileordir, fname)
693
+ for fname in listdir(fileordir)]):
694
+ return True
695
+ elif fileordir[-3:] == '.py':
696
+ mdate = self._mdate(fileordir)
697
+ if mdate is None:
698
+ continue # backup file, see _mdate implementation
699
+ elif "flymake" in fileordir:
700
+ # flymake + pylint in use, don't consider these they will corrupt the registry
701
+ continue
702
+ if fileordir not in lastmodifs or lastmodifs[fileordir] < mdate:
703
+ self.info('File %s changed since last visit', fileordir)
704
+ return True
705
+ return False
706
+
707
+ def load_file(self, filepath, modname):
708
+ """ load registrable objects (if any) from a python file """
709
+ from logilab.common.modutils import load_module_from_name
710
+ if modname in self._loadedmods:
711
+ return
712
+ self._loadedmods[modname] = {}
713
+ mdate = self._mdate(filepath)
714
+ if mdate is None:
715
+ return # backup file, see _mdate implementation
716
+ elif "flymake" in filepath:
717
+ # flymake + pylint in use, don't consider these they will corrupt the registry
718
+ return
719
+ # set update time before module loading, else we get some reloading
720
+ # weirdness in case of syntax error or other error while importing the
721
+ # module
722
+ self._lastmodifs[filepath] = mdate
723
+ # load the module
724
+ module = load_module_from_name(modname)
725
+ self.load_module(module)
726
+
727
+ def load_module(self, module):
728
+ """Automatically handle module objects registration.
729
+
730
+ Instances are registered as soon as they are hashable and have the
731
+ following attributes:
732
+
733
+ * __regid__ (a string)
734
+ * __select__ (a callable)
735
+ * __registries__ (a tuple/list of string)
736
+
737
+ For classes this is a bit more complicated :
738
+
739
+ - first ensure parent classes are already registered
740
+
741
+ - class with __abstract__ == True in their local dictionary are skipped
742
+
743
+ - object class needs to have registries and identifier properly set to a
744
+ non empty string to be registered.
745
+ """
746
+ self.info('loading %s from %s', module.__name__, module.__file__)
747
+ if hasattr(module, 'registration_callback'):
748
+ module.registration_callback(self)
749
+ else:
750
+ self.register_all(vars(module).itervalues(), module.__name__)
751
+
752
+ def _load_ancestors_then_object(self, modname, objectcls, butclasses=()):
753
+ """handle class registration according to rules defined in
754
+ :meth:`load_module`
755
+ """
756
+ # backward compat, we used to allow whatever else than classes
757
+ if not isinstance(objectcls, type):
758
+ if self.is_registrable(objectcls) and objectcls.__module__ == modname:
759
+ self.register(objectcls)
760
+ return
761
+ # imported classes
762
+ objmodname = objectcls.__module__
763
+ if objmodname != modname:
764
+ # The module of the object is not the same as the currently
765
+ # worked on module, or this is actually an instance, which
766
+ # has no module at all
767
+ if objmodname in self._toloadmods:
768
+ # if this is still scheduled for loading, let's proceed immediately,
769
+ # but using the object module
770
+ self.load_file(self._toloadmods[objmodname], objmodname)
771
+ return
772
+ # ensure object hasn't been already processed
773
+ clsid = '%s.%s' % (modname, objectcls.__name__)
774
+ if clsid in self._loadedmods[modname]:
775
+ return
776
+ self._loadedmods[modname][clsid] = objectcls
777
+ # ensure ancestors are registered
778
+ for parent in objectcls.__bases__:
779
+ self._load_ancestors_then_object(modname, parent, butclasses)
780
+ # ensure object is registrable
781
+ if objectcls in butclasses or not self.is_registrable(objectcls):
782
+ return
783
+ # backward compat
784
+ reg = self.setdefault(obj_registries(objectcls)[0])
785
+ if reg.objname(objectcls)[0] == '_':
786
+ warn("[lgc 0.59] object whose name start with '_' won't be "
787
+ "skipped anymore at some point, use __abstract__ = True "
788
+ "instead (%s)" % objectcls, DeprecationWarning)
789
+ return
790
+ # register, finally
791
+ self.register(objectcls)
792
+
793
+ @classmethod
794
+ def is_registrable(cls, obj):
795
+ """ensure `obj` should be registered
796
+
797
+ as arbitrary stuff may be registered, do a lot of check and warn about
798
+ weird cases (think to dumb proxy objects)
799
+ """
800
+ if isinstance(obj, type):
801
+ if not issubclass(obj, RegistrableObject):
802
+ # ducktyping backward compat
803
+ if not (getattr(obj, '__registries__', None)
804
+ and getattr(obj, '__regid__', None)
805
+ and getattr(obj, '__select__', None)):
806
+ return False
807
+ elif issubclass(obj, RegistrableInstance):
808
+ return False
809
+ elif not isinstance(obj, RegistrableInstance):
810
+ return False
811
+ if not obj.__regid__:
812
+ return False # no regid
813
+ registries = obj.__registries__
814
+ if not registries:
815
+ return False # no registries
816
+ selector = obj.__select__
817
+ if not selector:
818
+ return False # no selector
819
+ if obj.__dict__.get('__abstract__', False):
820
+ return False
821
+ # then detect potential problems that should be warned
822
+ if not isinstance(registries, (tuple, list)):
823
+ cls.warning('%s has __registries__ which is not a list or tuple', obj)
824
+ return False
825
+ if not callable(selector):
826
+ cls.warning('%s has not callable __select__', obj)
827
+ return False
828
+ return True
829
+
830
+ # these are overridden by set_log_methods below
831
+ # only defining here to prevent pylint from complaining
832
+ info = warning = error = critical = exception = debug = lambda msg, *a, **kw: None
833
+
834
+
835
+ # init logging
836
+ set_log_methods(RegistryStore, getLogger('registry.store'))
837
+ set_log_methods(Registry, getLogger('registry'))
838
+
839
+
840
+ # helpers for debugging selectors
841
+ TRACED_OIDS = None
842
+
843
+ def _trace_selector(cls, selector, args, ret):
844
+ vobj = args[0]
845
+ if TRACED_OIDS == 'all' or vobj.__regid__ in TRACED_OIDS:
846
+ print '%s -> %s for %s(%s)' % (cls, ret, vobj, vobj.__regid__)
847
+
848
+ def _lltrace(selector):
849
+ """use this decorator on your predicates so they become traceable with
850
+ :class:`traced_selection`
851
+ """
852
+ def traced(cls, *args, **kwargs):
853
+ ret = selector(cls, *args, **kwargs)
854
+ if TRACED_OIDS is not None:
855
+ _trace_selector(cls, selector, args, ret)
856
+ return ret
857
+ traced.__name__ = selector.__name__
858
+ traced.__doc__ = selector.__doc__
859
+ return traced
860
+
861
+ class traced_selection(object): # pylint: disable=C0103
862
+ """
863
+ Typical usage is :
864
+
865
+ .. sourcecode:: python
866
+
867
+ >>> from logilab.common.registry import traced_selection
868
+ >>> with traced_selection():
869
+ ... # some code in which you want to debug selectors
870
+ ... # for all objects
871
+
872
+ Don't forget the 'from __future__ import with_statement' at the module top-level
873
+ if you're using python prior to 2.6.
874
+
875
+ This will yield lines like this in the logs::
876
+
877
+ selector one_line_rset returned 0 for <class 'elephant.Babar'>
878
+
879
+ You can also give to :class:`traced_selection` the identifiers of objects on
880
+ which you want to debug selection ('oid1' and 'oid2' in the example above).
881
+
882
+ .. sourcecode:: python
883
+
884
+ >>> with traced_selection( ('regid1', 'regid2') ):
885
+ ... # some code in which you want to debug selectors
886
+ ... # for objects with __regid__ 'regid1' and 'regid2'
887
+
888
+ A potentially useful point to set up such a tracing function is
889
+ the `logilab.common.registry.Registry.select` method body.
890
+ """
891
+
892
+ def __init__(self, traced='all'):
893
+ self.traced = traced
894
+
895
+ def __enter__(self):
896
+ global TRACED_OIDS
897
+ TRACED_OIDS = self.traced
898
+
899
+ def __exit__(self, exctype, exc, traceback):
900
+ global TRACED_OIDS
901
+ TRACED_OIDS = None
902
+ return traceback is None
903
+
904
+ # selector base classes and operations ########################################
905
+
906
+ def objectify_predicate(selector_func):
907
+ """Most of the time, a simple score function is enough to build a selector.
908
+ The :func:`objectify_predicate` decorator turn it into a proper selector
909
+ class::
910
+
911
+ @objectify_predicate
912
+ def one(cls, req, rset=None, **kwargs):
913
+ return 1
914
+
915
+ class MyView(View):
916
+ __select__ = View.__select__ & one()
917
+
918
+ """
919
+ return type(selector_func.__name__, (Predicate,),
920
+ {'__doc__': selector_func.__doc__,
921
+ '__call__': lambda self, *a, **kw: selector_func(*a, **kw)})
922
+
923
+
924
+ _PREDICATES = {}
925
+
926
+ def wrap_predicates(decorator):
927
+ for predicate in _PREDICATES.itervalues():
928
+ if not '_decorators' in predicate.__dict__:
929
+ predicate._decorators = set()
930
+ if decorator in predicate._decorators:
931
+ continue
932
+ predicate._decorators.add(decorator)
933
+ predicate.__call__ = decorator(predicate.__call__)
934
+
935
+ class PredicateMetaClass(type):
936
+ def __new__(mcs, *args, **kwargs):
937
+ # use __new__ so subclasses doesn't have to call Predicate.__init__
938
+ inst = type.__new__(mcs, *args, **kwargs)
939
+ proxy = weakref.proxy(inst, lambda p: _PREDICATES.pop(id(p)))
940
+ _PREDICATES[id(proxy)] = proxy
941
+ return inst
942
+
943
+ class Predicate(object):
944
+ """base class for selector classes providing implementation
945
+ for operators ``&``, ``|`` and ``~``
946
+
947
+ This class is only here to give access to binary operators, the selector
948
+ logic itself should be implemented in the :meth:`__call__` method. Notice it
949
+ should usually accept any arbitrary arguments (the context), though that may
950
+ vary depending on your usage of the registry.
951
+
952
+ a selector is called to help choosing the correct object for a
953
+ particular context by returning a score (`int`) telling how well
954
+ the implementation given as first argument fit to the given context.
955
+
956
+ 0 score means that the class doesn't apply.
957
+ """
958
+ __metaclass__ = PredicateMetaClass
959
+
960
+ @property
961
+ def func_name(self):
962
+ # backward compatibility
963
+ return self.__class__.__name__
964
+
965
+ def search_selector(self, selector):
966
+ """search for the given selector, selector instance or tuple of
967
+ selectors in the selectors tree. Return None if not found.
968
+ """
969
+ if self is selector:
970
+ return self
971
+ if (isinstance(selector, type) or isinstance(selector, tuple)) and \
972
+ isinstance(self, selector):
973
+ return self
974
+ return None
975
+
976
+ def __str__(self):
977
+ return self.__class__.__name__
978
+
979
+ def __and__(self, other):
980
+ return AndPredicate(self, other)
981
+ def __rand__(self, other):
982
+ return AndPredicate(other, self)
983
+ def __iand__(self, other):
984
+ return AndPredicate(self, other)
985
+ def __or__(self, other):
986
+ return OrPredicate(self, other)
987
+ def __ror__(self, other):
988
+ return OrPredicate(other, self)
989
+ def __ior__(self, other):
990
+ return OrPredicate(self, other)
991
+
992
+ def __invert__(self):
993
+ return NotPredicate(self)
994
+
995
+ # XXX (function | function) or (function & function) not managed yet
996
+
997
+ def __call__(self, cls, *args, **kwargs):
998
+ return NotImplementedError("selector %s must implement its logic "
999
+ "in its __call__ method" % self.__class__)
1000
+
1001
+ def __repr__(self):
1002
+ return u'<Predicate %s at %x>' % (self.__class__.__name__, id(self))
1003
+
1004
+
1005
+ class MultiPredicate(Predicate):
1006
+ """base class for compound selector classes"""
1007
+
1008
+ def __init__(self, *selectors):
1009
+ self.selectors = self.merge_selectors(selectors)
1010
+
1011
+ def __str__(self):
1012
+ return '%s(%s)' % (self.__class__.__name__,
1013
+ ','.join(str(s) for s in self.selectors))
1014
+
1015
+ @classmethod
1016
+ def merge_selectors(cls, selectors):
1017
+ """deal with selector instanciation when necessary and merge
1018
+ multi-selectors if possible:
1019
+
1020
+ AndPredicate(AndPredicate(sel1, sel2), AndPredicate(sel3, sel4))
1021
+ ==> AndPredicate(sel1, sel2, sel3, sel4)
1022
+ """
1023
+ merged_selectors = []
1024
+ for selector in selectors:
1025
+ # XXX do we really want magic-transformations below?
1026
+ # if so, wanna warn about them?
1027
+ if isinstance(selector, types.FunctionType):
1028
+ selector = objectify_predicate(selector)()
1029
+ if isinstance(selector, type) and issubclass(selector, Predicate):
1030
+ selector = selector()
1031
+ assert isinstance(selector, Predicate), selector
1032
+ if isinstance(selector, cls):
1033
+ merged_selectors += selector.selectors
1034
+ else:
1035
+ merged_selectors.append(selector)
1036
+ return merged_selectors
1037
+
1038
+ def search_selector(self, selector):
1039
+ """search for the given selector or selector instance (or tuple of
1040
+ selectors) in the selectors tree. Return None if not found
1041
+ """
1042
+ for childselector in self.selectors:
1043
+ if childselector is selector:
1044
+ return childselector
1045
+ found = childselector.search_selector(selector)
1046
+ if found is not None:
1047
+ return found
1048
+ # if not found in children, maybe we are looking for self?
1049
+ return super(MultiPredicate, self).search_selector(selector)
1050
+
1051
+
1052
+ class AndPredicate(MultiPredicate):
1053
+ """and-chained selectors"""
1054
+ def __call__(self, cls, *args, **kwargs):
1055
+ score = 0
1056
+ for selector in self.selectors:
1057
+ partscore = selector(cls, *args, **kwargs)
1058
+ if not partscore:
1059
+ return 0
1060
+ score += partscore
1061
+ return score
1062
+
1063
+
1064
+ class OrPredicate(MultiPredicate):
1065
+ """or-chained selectors"""
1066
+ def __call__(self, cls, *args, **kwargs):
1067
+ for selector in self.selectors:
1068
+ partscore = selector(cls, *args, **kwargs)
1069
+ if partscore:
1070
+ return partscore
1071
+ return 0
1072
+
1073
+ class NotPredicate(Predicate):
1074
+ """negation selector"""
1075
+ def __init__(self, selector):
1076
+ self.selector = selector
1077
+
1078
+ def __call__(self, cls, *args, **kwargs):
1079
+ score = self.selector(cls, *args, **kwargs)
1080
+ return int(not score)
1081
+
1082
+ def __str__(self):
1083
+ return 'NOT(%s)' % self.selector
1084
+
1085
+
1086
+ class yes(Predicate): # pylint: disable=C0103
1087
+ """Return the score given as parameter, with a default score of 0.5 so any
1088
+ other selector take precedence.
1089
+
1090
+ Usually used for objects which can be selected whatever the context, or
1091
+ also sometimes to add arbitrary points to a score.
1092
+
1093
+ Take care, `yes(0)` could be named 'no'...
1094
+ """
1095
+ def __init__(self, score=0.5):
1096
+ self.score = score
1097
+
1098
+ def __call__(self, *args, **kwargs):
1099
+ return self.score
1100
+
1101
+
1102
+ # deprecated stuff #############################################################
1103
+
1104
+ from logilab.common.deprecation import deprecated
1105
+
1106
+ @deprecated('[lgc 0.59] use Registry.objid class method instead')
1107
+ def classid(cls):
1108
+ return '%s.%s' % (cls.__module__, cls.__name__)
1109
+
1110
+ @deprecated('[lgc 0.59] use obj_registries function instead')
1111
+ def class_registries(cls, registryname):
1112
+ return obj_registries(cls, registryname)
1113
+