busser-behave 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (418) hide show
  1. checksums.yaml +7 -0
  2. data/.cane +0 -0
  3. data/.gitignore +17 -0
  4. data/.tailor +4 -0
  5. data/.travis.yml +11 -0
  6. data/CHANGELOG.md +3 -0
  7. data/Gemfile +3 -0
  8. data/LICENSE +15 -0
  9. data/README.md +41 -0
  10. data/Rakefile +68 -0
  11. data/busser-behave.gemspec +30 -0
  12. data/features/plugin_install_command.feature +11 -0
  13. data/features/plugin_list_command.feature +8 -0
  14. data/features/support/env.rb +13 -0
  15. data/features/test_command.feature +31 -0
  16. data/lib/busser/behave/version.rb +26 -0
  17. data/lib/busser/runner_plugin/behave.rb +37 -0
  18. data/vendor/behave/CHANGES.rst +483 -0
  19. data/vendor/behave/LICENSE +23 -0
  20. data/vendor/behave/MANIFEST.in +37 -0
  21. data/vendor/behave/PROJECT_INFO.rst +21 -0
  22. data/vendor/behave/README.rst +112 -0
  23. data/vendor/behave/VERSION.txt +1 -0
  24. data/vendor/behave/behave.ini +22 -0
  25. data/vendor/behave/behave/__init__.py +30 -0
  26. data/vendor/behave/behave/__main__.py +187 -0
  27. data/vendor/behave/behave/_stepimport.py +185 -0
  28. data/vendor/behave/behave/_types.py +134 -0
  29. data/vendor/behave/behave/api/__init__.py +7 -0
  30. data/vendor/behave/behave/api/async_step.py +283 -0
  31. data/vendor/behave/behave/capture.py +227 -0
  32. data/vendor/behave/behave/compat/__init__.py +5 -0
  33. data/vendor/behave/behave/compat/collections.py +20 -0
  34. data/vendor/behave/behave/configuration.py +788 -0
  35. data/vendor/behave/behave/contrib/__init__.py +0 -0
  36. data/vendor/behave/behave/contrib/scenario_autoretry.py +73 -0
  37. data/vendor/behave/behave/formatter/__init__.py +12 -0
  38. data/vendor/behave/behave/formatter/_builtins.py +39 -0
  39. data/vendor/behave/behave/formatter/_registry.py +135 -0
  40. data/vendor/behave/behave/formatter/ansi_escapes.py +91 -0
  41. data/vendor/behave/behave/formatter/base.py +200 -0
  42. data/vendor/behave/behave/formatter/formatters.py +57 -0
  43. data/vendor/behave/behave/formatter/json.py +253 -0
  44. data/vendor/behave/behave/formatter/null.py +12 -0
  45. data/vendor/behave/behave/formatter/plain.py +158 -0
  46. data/vendor/behave/behave/formatter/pretty.py +351 -0
  47. data/vendor/behave/behave/formatter/progress.py +287 -0
  48. data/vendor/behave/behave/formatter/rerun.py +114 -0
  49. data/vendor/behave/behave/formatter/sphinx_steps.py +372 -0
  50. data/vendor/behave/behave/formatter/sphinx_util.py +118 -0
  51. data/vendor/behave/behave/formatter/steps.py +497 -0
  52. data/vendor/behave/behave/formatter/tags.py +178 -0
  53. data/vendor/behave/behave/i18n.py +614 -0
  54. data/vendor/behave/behave/importer.py +102 -0
  55. data/vendor/behave/behave/json_parser.py +264 -0
  56. data/vendor/behave/behave/log_capture.py +233 -0
  57. data/vendor/behave/behave/matchers.py +402 -0
  58. data/vendor/behave/behave/model.py +1737 -0
  59. data/vendor/behave/behave/model_core.py +416 -0
  60. data/vendor/behave/behave/model_describe.py +105 -0
  61. data/vendor/behave/behave/parser.py +615 -0
  62. data/vendor/behave/behave/reporter/__init__.py +0 -0
  63. data/vendor/behave/behave/reporter/base.py +45 -0
  64. data/vendor/behave/behave/reporter/junit.py +473 -0
  65. data/vendor/behave/behave/reporter/summary.py +94 -0
  66. data/vendor/behave/behave/runner.py +753 -0
  67. data/vendor/behave/behave/runner_util.py +417 -0
  68. data/vendor/behave/behave/step_registry.py +112 -0
  69. data/vendor/behave/behave/tag_expression.py +111 -0
  70. data/vendor/behave/behave/tag_matcher.py +465 -0
  71. data/vendor/behave/behave/textutil.py +137 -0
  72. data/vendor/behave/behave/userdata.py +130 -0
  73. data/vendor/behave/behave4cmd0/__all_steps__.py +12 -0
  74. data/vendor/behave/behave4cmd0/__init__.py +5 -0
  75. data/vendor/behave/behave4cmd0/__setup.py +11 -0
  76. data/vendor/behave/behave4cmd0/command_shell.py +216 -0
  77. data/vendor/behave/behave4cmd0/command_shell_proc.py +256 -0
  78. data/vendor/behave/behave4cmd0/command_steps.py +532 -0
  79. data/vendor/behave/behave4cmd0/command_util.py +147 -0
  80. data/vendor/behave/behave4cmd0/failing_steps.py +49 -0
  81. data/vendor/behave/behave4cmd0/log/__init__.py +1 -0
  82. data/vendor/behave/behave4cmd0/log/steps.py +395 -0
  83. data/vendor/behave/behave4cmd0/note_steps.py +29 -0
  84. data/vendor/behave/behave4cmd0/passing_steps.py +36 -0
  85. data/vendor/behave/behave4cmd0/pathutil.py +146 -0
  86. data/vendor/behave/behave4cmd0/setup_command_shell.py +24 -0
  87. data/vendor/behave/behave4cmd0/textutil.py +304 -0
  88. data/vendor/behave/bin/behave +44 -0
  89. data/vendor/behave/bin/behave.cmd +10 -0
  90. data/vendor/behave/bin/behave.junit_filter.py +85 -0
  91. data/vendor/behave/bin/behave.step_durations.py +163 -0
  92. data/vendor/behave/bin/behave2cucumber_json.py +63 -0
  93. data/vendor/behave/bin/behave_cmd.py +44 -0
  94. data/vendor/behave/bin/convert_i18n_yaml.py +77 -0
  95. data/vendor/behave/bin/explore_platform_encoding.py +24 -0
  96. data/vendor/behave/bin/i18n.yml +621 -0
  97. data/vendor/behave/bin/invoke +8 -0
  98. data/vendor/behave/bin/invoke.cmd +9 -0
  99. data/vendor/behave/bin/json.format.py +167 -0
  100. data/vendor/behave/bin/jsonschema_validate.py +122 -0
  101. data/vendor/behave/bin/make_localpi.py +279 -0
  102. data/vendor/behave/bin/project_bootstrap.sh +30 -0
  103. data/vendor/behave/bin/toxcmd.py +270 -0
  104. data/vendor/behave/bin/toxcmd3.py +270 -0
  105. data/vendor/behave/conftest.py +27 -0
  106. data/vendor/behave/docs/Makefile +154 -0
  107. data/vendor/behave/docs/_static/agogo.css +501 -0
  108. data/vendor/behave/docs/_static/behave_logo.png +0 -0
  109. data/vendor/behave/docs/_static/behave_logo1.png +0 -0
  110. data/vendor/behave/docs/_static/behave_logo2.png +0 -0
  111. data/vendor/behave/docs/_static/behave_logo3.png +0 -0
  112. data/vendor/behave/docs/_themes/LICENSE +45 -0
  113. data/vendor/behave/docs/_themes/kr/layout.html +17 -0
  114. data/vendor/behave/docs/_themes/kr/relations.html +19 -0
  115. data/vendor/behave/docs/_themes/kr/static/flasky.css_t +480 -0
  116. data/vendor/behave/docs/_themes/kr/static/small_flask.css +90 -0
  117. data/vendor/behave/docs/_themes/kr/theme.conf +7 -0
  118. data/vendor/behave/docs/_themes/kr_small/layout.html +22 -0
  119. data/vendor/behave/docs/_themes/kr_small/static/flasky.css_t +287 -0
  120. data/vendor/behave/docs/_themes/kr_small/theme.conf +10 -0
  121. data/vendor/behave/docs/api.rst +408 -0
  122. data/vendor/behave/docs/appendix.rst +19 -0
  123. data/vendor/behave/docs/behave.rst +640 -0
  124. data/vendor/behave/docs/behave.rst-template +86 -0
  125. data/vendor/behave/docs/behave_ecosystem.rst +81 -0
  126. data/vendor/behave/docs/comparison.rst +85 -0
  127. data/vendor/behave/docs/conf.py +293 -0
  128. data/vendor/behave/docs/context_attributes.rst +66 -0
  129. data/vendor/behave/docs/django.rst +192 -0
  130. data/vendor/behave/docs/formatters.rst +61 -0
  131. data/vendor/behave/docs/gherkin.rst +673 -0
  132. data/vendor/behave/docs/index.rst +57 -0
  133. data/vendor/behave/docs/install.rst +60 -0
  134. data/vendor/behave/docs/more_info.rst +184 -0
  135. data/vendor/behave/docs/new_and_noteworthy.rst +18 -0
  136. data/vendor/behave/docs/new_and_noteworthy_v1.2.4.rst +11 -0
  137. data/vendor/behave/docs/new_and_noteworthy_v1.2.5.rst +814 -0
  138. data/vendor/behave/docs/new_and_noteworthy_v1.2.6.rst +255 -0
  139. data/vendor/behave/docs/parse_builtin_types.rst +59 -0
  140. data/vendor/behave/docs/philosophy.rst +235 -0
  141. data/vendor/behave/docs/regular_expressions.rst +71 -0
  142. data/vendor/behave/docs/related.rst +14 -0
  143. data/vendor/behave/docs/test_domains.rst +62 -0
  144. data/vendor/behave/docs/tutorial.rst +636 -0
  145. data/vendor/behave/docs/update_behave_rst.py +100 -0
  146. data/vendor/behave/etc/json/behave.json-schema +172 -0
  147. data/vendor/behave/etc/junit.xml/behave_junit.xsd +103 -0
  148. data/vendor/behave/etc/junit.xml/junit-4.xsd +92 -0
  149. data/vendor/behave/examples/async_step/README.txt +8 -0
  150. data/vendor/behave/examples/async_step/behave.ini +14 -0
  151. data/vendor/behave/examples/async_step/features/async_dispatch.feature +8 -0
  152. data/vendor/behave/examples/async_step/features/async_run.feature +6 -0
  153. data/vendor/behave/examples/async_step/features/environment.py +28 -0
  154. data/vendor/behave/examples/async_step/features/steps/async_dispatch_steps.py +26 -0
  155. data/vendor/behave/examples/async_step/features/steps/async_steps34.py +10 -0
  156. data/vendor/behave/examples/async_step/features/steps/async_steps35.py +10 -0
  157. data/vendor/behave/examples/async_step/testrun_example.async_dispatch.txt +11 -0
  158. data/vendor/behave/examples/async_step/testrun_example.async_run.txt +9 -0
  159. data/vendor/behave/examples/env_vars/README.rst +26 -0
  160. data/vendor/behave/examples/env_vars/behave.ini +15 -0
  161. data/vendor/behave/examples/env_vars/behave_run.output_example.txt +12 -0
  162. data/vendor/behave/examples/env_vars/features/env_var.feature +6 -0
  163. data/vendor/behave/examples/env_vars/features/steps/env_var_steps.py +38 -0
  164. data/vendor/behave/features/README.txt +12 -0
  165. data/vendor/behave/features/background.feature +392 -0
  166. data/vendor/behave/features/capture_stderr.feature +172 -0
  167. data/vendor/behave/features/capture_stdout.feature +125 -0
  168. data/vendor/behave/features/cmdline.lang_list.feature +33 -0
  169. data/vendor/behave/features/configuration.default_paths.feature +116 -0
  170. data/vendor/behave/features/context.global_params.feature +35 -0
  171. data/vendor/behave/features/context.local_params.feature +17 -0
  172. data/vendor/behave/features/directory_layout.advanced.feature +147 -0
  173. data/vendor/behave/features/directory_layout.basic.feature +75 -0
  174. data/vendor/behave/features/directory_layout.basic2.feature +87 -0
  175. data/vendor/behave/features/environment.py +53 -0
  176. data/vendor/behave/features/exploratory_testing.with_table.feature +141 -0
  177. data/vendor/behave/features/feature.description.feature +0 -0
  178. data/vendor/behave/features/feature.exclude_from_run.feature +96 -0
  179. data/vendor/behave/features/formatter.help.feature +30 -0
  180. data/vendor/behave/features/formatter.json.feature +420 -0
  181. data/vendor/behave/features/formatter.progress3.feature +235 -0
  182. data/vendor/behave/features/formatter.rerun.feature +296 -0
  183. data/vendor/behave/features/formatter.steps.feature +181 -0
  184. data/vendor/behave/features/formatter.steps_catalog.feature +100 -0
  185. data/vendor/behave/features/formatter.steps_doc.feature +140 -0
  186. data/vendor/behave/features/formatter.steps_usage.feature +404 -0
  187. data/vendor/behave/features/formatter.tags.feature +134 -0
  188. data/vendor/behave/features/formatter.tags_location.feature +183 -0
  189. data/vendor/behave/features/formatter.user_defined.feature +196 -0
  190. data/vendor/behave/features/i18n.unicode_problems.feature +445 -0
  191. data/vendor/behave/features/logcapture.clear_handlers.feature +114 -0
  192. data/vendor/behave/features/logcapture.feature +188 -0
  193. data/vendor/behave/features/logcapture.filter.feature +130 -0
  194. data/vendor/behave/features/logging.no_capture.feature +99 -0
  195. data/vendor/behave/features/logging.setup_format.feature +157 -0
  196. data/vendor/behave/features/logging.setup_level.feature +168 -0
  197. data/vendor/behave/features/logging.setup_with_configfile.feature +137 -0
  198. data/vendor/behave/features/parser.background.sad_cases.feature +129 -0
  199. data/vendor/behave/features/parser.feature.sad_cases.feature +144 -0
  200. data/vendor/behave/features/runner.abort_by_user.feature +305 -0
  201. data/vendor/behave/features/runner.continue_after_failed_step.feature +136 -0
  202. data/vendor/behave/features/runner.default_format.feature +175 -0
  203. data/vendor/behave/features/runner.dry_run.feature +184 -0
  204. data/vendor/behave/features/runner.feature_listfile.feature +223 -0
  205. data/vendor/behave/features/runner.hook_errors.feature +382 -0
  206. data/vendor/behave/features/runner.multiple_formatters.feature +285 -0
  207. data/vendor/behave/features/runner.scenario_autoretry.feature +131 -0
  208. data/vendor/behave/features/runner.select_files_by_regexp.example.feature +71 -0
  209. data/vendor/behave/features/runner.select_files_by_regexp.feature +84 -0
  210. data/vendor/behave/features/runner.select_scenarios_by_file_location.feature +403 -0
  211. data/vendor/behave/features/runner.select_scenarios_by_name.feature +289 -0
  212. data/vendor/behave/features/runner.select_scenarios_by_tag.feature +225 -0
  213. data/vendor/behave/features/runner.stop_after_failure.feature +122 -0
  214. data/vendor/behave/features/runner.tag_logic.feature +67 -0
  215. data/vendor/behave/features/runner.unknown_formatter.feature +23 -0
  216. data/vendor/behave/features/runner.use_stage_implementations.feature +126 -0
  217. data/vendor/behave/features/scenario.description.feature +171 -0
  218. data/vendor/behave/features/scenario.exclude_from_run.feature +217 -0
  219. data/vendor/behave/features/scenario_outline.basics.feature +100 -0
  220. data/vendor/behave/features/scenario_outline.improved.feature +177 -0
  221. data/vendor/behave/features/scenario_outline.name_annotation.feature +157 -0
  222. data/vendor/behave/features/scenario_outline.parametrized.feature +401 -0
  223. data/vendor/behave/features/scenario_outline.tagged_examples.feature +118 -0
  224. data/vendor/behave/features/step.async_steps.feature +225 -0
  225. data/vendor/behave/features/step.duplicated_step.feature +106 -0
  226. data/vendor/behave/features/step.execute_steps.feature +59 -0
  227. data/vendor/behave/features/step.execute_steps.with_table.feature +65 -0
  228. data/vendor/behave/features/step.import_other_step_module.feature +103 -0
  229. data/vendor/behave/features/step.pending_steps.feature +128 -0
  230. data/vendor/behave/features/step.undefined_steps.feature +307 -0
  231. data/vendor/behave/features/step.use_step_library.feature +44 -0
  232. data/vendor/behave/features/step_dialect.generic_steps.feature +189 -0
  233. data/vendor/behave/features/step_dialect.given_when_then.feature +89 -0
  234. data/vendor/behave/features/step_param.builtin_types.with_float.feature +239 -0
  235. data/vendor/behave/features/step_param.builtin_types.with_integer.feature +305 -0
  236. data/vendor/behave/features/step_param.custom_types.feature +134 -0
  237. data/vendor/behave/features/steps/behave_active_tags_steps.py +86 -0
  238. data/vendor/behave/features/steps/behave_context_steps.py +67 -0
  239. data/vendor/behave/features/steps/behave_model_tag_logic_steps.py +105 -0
  240. data/vendor/behave/features/steps/behave_model_util.py +105 -0
  241. data/vendor/behave/features/steps/behave_select_files_steps.py +83 -0
  242. data/vendor/behave/features/steps/behave_tag_expression_steps.py +166 -0
  243. data/vendor/behave/features/steps/behave_undefined_steps.py +101 -0
  244. data/vendor/behave/features/steps/use_steplib_behave4cmd.py +12 -0
  245. data/vendor/behave/features/summary.undefined_steps.feature +114 -0
  246. data/vendor/behave/features/tags.active_tags.feature +385 -0
  247. data/vendor/behave/features/tags.default_tags.feature +104 -0
  248. data/vendor/behave/features/tags.tag_expression.feature +105 -0
  249. data/vendor/behave/features/userdata.feature +331 -0
  250. data/vendor/behave/invoke.yaml +21 -0
  251. data/vendor/behave/issue.features/README.txt +17 -0
  252. data/vendor/behave/issue.features/environment.py +97 -0
  253. data/vendor/behave/issue.features/issue0030.feature +21 -0
  254. data/vendor/behave/issue.features/issue0031.feature +16 -0
  255. data/vendor/behave/issue.features/issue0032.feature +28 -0
  256. data/vendor/behave/issue.features/issue0035.feature +74 -0
  257. data/vendor/behave/issue.features/issue0040.feature +154 -0
  258. data/vendor/behave/issue.features/issue0041.feature +135 -0
  259. data/vendor/behave/issue.features/issue0042.feature +230 -0
  260. data/vendor/behave/issue.features/issue0044.feature +51 -0
  261. data/vendor/behave/issue.features/issue0046.feature +77 -0
  262. data/vendor/behave/issue.features/issue0052.feature +66 -0
  263. data/vendor/behave/issue.features/issue0059.feature +29 -0
  264. data/vendor/behave/issue.features/issue0063.feature +102 -0
  265. data/vendor/behave/issue.features/issue0064.feature +97 -0
  266. data/vendor/behave/issue.features/issue0065.feature +18 -0
  267. data/vendor/behave/issue.features/issue0066.feature +80 -0
  268. data/vendor/behave/issue.features/issue0067.feature +90 -0
  269. data/vendor/behave/issue.features/issue0069.feature +64 -0
  270. data/vendor/behave/issue.features/issue0072.feature +32 -0
  271. data/vendor/behave/issue.features/issue0073.feature +228 -0
  272. data/vendor/behave/issue.features/issue0075.feature +18 -0
  273. data/vendor/behave/issue.features/issue0077.feature +89 -0
  274. data/vendor/behave/issue.features/issue0080.feature +49 -0
  275. data/vendor/behave/issue.features/issue0081.feature +138 -0
  276. data/vendor/behave/issue.features/issue0083.feature +69 -0
  277. data/vendor/behave/issue.features/issue0084.feature +69 -0
  278. data/vendor/behave/issue.features/issue0085.feature +119 -0
  279. data/vendor/behave/issue.features/issue0092.feature +66 -0
  280. data/vendor/behave/issue.features/issue0096.feature +173 -0
  281. data/vendor/behave/issue.features/issue0099.feature +130 -0
  282. data/vendor/behave/issue.features/issue0109.feature +60 -0
  283. data/vendor/behave/issue.features/issue0111.feature +53 -0
  284. data/vendor/behave/issue.features/issue0112.feature +64 -0
  285. data/vendor/behave/issue.features/issue0114.feature +118 -0
  286. data/vendor/behave/issue.features/issue0116.feature +71 -0
  287. data/vendor/behave/issue.features/issue0125.feature +49 -0
  288. data/vendor/behave/issue.features/issue0127.feature +64 -0
  289. data/vendor/behave/issue.features/issue0139.feature +67 -0
  290. data/vendor/behave/issue.features/issue0142.feature +37 -0
  291. data/vendor/behave/issue.features/issue0143.feature +54 -0
  292. data/vendor/behave/issue.features/issue0145.feature +63 -0
  293. data/vendor/behave/issue.features/issue0148.feature +105 -0
  294. data/vendor/behave/issue.features/issue0152.feature +52 -0
  295. data/vendor/behave/issue.features/issue0159.feature +74 -0
  296. data/vendor/behave/issue.features/issue0162.feature +86 -0
  297. data/vendor/behave/issue.features/issue0171.feature +16 -0
  298. data/vendor/behave/issue.features/issue0172.feature +51 -0
  299. data/vendor/behave/issue.features/issue0175.feature +91 -0
  300. data/vendor/behave/issue.features/issue0177.feature +40 -0
  301. data/vendor/behave/issue.features/issue0181.feature +36 -0
  302. data/vendor/behave/issue.features/issue0184.feature +144 -0
  303. data/vendor/behave/issue.features/issue0186.feature +12 -0
  304. data/vendor/behave/issue.features/issue0188.feature +60 -0
  305. data/vendor/behave/issue.features/issue0191.feature +178 -0
  306. data/vendor/behave/issue.features/issue0194.feature +215 -0
  307. data/vendor/behave/issue.features/issue0197.feature +11 -0
  308. data/vendor/behave/issue.features/issue0216.feature +129 -0
  309. data/vendor/behave/issue.features/issue0226.feature +51 -0
  310. data/vendor/behave/issue.features/issue0228.feature +41 -0
  311. data/vendor/behave/issue.features/issue0230.feature +46 -0
  312. data/vendor/behave/issue.features/issue0231.feature +77 -0
  313. data/vendor/behave/issue.features/issue0238.feature +52 -0
  314. data/vendor/behave/issue.features/issue0251.feature +15 -0
  315. data/vendor/behave/issue.features/issue0280.feature +118 -0
  316. data/vendor/behave/issue.features/issue0288.feature +95 -0
  317. data/vendor/behave/issue.features/issue0300.feature +49 -0
  318. data/vendor/behave/issue.features/issue0302.feature +91 -0
  319. data/vendor/behave/issue.features/issue0309.feature +52 -0
  320. data/vendor/behave/issue.features/issue0330.feature +124 -0
  321. data/vendor/behave/issue.features/issue0349.feature +9 -0
  322. data/vendor/behave/issue.features/issue0361.feature +79 -0
  323. data/vendor/behave/issue.features/issue0383.feature +76 -0
  324. data/vendor/behave/issue.features/issue0384.feature +103 -0
  325. data/vendor/behave/issue.features/issue0385.feature +109 -0
  326. data/vendor/behave/issue.features/issue0424.feature +66 -0
  327. data/vendor/behave/issue.features/issue0446.feature +116 -0
  328. data/vendor/behave/issue.features/issue0449.feature +42 -0
  329. data/vendor/behave/issue.features/issue0453.feature +42 -0
  330. data/vendor/behave/issue.features/issue0457.feature +65 -0
  331. data/vendor/behave/issue.features/issue0462.feature +38 -0
  332. data/vendor/behave/issue.features/issue0476.feature +39 -0
  333. data/vendor/behave/issue.features/issue0487.feature +92 -0
  334. data/vendor/behave/issue.features/issue0506.feature +77 -0
  335. data/vendor/behave/issue.features/issue0510.feature +51 -0
  336. data/vendor/behave/issue.features/requirements.txt +12 -0
  337. data/vendor/behave/issue.features/steps/ansi_steps.py +20 -0
  338. data/vendor/behave/issue.features/steps/behave_hooks_steps.py +10 -0
  339. data/vendor/behave/issue.features/steps/use_steplib_behave4cmd.py +13 -0
  340. data/vendor/behave/more.features/formatter.json.validate_output.feature +37 -0
  341. data/vendor/behave/more.features/steps/tutorial_steps.py +16 -0
  342. data/vendor/behave/more.features/steps/use_steplib_behave4cmd.py +7 -0
  343. data/vendor/behave/more.features/tutorial.feature +6 -0
  344. data/vendor/behave/py.requirements/README.txt +5 -0
  345. data/vendor/behave/py.requirements/all.txt +16 -0
  346. data/vendor/behave/py.requirements/basic.txt +21 -0
  347. data/vendor/behave/py.requirements/develop.txt +28 -0
  348. data/vendor/behave/py.requirements/docs.txt +6 -0
  349. data/vendor/behave/py.requirements/json.txt +7 -0
  350. data/vendor/behave/py.requirements/more_py26.txt +8 -0
  351. data/vendor/behave/py.requirements/testing.txt +10 -0
  352. data/vendor/behave/pytest.ini +24 -0
  353. data/vendor/behave/setup.cfg +29 -0
  354. data/vendor/behave/setup.py +118 -0
  355. data/vendor/behave/setuptools_behave.py +130 -0
  356. data/vendor/behave/tasks/__behave.py +45 -0
  357. data/vendor/behave/tasks/__init__.py +55 -0
  358. data/vendor/behave/tasks/__main__.py +70 -0
  359. data/vendor/behave/tasks/_setup.py +135 -0
  360. data/vendor/behave/tasks/_vendor/README.rst +35 -0
  361. data/vendor/behave/tasks/_vendor/invoke.zip +0 -0
  362. data/vendor/behave/tasks/_vendor/path.py +1725 -0
  363. data/vendor/behave/tasks/_vendor/pathlib.py +1280 -0
  364. data/vendor/behave/tasks/_vendor/six.py +868 -0
  365. data/vendor/behave/tasks/clean.py +246 -0
  366. data/vendor/behave/tasks/docs.py +97 -0
  367. data/vendor/behave/tasks/requirements.txt +17 -0
  368. data/vendor/behave/tasks/test.py +192 -0
  369. data/vendor/behave/test/__init__.py +0 -0
  370. data/vendor/behave/test/_importer_candidate.py +3 -0
  371. data/vendor/behave/test/reporters/__init__.py +0 -0
  372. data/vendor/behave/test/reporters/test_summary.py +240 -0
  373. data/vendor/behave/test/test_ansi_escapes.py +73 -0
  374. data/vendor/behave/test/test_configuration.py +172 -0
  375. data/vendor/behave/test/test_formatter.py +265 -0
  376. data/vendor/behave/test/test_formatter_progress.py +39 -0
  377. data/vendor/behave/test/test_formatter_rerun.py +97 -0
  378. data/vendor/behave/test/test_formatter_tags.py +57 -0
  379. data/vendor/behave/test/test_importer.py +151 -0
  380. data/vendor/behave/test/test_log_capture.py +29 -0
  381. data/vendor/behave/test/test_matchers.py +236 -0
  382. data/vendor/behave/test/test_model.py +871 -0
  383. data/vendor/behave/test/test_parser.py +1590 -0
  384. data/vendor/behave/test/test_runner.py +1074 -0
  385. data/vendor/behave/test/test_step_registry.py +96 -0
  386. data/vendor/behave/test/test_tag_expression.py +506 -0
  387. data/vendor/behave/test/test_tag_expression2.py +462 -0
  388. data/vendor/behave/test/test_tag_matcher.py +729 -0
  389. data/vendor/behave/test/test_userdata.py +184 -0
  390. data/vendor/behave/tests/README.txt +12 -0
  391. data/vendor/behave/tests/__init__.py +0 -0
  392. data/vendor/behave/tests/api/__ONLY_PY34_or_newer.txt +0 -0
  393. data/vendor/behave/tests/api/__init__.py +0 -0
  394. data/vendor/behave/tests/api/_test_async_step34.py +130 -0
  395. data/vendor/behave/tests/api/_test_async_step35.py +75 -0
  396. data/vendor/behave/tests/api/test_async_step.py +18 -0
  397. data/vendor/behave/tests/api/testing_support.py +94 -0
  398. data/vendor/behave/tests/api/testing_support_async.py +21 -0
  399. data/vendor/behave/tests/issues/test_issue0336.py +66 -0
  400. data/vendor/behave/tests/issues/test_issue0449.py +55 -0
  401. data/vendor/behave/tests/issues/test_issue0453.py +62 -0
  402. data/vendor/behave/tests/issues/test_issue0458.py +54 -0
  403. data/vendor/behave/tests/issues/test_issue0495.py +65 -0
  404. data/vendor/behave/tests/unit/__init__.py +0 -0
  405. data/vendor/behave/tests/unit/test_behave4cmd_command_shell_proc.py +135 -0
  406. data/vendor/behave/tests/unit/test_capture.py +280 -0
  407. data/vendor/behave/tests/unit/test_model_core.py +56 -0
  408. data/vendor/behave/tests/unit/test_textutil.py +267 -0
  409. data/vendor/behave/tools/test-features/background.feature +9 -0
  410. data/vendor/behave/tools/test-features/environment.py +8 -0
  411. data/vendor/behave/tools/test-features/french.feature +11 -0
  412. data/vendor/behave/tools/test-features/outline.feature +39 -0
  413. data/vendor/behave/tools/test-features/parse.feature +10 -0
  414. data/vendor/behave/tools/test-features/step-data.feature +60 -0
  415. data/vendor/behave/tools/test-features/steps/steps.py +120 -0
  416. data/vendor/behave/tools/test-features/tags.feature +18 -0
  417. data/vendor/behave/tox.ini +159 -0
  418. metadata +562 -0
@@ -0,0 +1,1280 @@
1
+ import fnmatch
2
+ import functools
3
+ import io
4
+ import ntpath
5
+ import os
6
+ import posixpath
7
+ import re
8
+ import sys
9
+ import time
10
+ from collections import Sequence
11
+ from contextlib import contextmanager
12
+ from errno import EINVAL, ENOENT
13
+ from operator import attrgetter
14
+ from stat import S_ISDIR, S_ISLNK, S_ISREG, S_ISSOCK, S_ISBLK, S_ISCHR, S_ISFIFO
15
+ try:
16
+ from urllib import quote as urlquote, quote as urlquote_from_bytes
17
+ except ImportError:
18
+ from urllib.parse import quote as urlquote, quote_from_bytes as urlquote_from_bytes
19
+
20
+
21
+ try:
22
+ intern = intern
23
+ except NameError:
24
+ intern = sys.intern
25
+ try:
26
+ basestring = basestring
27
+ except NameError:
28
+ basestring = str
29
+
30
+ supports_symlinks = True
31
+ try:
32
+ import nt
33
+ except ImportError:
34
+ nt = None
35
+ else:
36
+ if sys.getwindowsversion()[:2] >= (6, 0) and sys.version_info >= (3, 2):
37
+ from nt import _getfinalpathname
38
+ else:
39
+ supports_symlinks = False
40
+ _getfinalpathname = None
41
+
42
+
43
+ __all__ = [
44
+ "PurePath", "PurePosixPath", "PureWindowsPath",
45
+ "Path", "PosixPath", "WindowsPath",
46
+ ]
47
+
48
+ #
49
+ # Internals
50
+ #
51
+
52
+ _py2 = sys.version_info < (3,)
53
+ _py2_fs_encoding = 'ascii'
54
+
55
+ def _py2_fsencode(parts):
56
+ # py2 => minimal unicode support
57
+ return [part.encode(_py2_fs_encoding) if isinstance(part, unicode)
58
+ else part for part in parts]
59
+
60
+ def _is_wildcard_pattern(pat):
61
+ # Whether this pattern needs actual matching using fnmatch, or can
62
+ # be looked up directly as a file.
63
+ return "*" in pat or "?" in pat or "[" in pat
64
+
65
+
66
+ class _Flavour(object):
67
+ """A flavour implements a particular (platform-specific) set of path
68
+ semantics."""
69
+
70
+ def __init__(self):
71
+ self.join = self.sep.join
72
+
73
+ def parse_parts(self, parts):
74
+ if _py2:
75
+ parts = _py2_fsencode(parts)
76
+ parsed = []
77
+ sep = self.sep
78
+ altsep = self.altsep
79
+ drv = root = ''
80
+ it = reversed(parts)
81
+ for part in it:
82
+ if not part:
83
+ continue
84
+ if altsep:
85
+ part = part.replace(altsep, sep)
86
+ drv, root, rel = self.splitroot(part)
87
+ if sep in rel:
88
+ for x in reversed(rel.split(sep)):
89
+ if x and x != '.':
90
+ parsed.append(intern(x))
91
+ else:
92
+ if rel and rel != '.':
93
+ parsed.append(intern(rel))
94
+ if drv or root:
95
+ if not drv:
96
+ # If no drive is present, try to find one in the previous
97
+ # parts. This makes the result of parsing e.g.
98
+ # ("C:", "/", "a") reasonably intuitive.
99
+ for part in it:
100
+ drv = self.splitroot(part)[0]
101
+ if drv:
102
+ break
103
+ break
104
+ if drv or root:
105
+ parsed.append(drv + root)
106
+ parsed.reverse()
107
+ return drv, root, parsed
108
+
109
+ def join_parsed_parts(self, drv, root, parts, drv2, root2, parts2):
110
+ """
111
+ Join the two paths represented by the respective
112
+ (drive, root, parts) tuples. Return a new (drive, root, parts) tuple.
113
+ """
114
+ if root2:
115
+ if not drv2 and drv:
116
+ return drv, root2, [drv + root2] + parts2[1:]
117
+ elif drv2:
118
+ if drv2 == drv or self.casefold(drv2) == self.casefold(drv):
119
+ # Same drive => second path is relative to the first
120
+ return drv, root, parts + parts2[1:]
121
+ else:
122
+ # Second path is non-anchored (common case)
123
+ return drv, root, parts + parts2
124
+ return drv2, root2, parts2
125
+
126
+
127
+ class _WindowsFlavour(_Flavour):
128
+ # Reference for Windows paths can be found at
129
+ # http://msdn.microsoft.com/en-us/library/aa365247%28v=vs.85%29.aspx
130
+
131
+ sep = '\\'
132
+ altsep = '/'
133
+ has_drv = True
134
+ pathmod = ntpath
135
+
136
+ is_supported = (nt is not None)
137
+
138
+ drive_letters = (
139
+ set(chr(x) for x in range(ord('a'), ord('z') + 1)) |
140
+ set(chr(x) for x in range(ord('A'), ord('Z') + 1))
141
+ )
142
+ ext_namespace_prefix = '\\\\?\\'
143
+
144
+ reserved_names = (
145
+ set(['CON', 'PRN', 'AUX', 'NUL']) |
146
+ set(['COM%d' % i for i in range(1, 10)]) |
147
+ set(['LPT%d' % i for i in range(1, 10)])
148
+ )
149
+
150
+ # Interesting findings about extended paths:
151
+ # - '\\?\c:\a', '//?/c:\a' and '//?/c:/a' are all supported
152
+ # but '\\?\c:/a' is not
153
+ # - extended paths are always absolute; "relative" extended paths will
154
+ # fail.
155
+
156
+ def splitroot(self, part, sep=sep):
157
+ first = part[0:1]
158
+ second = part[1:2]
159
+ if (second == sep and first == sep):
160
+ # XXX extended paths should also disable the collapsing of "."
161
+ # components (according to MSDN docs).
162
+ prefix, part = self._split_extended_path(part)
163
+ first = part[0:1]
164
+ second = part[1:2]
165
+ else:
166
+ prefix = ''
167
+ third = part[2:3]
168
+ if (second == sep and first == sep and third != sep):
169
+ # is a UNC path:
170
+ # vvvvvvvvvvvvvvvvvvvvv root
171
+ # \\machine\mountpoint\directory\etc\...
172
+ # directory ^^^^^^^^^^^^^^
173
+ index = part.find(sep, 2)
174
+ if index != -1:
175
+ index2 = part.find(sep, index + 1)
176
+ # a UNC path can't have two slashes in a row
177
+ # (after the initial two)
178
+ if index2 != index + 1:
179
+ if index2 == -1:
180
+ index2 = len(part)
181
+ if prefix:
182
+ return prefix + part[1:index2], sep, part[index2+1:]
183
+ else:
184
+ return part[:index2], sep, part[index2+1:]
185
+ drv = root = ''
186
+ if second == ':' and first in self.drive_letters:
187
+ drv = part[:2]
188
+ part = part[2:]
189
+ first = third
190
+ if first == sep:
191
+ root = first
192
+ part = part.lstrip(sep)
193
+ return prefix + drv, root, part
194
+
195
+ def casefold(self, s):
196
+ return s.lower()
197
+
198
+ def casefold_parts(self, parts):
199
+ return [p.lower() for p in parts]
200
+
201
+ def resolve(self, path):
202
+ s = str(path)
203
+ if not s:
204
+ return os.getcwd()
205
+ if _getfinalpathname is not None:
206
+ return self._ext_to_normal(_getfinalpathname(s))
207
+ # Means fallback on absolute
208
+ return None
209
+
210
+ def _split_extended_path(self, s, ext_prefix=ext_namespace_prefix):
211
+ prefix = ''
212
+ if s.startswith(ext_prefix):
213
+ prefix = s[:4]
214
+ s = s[4:]
215
+ if s.startswith('UNC\\'):
216
+ prefix += s[:3]
217
+ s = '\\' + s[3:]
218
+ return prefix, s
219
+
220
+ def _ext_to_normal(self, s):
221
+ # Turn back an extended path into a normal DOS-like path
222
+ return self._split_extended_path(s)[1]
223
+
224
+ def is_reserved(self, parts):
225
+ # NOTE: the rules for reserved names seem somewhat complicated
226
+ # (e.g. r"..\NUL" is reserved but not r"foo\NUL").
227
+ # We err on the side of caution and return True for paths which are
228
+ # not considered reserved by Windows.
229
+ if not parts:
230
+ return False
231
+ if parts[0].startswith('\\\\'):
232
+ # UNC paths are never reserved
233
+ return False
234
+ return parts[-1].partition('.')[0].upper() in self.reserved_names
235
+
236
+ def make_uri(self, path):
237
+ # Under Windows, file URIs use the UTF-8 encoding.
238
+ drive = path.drive
239
+ if len(drive) == 2 and drive[1] == ':':
240
+ # It's a path on a local drive => 'file:///c:/a/b'
241
+ rest = path.as_posix()[2:].lstrip('/')
242
+ return 'file:///%s/%s' % (
243
+ drive, urlquote_from_bytes(rest.encode('utf-8')))
244
+ else:
245
+ # It's a path on a network drive => 'file://host/share/a/b'
246
+ return 'file:' + urlquote_from_bytes(path.as_posix().encode('utf-8'))
247
+
248
+
249
+ class _PosixFlavour(_Flavour):
250
+ sep = '/'
251
+ altsep = ''
252
+ has_drv = False
253
+ pathmod = posixpath
254
+
255
+ is_supported = (os.name != 'nt')
256
+
257
+ def splitroot(self, part, sep=sep):
258
+ if part and part[0] == sep:
259
+ stripped_part = part.lstrip(sep)
260
+ # According to POSIX path resolution:
261
+ # http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap04.html#tag_04_11
262
+ # "A pathname that begins with two successive slashes may be
263
+ # interpreted in an implementation-defined manner, although more
264
+ # than two leading slashes shall be treated as a single slash".
265
+ if len(part) - len(stripped_part) == 2:
266
+ return '', sep * 2, stripped_part
267
+ else:
268
+ return '', sep, stripped_part
269
+ else:
270
+ return '', '', part
271
+
272
+ def casefold(self, s):
273
+ return s
274
+
275
+ def casefold_parts(self, parts):
276
+ return parts
277
+
278
+ def resolve(self, path):
279
+ sep = self.sep
280
+ accessor = path._accessor
281
+ seen = {}
282
+ def _resolve(path, rest):
283
+ if rest.startswith(sep):
284
+ path = ''
285
+
286
+ for name in rest.split(sep):
287
+ if not name or name == '.':
288
+ # current dir
289
+ continue
290
+ if name == '..':
291
+ # parent dir
292
+ path, _, _ = path.rpartition(sep)
293
+ continue
294
+ newpath = path + sep + name
295
+ if newpath in seen:
296
+ # Already seen this path
297
+ path = seen[newpath]
298
+ if path is not None:
299
+ # use cached value
300
+ continue
301
+ # The symlink is not resolved, so we must have a symlink loop.
302
+ raise RuntimeError("Symlink loop from %r" % newpath)
303
+ # Resolve the symbolic link
304
+ try:
305
+ target = accessor.readlink(newpath)
306
+ except OSError as e:
307
+ if e.errno != EINVAL:
308
+ raise
309
+ # Not a symlink
310
+ path = newpath
311
+ else:
312
+ seen[newpath] = None # not resolved symlink
313
+ path = _resolve(path, target)
314
+ seen[newpath] = path # resolved symlink
315
+
316
+ return path
317
+ # NOTE: according to POSIX, getcwd() cannot contain path components
318
+ # which are symlinks.
319
+ base = '' if path.is_absolute() else os.getcwd()
320
+ return _resolve(base, str(path)) or sep
321
+
322
+ def is_reserved(self, parts):
323
+ return False
324
+
325
+ def make_uri(self, path):
326
+ # We represent the path using the local filesystem encoding,
327
+ # for portability to other applications.
328
+ bpath = bytes(path)
329
+ return 'file://' + urlquote_from_bytes(bpath)
330
+
331
+
332
+ _windows_flavour = _WindowsFlavour()
333
+ _posix_flavour = _PosixFlavour()
334
+
335
+
336
+ class _Accessor:
337
+ """An accessor implements a particular (system-specific or not) way of
338
+ accessing paths on the filesystem."""
339
+
340
+
341
+ class _NormalAccessor(_Accessor):
342
+
343
+ def _wrap_strfunc(strfunc):
344
+ @functools.wraps(strfunc)
345
+ def wrapped(pathobj, *args):
346
+ return strfunc(str(pathobj), *args)
347
+ return staticmethod(wrapped)
348
+
349
+ def _wrap_binary_strfunc(strfunc):
350
+ @functools.wraps(strfunc)
351
+ def wrapped(pathobjA, pathobjB, *args):
352
+ return strfunc(str(pathobjA), str(pathobjB), *args)
353
+ return staticmethod(wrapped)
354
+
355
+ stat = _wrap_strfunc(os.stat)
356
+
357
+ lstat = _wrap_strfunc(os.lstat)
358
+
359
+ open = _wrap_strfunc(os.open)
360
+
361
+ listdir = _wrap_strfunc(os.listdir)
362
+
363
+ chmod = _wrap_strfunc(os.chmod)
364
+
365
+ if hasattr(os, "lchmod"):
366
+ lchmod = _wrap_strfunc(os.lchmod)
367
+ else:
368
+ def lchmod(self, pathobj, mode):
369
+ raise NotImplementedError("lchmod() not available on this system")
370
+
371
+ mkdir = _wrap_strfunc(os.mkdir)
372
+
373
+ unlink = _wrap_strfunc(os.unlink)
374
+
375
+ rmdir = _wrap_strfunc(os.rmdir)
376
+
377
+ rename = _wrap_binary_strfunc(os.rename)
378
+
379
+ if sys.version_info >= (3, 3):
380
+ replace = _wrap_binary_strfunc(os.replace)
381
+
382
+ if nt:
383
+ if supports_symlinks:
384
+ symlink = _wrap_binary_strfunc(os.symlink)
385
+ else:
386
+ def symlink(a, b, target_is_directory):
387
+ raise NotImplementedError("symlink() not available on this system")
388
+ else:
389
+ # Under POSIX, os.symlink() takes two args
390
+ @staticmethod
391
+ def symlink(a, b, target_is_directory):
392
+ return os.symlink(str(a), str(b))
393
+
394
+ utime = _wrap_strfunc(os.utime)
395
+
396
+ # Helper for resolve()
397
+ def readlink(self, path):
398
+ return os.readlink(path)
399
+
400
+
401
+ _normal_accessor = _NormalAccessor()
402
+
403
+
404
+ #
405
+ # Globbing helpers
406
+ #
407
+
408
+ @contextmanager
409
+ def _cached(func):
410
+ try:
411
+ func.__cached__
412
+ yield func
413
+ except AttributeError:
414
+ cache = {}
415
+ def wrapper(*args):
416
+ try:
417
+ return cache[args]
418
+ except KeyError:
419
+ value = cache[args] = func(*args)
420
+ return value
421
+ wrapper.__cached__ = True
422
+ try:
423
+ yield wrapper
424
+ finally:
425
+ cache.clear()
426
+
427
+ def _make_selector(pattern_parts):
428
+ pat = pattern_parts[0]
429
+ child_parts = pattern_parts[1:]
430
+ if pat == '**':
431
+ cls = _RecursiveWildcardSelector
432
+ elif '**' in pat:
433
+ raise ValueError("Invalid pattern: '**' can only be an entire path component")
434
+ elif _is_wildcard_pattern(pat):
435
+ cls = _WildcardSelector
436
+ else:
437
+ cls = _PreciseSelector
438
+ return cls(pat, child_parts)
439
+
440
+ if hasattr(functools, "lru_cache"):
441
+ _make_selector = functools.lru_cache()(_make_selector)
442
+
443
+
444
+ class _Selector:
445
+ """A selector matches a specific glob pattern part against the children
446
+ of a given path."""
447
+
448
+ def __init__(self, child_parts):
449
+ self.child_parts = child_parts
450
+ if child_parts:
451
+ self.successor = _make_selector(child_parts)
452
+ else:
453
+ self.successor = _TerminatingSelector()
454
+
455
+ def select_from(self, parent_path):
456
+ """Iterate over all child paths of `parent_path` matched by this
457
+ selector. This can contain parent_path itself."""
458
+ path_cls = type(parent_path)
459
+ is_dir = path_cls.is_dir
460
+ exists = path_cls.exists
461
+ listdir = parent_path._accessor.listdir
462
+ return self._select_from(parent_path, is_dir, exists, listdir)
463
+
464
+
465
+ class _TerminatingSelector:
466
+
467
+ def _select_from(self, parent_path, is_dir, exists, listdir):
468
+ yield parent_path
469
+
470
+
471
+ class _PreciseSelector(_Selector):
472
+
473
+ def __init__(self, name, child_parts):
474
+ self.name = name
475
+ _Selector.__init__(self, child_parts)
476
+
477
+ def _select_from(self, parent_path, is_dir, exists, listdir):
478
+ if not is_dir(parent_path):
479
+ return
480
+ path = parent_path._make_child_relpath(self.name)
481
+ if exists(path):
482
+ for p in self.successor._select_from(path, is_dir, exists, listdir):
483
+ yield p
484
+
485
+
486
+ class _WildcardSelector(_Selector):
487
+
488
+ def __init__(self, pat, child_parts):
489
+ self.pat = re.compile(fnmatch.translate(pat))
490
+ _Selector.__init__(self, child_parts)
491
+
492
+ def _select_from(self, parent_path, is_dir, exists, listdir):
493
+ if not is_dir(parent_path):
494
+ return
495
+ cf = parent_path._flavour.casefold
496
+ for name in listdir(parent_path):
497
+ casefolded = cf(name)
498
+ if self.pat.match(casefolded):
499
+ path = parent_path._make_child_relpath(name)
500
+ for p in self.successor._select_from(path, is_dir, exists, listdir):
501
+ yield p
502
+
503
+
504
+ class _RecursiveWildcardSelector(_Selector):
505
+
506
+ def __init__(self, pat, child_parts):
507
+ _Selector.__init__(self, child_parts)
508
+
509
+ def _iterate_directories(self, parent_path, is_dir, listdir):
510
+ yield parent_path
511
+ for name in listdir(parent_path):
512
+ path = parent_path._make_child_relpath(name)
513
+ if is_dir(path):
514
+ for p in self._iterate_directories(path, is_dir, listdir):
515
+ yield p
516
+
517
+ def _select_from(self, parent_path, is_dir, exists, listdir):
518
+ if not is_dir(parent_path):
519
+ return
520
+ with _cached(listdir) as listdir:
521
+ yielded = set()
522
+ try:
523
+ successor_select = self.successor._select_from
524
+ for starting_point in self._iterate_directories(parent_path, is_dir, listdir):
525
+ for p in successor_select(starting_point, is_dir, exists, listdir):
526
+ if p not in yielded:
527
+ yield p
528
+ yielded.add(p)
529
+ finally:
530
+ yielded.clear()
531
+
532
+
533
+ #
534
+ # Public API
535
+ #
536
+
537
+ class _PathParents(Sequence):
538
+ """This object provides sequence-like access to the logical ancestors
539
+ of a path. Don't try to construct it yourself."""
540
+ __slots__ = ('_pathcls', '_drv', '_root', '_parts')
541
+
542
+ def __init__(self, path):
543
+ # We don't store the instance to avoid reference cycles
544
+ self._pathcls = type(path)
545
+ self._drv = path._drv
546
+ self._root = path._root
547
+ self._parts = path._parts
548
+
549
+ def __len__(self):
550
+ if self._drv or self._root:
551
+ return len(self._parts) - 1
552
+ else:
553
+ return len(self._parts)
554
+
555
+ def __getitem__(self, idx):
556
+ if idx < 0 or idx >= len(self):
557
+ raise IndexError(idx)
558
+ return self._pathcls._from_parsed_parts(self._drv, self._root,
559
+ self._parts[:-idx - 1])
560
+
561
+ def __repr__(self):
562
+ return "<{0}.parents>".format(self._pathcls.__name__)
563
+
564
+
565
+ class PurePath(object):
566
+ """PurePath represents a filesystem path and offers operations which
567
+ don't imply any actual filesystem I/O. Depending on your system,
568
+ instantiating a PurePath will return either a PurePosixPath or a
569
+ PureWindowsPath object. You can also instantiate either of these classes
570
+ directly, regardless of your system.
571
+ """
572
+ __slots__ = (
573
+ '_drv', '_root', '_parts',
574
+ '_str', '_hash', '_pparts', '_cached_cparts',
575
+ )
576
+
577
+ def __new__(cls, *args):
578
+ """Construct a PurePath from one or several strings and or existing
579
+ PurePath objects. The strings and path objects are combined so as
580
+ to yield a canonicalized path, which is incorporated into the
581
+ new PurePath object.
582
+ """
583
+ if cls is PurePath:
584
+ cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
585
+ return cls._from_parts(args)
586
+
587
+ def __reduce__(self):
588
+ # Using the parts tuple helps share interned path parts
589
+ # when pickling related paths.
590
+ return (self.__class__, tuple(self._parts))
591
+
592
+ @classmethod
593
+ def _parse_args(cls, args):
594
+ # This is useful when you don't want to create an instance, just
595
+ # canonicalize some constructor arguments.
596
+ parts = []
597
+ for a in args:
598
+ if isinstance(a, PurePath):
599
+ parts += a._parts
600
+ elif isinstance(a, basestring):
601
+ parts.append(a)
602
+ else:
603
+ raise TypeError(
604
+ "argument should be a path or str object, not %r"
605
+ % type(a))
606
+ return cls._flavour.parse_parts(parts)
607
+
608
+ @classmethod
609
+ def _from_parts(cls, args, init=True):
610
+ # We need to call _parse_args on the instance, so as to get the
611
+ # right flavour.
612
+ self = object.__new__(cls)
613
+ drv, root, parts = self._parse_args(args)
614
+ self._drv = drv
615
+ self._root = root
616
+ self._parts = parts
617
+ if init:
618
+ self._init()
619
+ return self
620
+
621
+ @classmethod
622
+ def _from_parsed_parts(cls, drv, root, parts, init=True):
623
+ self = object.__new__(cls)
624
+ self._drv = drv
625
+ self._root = root
626
+ self._parts = parts
627
+ if init:
628
+ self._init()
629
+ return self
630
+
631
+ @classmethod
632
+ def _format_parsed_parts(cls, drv, root, parts):
633
+ if drv or root:
634
+ return drv + root + cls._flavour.join(parts[1:])
635
+ else:
636
+ return cls._flavour.join(parts)
637
+
638
+ def _init(self):
639
+ # Overriden in concrete Path
640
+ pass
641
+
642
+ def _make_child(self, args):
643
+ drv, root, parts = self._parse_args(args)
644
+ drv, root, parts = self._flavour.join_parsed_parts(
645
+ self._drv, self._root, self._parts, drv, root, parts)
646
+ return self._from_parsed_parts(drv, root, parts)
647
+
648
+ def __str__(self):
649
+ """Return the string representation of the path, suitable for
650
+ passing to system calls."""
651
+ try:
652
+ return self._str
653
+ except AttributeError:
654
+ self._str = self._format_parsed_parts(self._drv, self._root,
655
+ self._parts) or '.'
656
+ return self._str
657
+
658
+ def as_posix(self):
659
+ """Return the string representation of the path with forward (/)
660
+ slashes."""
661
+ f = self._flavour
662
+ return str(self).replace(f.sep, '/')
663
+
664
+ def __bytes__(self):
665
+ """Return the bytes representation of the path. This is only
666
+ recommended to use under Unix."""
667
+ if sys.version_info < (3, 2):
668
+ raise NotImplementedError("needs Python 3.2 or later")
669
+ return os.fsencode(str(self))
670
+
671
+ def __repr__(self):
672
+ return "{0}({1!r})".format(self.__class__.__name__, self.as_posix())
673
+
674
+ def as_uri(self):
675
+ """Return the path as a 'file' URI."""
676
+ if not self.is_absolute():
677
+ raise ValueError("relative path can't be expressed as a file URI")
678
+ return self._flavour.make_uri(self)
679
+
680
+ @property
681
+ def _cparts(self):
682
+ # Cached casefolded parts, for hashing and comparison
683
+ try:
684
+ return self._cached_cparts
685
+ except AttributeError:
686
+ self._cached_cparts = self._flavour.casefold_parts(self._parts)
687
+ return self._cached_cparts
688
+
689
+ def __eq__(self, other):
690
+ if not isinstance(other, PurePath):
691
+ return NotImplemented
692
+ return self._cparts == other._cparts and self._flavour is other._flavour
693
+
694
+ def __ne__(self, other):
695
+ return not self == other
696
+
697
+ def __hash__(self):
698
+ try:
699
+ return self._hash
700
+ except AttributeError:
701
+ self._hash = hash(tuple(self._cparts))
702
+ return self._hash
703
+
704
+ def __lt__(self, other):
705
+ if not isinstance(other, PurePath) or self._flavour is not other._flavour:
706
+ return NotImplemented
707
+ return self._cparts < other._cparts
708
+
709
+ def __le__(self, other):
710
+ if not isinstance(other, PurePath) or self._flavour is not other._flavour:
711
+ return NotImplemented
712
+ return self._cparts <= other._cparts
713
+
714
+ def __gt__(self, other):
715
+ if not isinstance(other, PurePath) or self._flavour is not other._flavour:
716
+ return NotImplemented
717
+ return self._cparts > other._cparts
718
+
719
+ def __ge__(self, other):
720
+ if not isinstance(other, PurePath) or self._flavour is not other._flavour:
721
+ return NotImplemented
722
+ return self._cparts >= other._cparts
723
+
724
+ drive = property(attrgetter('_drv'),
725
+ doc="""The drive prefix (letter or UNC path), if any.""")
726
+
727
+ root = property(attrgetter('_root'),
728
+ doc="""The root of the path, if any.""")
729
+
730
+ @property
731
+ def anchor(self):
732
+ """The concatenation of the drive and root, or ''."""
733
+ anchor = self._drv + self._root
734
+ return anchor
735
+
736
+ @property
737
+ def name(self):
738
+ """The final path component, if any."""
739
+ parts = self._parts
740
+ if len(parts) == (1 if (self._drv or self._root) else 0):
741
+ return ''
742
+ return parts[-1]
743
+
744
+ @property
745
+ def suffix(self):
746
+ """The final component's last suffix, if any."""
747
+ name = self.name
748
+ i = name.rfind('.')
749
+ if 0 < i < len(name) - 1:
750
+ return name[i:]
751
+ else:
752
+ return ''
753
+
754
+ @property
755
+ def suffixes(self):
756
+ """A list of the final component's suffixes, if any."""
757
+ name = self.name
758
+ if name.endswith('.'):
759
+ return []
760
+ name = name.lstrip('.')
761
+ return ['.' + suffix for suffix in name.split('.')[1:]]
762
+
763
+ @property
764
+ def stem(self):
765
+ """The final path component, minus its last suffix."""
766
+ name = self.name
767
+ i = name.rfind('.')
768
+ if 0 < i < len(name) - 1:
769
+ return name[:i]
770
+ else:
771
+ return name
772
+
773
+ def with_name(self, name):
774
+ """Return a new path with the file name changed."""
775
+ if not self.name:
776
+ raise ValueError("%r has an empty name" % (self,))
777
+ return self._from_parsed_parts(self._drv, self._root,
778
+ self._parts[:-1] + [name])
779
+
780
+ def with_suffix(self, suffix):
781
+ """Return a new path with the file suffix changed (or added, if none)."""
782
+ # XXX if suffix is None, should the current suffix be removed?
783
+ drv, root, parts = self._flavour.parse_parts((suffix,))
784
+ if drv or root or len(parts) != 1:
785
+ raise ValueError("Invalid suffix %r" % (suffix))
786
+ suffix = parts[0]
787
+ if not suffix.startswith('.'):
788
+ raise ValueError("Invalid suffix %r" % (suffix))
789
+ name = self.name
790
+ if not name:
791
+ raise ValueError("%r has an empty name" % (self,))
792
+ old_suffix = self.suffix
793
+ if not old_suffix:
794
+ name = name + suffix
795
+ else:
796
+ name = name[:-len(old_suffix)] + suffix
797
+ return self._from_parsed_parts(self._drv, self._root,
798
+ self._parts[:-1] + [name])
799
+
800
+ def relative_to(self, *other):
801
+ """Return the relative path to another path identified by the passed
802
+ arguments. If the operation is not possible (because this is not
803
+ a subpath of the other path), raise ValueError.
804
+ """
805
+ # For the purpose of this method, drive and root are considered
806
+ # separate parts, i.e.:
807
+ # Path('c:/').relative_to('c:') gives Path('/')
808
+ # Path('c:/').relative_to('/') raise ValueError
809
+ if not other:
810
+ raise TypeError("need at least one argument")
811
+ parts = self._parts
812
+ drv = self._drv
813
+ root = self._root
814
+ if root:
815
+ abs_parts = [drv, root] + parts[1:]
816
+ else:
817
+ abs_parts = parts
818
+ to_drv, to_root, to_parts = self._parse_args(other)
819
+ if to_root:
820
+ to_abs_parts = [to_drv, to_root] + to_parts[1:]
821
+ else:
822
+ to_abs_parts = to_parts
823
+ n = len(to_abs_parts)
824
+ cf = self._flavour.casefold_parts
825
+ if (root or drv) if n == 0 else cf(abs_parts[:n]) != cf(to_abs_parts):
826
+ formatted = self._format_parsed_parts(to_drv, to_root, to_parts)
827
+ raise ValueError("{!r} does not start with {!r}"
828
+ .format(str(self), str(formatted)))
829
+ return self._from_parsed_parts('', root if n == 1 else '',
830
+ abs_parts[n:])
831
+
832
+ @property
833
+ def parts(self):
834
+ """An object providing sequence-like access to the
835
+ components in the filesystem path."""
836
+ # We cache the tuple to avoid building a new one each time .parts
837
+ # is accessed. XXX is this necessary?
838
+ try:
839
+ return self._pparts
840
+ except AttributeError:
841
+ self._pparts = tuple(self._parts)
842
+ return self._pparts
843
+
844
+ def joinpath(self, *args):
845
+ """Combine this path with one or several arguments, and return a
846
+ new path representing either a subpath (if all arguments are relative
847
+ paths) or a totally different path (if one of the arguments is
848
+ anchored).
849
+ """
850
+ return self._make_child(args)
851
+
852
+ def __truediv__(self, key):
853
+ return self._make_child((key,))
854
+
855
+ def __rtruediv__(self, key):
856
+ return self._from_parts([key] + self._parts)
857
+
858
+ if sys.version_info < (3,):
859
+ __div__ = __truediv__
860
+ __rdiv__ = __rtruediv__
861
+
862
+ @property
863
+ def parent(self):
864
+ """The logical parent of the path."""
865
+ drv = self._drv
866
+ root = self._root
867
+ parts = self._parts
868
+ if len(parts) == 1 and (drv or root):
869
+ return self
870
+ return self._from_parsed_parts(drv, root, parts[:-1])
871
+
872
+ @property
873
+ def parents(self):
874
+ """A sequence of this path's logical parents."""
875
+ return _PathParents(self)
876
+
877
+ def is_absolute(self):
878
+ """True if the path is absolute (has both a root and, if applicable,
879
+ a drive)."""
880
+ if not self._root:
881
+ return False
882
+ return not self._flavour.has_drv or bool(self._drv)
883
+
884
+ def is_reserved(self):
885
+ """Return True if the path contains one of the special names reserved
886
+ by the system, if any."""
887
+ return self._flavour.is_reserved(self._parts)
888
+
889
+ def match(self, path_pattern):
890
+ """
891
+ Return True if this path matches the given pattern.
892
+ """
893
+ cf = self._flavour.casefold
894
+ path_pattern = cf(path_pattern)
895
+ drv, root, pat_parts = self._flavour.parse_parts((path_pattern,))
896
+ if not pat_parts:
897
+ raise ValueError("empty pattern")
898
+ if drv and drv != cf(self._drv):
899
+ return False
900
+ if root and root != cf(self._root):
901
+ return False
902
+ parts = self._cparts
903
+ if drv or root:
904
+ if len(pat_parts) != len(parts):
905
+ return False
906
+ pat_parts = pat_parts[1:]
907
+ elif len(pat_parts) > len(parts):
908
+ return False
909
+ for part, pat in zip(reversed(parts), reversed(pat_parts)):
910
+ if not fnmatch.fnmatchcase(part, pat):
911
+ return False
912
+ return True
913
+
914
+
915
+ class PurePosixPath(PurePath):
916
+ _flavour = _posix_flavour
917
+ __slots__ = ()
918
+
919
+
920
+ class PureWindowsPath(PurePath):
921
+ _flavour = _windows_flavour
922
+ __slots__ = ()
923
+
924
+
925
+ # Filesystem-accessing classes
926
+
927
+
928
+ class Path(PurePath):
929
+ __slots__ = (
930
+ '_accessor',
931
+ )
932
+
933
+ def __new__(cls, *args, **kwargs):
934
+ if cls is Path:
935
+ cls = WindowsPath if os.name == 'nt' else PosixPath
936
+ self = cls._from_parts(args, init=False)
937
+ if not self._flavour.is_supported:
938
+ raise NotImplementedError("cannot instantiate %r on your system"
939
+ % (cls.__name__,))
940
+ self._init()
941
+ return self
942
+
943
+ def _init(self,
944
+ # Private non-constructor arguments
945
+ template=None,
946
+ ):
947
+ if template is not None:
948
+ self._accessor = template._accessor
949
+ else:
950
+ self._accessor = _normal_accessor
951
+
952
+ def _make_child_relpath(self, part):
953
+ # This is an optimization used for dir walking. `part` must be
954
+ # a single part relative to this path.
955
+ parts = self._parts + [part]
956
+ return self._from_parsed_parts(self._drv, self._root, parts)
957
+
958
+ def _opener(self, name, flags, mode=0o666):
959
+ # A stub for the opener argument to built-in open()
960
+ return self._accessor.open(self, flags, mode)
961
+
962
+ def _raw_open(self, flags, mode=0o777):
963
+ """
964
+ Open the file pointed by this path and return a file descriptor,
965
+ as os.open() does.
966
+ """
967
+ return self._accessor.open(self, flags, mode)
968
+
969
+ # Public API
970
+
971
+ @classmethod
972
+ def cwd(cls):
973
+ """Return a new path pointing to the current working directory
974
+ (as returned by os.getcwd()).
975
+ """
976
+ return cls(os.getcwd())
977
+
978
+ def iterdir(self):
979
+ """Iterate over the files in this directory. Does not yield any
980
+ result for the special paths '.' and '..'.
981
+ """
982
+ for name in self._accessor.listdir(self):
983
+ if name in ('.', '..'):
984
+ # Yielding a path object for these makes little sense
985
+ continue
986
+ yield self._make_child_relpath(name)
987
+
988
+ def glob(self, pattern):
989
+ """Iterate over this subtree and yield all existing files (of any
990
+ kind, including directories) matching the given pattern.
991
+ """
992
+ pattern = self._flavour.casefold(pattern)
993
+ drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
994
+ if drv or root:
995
+ raise NotImplementedError("Non-relative patterns are unsupported")
996
+ selector = _make_selector(tuple(pattern_parts))
997
+ for p in selector.select_from(self):
998
+ yield p
999
+
1000
+ def rglob(self, pattern):
1001
+ """Recursively yield all existing files (of any kind, including
1002
+ directories) matching the given pattern, anywhere in this subtree.
1003
+ """
1004
+ pattern = self._flavour.casefold(pattern)
1005
+ drv, root, pattern_parts = self._flavour.parse_parts((pattern,))
1006
+ if drv or root:
1007
+ raise NotImplementedError("Non-relative patterns are unsupported")
1008
+ selector = _make_selector(("**",) + tuple(pattern_parts))
1009
+ for p in selector.select_from(self):
1010
+ yield p
1011
+
1012
+ def absolute(self):
1013
+ """Return an absolute version of this path. This function works
1014
+ even if the path doesn't point to anything.
1015
+
1016
+ No normalization is done, i.e. all '.' and '..' will be kept along.
1017
+ Use resolve() to get the canonical path to a file.
1018
+ """
1019
+ # XXX untested yet!
1020
+ if self.is_absolute():
1021
+ return self
1022
+ # FIXME this must defer to the specific flavour (and, under Windows,
1023
+ # use nt._getfullpathname())
1024
+ obj = self._from_parts([os.getcwd()] + self._parts, init=False)
1025
+ obj._init(template=self)
1026
+ return obj
1027
+
1028
+ def resolve(self):
1029
+ """
1030
+ Make the path absolute, resolving all symlinks on the way and also
1031
+ normalizing it (for example turning slashes into backslashes under
1032
+ Windows).
1033
+ """
1034
+ s = self._flavour.resolve(self)
1035
+ if s is None:
1036
+ # No symlink resolution => for consistency, raise an error if
1037
+ # the path doesn't exist or is forbidden
1038
+ self.stat()
1039
+ s = str(self.absolute())
1040
+ # Now we have no symlinks in the path, it's safe to normalize it.
1041
+ normed = self._flavour.pathmod.normpath(s)
1042
+ obj = self._from_parts((normed,), init=False)
1043
+ obj._init(template=self)
1044
+ return obj
1045
+
1046
+ def stat(self):
1047
+ """
1048
+ Return the result of the stat() system call on this path, like
1049
+ os.stat() does.
1050
+ """
1051
+ return self._accessor.stat(self)
1052
+
1053
+ def owner(self):
1054
+ """
1055
+ Return the login name of the file owner.
1056
+ """
1057
+ import pwd
1058
+ return pwd.getpwuid(self.stat().st_uid).pw_name
1059
+
1060
+ def group(self):
1061
+ """
1062
+ Return the group name of the file gid.
1063
+ """
1064
+ import grp
1065
+ return grp.getgrgid(self.stat().st_gid).gr_name
1066
+
1067
+ def open(self, mode='r', buffering=-1, encoding=None,
1068
+ errors=None, newline=None):
1069
+ """
1070
+ Open the file pointed by this path and return a file object, as
1071
+ the built-in open() function does.
1072
+ """
1073
+ if sys.version_info >= (3, 3):
1074
+ return io.open(str(self), mode, buffering, encoding, errors, newline,
1075
+ opener=self._opener)
1076
+ else:
1077
+ return io.open(str(self), mode, buffering, encoding, errors, newline)
1078
+
1079
+ def touch(self, mode=0o666, exist_ok=True):
1080
+ """
1081
+ Create this file with the given access mode, if it doesn't exist.
1082
+ """
1083
+ if exist_ok:
1084
+ # First try to bump modification time
1085
+ # Implementation note: GNU touch uses the UTIME_NOW option of
1086
+ # the utimensat() / futimens() functions.
1087
+ t = time.time()
1088
+ try:
1089
+ self._accessor.utime(self, (t, t))
1090
+ except OSError:
1091
+ # Avoid exception chaining
1092
+ pass
1093
+ else:
1094
+ return
1095
+ flags = os.O_CREAT | os.O_WRONLY
1096
+ if not exist_ok:
1097
+ flags |= os.O_EXCL
1098
+ fd = self._raw_open(flags, mode)
1099
+ os.close(fd)
1100
+
1101
+ def mkdir(self, mode=0o777, parents=False):
1102
+ if not parents:
1103
+ self._accessor.mkdir(self, mode)
1104
+ else:
1105
+ try:
1106
+ self._accessor.mkdir(self, mode)
1107
+ except OSError as e:
1108
+ if e.errno != ENOENT:
1109
+ raise
1110
+ self.parent.mkdir(parents=True)
1111
+ self._accessor.mkdir(self, mode)
1112
+
1113
+ def chmod(self, mode):
1114
+ """
1115
+ Change the permissions of the path, like os.chmod().
1116
+ """
1117
+ self._accessor.chmod(self, mode)
1118
+
1119
+ def lchmod(self, mode):
1120
+ """
1121
+ Like chmod(), except if the path points to a symlink, the symlink's
1122
+ permissions are changed, rather than its target's.
1123
+ """
1124
+ self._accessor.lchmod(self, mode)
1125
+
1126
+ def unlink(self):
1127
+ """
1128
+ Remove this file or link.
1129
+ If the path is a directory, use rmdir() instead.
1130
+ """
1131
+ self._accessor.unlink(self)
1132
+
1133
+ def rmdir(self):
1134
+ """
1135
+ Remove this directory. The directory must be empty.
1136
+ """
1137
+ self._accessor.rmdir(self)
1138
+
1139
+ def lstat(self):
1140
+ """
1141
+ Like stat(), except if the path points to a symlink, the symlink's
1142
+ status information is returned, rather than its target's.
1143
+ """
1144
+ return self._accessor.lstat(self)
1145
+
1146
+ def rename(self, target):
1147
+ """
1148
+ Rename this path to the given path.
1149
+ """
1150
+ self._accessor.rename(self, target)
1151
+
1152
+ def replace(self, target):
1153
+ """
1154
+ Rename this path to the given path, clobbering the existing
1155
+ destination if it exists.
1156
+ """
1157
+ if sys.version_info < (3, 3):
1158
+ raise NotImplementedError("replace() is only available "
1159
+ "with Python 3.3 and later")
1160
+ self._accessor.replace(self, target)
1161
+
1162
+ def symlink_to(self, target, target_is_directory=False):
1163
+ """
1164
+ Make this path a symlink pointing to the given path.
1165
+ Note the order of arguments (self, target) is the reverse of os.symlink's.
1166
+ """
1167
+ self._accessor.symlink(target, self, target_is_directory)
1168
+
1169
+ # Convenience functions for querying the stat results
1170
+
1171
+ def exists(self):
1172
+ """
1173
+ Whether this path exists.
1174
+ """
1175
+ try:
1176
+ self.stat()
1177
+ except OSError as e:
1178
+ if e.errno != ENOENT:
1179
+ raise
1180
+ return False
1181
+ return True
1182
+
1183
+ def is_dir(self):
1184
+ """
1185
+ Whether this path is a directory.
1186
+ """
1187
+ try:
1188
+ return S_ISDIR(self.stat().st_mode)
1189
+ except OSError as e:
1190
+ if e.errno != ENOENT:
1191
+ raise
1192
+ # Path doesn't exist or is a broken symlink
1193
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1194
+ return False
1195
+
1196
+ def is_file(self):
1197
+ """
1198
+ Whether this path is a regular file (also True for symlinks pointing
1199
+ to regular files).
1200
+ """
1201
+ try:
1202
+ return S_ISREG(self.stat().st_mode)
1203
+ except OSError as e:
1204
+ if e.errno != ENOENT:
1205
+ raise
1206
+ # Path doesn't exist or is a broken symlink
1207
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1208
+ return False
1209
+
1210
+ def is_symlink(self):
1211
+ """
1212
+ Whether this path is a symbolic link.
1213
+ """
1214
+ try:
1215
+ return S_ISLNK(self.lstat().st_mode)
1216
+ except OSError as e:
1217
+ if e.errno != ENOENT:
1218
+ raise
1219
+ # Path doesn't exist
1220
+ return False
1221
+
1222
+ def is_block_device(self):
1223
+ """
1224
+ Whether this path is a block device.
1225
+ """
1226
+ try:
1227
+ return S_ISBLK(self.stat().st_mode)
1228
+ except OSError as e:
1229
+ if e.errno != ENOENT:
1230
+ raise
1231
+ # Path doesn't exist or is a broken symlink
1232
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1233
+ return False
1234
+
1235
+ def is_char_device(self):
1236
+ """
1237
+ Whether this path is a character device.
1238
+ """
1239
+ try:
1240
+ return S_ISCHR(self.stat().st_mode)
1241
+ except OSError as e:
1242
+ if e.errno != ENOENT:
1243
+ raise
1244
+ # Path doesn't exist or is a broken symlink
1245
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1246
+ return False
1247
+
1248
+ def is_fifo(self):
1249
+ """
1250
+ Whether this path is a FIFO.
1251
+ """
1252
+ try:
1253
+ return S_ISFIFO(self.stat().st_mode)
1254
+ except OSError as e:
1255
+ if e.errno != ENOENT:
1256
+ raise
1257
+ # Path doesn't exist or is a broken symlink
1258
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1259
+ return False
1260
+
1261
+ def is_socket(self):
1262
+ """
1263
+ Whether this path is a socket.
1264
+ """
1265
+ try:
1266
+ return S_ISSOCK(self.stat().st_mode)
1267
+ except OSError as e:
1268
+ if e.errno != ENOENT:
1269
+ raise
1270
+ # Path doesn't exist or is a broken symlink
1271
+ # (see https://bitbucket.org/pitrou/pathlib/issue/12/)
1272
+ return False
1273
+
1274
+
1275
+ class PosixPath(Path, PurePosixPath):
1276
+ __slots__ = ()
1277
+
1278
+ class WindowsPath(Path, PureWindowsPath):
1279
+ __slots__ = ()
1280
+