decidim 0.27.4 → 0.27.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +2 -16
  3. data/docs/modules/install/pages/manual.adoc +1 -1
  4. data/docs/modules/services/pages/maps.adoc +8 -0
  5. data/lib/decidim/version.rb +1 -1
  6. data/package-lock.json +7 -7
  7. data/packages/browserslist-config/package.json +1 -1
  8. data/packages/core/node_modules/uuid/AUTHORS +5 -0
  9. data/packages/core/node_modules/uuid/CHANGELOG.md +119 -0
  10. data/packages/{webpacker/node_modules/brace-expansion/LICENSE → core/node_modules/uuid/LICENSE.md} +2 -2
  11. data/packages/core/node_modules/uuid/README.md +276 -0
  12. data/packages/core/node_modules/uuid/bin/uuid +65 -0
  13. data/packages/core/node_modules/uuid/index.js +8 -0
  14. data/packages/core/node_modules/uuid/lib/bytesToUuid.js +26 -0
  15. data/packages/core/node_modules/uuid/lib/md5-browser.js +216 -0
  16. data/packages/core/node_modules/uuid/lib/md5.js +25 -0
  17. data/packages/core/node_modules/uuid/lib/rng-browser.js +34 -0
  18. data/packages/core/node_modules/uuid/lib/rng.js +8 -0
  19. data/packages/core/node_modules/uuid/lib/sha1-browser.js +89 -0
  20. data/packages/core/node_modules/uuid/lib/sha1.js +25 -0
  21. data/packages/core/node_modules/uuid/lib/v35.js +57 -0
  22. data/packages/core/node_modules/uuid/package.json +49 -0
  23. data/packages/core/node_modules/uuid/v1.js +109 -0
  24. data/packages/core/node_modules/uuid/v3.js +4 -0
  25. data/packages/core/node_modules/uuid/v4.js +29 -0
  26. data/packages/core/node_modules/uuid/v5.js +3 -0
  27. data/packages/core/package-lock.json +347 -3079
  28. data/packages/core/package.json +1 -1
  29. data/packages/dev/package.json +1 -1
  30. data/packages/elections/package.json +1 -1
  31. data/packages/eslint-config/package-lock.json +4797 -0
  32. data/packages/eslint-config/package.json +1 -1
  33. data/packages/stylelint-config/package.json +1 -1
  34. data/packages/webpacker/package.json +1 -1
  35. metadata +63 -234
  36. data/lib/decidim/release_manager.rb.new +0 -43
  37. data/packages/core/node_modules/diff/CONTRIBUTING.md +0 -39
  38. data/packages/core/node_modules/diff/LICENSE +0 -31
  39. data/packages/core/node_modules/diff/README.md +0 -211
  40. data/packages/core/node_modules/diff/dist/diff.js +0 -1627
  41. data/packages/core/node_modules/diff/dist/diff.min.js +0 -38
  42. data/packages/core/node_modules/diff/lib/convert/dmp.js +0 -32
  43. data/packages/core/node_modules/diff/lib/convert/xml.js +0 -42
  44. data/packages/core/node_modules/diff/lib/diff/array.js +0 -45
  45. data/packages/core/node_modules/diff/lib/diff/base.js +0 -307
  46. data/packages/core/node_modules/diff/lib/diff/character.js +0 -37
  47. data/packages/core/node_modules/diff/lib/diff/css.js +0 -41
  48. data/packages/core/node_modules/diff/lib/diff/json.js +0 -163
  49. data/packages/core/node_modules/diff/lib/diff/line.js +0 -89
  50. data/packages/core/node_modules/diff/lib/diff/sentence.js +0 -41
  51. data/packages/core/node_modules/diff/lib/diff/word.js +0 -108
  52. data/packages/core/node_modules/diff/lib/index.es6.js +0 -1561
  53. data/packages/core/node_modules/diff/lib/index.js +0 -216
  54. data/packages/core/node_modules/diff/lib/index.mjs +0 -1561
  55. data/packages/core/node_modules/diff/lib/patch/apply.js +0 -238
  56. data/packages/core/node_modules/diff/lib/patch/create.js +0 -272
  57. data/packages/core/node_modules/diff/lib/patch/merge.js +0 -613
  58. data/packages/core/node_modules/diff/lib/patch/parse.js +0 -167
  59. data/packages/core/node_modules/diff/lib/util/array.js +0 -32
  60. data/packages/core/node_modules/diff/lib/util/distance-iterator.js +0 -57
  61. data/packages/core/node_modules/diff/lib/util/params.js +0 -24
  62. data/packages/core/node_modules/diff/package.json +0 -87
  63. data/packages/core/node_modules/diff/release-notes.md +0 -309
  64. data/packages/core/node_modules/diff/runtime.js +0 -3
  65. data/packages/webpacker/node_modules/argparse/CHANGELOG.md +0 -216
  66. data/packages/webpacker/node_modules/argparse/LICENSE +0 -254
  67. data/packages/webpacker/node_modules/argparse/README.md +0 -84
  68. data/packages/webpacker/node_modules/argparse/argparse.js +0 -3707
  69. data/packages/webpacker/node_modules/argparse/lib/sub.js +0 -67
  70. data/packages/webpacker/node_modules/argparse/lib/textwrap.js +0 -440
  71. data/packages/webpacker/node_modules/argparse/package.json +0 -31
  72. data/packages/webpacker/node_modules/brace-expansion/README.md +0 -135
  73. data/packages/webpacker/node_modules/brace-expansion/index.js +0 -203
  74. data/packages/webpacker/node_modules/brace-expansion/package.json +0 -46
  75. data/packages/webpacker/node_modules/glob/LICENSE +0 -15
  76. data/packages/webpacker/node_modules/glob/README.md +0 -1214
  77. data/packages/webpacker/node_modules/glob/dist/cjs/package.json +0 -4
  78. data/packages/webpacker/node_modules/glob/dist/cjs/src/bin.d.ts +0 -3
  79. data/packages/webpacker/node_modules/glob/dist/cjs/src/bin.d.ts.map +0 -1
  80. data/packages/webpacker/node_modules/glob/dist/cjs/src/bin.js +0 -270
  81. data/packages/webpacker/node_modules/glob/dist/cjs/src/bin.js.map +0 -1
  82. data/packages/webpacker/node_modules/glob/dist/cjs/src/glob.d.ts +0 -344
  83. data/packages/webpacker/node_modules/glob/dist/cjs/src/glob.d.ts.map +0 -1
  84. data/packages/webpacker/node_modules/glob/dist/cjs/src/glob.js +0 -238
  85. data/packages/webpacker/node_modules/glob/dist/cjs/src/glob.js.map +0 -1
  86. data/packages/webpacker/node_modules/glob/dist/cjs/src/has-magic.d.ts +0 -14
  87. data/packages/webpacker/node_modules/glob/dist/cjs/src/has-magic.d.ts.map +0 -1
  88. data/packages/webpacker/node_modules/glob/dist/cjs/src/has-magic.js +0 -27
  89. data/packages/webpacker/node_modules/glob/dist/cjs/src/has-magic.js.map +0 -1
  90. data/packages/webpacker/node_modules/glob/dist/cjs/src/ignore.d.ts +0 -20
  91. data/packages/webpacker/node_modules/glob/dist/cjs/src/ignore.d.ts.map +0 -1
  92. data/packages/webpacker/node_modules/glob/dist/cjs/src/ignore.js +0 -103
  93. data/packages/webpacker/node_modules/glob/dist/cjs/src/ignore.js.map +0 -1
  94. data/packages/webpacker/node_modules/glob/dist/cjs/src/index.d.ts +0 -95
  95. data/packages/webpacker/node_modules/glob/dist/cjs/src/index.d.ts.map +0 -1
  96. data/packages/webpacker/node_modules/glob/dist/cjs/src/index.js +0 -68
  97. data/packages/webpacker/node_modules/glob/dist/cjs/src/index.js.map +0 -1
  98. data/packages/webpacker/node_modules/glob/dist/cjs/src/pattern.d.ts +0 -77
  99. data/packages/webpacker/node_modules/glob/dist/cjs/src/pattern.d.ts.map +0 -1
  100. data/packages/webpacker/node_modules/glob/dist/cjs/src/pattern.js +0 -219
  101. data/packages/webpacker/node_modules/glob/dist/cjs/src/pattern.js.map +0 -1
  102. data/packages/webpacker/node_modules/glob/dist/cjs/src/processor.d.ts +0 -59
  103. data/packages/webpacker/node_modules/glob/dist/cjs/src/processor.d.ts.map +0 -1
  104. data/packages/webpacker/node_modules/glob/dist/cjs/src/processor.js +0 -309
  105. data/packages/webpacker/node_modules/glob/dist/cjs/src/processor.js.map +0 -1
  106. data/packages/webpacker/node_modules/glob/dist/cjs/src/walker.d.ts +0 -96
  107. data/packages/webpacker/node_modules/glob/dist/cjs/src/walker.d.ts.map +0 -1
  108. data/packages/webpacker/node_modules/glob/dist/cjs/src/walker.js +0 -358
  109. data/packages/webpacker/node_modules/glob/dist/cjs/src/walker.js.map +0 -1
  110. data/packages/webpacker/node_modules/glob/dist/mjs/glob.d.ts +0 -344
  111. data/packages/webpacker/node_modules/glob/dist/mjs/glob.d.ts.map +0 -1
  112. data/packages/webpacker/node_modules/glob/dist/mjs/glob.js +0 -234
  113. data/packages/webpacker/node_modules/glob/dist/mjs/glob.js.map +0 -1
  114. data/packages/webpacker/node_modules/glob/dist/mjs/has-magic.d.ts +0 -14
  115. data/packages/webpacker/node_modules/glob/dist/mjs/has-magic.d.ts.map +0 -1
  116. data/packages/webpacker/node_modules/glob/dist/mjs/has-magic.js +0 -23
  117. data/packages/webpacker/node_modules/glob/dist/mjs/has-magic.js.map +0 -1
  118. data/packages/webpacker/node_modules/glob/dist/mjs/ignore.d.ts +0 -20
  119. data/packages/webpacker/node_modules/glob/dist/mjs/ignore.d.ts.map +0 -1
  120. data/packages/webpacker/node_modules/glob/dist/mjs/ignore.js +0 -99
  121. data/packages/webpacker/node_modules/glob/dist/mjs/ignore.js.map +0 -1
  122. data/packages/webpacker/node_modules/glob/dist/mjs/index.d.ts +0 -95
  123. data/packages/webpacker/node_modules/glob/dist/mjs/index.d.ts.map +0 -1
  124. data/packages/webpacker/node_modules/glob/dist/mjs/index.js +0 -56
  125. data/packages/webpacker/node_modules/glob/dist/mjs/index.js.map +0 -1
  126. data/packages/webpacker/node_modules/glob/dist/mjs/package.json +0 -4
  127. data/packages/webpacker/node_modules/glob/dist/mjs/pattern.d.ts +0 -77
  128. data/packages/webpacker/node_modules/glob/dist/mjs/pattern.d.ts.map +0 -1
  129. data/packages/webpacker/node_modules/glob/dist/mjs/pattern.js +0 -215
  130. data/packages/webpacker/node_modules/glob/dist/mjs/pattern.js.map +0 -1
  131. data/packages/webpacker/node_modules/glob/dist/mjs/processor.d.ts +0 -59
  132. data/packages/webpacker/node_modules/glob/dist/mjs/processor.d.ts.map +0 -1
  133. data/packages/webpacker/node_modules/glob/dist/mjs/processor.js +0 -302
  134. data/packages/webpacker/node_modules/glob/dist/mjs/processor.js.map +0 -1
  135. data/packages/webpacker/node_modules/glob/dist/mjs/walker.d.ts +0 -96
  136. data/packages/webpacker/node_modules/glob/dist/mjs/walker.d.ts.map +0 -1
  137. data/packages/webpacker/node_modules/glob/dist/mjs/walker.js +0 -352
  138. data/packages/webpacker/node_modules/glob/dist/mjs/walker.js.map +0 -1
  139. data/packages/webpacker/node_modules/glob/package.json +0 -98
  140. data/packages/webpacker/node_modules/js-yaml/CHANGELOG.md +0 -616
  141. data/packages/webpacker/node_modules/js-yaml/LICENSE +0 -21
  142. data/packages/webpacker/node_modules/js-yaml/README.md +0 -246
  143. data/packages/webpacker/node_modules/js-yaml/bin/js-yaml.js +0 -126
  144. data/packages/webpacker/node_modules/js-yaml/dist/js-yaml.js +0 -3874
  145. data/packages/webpacker/node_modules/js-yaml/dist/js-yaml.min.js +0 -2
  146. data/packages/webpacker/node_modules/js-yaml/dist/js-yaml.mjs +0 -3851
  147. data/packages/webpacker/node_modules/js-yaml/index.js +0 -47
  148. data/packages/webpacker/node_modules/js-yaml/lib/common.js +0 -59
  149. data/packages/webpacker/node_modules/js-yaml/lib/dumper.js +0 -965
  150. data/packages/webpacker/node_modules/js-yaml/lib/exception.js +0 -55
  151. data/packages/webpacker/node_modules/js-yaml/lib/loader.js +0 -1727
  152. data/packages/webpacker/node_modules/js-yaml/lib/schema/core.js +0 -11
  153. data/packages/webpacker/node_modules/js-yaml/lib/schema/default.js +0 -22
  154. data/packages/webpacker/node_modules/js-yaml/lib/schema/failsafe.js +0 -17
  155. data/packages/webpacker/node_modules/js-yaml/lib/schema/json.js +0 -19
  156. data/packages/webpacker/node_modules/js-yaml/lib/schema.js +0 -121
  157. data/packages/webpacker/node_modules/js-yaml/lib/snippet.js +0 -101
  158. data/packages/webpacker/node_modules/js-yaml/lib/type/binary.js +0 -125
  159. data/packages/webpacker/node_modules/js-yaml/lib/type/bool.js +0 -35
  160. data/packages/webpacker/node_modules/js-yaml/lib/type/float.js +0 -97
  161. data/packages/webpacker/node_modules/js-yaml/lib/type/int.js +0 -156
  162. data/packages/webpacker/node_modules/js-yaml/lib/type/map.js +0 -8
  163. data/packages/webpacker/node_modules/js-yaml/lib/type/merge.js +0 -12
  164. data/packages/webpacker/node_modules/js-yaml/lib/type/null.js +0 -35
  165. data/packages/webpacker/node_modules/js-yaml/lib/type/omap.js +0 -44
  166. data/packages/webpacker/node_modules/js-yaml/lib/type/pairs.js +0 -53
  167. data/packages/webpacker/node_modules/js-yaml/lib/type/seq.js +0 -8
  168. data/packages/webpacker/node_modules/js-yaml/lib/type/set.js +0 -29
  169. data/packages/webpacker/node_modules/js-yaml/lib/type/str.js +0 -8
  170. data/packages/webpacker/node_modules/js-yaml/lib/type/timestamp.js +0 -88
  171. data/packages/webpacker/node_modules/js-yaml/lib/type.js +0 -66
  172. data/packages/webpacker/node_modules/js-yaml/package.json +0 -66
  173. data/packages/webpacker/node_modules/minimatch/LICENSE +0 -15
  174. data/packages/webpacker/node_modules/minimatch/README.md +0 -454
  175. data/packages/webpacker/node_modules/minimatch/dist/cjs/assert-valid-pattern.d.ts +0 -2
  176. data/packages/webpacker/node_modules/minimatch/dist/cjs/assert-valid-pattern.d.ts.map +0 -1
  177. data/packages/webpacker/node_modules/minimatch/dist/cjs/assert-valid-pattern.js +0 -14
  178. data/packages/webpacker/node_modules/minimatch/dist/cjs/assert-valid-pattern.js.map +0 -1
  179. data/packages/webpacker/node_modules/minimatch/dist/cjs/ast.d.ts +0 -19
  180. data/packages/webpacker/node_modules/minimatch/dist/cjs/ast.d.ts.map +0 -1
  181. data/packages/webpacker/node_modules/minimatch/dist/cjs/ast.js +0 -589
  182. data/packages/webpacker/node_modules/minimatch/dist/cjs/ast.js.map +0 -1
  183. data/packages/webpacker/node_modules/minimatch/dist/cjs/brace-expressions.d.ts +0 -8
  184. data/packages/webpacker/node_modules/minimatch/dist/cjs/brace-expressions.d.ts.map +0 -1
  185. data/packages/webpacker/node_modules/minimatch/dist/cjs/brace-expressions.js +0 -152
  186. data/packages/webpacker/node_modules/minimatch/dist/cjs/brace-expressions.js.map +0 -1
  187. data/packages/webpacker/node_modules/minimatch/dist/cjs/escape.d.ts +0 -12
  188. data/packages/webpacker/node_modules/minimatch/dist/cjs/escape.d.ts.map +0 -1
  189. data/packages/webpacker/node_modules/minimatch/dist/cjs/escape.js +0 -22
  190. data/packages/webpacker/node_modules/minimatch/dist/cjs/escape.js.map +0 -1
  191. data/packages/webpacker/node_modules/minimatch/dist/cjs/index.d.ts +0 -94
  192. data/packages/webpacker/node_modules/minimatch/dist/cjs/index.d.ts.map +0 -1
  193. data/packages/webpacker/node_modules/minimatch/dist/cjs/index.js +0 -1011
  194. data/packages/webpacker/node_modules/minimatch/dist/cjs/index.js.map +0 -1
  195. data/packages/webpacker/node_modules/minimatch/dist/cjs/package.json +0 -3
  196. data/packages/webpacker/node_modules/minimatch/dist/cjs/unescape.d.ts +0 -17
  197. data/packages/webpacker/node_modules/minimatch/dist/cjs/unescape.d.ts.map +0 -1
  198. data/packages/webpacker/node_modules/minimatch/dist/cjs/unescape.js +0 -24
  199. data/packages/webpacker/node_modules/minimatch/dist/cjs/unescape.js.map +0 -1
  200. data/packages/webpacker/node_modules/minimatch/dist/mjs/assert-valid-pattern.d.ts +0 -2
  201. data/packages/webpacker/node_modules/minimatch/dist/mjs/assert-valid-pattern.d.ts.map +0 -1
  202. data/packages/webpacker/node_modules/minimatch/dist/mjs/assert-valid-pattern.js +0 -10
  203. data/packages/webpacker/node_modules/minimatch/dist/mjs/assert-valid-pattern.js.map +0 -1
  204. data/packages/webpacker/node_modules/minimatch/dist/mjs/ast.d.ts +0 -19
  205. data/packages/webpacker/node_modules/minimatch/dist/mjs/ast.d.ts.map +0 -1
  206. data/packages/webpacker/node_modules/minimatch/dist/mjs/ast.js +0 -585
  207. data/packages/webpacker/node_modules/minimatch/dist/mjs/ast.js.map +0 -1
  208. data/packages/webpacker/node_modules/minimatch/dist/mjs/brace-expressions.d.ts +0 -8
  209. data/packages/webpacker/node_modules/minimatch/dist/mjs/brace-expressions.d.ts.map +0 -1
  210. data/packages/webpacker/node_modules/minimatch/dist/mjs/brace-expressions.js +0 -148
  211. data/packages/webpacker/node_modules/minimatch/dist/mjs/brace-expressions.js.map +0 -1
  212. data/packages/webpacker/node_modules/minimatch/dist/mjs/escape.d.ts +0 -12
  213. data/packages/webpacker/node_modules/minimatch/dist/mjs/escape.d.ts.map +0 -1
  214. data/packages/webpacker/node_modules/minimatch/dist/mjs/escape.js +0 -18
  215. data/packages/webpacker/node_modules/minimatch/dist/mjs/escape.js.map +0 -1
  216. data/packages/webpacker/node_modules/minimatch/dist/mjs/index.d.ts +0 -94
  217. data/packages/webpacker/node_modules/minimatch/dist/mjs/index.d.ts.map +0 -1
  218. data/packages/webpacker/node_modules/minimatch/dist/mjs/index.js +0 -995
  219. data/packages/webpacker/node_modules/minimatch/dist/mjs/index.js.map +0 -1
  220. data/packages/webpacker/node_modules/minimatch/dist/mjs/package.json +0 -3
  221. data/packages/webpacker/node_modules/minimatch/dist/mjs/unescape.d.ts +0 -17
  222. data/packages/webpacker/node_modules/minimatch/dist/mjs/unescape.d.ts.map +0 -1
  223. data/packages/webpacker/node_modules/minimatch/dist/mjs/unescape.js +0 -20
  224. data/packages/webpacker/node_modules/minimatch/dist/mjs/unescape.js.map +0 -1
  225. data/packages/webpacker/node_modules/minimatch/package.json +0 -86
@@ -1,3707 +0,0 @@
1
- // Port of python's argparse module, version 3.9.0:
2
- // https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py
3
-
4
- 'use strict'
5
-
6
- // Copyright (C) 2010-2020 Python Software Foundation.
7
- // Copyright (C) 2020 argparse.js authors
8
-
9
- /*
10
- * Command-line parsing library
11
- *
12
- * This module is an optparse-inspired command-line parsing library that:
13
- *
14
- * - handles both optional and positional arguments
15
- * - produces highly informative usage messages
16
- * - supports parsers that dispatch to sub-parsers
17
- *
18
- * The following is a simple usage example that sums integers from the
19
- * command-line and writes the result to a file::
20
- *
21
- * parser = argparse.ArgumentParser(
22
- * description='sum the integers at the command line')
23
- * parser.add_argument(
24
- * 'integers', metavar='int', nargs='+', type=int,
25
- * help='an integer to be summed')
26
- * parser.add_argument(
27
- * '--log', default=sys.stdout, type=argparse.FileType('w'),
28
- * help='the file where the sum should be written')
29
- * args = parser.parse_args()
30
- * args.log.write('%s' % sum(args.integers))
31
- * args.log.close()
32
- *
33
- * The module contains the following public classes:
34
- *
35
- * - ArgumentParser -- The main entry point for command-line parsing. As the
36
- * example above shows, the add_argument() method is used to populate
37
- * the parser with actions for optional and positional arguments. Then
38
- * the parse_args() method is invoked to convert the args at the
39
- * command-line into an object with attributes.
40
- *
41
- * - ArgumentError -- The exception raised by ArgumentParser objects when
42
- * there are errors with the parser's actions. Errors raised while
43
- * parsing the command-line are caught by ArgumentParser and emitted
44
- * as command-line messages.
45
- *
46
- * - FileType -- A factory for defining types of files to be created. As the
47
- * example above shows, instances of FileType are typically passed as
48
- * the type= argument of add_argument() calls.
49
- *
50
- * - Action -- The base class for parser actions. Typically actions are
51
- * selected by passing strings like 'store_true' or 'append_const' to
52
- * the action= argument of add_argument(). However, for greater
53
- * customization of ArgumentParser actions, subclasses of Action may
54
- * be defined and passed as the action= argument.
55
- *
56
- * - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,
57
- * ArgumentDefaultsHelpFormatter -- Formatter classes which
58
- * may be passed as the formatter_class= argument to the
59
- * ArgumentParser constructor. HelpFormatter is the default,
60
- * RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser
61
- * not to change the formatting for help text, and
62
- * ArgumentDefaultsHelpFormatter adds information about argument defaults
63
- * to the help.
64
- *
65
- * All other classes in this module are considered implementation details.
66
- * (Also note that HelpFormatter and RawDescriptionHelpFormatter are only
67
- * considered public as object names -- the API of the formatter objects is
68
- * still considered an implementation detail.)
69
- */
70
-
71
- const SUPPRESS = '==SUPPRESS=='
72
-
73
- const OPTIONAL = '?'
74
- const ZERO_OR_MORE = '*'
75
- const ONE_OR_MORE = '+'
76
- const PARSER = 'A...'
77
- const REMAINDER = '...'
78
- const _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
79
-
80
-
81
- // ==================================
82
- // Utility functions used for porting
83
- // ==================================
84
- const assert = require('assert')
85
- const util = require('util')
86
- const fs = require('fs')
87
- const sub = require('./lib/sub')
88
- const path = require('path')
89
- const repr = util.inspect
90
-
91
- function get_argv() {
92
- // omit first argument (which is assumed to be interpreter - `node`, `coffee`, `ts-node`, etc.)
93
- return process.argv.slice(1)
94
- }
95
-
96
- function get_terminal_size() {
97
- return {
98
- columns: +process.env.COLUMNS || process.stdout.columns || 80
99
- }
100
- }
101
-
102
- function hasattr(object, name) {
103
- return Object.prototype.hasOwnProperty.call(object, name)
104
- }
105
-
106
- function getattr(object, name, value) {
107
- return hasattr(object, name) ? object[name] : value
108
- }
109
-
110
- function setattr(object, name, value) {
111
- object[name] = value
112
- }
113
-
114
- function setdefault(object, name, value) {
115
- if (!hasattr(object, name)) object[name] = value
116
- return object[name]
117
- }
118
-
119
- function delattr(object, name) {
120
- delete object[name]
121
- }
122
-
123
- function range(from, to, step=1) {
124
- // range(10) is equivalent to range(0, 10)
125
- if (arguments.length === 1) [ to, from ] = [ from, 0 ]
126
- if (typeof from !== 'number' || typeof to !== 'number' || typeof step !== 'number') {
127
- throw new TypeError('argument cannot be interpreted as an integer')
128
- }
129
- if (step === 0) throw new TypeError('range() arg 3 must not be zero')
130
-
131
- let result = []
132
- if (step > 0) {
133
- for (let i = from; i < to; i += step) result.push(i)
134
- } else {
135
- for (let i = from; i > to; i += step) result.push(i)
136
- }
137
- return result
138
- }
139
-
140
- function splitlines(str, keepends = false) {
141
- let result
142
- if (!keepends) {
143
- result = str.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]/)
144
- } else {
145
- result = []
146
- let parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/)
147
- for (let i = 0; i < parts.length; i += 2) {
148
- result.push(parts[i] + (i + 1 < parts.length ? parts[i + 1] : ''))
149
- }
150
- }
151
- if (!result[result.length - 1]) result.pop()
152
- return result
153
- }
154
-
155
- function _string_lstrip(string, prefix_chars) {
156
- let idx = 0
157
- while (idx < string.length && prefix_chars.includes(string[idx])) idx++
158
- return idx ? string.slice(idx) : string
159
- }
160
-
161
- function _string_split(string, sep, maxsplit) {
162
- let result = string.split(sep)
163
- if (result.length > maxsplit) {
164
- result = result.slice(0, maxsplit).concat([ result.slice(maxsplit).join(sep) ])
165
- }
166
- return result
167
- }
168
-
169
- function _array_equal(array1, array2) {
170
- if (array1.length !== array2.length) return false
171
- for (let i = 0; i < array1.length; i++) {
172
- if (array1[i] !== array2[i]) return false
173
- }
174
- return true
175
- }
176
-
177
- function _array_remove(array, item) {
178
- let idx = array.indexOf(item)
179
- if (idx === -1) throw new TypeError(sub('%r not in list', item))
180
- array.splice(idx, 1)
181
- }
182
-
183
- // normalize choices to array;
184
- // this isn't required in python because `in` and `map` operators work with anything,
185
- // but in js dealing with multiple types here is too clunky
186
- function _choices_to_array(choices) {
187
- if (choices === undefined) {
188
- return []
189
- } else if (Array.isArray(choices)) {
190
- return choices
191
- } else if (choices !== null && typeof choices[Symbol.iterator] === 'function') {
192
- return Array.from(choices)
193
- } else if (typeof choices === 'object' && choices !== null) {
194
- return Object.keys(choices)
195
- } else {
196
- throw new Error(sub('invalid choices value: %r', choices))
197
- }
198
- }
199
-
200
- // decorator that allows a class to be called without new
201
- function _callable(cls) {
202
- let result = { // object is needed for inferred class name
203
- [cls.name]: function (...args) {
204
- let this_class = new.target === result || !new.target
205
- return Reflect.construct(cls, args, this_class ? cls : new.target)
206
- }
207
- }
208
- result[cls.name].prototype = cls.prototype
209
- // fix default tag for toString, e.g. [object Action] instead of [object Object]
210
- cls.prototype[Symbol.toStringTag] = cls.name
211
- return result[cls.name]
212
- }
213
-
214
- function _alias(object, from, to) {
215
- try {
216
- let name = object.constructor.name
217
- Object.defineProperty(object, from, {
218
- value: util.deprecate(object[to], sub('%s.%s() is renamed to %s.%s()',
219
- name, from, name, to)),
220
- enumerable: false
221
- })
222
- } catch {}
223
- }
224
-
225
- // decorator that allows snake_case class methods to be called with camelCase and vice versa
226
- function _camelcase_alias(_class) {
227
- for (let name of Object.getOwnPropertyNames(_class.prototype)) {
228
- let camelcase = name.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase())
229
- if (camelcase !== name) _alias(_class.prototype, camelcase, name)
230
- }
231
- return _class
232
- }
233
-
234
- function _to_legacy_name(key) {
235
- key = key.replace(/\w_[a-z]/g, s => s[0] + s[2].toUpperCase())
236
- if (key === 'default') key = 'defaultValue'
237
- if (key === 'const') key = 'constant'
238
- return key
239
- }
240
-
241
- function _to_new_name(key) {
242
- if (key === 'defaultValue') key = 'default'
243
- if (key === 'constant') key = 'const'
244
- key = key.replace(/[A-Z]/g, c => '_' + c.toLowerCase())
245
- return key
246
- }
247
-
248
- // parse options
249
- let no_default = Symbol('no_default_value')
250
- function _parse_opts(args, descriptor) {
251
- function get_name() {
252
- let stack = new Error().stack.split('\n')
253
- .map(x => x.match(/^ at (.*) \(.*\)$/))
254
- .filter(Boolean)
255
- .map(m => m[1])
256
- .map(fn => fn.match(/[^ .]*$/)[0])
257
-
258
- if (stack.length && stack[0] === get_name.name) stack.shift()
259
- if (stack.length && stack[0] === _parse_opts.name) stack.shift()
260
- return stack.length ? stack[0] : ''
261
- }
262
-
263
- args = Array.from(args)
264
- let kwargs = {}
265
- let result = []
266
- let last_opt = args.length && args[args.length - 1]
267
-
268
- if (typeof last_opt === 'object' && last_opt !== null && !Array.isArray(last_opt) &&
269
- (!last_opt.constructor || last_opt.constructor.name === 'Object')) {
270
- kwargs = Object.assign({}, args.pop())
271
- }
272
-
273
- // LEGACY (v1 compatibility): camelcase
274
- let renames = []
275
- for (let key of Object.keys(descriptor)) {
276
- let old_name = _to_legacy_name(key)
277
- if (old_name !== key && (old_name in kwargs)) {
278
- if (key in kwargs) {
279
- // default and defaultValue specified at the same time, happens often in old tests
280
- //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key))
281
- } else {
282
- kwargs[key] = kwargs[old_name]
283
- }
284
- renames.push([ old_name, key ])
285
- delete kwargs[old_name]
286
- }
287
- }
288
- if (renames.length) {
289
- let name = get_name()
290
- deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s',
291
- name, renames.map(([ a, b ]) => sub('%r -> %r', a, b))))
292
- }
293
- // end
294
-
295
- let missing_positionals = []
296
- let positional_count = args.length
297
-
298
- for (let [ key, def ] of Object.entries(descriptor)) {
299
- if (key[0] === '*') {
300
- if (key.length > 0 && key[1] === '*') {
301
- // LEGACY (v1 compatibility): camelcase
302
- let renames = []
303
- for (let key of Object.keys(kwargs)) {
304
- let new_name = _to_new_name(key)
305
- if (new_name !== key && (key in kwargs)) {
306
- if (new_name in kwargs) {
307
- // default and defaultValue specified at the same time, happens often in old tests
308
- //throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), new_name))
309
- } else {
310
- kwargs[new_name] = kwargs[key]
311
- }
312
- renames.push([ key, new_name ])
313
- delete kwargs[key]
314
- }
315
- }
316
- if (renames.length) {
317
- let name = get_name()
318
- deprecate('camelcase_' + name, sub('%s(): following options are renamed: %s',
319
- name, renames.map(([ a, b ]) => sub('%r -> %r', a, b))))
320
- }
321
- // end
322
- result.push(kwargs)
323
- kwargs = {}
324
- } else {
325
- result.push(args)
326
- args = []
327
- }
328
- } else if (key in kwargs && args.length > 0) {
329
- throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key))
330
- } else if (key in kwargs) {
331
- result.push(kwargs[key])
332
- delete kwargs[key]
333
- } else if (args.length > 0) {
334
- result.push(args.shift())
335
- } else if (def !== no_default) {
336
- result.push(def)
337
- } else {
338
- missing_positionals.push(key)
339
- }
340
- }
341
-
342
- if (Object.keys(kwargs).length) {
343
- throw new TypeError(sub('%s() got an unexpected keyword argument %r',
344
- get_name(), Object.keys(kwargs)[0]))
345
- }
346
-
347
- if (args.length) {
348
- let from = Object.entries(descriptor).filter(([ k, v ]) => k[0] !== '*' && v !== no_default).length
349
- let to = Object.entries(descriptor).filter(([ k ]) => k[0] !== '*').length
350
- throw new TypeError(sub('%s() takes %s positional argument%s but %s %s given',
351
- get_name(),
352
- from === to ? sub('from %s to %s', from, to) : to,
353
- from === to && to === 1 ? '' : 's',
354
- positional_count,
355
- positional_count === 1 ? 'was' : 'were'))
356
- }
357
-
358
- if (missing_positionals.length) {
359
- let strs = missing_positionals.map(repr)
360
- if (strs.length > 1) strs[strs.length - 1] = 'and ' + strs[strs.length - 1]
361
- let str_joined = strs.join(strs.length === 2 ? '' : ', ')
362
- throw new TypeError(sub('%s() missing %i required positional argument%s: %s',
363
- get_name(), strs.length, strs.length === 1 ? '' : 's', str_joined))
364
- }
365
-
366
- return result
367
- }
368
-
369
- let _deprecations = {}
370
- function deprecate(id, string) {
371
- _deprecations[id] = _deprecations[id] || util.deprecate(() => {}, string)
372
- _deprecations[id]()
373
- }
374
-
375
-
376
- // =============================
377
- // Utility functions and classes
378
- // =============================
379
- function _AttributeHolder(cls = Object) {
380
- /*
381
- * Abstract base class that provides __repr__.
382
- *
383
- * The __repr__ method returns a string in the format::
384
- * ClassName(attr=name, attr=name, ...)
385
- * The attributes are determined either by a class-level attribute,
386
- * '_kwarg_names', or by inspecting the instance __dict__.
387
- */
388
-
389
- return class _AttributeHolder extends cls {
390
- [util.inspect.custom]() {
391
- let type_name = this.constructor.name
392
- let arg_strings = []
393
- let star_args = {}
394
- for (let arg of this._get_args()) {
395
- arg_strings.push(repr(arg))
396
- }
397
- for (let [ name, value ] of this._get_kwargs()) {
398
- if (/^[a-z_][a-z0-9_$]*$/i.test(name)) {
399
- arg_strings.push(sub('%s=%r', name, value))
400
- } else {
401
- star_args[name] = value
402
- }
403
- }
404
- if (Object.keys(star_args).length) {
405
- arg_strings.push(sub('**%s', repr(star_args)))
406
- }
407
- return sub('%s(%s)', type_name, arg_strings.join(', '))
408
- }
409
-
410
- toString() {
411
- return this[util.inspect.custom]()
412
- }
413
-
414
- _get_kwargs() {
415
- return Object.entries(this)
416
- }
417
-
418
- _get_args() {
419
- return []
420
- }
421
- }
422
- }
423
-
424
-
425
- function _copy_items(items) {
426
- if (items === undefined) {
427
- return []
428
- }
429
- return items.slice(0)
430
- }
431
-
432
-
433
- // ===============
434
- // Formatting Help
435
- // ===============
436
- const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
437
- /*
438
- * Formatter for generating usage messages and argument help strings.
439
- *
440
- * Only the name of this class is considered a public API. All the methods
441
- * provided by the class are considered an implementation detail.
442
- */
443
-
444
- constructor() {
445
- let [
446
- prog,
447
- indent_increment,
448
- max_help_position,
449
- width
450
- ] = _parse_opts(arguments, {
451
- prog: no_default,
452
- indent_increment: 2,
453
- max_help_position: 24,
454
- width: undefined
455
- })
456
-
457
- // default setting for width
458
- if (width === undefined) {
459
- width = get_terminal_size().columns
460
- width -= 2
461
- }
462
-
463
- this._prog = prog
464
- this._indent_increment = indent_increment
465
- this._max_help_position = Math.min(max_help_position,
466
- Math.max(width - 20, indent_increment * 2))
467
- this._width = width
468
-
469
- this._current_indent = 0
470
- this._level = 0
471
- this._action_max_length = 0
472
-
473
- this._root_section = this._Section(this, undefined)
474
- this._current_section = this._root_section
475
-
476
- this._whitespace_matcher = /[ \t\n\r\f\v]+/g // equivalent to python /\s+/ with ASCII flag
477
- this._long_break_matcher = /\n\n\n+/g
478
- }
479
-
480
- // ===============================
481
- // Section and indentation methods
482
- // ===============================
483
- _indent() {
484
- this._current_indent += this._indent_increment
485
- this._level += 1
486
- }
487
-
488
- _dedent() {
489
- this._current_indent -= this._indent_increment
490
- assert(this._current_indent >= 0, 'Indent decreased below 0.')
491
- this._level -= 1
492
- }
493
-
494
- _add_item(func, args) {
495
- this._current_section.items.push([ func, args ])
496
- }
497
-
498
- // ========================
499
- // Message building methods
500
- // ========================
501
- start_section(heading) {
502
- this._indent()
503
- let section = this._Section(this, this._current_section, heading)
504
- this._add_item(section.format_help.bind(section), [])
505
- this._current_section = section
506
- }
507
-
508
- end_section() {
509
- this._current_section = this._current_section.parent
510
- this._dedent()
511
- }
512
-
513
- add_text(text) {
514
- if (text !== SUPPRESS && text !== undefined) {
515
- this._add_item(this._format_text.bind(this), [text])
516
- }
517
- }
518
-
519
- add_usage(usage, actions, groups, prefix = undefined) {
520
- if (usage !== SUPPRESS) {
521
- let args = [ usage, actions, groups, prefix ]
522
- this._add_item(this._format_usage.bind(this), args)
523
- }
524
- }
525
-
526
- add_argument(action) {
527
- if (action.help !== SUPPRESS) {
528
-
529
- // find all invocations
530
- let invocations = [this._format_action_invocation(action)]
531
- for (let subaction of this._iter_indented_subactions(action)) {
532
- invocations.push(this._format_action_invocation(subaction))
533
- }
534
-
535
- // update the maximum item length
536
- let invocation_length = Math.max(...invocations.map(invocation => invocation.length))
537
- let action_length = invocation_length + this._current_indent
538
- this._action_max_length = Math.max(this._action_max_length,
539
- action_length)
540
-
541
- // add the item to the list
542
- this._add_item(this._format_action.bind(this), [action])
543
- }
544
- }
545
-
546
- add_arguments(actions) {
547
- for (let action of actions) {
548
- this.add_argument(action)
549
- }
550
- }
551
-
552
- // =======================
553
- // Help-formatting methods
554
- // =======================
555
- format_help() {
556
- let help = this._root_section.format_help()
557
- if (help) {
558
- help = help.replace(this._long_break_matcher, '\n\n')
559
- help = help.replace(/^\n+|\n+$/g, '') + '\n'
560
- }
561
- return help
562
- }
563
-
564
- _join_parts(part_strings) {
565
- return part_strings.filter(part => part && part !== SUPPRESS).join('')
566
- }
567
-
568
- _format_usage(usage, actions, groups, prefix) {
569
- if (prefix === undefined) {
570
- prefix = 'usage: '
571
- }
572
-
573
- // if usage is specified, use that
574
- if (usage !== undefined) {
575
- usage = sub(usage, { prog: this._prog })
576
-
577
- // if no optionals or positionals are available, usage is just prog
578
- } else if (usage === undefined && !actions.length) {
579
- usage = sub('%(prog)s', { prog: this._prog })
580
-
581
- // if optionals and positionals are available, calculate usage
582
- } else if (usage === undefined) {
583
- let prog = sub('%(prog)s', { prog: this._prog })
584
-
585
- // split optionals from positionals
586
- let optionals = []
587
- let positionals = []
588
- for (let action of actions) {
589
- if (action.option_strings.length) {
590
- optionals.push(action)
591
- } else {
592
- positionals.push(action)
593
- }
594
- }
595
-
596
- // build full usage string
597
- let action_usage = this._format_actions_usage([].concat(optionals).concat(positionals), groups)
598
- usage = [ prog, action_usage ].map(String).join(' ')
599
-
600
- // wrap the usage parts if it's too long
601
- let text_width = this._width - this._current_indent
602
- if (prefix.length + usage.length > text_width) {
603
-
604
- // break usage into wrappable parts
605
- let part_regexp = /\(.*?\)+(?=\s|$)|\[.*?\]+(?=\s|$)|\S+/g
606
- let opt_usage = this._format_actions_usage(optionals, groups)
607
- let pos_usage = this._format_actions_usage(positionals, groups)
608
- let opt_parts = opt_usage.match(part_regexp) || []
609
- let pos_parts = pos_usage.match(part_regexp) || []
610
- assert(opt_parts.join(' ') === opt_usage)
611
- assert(pos_parts.join(' ') === pos_usage)
612
-
613
- // helper for wrapping lines
614
- let get_lines = (parts, indent, prefix = undefined) => {
615
- let lines = []
616
- let line = []
617
- let line_len
618
- if (prefix !== undefined) {
619
- line_len = prefix.length - 1
620
- } else {
621
- line_len = indent.length - 1
622
- }
623
- for (let part of parts) {
624
- if (line_len + 1 + part.length > text_width && line) {
625
- lines.push(indent + line.join(' '))
626
- line = []
627
- line_len = indent.length - 1
628
- }
629
- line.push(part)
630
- line_len += part.length + 1
631
- }
632
- if (line.length) {
633
- lines.push(indent + line.join(' '))
634
- }
635
- if (prefix !== undefined) {
636
- lines[0] = lines[0].slice(indent.length)
637
- }
638
- return lines
639
- }
640
-
641
- let lines
642
-
643
- // if prog is short, follow it with optionals or positionals
644
- if (prefix.length + prog.length <= 0.75 * text_width) {
645
- let indent = ' '.repeat(prefix.length + prog.length + 1)
646
- if (opt_parts.length) {
647
- lines = get_lines([prog].concat(opt_parts), indent, prefix)
648
- lines = lines.concat(get_lines(pos_parts, indent))
649
- } else if (pos_parts.length) {
650
- lines = get_lines([prog].concat(pos_parts), indent, prefix)
651
- } else {
652
- lines = [prog]
653
- }
654
-
655
- // if prog is long, put it on its own line
656
- } else {
657
- let indent = ' '.repeat(prefix.length)
658
- let parts = [].concat(opt_parts).concat(pos_parts)
659
- lines = get_lines(parts, indent)
660
- if (lines.length > 1) {
661
- lines = []
662
- lines = lines.concat(get_lines(opt_parts, indent))
663
- lines = lines.concat(get_lines(pos_parts, indent))
664
- }
665
- lines = [prog].concat(lines)
666
- }
667
-
668
- // join lines into usage
669
- usage = lines.join('\n')
670
- }
671
- }
672
-
673
- // prefix with 'usage:'
674
- return sub('%s%s\n\n', prefix, usage)
675
- }
676
-
677
- _format_actions_usage(actions, groups) {
678
- // find group indices and identify actions in groups
679
- let group_actions = new Set()
680
- let inserts = {}
681
- for (let group of groups) {
682
- let start = actions.indexOf(group._group_actions[0])
683
- if (start === -1) {
684
- continue
685
- } else {
686
- let end = start + group._group_actions.length
687
- if (_array_equal(actions.slice(start, end), group._group_actions)) {
688
- for (let action of group._group_actions) {
689
- group_actions.add(action)
690
- }
691
- if (!group.required) {
692
- if (start in inserts) {
693
- inserts[start] += ' ['
694
- } else {
695
- inserts[start] = '['
696
- }
697
- if (end in inserts) {
698
- inserts[end] += ']'
699
- } else {
700
- inserts[end] = ']'
701
- }
702
- } else {
703
- if (start in inserts) {
704
- inserts[start] += ' ('
705
- } else {
706
- inserts[start] = '('
707
- }
708
- if (end in inserts) {
709
- inserts[end] += ')'
710
- } else {
711
- inserts[end] = ')'
712
- }
713
- }
714
- for (let i of range(start + 1, end)) {
715
- inserts[i] = '|'
716
- }
717
- }
718
- }
719
- }
720
-
721
- // collect all actions format strings
722
- let parts = []
723
- for (let [ i, action ] of Object.entries(actions)) {
724
-
725
- // suppressed arguments are marked with None
726
- // remove | separators for suppressed arguments
727
- if (action.help === SUPPRESS) {
728
- parts.push(undefined)
729
- if (inserts[+i] === '|') {
730
- delete inserts[+i]
731
- } else if (inserts[+i + 1] === '|') {
732
- delete inserts[+i + 1]
733
- }
734
-
735
- // produce all arg strings
736
- } else if (!action.option_strings.length) {
737
- let default_value = this._get_default_metavar_for_positional(action)
738
- let part = this._format_args(action, default_value)
739
-
740
- // if it's in a group, strip the outer []
741
- if (group_actions.has(action)) {
742
- if (part[0] === '[' && part[part.length - 1] === ']') {
743
- part = part.slice(1, -1)
744
- }
745
- }
746
-
747
- // add the action string to the list
748
- parts.push(part)
749
-
750
- // produce the first way to invoke the option in brackets
751
- } else {
752
- let option_string = action.option_strings[0]
753
- let part
754
-
755
- // if the Optional doesn't take a value, format is:
756
- // -s or --long
757
- if (action.nargs === 0) {
758
- part = action.format_usage()
759
-
760
- // if the Optional takes a value, format is:
761
- // -s ARGS or --long ARGS
762
- } else {
763
- let default_value = this._get_default_metavar_for_optional(action)
764
- let args_string = this._format_args(action, default_value)
765
- part = sub('%s %s', option_string, args_string)
766
- }
767
-
768
- // make it look optional if it's not required or in a group
769
- if (!action.required && !group_actions.has(action)) {
770
- part = sub('[%s]', part)
771
- }
772
-
773
- // add the action string to the list
774
- parts.push(part)
775
- }
776
- }
777
-
778
- // insert things at the necessary indices
779
- for (let i of Object.keys(inserts).map(Number).sort((a, b) => b - a)) {
780
- parts.splice(+i, 0, inserts[+i])
781
- }
782
-
783
- // join all the action items with spaces
784
- let text = parts.filter(Boolean).join(' ')
785
-
786
- // clean up separators for mutually exclusive groups
787
- text = text.replace(/([\[(]) /g, '$1')
788
- text = text.replace(/ ([\])])/g, '$1')
789
- text = text.replace(/[\[(] *[\])]/g, '')
790
- text = text.replace(/\(([^|]*)\)/g, '$1', text)
791
- text = text.trim()
792
-
793
- // return the text
794
- return text
795
- }
796
-
797
- _format_text(text) {
798
- if (text.includes('%(prog)')) {
799
- text = sub(text, { prog: this._prog })
800
- }
801
- let text_width = Math.max(this._width - this._current_indent, 11)
802
- let indent = ' '.repeat(this._current_indent)
803
- return this._fill_text(text, text_width, indent) + '\n\n'
804
- }
805
-
806
- _format_action(action) {
807
- // determine the required width and the entry label
808
- let help_position = Math.min(this._action_max_length + 2,
809
- this._max_help_position)
810
- let help_width = Math.max(this._width - help_position, 11)
811
- let action_width = help_position - this._current_indent - 2
812
- let action_header = this._format_action_invocation(action)
813
- let indent_first
814
-
815
- // no help; start on same line and add a final newline
816
- if (!action.help) {
817
- let tup = [ this._current_indent, '', action_header ]
818
- action_header = sub('%*s%s\n', ...tup)
819
-
820
- // short action name; start on the same line and pad two spaces
821
- } else if (action_header.length <= action_width) {
822
- let tup = [ this._current_indent, '', action_width, action_header ]
823
- action_header = sub('%*s%-*s ', ...tup)
824
- indent_first = 0
825
-
826
- // long action name; start on the next line
827
- } else {
828
- let tup = [ this._current_indent, '', action_header ]
829
- action_header = sub('%*s%s\n', ...tup)
830
- indent_first = help_position
831
- }
832
-
833
- // collect the pieces of the action help
834
- let parts = [action_header]
835
-
836
- // if there was help for the action, add lines of help text
837
- if (action.help) {
838
- let help_text = this._expand_help(action)
839
- let help_lines = this._split_lines(help_text, help_width)
840
- parts.push(sub('%*s%s\n', indent_first, '', help_lines[0]))
841
- for (let line of help_lines.slice(1)) {
842
- parts.push(sub('%*s%s\n', help_position, '', line))
843
- }
844
-
845
- // or add a newline if the description doesn't end with one
846
- } else if (!action_header.endsWith('\n')) {
847
- parts.push('\n')
848
- }
849
-
850
- // if there are any sub-actions, add their help as well
851
- for (let subaction of this._iter_indented_subactions(action)) {
852
- parts.push(this._format_action(subaction))
853
- }
854
-
855
- // return a single string
856
- return this._join_parts(parts)
857
- }
858
-
859
- _format_action_invocation(action) {
860
- if (!action.option_strings.length) {
861
- let default_value = this._get_default_metavar_for_positional(action)
862
- let metavar = this._metavar_formatter(action, default_value)(1)[0]
863
- return metavar
864
-
865
- } else {
866
- let parts = []
867
-
868
- // if the Optional doesn't take a value, format is:
869
- // -s, --long
870
- if (action.nargs === 0) {
871
- parts = parts.concat(action.option_strings)
872
-
873
- // if the Optional takes a value, format is:
874
- // -s ARGS, --long ARGS
875
- } else {
876
- let default_value = this._get_default_metavar_for_optional(action)
877
- let args_string = this._format_args(action, default_value)
878
- for (let option_string of action.option_strings) {
879
- parts.push(sub('%s %s', option_string, args_string))
880
- }
881
- }
882
-
883
- return parts.join(', ')
884
- }
885
- }
886
-
887
- _metavar_formatter(action, default_metavar) {
888
- let result
889
- if (action.metavar !== undefined) {
890
- result = action.metavar
891
- } else if (action.choices !== undefined) {
892
- let choice_strs = _choices_to_array(action.choices).map(String)
893
- result = sub('{%s}', choice_strs.join(','))
894
- } else {
895
- result = default_metavar
896
- }
897
-
898
- function format(tuple_size) {
899
- if (Array.isArray(result)) {
900
- return result
901
- } else {
902
- return Array(tuple_size).fill(result)
903
- }
904
- }
905
- return format
906
- }
907
-
908
- _format_args(action, default_metavar) {
909
- let get_metavar = this._metavar_formatter(action, default_metavar)
910
- let result
911
- if (action.nargs === undefined) {
912
- result = sub('%s', ...get_metavar(1))
913
- } else if (action.nargs === OPTIONAL) {
914
- result = sub('[%s]', ...get_metavar(1))
915
- } else if (action.nargs === ZERO_OR_MORE) {
916
- let metavar = get_metavar(1)
917
- if (metavar.length === 2) {
918
- result = sub('[%s [%s ...]]', ...metavar)
919
- } else {
920
- result = sub('[%s ...]', ...metavar)
921
- }
922
- } else if (action.nargs === ONE_OR_MORE) {
923
- result = sub('%s [%s ...]', ...get_metavar(2))
924
- } else if (action.nargs === REMAINDER) {
925
- result = '...'
926
- } else if (action.nargs === PARSER) {
927
- result = sub('%s ...', ...get_metavar(1))
928
- } else if (action.nargs === SUPPRESS) {
929
- result = ''
930
- } else {
931
- let formats
932
- try {
933
- formats = range(action.nargs).map(() => '%s')
934
- } catch (err) {
935
- throw new TypeError('invalid nargs value')
936
- }
937
- result = sub(formats.join(' '), ...get_metavar(action.nargs))
938
- }
939
- return result
940
- }
941
-
942
- _expand_help(action) {
943
- let params = Object.assign({ prog: this._prog }, action)
944
- for (let name of Object.keys(params)) {
945
- if (params[name] === SUPPRESS) {
946
- delete params[name]
947
- }
948
- }
949
- for (let name of Object.keys(params)) {
950
- if (params[name] && params[name].name) {
951
- params[name] = params[name].name
952
- }
953
- }
954
- if (params.choices !== undefined) {
955
- let choices_str = _choices_to_array(params.choices).map(String).join(', ')
956
- params.choices = choices_str
957
- }
958
- // LEGACY (v1 compatibility): camelcase
959
- for (let key of Object.keys(params)) {
960
- let old_name = _to_legacy_name(key)
961
- if (old_name !== key) {
962
- params[old_name] = params[key]
963
- }
964
- }
965
- // end
966
- return sub(this._get_help_string(action), params)
967
- }
968
-
969
- * _iter_indented_subactions(action) {
970
- if (typeof action._get_subactions === 'function') {
971
- this._indent()
972
- yield* action._get_subactions()
973
- this._dedent()
974
- }
975
- }
976
-
977
- _split_lines(text, width) {
978
- text = text.replace(this._whitespace_matcher, ' ').trim()
979
- // The textwrap module is used only for formatting help.
980
- // Delay its import for speeding up the common usage of argparse.
981
- let textwrap = require('./lib/textwrap')
982
- return textwrap.wrap(text, { width })
983
- }
984
-
985
- _fill_text(text, width, indent) {
986
- text = text.replace(this._whitespace_matcher, ' ').trim()
987
- let textwrap = require('./lib/textwrap')
988
- return textwrap.fill(text, { width,
989
- initial_indent: indent,
990
- subsequent_indent: indent })
991
- }
992
-
993
- _get_help_string(action) {
994
- return action.help
995
- }
996
-
997
- _get_default_metavar_for_optional(action) {
998
- return action.dest.toUpperCase()
999
- }
1000
-
1001
- _get_default_metavar_for_positional(action) {
1002
- return action.dest
1003
- }
1004
- }))
1005
-
1006
- HelpFormatter.prototype._Section = _callable(class _Section {
1007
-
1008
- constructor(formatter, parent, heading = undefined) {
1009
- this.formatter = formatter
1010
- this.parent = parent
1011
- this.heading = heading
1012
- this.items = []
1013
- }
1014
-
1015
- format_help() {
1016
- // format the indented section
1017
- if (this.parent !== undefined) {
1018
- this.formatter._indent()
1019
- }
1020
- let item_help = this.formatter._join_parts(this.items.map(([ func, args ]) => func.apply(null, args)))
1021
- if (this.parent !== undefined) {
1022
- this.formatter._dedent()
1023
- }
1024
-
1025
- // return nothing if the section was empty
1026
- if (!item_help) {
1027
- return ''
1028
- }
1029
-
1030
- // add the heading if the section was non-empty
1031
- let heading
1032
- if (this.heading !== SUPPRESS && this.heading !== undefined) {
1033
- let current_indent = this.formatter._current_indent
1034
- heading = sub('%*s%s:\n', current_indent, '', this.heading)
1035
- } else {
1036
- heading = ''
1037
- }
1038
-
1039
- // join the section-initial newline, the heading and the help
1040
- return this.formatter._join_parts(['\n', heading, item_help, '\n'])
1041
- }
1042
- })
1043
-
1044
-
1045
- const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescriptionHelpFormatter extends HelpFormatter {
1046
- /*
1047
- * Help message formatter which retains any formatting in descriptions.
1048
- *
1049
- * Only the name of this class is considered a public API. All the methods
1050
- * provided by the class are considered an implementation detail.
1051
- */
1052
-
1053
- _fill_text(text, width, indent) {
1054
- return splitlines(text, true).map(line => indent + line).join('')
1055
- }
1056
- }))
1057
-
1058
-
1059
- const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter {
1060
- /*
1061
- * Help message formatter which retains formatting of all help text.
1062
- *
1063
- * Only the name of this class is considered a public API. All the methods
1064
- * provided by the class are considered an implementation detail.
1065
- */
1066
-
1067
- _split_lines(text/*, width*/) {
1068
- return splitlines(text)
1069
- }
1070
- }))
1071
-
1072
-
1073
- const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter {
1074
- /*
1075
- * Help message formatter which adds default values to argument help.
1076
- *
1077
- * Only the name of this class is considered a public API. All the methods
1078
- * provided by the class are considered an implementation detail.
1079
- */
1080
-
1081
- _get_help_string(action) {
1082
- let help = action.help
1083
- // LEGACY (v1 compatibility): additional check for defaultValue needed
1084
- if (!action.help.includes('%(default)') && !action.help.includes('%(defaultValue)')) {
1085
- if (action.default !== SUPPRESS) {
1086
- let defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
1087
- if (action.option_strings.length || defaulting_nargs.includes(action.nargs)) {
1088
- help += ' (default: %(default)s)'
1089
- }
1090
- }
1091
- }
1092
- return help
1093
- }
1094
- }))
1095
-
1096
-
1097
- const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHelpFormatter extends HelpFormatter {
1098
- /*
1099
- * Help message formatter which uses the argument 'type' as the default
1100
- * metavar value (instead of the argument 'dest')
1101
- *
1102
- * Only the name of this class is considered a public API. All the methods
1103
- * provided by the class are considered an implementation detail.
1104
- */
1105
-
1106
- _get_default_metavar_for_optional(action) {
1107
- return typeof action.type === 'function' ? action.type.name : action.type
1108
- }
1109
-
1110
- _get_default_metavar_for_positional(action) {
1111
- return typeof action.type === 'function' ? action.type.name : action.type
1112
- }
1113
- }))
1114
-
1115
-
1116
- // =====================
1117
- // Options and Arguments
1118
- // =====================
1119
- function _get_action_name(argument) {
1120
- if (argument === undefined) {
1121
- return undefined
1122
- } else if (argument.option_strings.length) {
1123
- return argument.option_strings.join('/')
1124
- } else if (![ undefined, SUPPRESS ].includes(argument.metavar)) {
1125
- return argument.metavar
1126
- } else if (![ undefined, SUPPRESS ].includes(argument.dest)) {
1127
- return argument.dest
1128
- } else {
1129
- return undefined
1130
- }
1131
- }
1132
-
1133
-
1134
- const ArgumentError = _callable(class ArgumentError extends Error {
1135
- /*
1136
- * An error from creating or using an argument (optional or positional).
1137
- *
1138
- * The string value of this exception is the message, augmented with
1139
- * information about the argument that caused it.
1140
- */
1141
-
1142
- constructor(argument, message) {
1143
- super()
1144
- this.name = 'ArgumentError'
1145
- this._argument_name = _get_action_name(argument)
1146
- this._message = message
1147
- this.message = this.str()
1148
- }
1149
-
1150
- str() {
1151
- let format
1152
- if (this._argument_name === undefined) {
1153
- format = '%(message)s'
1154
- } else {
1155
- format = 'argument %(argument_name)s: %(message)s'
1156
- }
1157
- return sub(format, { message: this._message,
1158
- argument_name: this._argument_name })
1159
- }
1160
- })
1161
-
1162
-
1163
- const ArgumentTypeError = _callable(class ArgumentTypeError extends Error {
1164
- /*
1165
- * An error from trying to convert a command line string to a type.
1166
- */
1167
-
1168
- constructor(message) {
1169
- super(message)
1170
- this.name = 'ArgumentTypeError'
1171
- }
1172
- })
1173
-
1174
-
1175
- // ==============
1176
- // Action classes
1177
- // ==============
1178
- const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(Function) {
1179
- /*
1180
- * Information about how to convert command line strings to Python objects.
1181
- *
1182
- * Action objects are used by an ArgumentParser to represent the information
1183
- * needed to parse a single argument from one or more strings from the
1184
- * command line. The keyword arguments to the Action constructor are also
1185
- * all attributes of Action instances.
1186
- *
1187
- * Keyword Arguments:
1188
- *
1189
- * - option_strings -- A list of command-line option strings which
1190
- * should be associated with this action.
1191
- *
1192
- * - dest -- The name of the attribute to hold the created object(s)
1193
- *
1194
- * - nargs -- The number of command-line arguments that should be
1195
- * consumed. By default, one argument will be consumed and a single
1196
- * value will be produced. Other values include:
1197
- * - N (an integer) consumes N arguments (and produces a list)
1198
- * - '?' consumes zero or one arguments
1199
- * - '*' consumes zero or more arguments (and produces a list)
1200
- * - '+' consumes one or more arguments (and produces a list)
1201
- * Note that the difference between the default and nargs=1 is that
1202
- * with the default, a single value will be produced, while with
1203
- * nargs=1, a list containing a single value will be produced.
1204
- *
1205
- * - const -- The value to be produced if the option is specified and the
1206
- * option uses an action that takes no values.
1207
- *
1208
- * - default -- The value to be produced if the option is not specified.
1209
- *
1210
- * - type -- A callable that accepts a single string argument, and
1211
- * returns the converted value. The standard Python types str, int,
1212
- * float, and complex are useful examples of such callables. If None,
1213
- * str is used.
1214
- *
1215
- * - choices -- A container of values that should be allowed. If not None,
1216
- * after a command-line argument has been converted to the appropriate
1217
- * type, an exception will be raised if it is not a member of this
1218
- * collection.
1219
- *
1220
- * - required -- True if the action must always be specified at the
1221
- * command line. This is only meaningful for optional command-line
1222
- * arguments.
1223
- *
1224
- * - help -- The help string describing the argument.
1225
- *
1226
- * - metavar -- The name to be used for the option's argument with the
1227
- * help string. If None, the 'dest' value will be used as the name.
1228
- */
1229
-
1230
- constructor() {
1231
- let [
1232
- option_strings,
1233
- dest,
1234
- nargs,
1235
- const_value,
1236
- default_value,
1237
- type,
1238
- choices,
1239
- required,
1240
- help,
1241
- metavar
1242
- ] = _parse_opts(arguments, {
1243
- option_strings: no_default,
1244
- dest: no_default,
1245
- nargs: undefined,
1246
- const: undefined,
1247
- default: undefined,
1248
- type: undefined,
1249
- choices: undefined,
1250
- required: false,
1251
- help: undefined,
1252
- metavar: undefined
1253
- })
1254
-
1255
- // when this class is called as a function, redirect it to .call() method of itself
1256
- super('return arguments.callee.call.apply(arguments.callee, arguments)')
1257
-
1258
- this.option_strings = option_strings
1259
- this.dest = dest
1260
- this.nargs = nargs
1261
- this.const = const_value
1262
- this.default = default_value
1263
- this.type = type
1264
- this.choices = choices
1265
- this.required = required
1266
- this.help = help
1267
- this.metavar = metavar
1268
- }
1269
-
1270
- _get_kwargs() {
1271
- let names = [
1272
- 'option_strings',
1273
- 'dest',
1274
- 'nargs',
1275
- 'const',
1276
- 'default',
1277
- 'type',
1278
- 'choices',
1279
- 'help',
1280
- 'metavar'
1281
- ]
1282
- return names.map(name => [ name, getattr(this, name) ])
1283
- }
1284
-
1285
- format_usage() {
1286
- return this.option_strings[0]
1287
- }
1288
-
1289
- call(/*parser, namespace, values, option_string = undefined*/) {
1290
- throw new Error('.call() not defined')
1291
- }
1292
- }))
1293
-
1294
-
1295
- const BooleanOptionalAction = _camelcase_alias(_callable(class BooleanOptionalAction extends Action {
1296
-
1297
- constructor() {
1298
- let [
1299
- option_strings,
1300
- dest,
1301
- default_value,
1302
- type,
1303
- choices,
1304
- required,
1305
- help,
1306
- metavar
1307
- ] = _parse_opts(arguments, {
1308
- option_strings: no_default,
1309
- dest: no_default,
1310
- default: undefined,
1311
- type: undefined,
1312
- choices: undefined,
1313
- required: false,
1314
- help: undefined,
1315
- metavar: undefined
1316
- })
1317
-
1318
- let _option_strings = []
1319
- for (let option_string of option_strings) {
1320
- _option_strings.push(option_string)
1321
-
1322
- if (option_string.startsWith('--')) {
1323
- option_string = '--no-' + option_string.slice(2)
1324
- _option_strings.push(option_string)
1325
- }
1326
- }
1327
-
1328
- if (help !== undefined && default_value !== undefined) {
1329
- help += ` (default: ${default_value})`
1330
- }
1331
-
1332
- super({
1333
- option_strings: _option_strings,
1334
- dest,
1335
- nargs: 0,
1336
- default: default_value,
1337
- type,
1338
- choices,
1339
- required,
1340
- help,
1341
- metavar
1342
- })
1343
- }
1344
-
1345
- call(parser, namespace, values, option_string = undefined) {
1346
- if (this.option_strings.includes(option_string)) {
1347
- setattr(namespace, this.dest, !option_string.startsWith('--no-'))
1348
- }
1349
- }
1350
-
1351
- format_usage() {
1352
- return this.option_strings.join(' | ')
1353
- }
1354
- }))
1355
-
1356
-
1357
- const _StoreAction = _callable(class _StoreAction extends Action {
1358
-
1359
- constructor() {
1360
- let [
1361
- option_strings,
1362
- dest,
1363
- nargs,
1364
- const_value,
1365
- default_value,
1366
- type,
1367
- choices,
1368
- required,
1369
- help,
1370
- metavar
1371
- ] = _parse_opts(arguments, {
1372
- option_strings: no_default,
1373
- dest: no_default,
1374
- nargs: undefined,
1375
- const: undefined,
1376
- default: undefined,
1377
- type: undefined,
1378
- choices: undefined,
1379
- required: false,
1380
- help: undefined,
1381
- metavar: undefined
1382
- })
1383
-
1384
- if (nargs === 0) {
1385
- throw new TypeError('nargs for store actions must be != 0; if you ' +
1386
- 'have nothing to store, actions such as store ' +
1387
- 'true or store const may be more appropriate')
1388
- }
1389
- if (const_value !== undefined && nargs !== OPTIONAL) {
1390
- throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL))
1391
- }
1392
- super({
1393
- option_strings,
1394
- dest,
1395
- nargs,
1396
- const: const_value,
1397
- default: default_value,
1398
- type,
1399
- choices,
1400
- required,
1401
- help,
1402
- metavar
1403
- })
1404
- }
1405
-
1406
- call(parser, namespace, values/*, option_string = undefined*/) {
1407
- setattr(namespace, this.dest, values)
1408
- }
1409
- })
1410
-
1411
-
1412
- const _StoreConstAction = _callable(class _StoreConstAction extends Action {
1413
-
1414
- constructor() {
1415
- let [
1416
- option_strings,
1417
- dest,
1418
- const_value,
1419
- default_value,
1420
- required,
1421
- help
1422
- //, metavar
1423
- ] = _parse_opts(arguments, {
1424
- option_strings: no_default,
1425
- dest: no_default,
1426
- const: no_default,
1427
- default: undefined,
1428
- required: false,
1429
- help: undefined,
1430
- metavar: undefined
1431
- })
1432
-
1433
- super({
1434
- option_strings,
1435
- dest,
1436
- nargs: 0,
1437
- const: const_value,
1438
- default: default_value,
1439
- required,
1440
- help
1441
- })
1442
- }
1443
-
1444
- call(parser, namespace/*, values, option_string = undefined*/) {
1445
- setattr(namespace, this.dest, this.const)
1446
- }
1447
- })
1448
-
1449
-
1450
- const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAction {
1451
-
1452
- constructor() {
1453
- let [
1454
- option_strings,
1455
- dest,
1456
- default_value,
1457
- required,
1458
- help
1459
- ] = _parse_opts(arguments, {
1460
- option_strings: no_default,
1461
- dest: no_default,
1462
- default: false,
1463
- required: false,
1464
- help: undefined
1465
- })
1466
-
1467
- super({
1468
- option_strings,
1469
- dest,
1470
- const: true,
1471
- default: default_value,
1472
- required,
1473
- help
1474
- })
1475
- }
1476
- })
1477
-
1478
-
1479
- const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstAction {
1480
-
1481
- constructor() {
1482
- let [
1483
- option_strings,
1484
- dest,
1485
- default_value,
1486
- required,
1487
- help
1488
- ] = _parse_opts(arguments, {
1489
- option_strings: no_default,
1490
- dest: no_default,
1491
- default: true,
1492
- required: false,
1493
- help: undefined
1494
- })
1495
-
1496
- super({
1497
- option_strings,
1498
- dest,
1499
- const: false,
1500
- default: default_value,
1501
- required,
1502
- help
1503
- })
1504
- }
1505
- })
1506
-
1507
-
1508
- const _AppendAction = _callable(class _AppendAction extends Action {
1509
-
1510
- constructor() {
1511
- let [
1512
- option_strings,
1513
- dest,
1514
- nargs,
1515
- const_value,
1516
- default_value,
1517
- type,
1518
- choices,
1519
- required,
1520
- help,
1521
- metavar
1522
- ] = _parse_opts(arguments, {
1523
- option_strings: no_default,
1524
- dest: no_default,
1525
- nargs: undefined,
1526
- const: undefined,
1527
- default: undefined,
1528
- type: undefined,
1529
- choices: undefined,
1530
- required: false,
1531
- help: undefined,
1532
- metavar: undefined
1533
- })
1534
-
1535
- if (nargs === 0) {
1536
- throw new TypeError('nargs for append actions must be != 0; if arg ' +
1537
- 'strings are not supplying the value to append, ' +
1538
- 'the append const action may be more appropriate')
1539
- }
1540
- if (const_value !== undefined && nargs !== OPTIONAL) {
1541
- throw new TypeError(sub('nargs must be %r to supply const', OPTIONAL))
1542
- }
1543
- super({
1544
- option_strings,
1545
- dest,
1546
- nargs,
1547
- const: const_value,
1548
- default: default_value,
1549
- type,
1550
- choices,
1551
- required,
1552
- help,
1553
- metavar
1554
- })
1555
- }
1556
-
1557
- call(parser, namespace, values/*, option_string = undefined*/) {
1558
- let items = getattr(namespace, this.dest, undefined)
1559
- items = _copy_items(items)
1560
- items.push(values)
1561
- setattr(namespace, this.dest, items)
1562
- }
1563
- })
1564
-
1565
-
1566
- const _AppendConstAction = _callable(class _AppendConstAction extends Action {
1567
-
1568
- constructor() {
1569
- let [
1570
- option_strings,
1571
- dest,
1572
- const_value,
1573
- default_value,
1574
- required,
1575
- help,
1576
- metavar
1577
- ] = _parse_opts(arguments, {
1578
- option_strings: no_default,
1579
- dest: no_default,
1580
- const: no_default,
1581
- default: undefined,
1582
- required: false,
1583
- help: undefined,
1584
- metavar: undefined
1585
- })
1586
-
1587
- super({
1588
- option_strings,
1589
- dest,
1590
- nargs: 0,
1591
- const: const_value,
1592
- default: default_value,
1593
- required,
1594
- help,
1595
- metavar
1596
- })
1597
- }
1598
-
1599
- call(parser, namespace/*, values, option_string = undefined*/) {
1600
- let items = getattr(namespace, this.dest, undefined)
1601
- items = _copy_items(items)
1602
- items.push(this.const)
1603
- setattr(namespace, this.dest, items)
1604
- }
1605
- })
1606
-
1607
-
1608
- const _CountAction = _callable(class _CountAction extends Action {
1609
-
1610
- constructor() {
1611
- let [
1612
- option_strings,
1613
- dest,
1614
- default_value,
1615
- required,
1616
- help
1617
- ] = _parse_opts(arguments, {
1618
- option_strings: no_default,
1619
- dest: no_default,
1620
- default: undefined,
1621
- required: false,
1622
- help: undefined
1623
- })
1624
-
1625
- super({
1626
- option_strings,
1627
- dest,
1628
- nargs: 0,
1629
- default: default_value,
1630
- required,
1631
- help
1632
- })
1633
- }
1634
-
1635
- call(parser, namespace/*, values, option_string = undefined*/) {
1636
- let count = getattr(namespace, this.dest, undefined)
1637
- if (count === undefined) {
1638
- count = 0
1639
- }
1640
- setattr(namespace, this.dest, count + 1)
1641
- }
1642
- })
1643
-
1644
-
1645
- const _HelpAction = _callable(class _HelpAction extends Action {
1646
-
1647
- constructor() {
1648
- let [
1649
- option_strings,
1650
- dest,
1651
- default_value,
1652
- help
1653
- ] = _parse_opts(arguments, {
1654
- option_strings: no_default,
1655
- dest: SUPPRESS,
1656
- default: SUPPRESS,
1657
- help: undefined
1658
- })
1659
-
1660
- super({
1661
- option_strings,
1662
- dest,
1663
- default: default_value,
1664
- nargs: 0,
1665
- help
1666
- })
1667
- }
1668
-
1669
- call(parser/*, namespace, values, option_string = undefined*/) {
1670
- parser.print_help()
1671
- parser.exit()
1672
- }
1673
- })
1674
-
1675
-
1676
- const _VersionAction = _callable(class _VersionAction extends Action {
1677
-
1678
- constructor() {
1679
- let [
1680
- option_strings,
1681
- version,
1682
- dest,
1683
- default_value,
1684
- help
1685
- ] = _parse_opts(arguments, {
1686
- option_strings: no_default,
1687
- version: undefined,
1688
- dest: SUPPRESS,
1689
- default: SUPPRESS,
1690
- help: "show program's version number and exit"
1691
- })
1692
-
1693
- super({
1694
- option_strings,
1695
- dest,
1696
- default: default_value,
1697
- nargs: 0,
1698
- help
1699
- })
1700
- this.version = version
1701
- }
1702
-
1703
- call(parser/*, namespace, values, option_string = undefined*/) {
1704
- let version = this.version
1705
- if (version === undefined) {
1706
- version = parser.version
1707
- }
1708
- let formatter = parser._get_formatter()
1709
- formatter.add_text(version)
1710
- parser._print_message(formatter.format_help(), process.stdout)
1711
- parser.exit()
1712
- }
1713
- })
1714
-
1715
-
1716
- const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction extends Action {
1717
-
1718
- constructor() {
1719
- let [
1720
- option_strings,
1721
- prog,
1722
- parser_class,
1723
- dest,
1724
- required,
1725
- help,
1726
- metavar
1727
- ] = _parse_opts(arguments, {
1728
- option_strings: no_default,
1729
- prog: no_default,
1730
- parser_class: no_default,
1731
- dest: SUPPRESS,
1732
- required: false,
1733
- help: undefined,
1734
- metavar: undefined
1735
- })
1736
-
1737
- let name_parser_map = {}
1738
-
1739
- super({
1740
- option_strings,
1741
- dest,
1742
- nargs: PARSER,
1743
- choices: name_parser_map,
1744
- required,
1745
- help,
1746
- metavar
1747
- })
1748
-
1749
- this._prog_prefix = prog
1750
- this._parser_class = parser_class
1751
- this._name_parser_map = name_parser_map
1752
- this._choices_actions = []
1753
- }
1754
-
1755
- add_parser() {
1756
- let [
1757
- name,
1758
- kwargs
1759
- ] = _parse_opts(arguments, {
1760
- name: no_default,
1761
- '**kwargs': no_default
1762
- })
1763
-
1764
- // set prog from the existing prefix
1765
- if (kwargs.prog === undefined) {
1766
- kwargs.prog = sub('%s %s', this._prog_prefix, name)
1767
- }
1768
-
1769
- let aliases = getattr(kwargs, 'aliases', [])
1770
- delete kwargs.aliases
1771
-
1772
- // create a pseudo-action to hold the choice help
1773
- if ('help' in kwargs) {
1774
- let help = kwargs.help
1775
- delete kwargs.help
1776
- let choice_action = this._ChoicesPseudoAction(name, aliases, help)
1777
- this._choices_actions.push(choice_action)
1778
- }
1779
-
1780
- // create the parser and add it to the map
1781
- let parser = new this._parser_class(kwargs)
1782
- this._name_parser_map[name] = parser
1783
-
1784
- // make parser available under aliases also
1785
- for (let alias of aliases) {
1786
- this._name_parser_map[alias] = parser
1787
- }
1788
-
1789
- return parser
1790
- }
1791
-
1792
- _get_subactions() {
1793
- return this._choices_actions
1794
- }
1795
-
1796
- call(parser, namespace, values/*, option_string = undefined*/) {
1797
- let parser_name = values[0]
1798
- let arg_strings = values.slice(1)
1799
-
1800
- // set the parser name if requested
1801
- if (this.dest !== SUPPRESS) {
1802
- setattr(namespace, this.dest, parser_name)
1803
- }
1804
-
1805
- // select the parser
1806
- if (hasattr(this._name_parser_map, parser_name)) {
1807
- parser = this._name_parser_map[parser_name]
1808
- } else {
1809
- let args = {parser_name,
1810
- choices: this._name_parser_map.join(', ')}
1811
- let msg = sub('unknown parser %(parser_name)r (choices: %(choices)s)', args)
1812
- throw new ArgumentError(this, msg)
1813
- }
1814
-
1815
- // parse all the remaining options into the namespace
1816
- // store any unrecognized options on the object, so that the top
1817
- // level parser can decide what to do with them
1818
-
1819
- // In case this subparser defines new defaults, we parse them
1820
- // in a new namespace object and then update the original
1821
- // namespace for the relevant parts.
1822
- let subnamespace
1823
- [ subnamespace, arg_strings ] = parser.parse_known_args(arg_strings, undefined)
1824
- for (let [ key, value ] of Object.entries(subnamespace)) {
1825
- setattr(namespace, key, value)
1826
- }
1827
-
1828
- if (arg_strings.length) {
1829
- setdefault(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
1830
- getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).push(...arg_strings)
1831
- }
1832
- }
1833
- }))
1834
-
1835
-
1836
- _SubParsersAction.prototype._ChoicesPseudoAction = _callable(class _ChoicesPseudoAction extends Action {
1837
- constructor(name, aliases, help) {
1838
- let metavar = name, dest = name
1839
- if (aliases.length) {
1840
- metavar += sub(' (%s)', aliases.join(', '))
1841
- }
1842
- super({ option_strings: [], dest, help, metavar })
1843
- }
1844
- })
1845
-
1846
-
1847
- const _ExtendAction = _callable(class _ExtendAction extends _AppendAction {
1848
- call(parser, namespace, values/*, option_string = undefined*/) {
1849
- let items = getattr(namespace, this.dest, undefined)
1850
- items = _copy_items(items)
1851
- items = items.concat(values)
1852
- setattr(namespace, this.dest, items)
1853
- }
1854
- })
1855
-
1856
-
1857
- // ==============
1858
- // Type classes
1859
- // ==============
1860
- const FileType = _callable(class FileType extends Function {
1861
- /*
1862
- * Factory for creating file object types
1863
- *
1864
- * Instances of FileType are typically passed as type= arguments to the
1865
- * ArgumentParser add_argument() method.
1866
- *
1867
- * Keyword Arguments:
1868
- * - mode -- A string indicating how the file is to be opened. Accepts the
1869
- * same values as the builtin open() function.
1870
- * - bufsize -- The file's desired buffer size. Accepts the same values as
1871
- * the builtin open() function.
1872
- * - encoding -- The file's encoding. Accepts the same values as the
1873
- * builtin open() function.
1874
- * - errors -- A string indicating how encoding and decoding errors are to
1875
- * be handled. Accepts the same value as the builtin open() function.
1876
- */
1877
-
1878
- constructor() {
1879
- let [
1880
- flags,
1881
- encoding,
1882
- mode,
1883
- autoClose,
1884
- emitClose,
1885
- start,
1886
- end,
1887
- highWaterMark,
1888
- fs
1889
- ] = _parse_opts(arguments, {
1890
- flags: 'r',
1891
- encoding: undefined,
1892
- mode: undefined, // 0o666
1893
- autoClose: undefined, // true
1894
- emitClose: undefined, // false
1895
- start: undefined, // 0
1896
- end: undefined, // Infinity
1897
- highWaterMark: undefined, // 64 * 1024
1898
- fs: undefined
1899
- })
1900
-
1901
- // when this class is called as a function, redirect it to .call() method of itself
1902
- super('return arguments.callee.call.apply(arguments.callee, arguments)')
1903
-
1904
- Object.defineProperty(this, 'name', {
1905
- get() {
1906
- return sub('FileType(%r)', flags)
1907
- }
1908
- })
1909
- this._flags = flags
1910
- this._options = {}
1911
- if (encoding !== undefined) this._options.encoding = encoding
1912
- if (mode !== undefined) this._options.mode = mode
1913
- if (autoClose !== undefined) this._options.autoClose = autoClose
1914
- if (emitClose !== undefined) this._options.emitClose = emitClose
1915
- if (start !== undefined) this._options.start = start
1916
- if (end !== undefined) this._options.end = end
1917
- if (highWaterMark !== undefined) this._options.highWaterMark = highWaterMark
1918
- if (fs !== undefined) this._options.fs = fs
1919
- }
1920
-
1921
- call(string) {
1922
- // the special argument "-" means sys.std{in,out}
1923
- if (string === '-') {
1924
- if (this._flags.includes('r')) {
1925
- return process.stdin
1926
- } else if (this._flags.includes('w')) {
1927
- return process.stdout
1928
- } else {
1929
- let msg = sub('argument "-" with mode %r', this._flags)
1930
- throw new TypeError(msg)
1931
- }
1932
- }
1933
-
1934
- // all other arguments are used as file names
1935
- let fd
1936
- try {
1937
- fd = fs.openSync(string, this._flags, this._options.mode)
1938
- } catch (e) {
1939
- let args = { filename: string, error: e.message }
1940
- let message = "can't open '%(filename)s': %(error)s"
1941
- throw new ArgumentTypeError(sub(message, args))
1942
- }
1943
-
1944
- let options = Object.assign({ fd, flags: this._flags }, this._options)
1945
- if (this._flags.includes('r')) {
1946
- return fs.createReadStream(undefined, options)
1947
- } else if (this._flags.includes('w')) {
1948
- return fs.createWriteStream(undefined, options)
1949
- } else {
1950
- let msg = sub('argument "%s" with mode %r', string, this._flags)
1951
- throw new TypeError(msg)
1952
- }
1953
- }
1954
-
1955
- [util.inspect.custom]() {
1956
- let args = [ this._flags ]
1957
- let kwargs = Object.entries(this._options).map(([ k, v ]) => {
1958
- if (k === 'mode') v = { value: v, [util.inspect.custom]() { return '0o' + this.value.toString(8) } }
1959
- return [ k, v ]
1960
- })
1961
- let args_str = []
1962
- .concat(args.filter(arg => arg !== -1).map(repr))
1963
- .concat(kwargs.filter(([/*kw*/, arg]) => arg !== undefined)
1964
- .map(([kw, arg]) => sub('%s=%r', kw, arg)))
1965
- .join(', ')
1966
- return sub('%s(%s)', this.constructor.name, args_str)
1967
- }
1968
-
1969
- toString() {
1970
- return this[util.inspect.custom]()
1971
- }
1972
- })
1973
-
1974
- // ===========================
1975
- // Optional and Positional Parsing
1976
- // ===========================
1977
- const Namespace = _callable(class Namespace extends _AttributeHolder() {
1978
- /*
1979
- * Simple object for storing attributes.
1980
- *
1981
- * Implements equality by attribute names and values, and provides a simple
1982
- * string representation.
1983
- */
1984
-
1985
- constructor(options = {}) {
1986
- super()
1987
- Object.assign(this, options)
1988
- }
1989
- })
1990
-
1991
- // unset string tag to mimic plain object
1992
- Namespace.prototype[Symbol.toStringTag] = undefined
1993
-
1994
-
1995
- const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
1996
-
1997
- constructor() {
1998
- let [
1999
- description,
2000
- prefix_chars,
2001
- argument_default,
2002
- conflict_handler
2003
- ] = _parse_opts(arguments, {
2004
- description: no_default,
2005
- prefix_chars: no_default,
2006
- argument_default: no_default,
2007
- conflict_handler: no_default
2008
- })
2009
-
2010
- this.description = description
2011
- this.argument_default = argument_default
2012
- this.prefix_chars = prefix_chars
2013
- this.conflict_handler = conflict_handler
2014
-
2015
- // set up registries
2016
- this._registries = {}
2017
-
2018
- // register actions
2019
- this.register('action', undefined, _StoreAction)
2020
- this.register('action', 'store', _StoreAction)
2021
- this.register('action', 'store_const', _StoreConstAction)
2022
- this.register('action', 'store_true', _StoreTrueAction)
2023
- this.register('action', 'store_false', _StoreFalseAction)
2024
- this.register('action', 'append', _AppendAction)
2025
- this.register('action', 'append_const', _AppendConstAction)
2026
- this.register('action', 'count', _CountAction)
2027
- this.register('action', 'help', _HelpAction)
2028
- this.register('action', 'version', _VersionAction)
2029
- this.register('action', 'parsers', _SubParsersAction)
2030
- this.register('action', 'extend', _ExtendAction)
2031
- // LEGACY (v1 compatibility): camelcase variants
2032
- ;[ 'storeConst', 'storeTrue', 'storeFalse', 'appendConst' ].forEach(old_name => {
2033
- let new_name = _to_new_name(old_name)
2034
- this.register('action', old_name, util.deprecate(this._registry_get('action', new_name),
2035
- sub('{action: "%s"} is renamed to {action: "%s"}', old_name, new_name)))
2036
- })
2037
- // end
2038
-
2039
- // raise an exception if the conflict handler is invalid
2040
- this._get_handler()
2041
-
2042
- // action storage
2043
- this._actions = []
2044
- this._option_string_actions = {}
2045
-
2046
- // groups
2047
- this._action_groups = []
2048
- this._mutually_exclusive_groups = []
2049
-
2050
- // defaults storage
2051
- this._defaults = {}
2052
-
2053
- // determines whether an "option" looks like a negative number
2054
- this._negative_number_matcher = /^-\d+$|^-\d*\.\d+$/
2055
-
2056
- // whether or not there are any optionals that look like negative
2057
- // numbers -- uses a list so it can be shared and edited
2058
- this._has_negative_number_optionals = []
2059
- }
2060
-
2061
- // ====================
2062
- // Registration methods
2063
- // ====================
2064
- register(registry_name, value, object) {
2065
- let registry = setdefault(this._registries, registry_name, {})
2066
- registry[value] = object
2067
- }
2068
-
2069
- _registry_get(registry_name, value, default_value = undefined) {
2070
- return getattr(this._registries[registry_name], value, default_value)
2071
- }
2072
-
2073
- // ==================================
2074
- // Namespace default accessor methods
2075
- // ==================================
2076
- set_defaults(kwargs) {
2077
- Object.assign(this._defaults, kwargs)
2078
-
2079
- // if these defaults match any existing arguments, replace
2080
- // the previous default on the object with the new one
2081
- for (let action of this._actions) {
2082
- if (action.dest in kwargs) {
2083
- action.default = kwargs[action.dest]
2084
- }
2085
- }
2086
- }
2087
-
2088
- get_default(dest) {
2089
- for (let action of this._actions) {
2090
- if (action.dest === dest && action.default !== undefined) {
2091
- return action.default
2092
- }
2093
- }
2094
- return this._defaults[dest]
2095
- }
2096
-
2097
-
2098
- // =======================
2099
- // Adding argument actions
2100
- // =======================
2101
- add_argument() {
2102
- /*
2103
- * add_argument(dest, ..., name=value, ...)
2104
- * add_argument(option_string, option_string, ..., name=value, ...)
2105
- */
2106
- let [
2107
- args,
2108
- kwargs
2109
- ] = _parse_opts(arguments, {
2110
- '*args': no_default,
2111
- '**kwargs': no_default
2112
- })
2113
- // LEGACY (v1 compatibility), old-style add_argument([ args ], { options })
2114
- if (args.length === 1 && Array.isArray(args[0])) {
2115
- args = args[0]
2116
- deprecate('argument-array',
2117
- sub('use add_argument(%(args)s, {...}) instead of add_argument([ %(args)s ], { ... })', {
2118
- args: args.map(repr).join(', ')
2119
- }))
2120
- }
2121
- // end
2122
-
2123
- // if no positional args are supplied or only one is supplied and
2124
- // it doesn't look like an option string, parse a positional
2125
- // argument
2126
- let chars = this.prefix_chars
2127
- if (!args.length || args.length === 1 && !chars.includes(args[0][0])) {
2128
- if (args.length && 'dest' in kwargs) {
2129
- throw new TypeError('dest supplied twice for positional argument')
2130
- }
2131
- kwargs = this._get_positional_kwargs(...args, kwargs)
2132
-
2133
- // otherwise, we're adding an optional argument
2134
- } else {
2135
- kwargs = this._get_optional_kwargs(...args, kwargs)
2136
- }
2137
-
2138
- // if no default was supplied, use the parser-level default
2139
- if (!('default' in kwargs)) {
2140
- let dest = kwargs.dest
2141
- if (dest in this._defaults) {
2142
- kwargs.default = this._defaults[dest]
2143
- } else if (this.argument_default !== undefined) {
2144
- kwargs.default = this.argument_default
2145
- }
2146
- }
2147
-
2148
- // create the action object, and add it to the parser
2149
- let action_class = this._pop_action_class(kwargs)
2150
- if (typeof action_class !== 'function') {
2151
- throw new TypeError(sub('unknown action "%s"', action_class))
2152
- }
2153
- // eslint-disable-next-line new-cap
2154
- let action = new action_class(kwargs)
2155
-
2156
- // raise an error if the action type is not callable
2157
- let type_func = this._registry_get('type', action.type, action.type)
2158
- if (typeof type_func !== 'function') {
2159
- throw new TypeError(sub('%r is not callable', type_func))
2160
- }
2161
-
2162
- if (type_func === FileType) {
2163
- throw new TypeError(sub('%r is a FileType class object, instance of it' +
2164
- ' must be passed', type_func))
2165
- }
2166
-
2167
- // raise an error if the metavar does not match the type
2168
- if ('_get_formatter' in this) {
2169
- try {
2170
- this._get_formatter()._format_args(action, undefined)
2171
- } catch (err) {
2172
- // check for 'invalid nargs value' is an artifact of TypeError and ValueError in js being the same
2173
- if (err instanceof TypeError && err.message !== 'invalid nargs value') {
2174
- throw new TypeError('length of metavar tuple does not match nargs')
2175
- } else {
2176
- throw err
2177
- }
2178
- }
2179
- }
2180
-
2181
- return this._add_action(action)
2182
- }
2183
-
2184
- add_argument_group() {
2185
- let group = _ArgumentGroup(this, ...arguments)
2186
- this._action_groups.push(group)
2187
- return group
2188
- }
2189
-
2190
- add_mutually_exclusive_group() {
2191
- // eslint-disable-next-line no-use-before-define
2192
- let group = _MutuallyExclusiveGroup(this, ...arguments)
2193
- this._mutually_exclusive_groups.push(group)
2194
- return group
2195
- }
2196
-
2197
- _add_action(action) {
2198
- // resolve any conflicts
2199
- this._check_conflict(action)
2200
-
2201
- // add to actions list
2202
- this._actions.push(action)
2203
- action.container = this
2204
-
2205
- // index the action by any option strings it has
2206
- for (let option_string of action.option_strings) {
2207
- this._option_string_actions[option_string] = action
2208
- }
2209
-
2210
- // set the flag if any option strings look like negative numbers
2211
- for (let option_string of action.option_strings) {
2212
- if (this._negative_number_matcher.test(option_string)) {
2213
- if (!this._has_negative_number_optionals.length) {
2214
- this._has_negative_number_optionals.push(true)
2215
- }
2216
- }
2217
- }
2218
-
2219
- // return the created action
2220
- return action
2221
- }
2222
-
2223
- _remove_action(action) {
2224
- _array_remove(this._actions, action)
2225
- }
2226
-
2227
- _add_container_actions(container) {
2228
- // collect groups by titles
2229
- let title_group_map = {}
2230
- for (let group of this._action_groups) {
2231
- if (group.title in title_group_map) {
2232
- let msg = 'cannot merge actions - two groups are named %r'
2233
- throw new TypeError(sub(msg, group.title))
2234
- }
2235
- title_group_map[group.title] = group
2236
- }
2237
-
2238
- // map each action to its group
2239
- let group_map = new Map()
2240
- for (let group of container._action_groups) {
2241
-
2242
- // if a group with the title exists, use that, otherwise
2243
- // create a new group matching the container's group
2244
- if (!(group.title in title_group_map)) {
2245
- title_group_map[group.title] = this.add_argument_group({
2246
- title: group.title,
2247
- description: group.description,
2248
- conflict_handler: group.conflict_handler
2249
- })
2250
- }
2251
-
2252
- // map the actions to their new group
2253
- for (let action of group._group_actions) {
2254
- group_map.set(action, title_group_map[group.title])
2255
- }
2256
- }
2257
-
2258
- // add container's mutually exclusive groups
2259
- // NOTE: if add_mutually_exclusive_group ever gains title= and
2260
- // description= then this code will need to be expanded as above
2261
- for (let group of container._mutually_exclusive_groups) {
2262
- let mutex_group = this.add_mutually_exclusive_group({
2263
- required: group.required
2264
- })
2265
-
2266
- // map the actions to their new mutex group
2267
- for (let action of group._group_actions) {
2268
- group_map.set(action, mutex_group)
2269
- }
2270
- }
2271
-
2272
- // add all actions to this container or their group
2273
- for (let action of container._actions) {
2274
- group_map.get(action)._add_action(action)
2275
- }
2276
- }
2277
-
2278
- _get_positional_kwargs() {
2279
- let [
2280
- dest,
2281
- kwargs
2282
- ] = _parse_opts(arguments, {
2283
- dest: no_default,
2284
- '**kwargs': no_default
2285
- })
2286
-
2287
- // make sure required is not specified
2288
- if ('required' in kwargs) {
2289
- let msg = "'required' is an invalid argument for positionals"
2290
- throw new TypeError(msg)
2291
- }
2292
-
2293
- // mark positional arguments as required if at least one is
2294
- // always required
2295
- if (![OPTIONAL, ZERO_OR_MORE].includes(kwargs.nargs)) {
2296
- kwargs.required = true
2297
- }
2298
- if (kwargs.nargs === ZERO_OR_MORE && !('default' in kwargs)) {
2299
- kwargs.required = true
2300
- }
2301
-
2302
- // return the keyword arguments with no option strings
2303
- return Object.assign(kwargs, { dest, option_strings: [] })
2304
- }
2305
-
2306
- _get_optional_kwargs() {
2307
- let [
2308
- args,
2309
- kwargs
2310
- ] = _parse_opts(arguments, {
2311
- '*args': no_default,
2312
- '**kwargs': no_default
2313
- })
2314
-
2315
- // determine short and long option strings
2316
- let option_strings = []
2317
- let long_option_strings = []
2318
- let option_string
2319
- for (option_string of args) {
2320
- // error on strings that don't start with an appropriate prefix
2321
- if (!this.prefix_chars.includes(option_string[0])) {
2322
- let args = {option: option_string,
2323
- prefix_chars: this.prefix_chars}
2324
- let msg = 'invalid option string %(option)r: ' +
2325
- 'must start with a character %(prefix_chars)r'
2326
- throw new TypeError(sub(msg, args))
2327
- }
2328
-
2329
- // strings starting with two prefix characters are long options
2330
- option_strings.push(option_string)
2331
- if (option_string.length > 1 && this.prefix_chars.includes(option_string[1])) {
2332
- long_option_strings.push(option_string)
2333
- }
2334
- }
2335
-
2336
- // infer destination, '--foo-bar' -> 'foo_bar' and '-x' -> 'x'
2337
- let dest = kwargs.dest
2338
- delete kwargs.dest
2339
- if (dest === undefined) {
2340
- let dest_option_string
2341
- if (long_option_strings.length) {
2342
- dest_option_string = long_option_strings[0]
2343
- } else {
2344
- dest_option_string = option_strings[0]
2345
- }
2346
- dest = _string_lstrip(dest_option_string, this.prefix_chars)
2347
- if (!dest) {
2348
- let msg = 'dest= is required for options like %r'
2349
- throw new TypeError(sub(msg, option_string))
2350
- }
2351
- dest = dest.replace(/-/g, '_')
2352
- }
2353
-
2354
- // return the updated keyword arguments
2355
- return Object.assign(kwargs, { dest, option_strings })
2356
- }
2357
-
2358
- _pop_action_class(kwargs, default_value = undefined) {
2359
- let action = getattr(kwargs, 'action', default_value)
2360
- delete kwargs.action
2361
- return this._registry_get('action', action, action)
2362
- }
2363
-
2364
- _get_handler() {
2365
- // determine function from conflict handler string
2366
- let handler_func_name = sub('_handle_conflict_%s', this.conflict_handler)
2367
- if (typeof this[handler_func_name] === 'function') {
2368
- return this[handler_func_name]
2369
- } else {
2370
- let msg = 'invalid conflict_resolution value: %r'
2371
- throw new TypeError(sub(msg, this.conflict_handler))
2372
- }
2373
- }
2374
-
2375
- _check_conflict(action) {
2376
-
2377
- // find all options that conflict with this option
2378
- let confl_optionals = []
2379
- for (let option_string of action.option_strings) {
2380
- if (hasattr(this._option_string_actions, option_string)) {
2381
- let confl_optional = this._option_string_actions[option_string]
2382
- confl_optionals.push([ option_string, confl_optional ])
2383
- }
2384
- }
2385
-
2386
- // resolve any conflicts
2387
- if (confl_optionals.length) {
2388
- let conflict_handler = this._get_handler()
2389
- conflict_handler.call(this, action, confl_optionals)
2390
- }
2391
- }
2392
-
2393
- _handle_conflict_error(action, conflicting_actions) {
2394
- let message = conflicting_actions.length === 1 ?
2395
- 'conflicting option string: %s' :
2396
- 'conflicting option strings: %s'
2397
- let conflict_string = conflicting_actions.map(([ option_string/*, action*/ ]) => option_string).join(', ')
2398
- throw new ArgumentError(action, sub(message, conflict_string))
2399
- }
2400
-
2401
- _handle_conflict_resolve(action, conflicting_actions) {
2402
-
2403
- // remove all conflicting options
2404
- for (let [ option_string, action ] of conflicting_actions) {
2405
-
2406
- // remove the conflicting option
2407
- _array_remove(action.option_strings, option_string)
2408
- delete this._option_string_actions[option_string]
2409
-
2410
- // if the option now has no option string, remove it from the
2411
- // container holding it
2412
- if (!action.option_strings.length) {
2413
- action.container._remove_action(action)
2414
- }
2415
- }
2416
- }
2417
- }))
2418
-
2419
-
2420
- const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer {
2421
-
2422
- constructor() {
2423
- let [
2424
- container,
2425
- title,
2426
- description,
2427
- kwargs
2428
- ] = _parse_opts(arguments, {
2429
- container: no_default,
2430
- title: undefined,
2431
- description: undefined,
2432
- '**kwargs': no_default
2433
- })
2434
-
2435
- // add any missing keyword arguments by checking the container
2436
- setdefault(kwargs, 'conflict_handler', container.conflict_handler)
2437
- setdefault(kwargs, 'prefix_chars', container.prefix_chars)
2438
- setdefault(kwargs, 'argument_default', container.argument_default)
2439
- super(Object.assign({ description }, kwargs))
2440
-
2441
- // group attributes
2442
- this.title = title
2443
- this._group_actions = []
2444
-
2445
- // share most attributes with the container
2446
- this._registries = container._registries
2447
- this._actions = container._actions
2448
- this._option_string_actions = container._option_string_actions
2449
- this._defaults = container._defaults
2450
- this._has_negative_number_optionals =
2451
- container._has_negative_number_optionals
2452
- this._mutually_exclusive_groups = container._mutually_exclusive_groups
2453
- }
2454
-
2455
- _add_action(action) {
2456
- action = super._add_action(action)
2457
- this._group_actions.push(action)
2458
- return action
2459
- }
2460
-
2461
- _remove_action(action) {
2462
- super._remove_action(action)
2463
- _array_remove(this._group_actions, action)
2464
- }
2465
- })
2466
-
2467
-
2468
- const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends _ArgumentGroup {
2469
-
2470
- constructor() {
2471
- let [
2472
- container,
2473
- required
2474
- ] = _parse_opts(arguments, {
2475
- container: no_default,
2476
- required: false
2477
- })
2478
-
2479
- super(container)
2480
- this.required = required
2481
- this._container = container
2482
- }
2483
-
2484
- _add_action(action) {
2485
- if (action.required) {
2486
- let msg = 'mutually exclusive arguments must be optional'
2487
- throw new TypeError(msg)
2488
- }
2489
- action = this._container._add_action(action)
2490
- this._group_actions.push(action)
2491
- return action
2492
- }
2493
-
2494
- _remove_action(action) {
2495
- this._container._remove_action(action)
2496
- _array_remove(this._group_actions, action)
2497
- }
2498
- })
2499
-
2500
-
2501
- const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _AttributeHolder(_ActionsContainer) {
2502
- /*
2503
- * Object for parsing command line strings into Python objects.
2504
- *
2505
- * Keyword Arguments:
2506
- * - prog -- The name of the program (default: sys.argv[0])
2507
- * - usage -- A usage message (default: auto-generated from arguments)
2508
- * - description -- A description of what the program does
2509
- * - epilog -- Text following the argument descriptions
2510
- * - parents -- Parsers whose arguments should be copied into this one
2511
- * - formatter_class -- HelpFormatter class for printing help messages
2512
- * - prefix_chars -- Characters that prefix optional arguments
2513
- * - fromfile_prefix_chars -- Characters that prefix files containing
2514
- * additional arguments
2515
- * - argument_default -- The default value for all arguments
2516
- * - conflict_handler -- String indicating how to handle conflicts
2517
- * - add_help -- Add a -h/-help option
2518
- * - allow_abbrev -- Allow long options to be abbreviated unambiguously
2519
- * - exit_on_error -- Determines whether or not ArgumentParser exits with
2520
- * error info when an error occurs
2521
- */
2522
-
2523
- constructor() {
2524
- let [
2525
- prog,
2526
- usage,
2527
- description,
2528
- epilog,
2529
- parents,
2530
- formatter_class,
2531
- prefix_chars,
2532
- fromfile_prefix_chars,
2533
- argument_default,
2534
- conflict_handler,
2535
- add_help,
2536
- allow_abbrev,
2537
- exit_on_error,
2538
- debug, // LEGACY (v1 compatibility), debug mode
2539
- version // LEGACY (v1 compatibility), version
2540
- ] = _parse_opts(arguments, {
2541
- prog: undefined,
2542
- usage: undefined,
2543
- description: undefined,
2544
- epilog: undefined,
2545
- parents: [],
2546
- formatter_class: HelpFormatter,
2547
- prefix_chars: '-',
2548
- fromfile_prefix_chars: undefined,
2549
- argument_default: undefined,
2550
- conflict_handler: 'error',
2551
- add_help: true,
2552
- allow_abbrev: true,
2553
- exit_on_error: true,
2554
- debug: undefined, // LEGACY (v1 compatibility), debug mode
2555
- version: undefined // LEGACY (v1 compatibility), version
2556
- })
2557
-
2558
- // LEGACY (v1 compatibility)
2559
- if (debug !== undefined) {
2560
- deprecate('debug',
2561
- 'The "debug" argument to ArgumentParser is deprecated. Please ' +
2562
- 'override ArgumentParser.exit function instead.'
2563
- )
2564
- }
2565
-
2566
- if (version !== undefined) {
2567
- deprecate('version',
2568
- 'The "version" argument to ArgumentParser is deprecated. Please use ' +
2569
- "add_argument(..., { action: 'version', version: 'N', ... }) instead."
2570
- )
2571
- }
2572
- // end
2573
-
2574
- super({
2575
- description,
2576
- prefix_chars,
2577
- argument_default,
2578
- conflict_handler
2579
- })
2580
-
2581
- // default setting for prog
2582
- if (prog === undefined) {
2583
- prog = path.basename(get_argv()[0] || '')
2584
- }
2585
-
2586
- this.prog = prog
2587
- this.usage = usage
2588
- this.epilog = epilog
2589
- this.formatter_class = formatter_class
2590
- this.fromfile_prefix_chars = fromfile_prefix_chars
2591
- this.add_help = add_help
2592
- this.allow_abbrev = allow_abbrev
2593
- this.exit_on_error = exit_on_error
2594
- // LEGACY (v1 compatibility), debug mode
2595
- this.debug = debug
2596
- // end
2597
-
2598
- this._positionals = this.add_argument_group('positional arguments')
2599
- this._optionals = this.add_argument_group('optional arguments')
2600
- this._subparsers = undefined
2601
-
2602
- // register types
2603
- function identity(string) {
2604
- return string
2605
- }
2606
- this.register('type', undefined, identity)
2607
- this.register('type', null, identity)
2608
- this.register('type', 'auto', identity)
2609
- this.register('type', 'int', function (x) {
2610
- let result = Number(x)
2611
- if (!Number.isInteger(result)) {
2612
- throw new TypeError(sub('could not convert string to int: %r', x))
2613
- }
2614
- return result
2615
- })
2616
- this.register('type', 'float', function (x) {
2617
- let result = Number(x)
2618
- if (isNaN(result)) {
2619
- throw new TypeError(sub('could not convert string to float: %r', x))
2620
- }
2621
- return result
2622
- })
2623
- this.register('type', 'str', String)
2624
- // LEGACY (v1 compatibility): custom types
2625
- this.register('type', 'string',
2626
- util.deprecate(String, 'use {type:"str"} or {type:String} instead of {type:"string"}'))
2627
- // end
2628
-
2629
- // add help argument if necessary
2630
- // (using explicit default to override global argument_default)
2631
- let default_prefix = prefix_chars.includes('-') ? '-' : prefix_chars[0]
2632
- if (this.add_help) {
2633
- this.add_argument(
2634
- default_prefix + 'h',
2635
- default_prefix.repeat(2) + 'help',
2636
- {
2637
- action: 'help',
2638
- default: SUPPRESS,
2639
- help: 'show this help message and exit'
2640
- }
2641
- )
2642
- }
2643
- // LEGACY (v1 compatibility), version
2644
- if (version) {
2645
- this.add_argument(
2646
- default_prefix + 'v',
2647
- default_prefix.repeat(2) + 'version',
2648
- {
2649
- action: 'version',
2650
- default: SUPPRESS,
2651
- version: this.version,
2652
- help: "show program's version number and exit"
2653
- }
2654
- )
2655
- }
2656
- // end
2657
-
2658
- // add parent arguments and defaults
2659
- for (let parent of parents) {
2660
- this._add_container_actions(parent)
2661
- Object.assign(this._defaults, parent._defaults)
2662
- }
2663
- }
2664
-
2665
- // =======================
2666
- // Pretty __repr__ methods
2667
- // =======================
2668
- _get_kwargs() {
2669
- let names = [
2670
- 'prog',
2671
- 'usage',
2672
- 'description',
2673
- 'formatter_class',
2674
- 'conflict_handler',
2675
- 'add_help'
2676
- ]
2677
- return names.map(name => [ name, getattr(this, name) ])
2678
- }
2679
-
2680
- // ==================================
2681
- // Optional/Positional adding methods
2682
- // ==================================
2683
- add_subparsers() {
2684
- let [
2685
- kwargs
2686
- ] = _parse_opts(arguments, {
2687
- '**kwargs': no_default
2688
- })
2689
-
2690
- if (this._subparsers !== undefined) {
2691
- this.error('cannot have multiple subparser arguments')
2692
- }
2693
-
2694
- // add the parser class to the arguments if it's not present
2695
- setdefault(kwargs, 'parser_class', this.constructor)
2696
-
2697
- if ('title' in kwargs || 'description' in kwargs) {
2698
- let title = getattr(kwargs, 'title', 'subcommands')
2699
- let description = getattr(kwargs, 'description', undefined)
2700
- delete kwargs.title
2701
- delete kwargs.description
2702
- this._subparsers = this.add_argument_group(title, description)
2703
- } else {
2704
- this._subparsers = this._positionals
2705
- }
2706
-
2707
- // prog defaults to the usage message of this parser, skipping
2708
- // optional arguments and with no "usage:" prefix
2709
- if (kwargs.prog === undefined) {
2710
- let formatter = this._get_formatter()
2711
- let positionals = this._get_positional_actions()
2712
- let groups = this._mutually_exclusive_groups
2713
- formatter.add_usage(this.usage, positionals, groups, '')
2714
- kwargs.prog = formatter.format_help().trim()
2715
- }
2716
-
2717
- // create the parsers action and add it to the positionals list
2718
- let parsers_class = this._pop_action_class(kwargs, 'parsers')
2719
- // eslint-disable-next-line new-cap
2720
- let action = new parsers_class(Object.assign({ option_strings: [] }, kwargs))
2721
- this._subparsers._add_action(action)
2722
-
2723
- // return the created parsers action
2724
- return action
2725
- }
2726
-
2727
- _add_action(action) {
2728
- if (action.option_strings.length) {
2729
- this._optionals._add_action(action)
2730
- } else {
2731
- this._positionals._add_action(action)
2732
- }
2733
- return action
2734
- }
2735
-
2736
- _get_optional_actions() {
2737
- return this._actions.filter(action => action.option_strings.length)
2738
- }
2739
-
2740
- _get_positional_actions() {
2741
- return this._actions.filter(action => !action.option_strings.length)
2742
- }
2743
-
2744
- // =====================================
2745
- // Command line argument parsing methods
2746
- // =====================================
2747
- parse_args(args = undefined, namespace = undefined) {
2748
- let argv
2749
- [ args, argv ] = this.parse_known_args(args, namespace)
2750
- if (argv && argv.length > 0) {
2751
- let msg = 'unrecognized arguments: %s'
2752
- this.error(sub(msg, argv.join(' ')))
2753
- }
2754
- return args
2755
- }
2756
-
2757
- parse_known_args(args = undefined, namespace = undefined) {
2758
- if (args === undefined) {
2759
- args = get_argv().slice(1)
2760
- }
2761
-
2762
- // default Namespace built from parser defaults
2763
- if (namespace === undefined) {
2764
- namespace = new Namespace()
2765
- }
2766
-
2767
- // add any action defaults that aren't present
2768
- for (let action of this._actions) {
2769
- if (action.dest !== SUPPRESS) {
2770
- if (!hasattr(namespace, action.dest)) {
2771
- if (action.default !== SUPPRESS) {
2772
- setattr(namespace, action.dest, action.default)
2773
- }
2774
- }
2775
- }
2776
- }
2777
-
2778
- // add any parser defaults that aren't present
2779
- for (let dest of Object.keys(this._defaults)) {
2780
- if (!hasattr(namespace, dest)) {
2781
- setattr(namespace, dest, this._defaults[dest])
2782
- }
2783
- }
2784
-
2785
- // parse the arguments and exit if there are any errors
2786
- if (this.exit_on_error) {
2787
- try {
2788
- [ namespace, args ] = this._parse_known_args(args, namespace)
2789
- } catch (err) {
2790
- if (err instanceof ArgumentError) {
2791
- this.error(err.message)
2792
- } else {
2793
- throw err
2794
- }
2795
- }
2796
- } else {
2797
- [ namespace, args ] = this._parse_known_args(args, namespace)
2798
- }
2799
-
2800
- if (hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) {
2801
- args = args.concat(getattr(namespace, _UNRECOGNIZED_ARGS_ATTR))
2802
- delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
2803
- }
2804
-
2805
- return [ namespace, args ]
2806
- }
2807
-
2808
- _parse_known_args(arg_strings, namespace) {
2809
- // replace arg strings that are file references
2810
- if (this.fromfile_prefix_chars !== undefined) {
2811
- arg_strings = this._read_args_from_files(arg_strings)
2812
- }
2813
-
2814
- // map all mutually exclusive arguments to the other arguments
2815
- // they can't occur with
2816
- let action_conflicts = new Map()
2817
- for (let mutex_group of this._mutually_exclusive_groups) {
2818
- let group_actions = mutex_group._group_actions
2819
- for (let [ i, mutex_action ] of Object.entries(mutex_group._group_actions)) {
2820
- let conflicts = action_conflicts.get(mutex_action) || []
2821
- conflicts = conflicts.concat(group_actions.slice(0, +i))
2822
- conflicts = conflicts.concat(group_actions.slice(+i + 1))
2823
- action_conflicts.set(mutex_action, conflicts)
2824
- }
2825
- }
2826
-
2827
- // find all option indices, and determine the arg_string_pattern
2828
- // which has an 'O' if there is an option at an index,
2829
- // an 'A' if there is an argument, or a '-' if there is a '--'
2830
- let option_string_indices = {}
2831
- let arg_string_pattern_parts = []
2832
- let arg_strings_iter = Object.entries(arg_strings)[Symbol.iterator]()
2833
- for (let [ i, arg_string ] of arg_strings_iter) {
2834
-
2835
- // all args after -- are non-options
2836
- if (arg_string === '--') {
2837
- arg_string_pattern_parts.push('-')
2838
- for ([ i, arg_string ] of arg_strings_iter) {
2839
- arg_string_pattern_parts.push('A')
2840
- }
2841
-
2842
- // otherwise, add the arg to the arg strings
2843
- // and note the index if it was an option
2844
- } else {
2845
- let option_tuple = this._parse_optional(arg_string)
2846
- let pattern
2847
- if (option_tuple === undefined) {
2848
- pattern = 'A'
2849
- } else {
2850
- option_string_indices[i] = option_tuple
2851
- pattern = 'O'
2852
- }
2853
- arg_string_pattern_parts.push(pattern)
2854
- }
2855
- }
2856
-
2857
- // join the pieces together to form the pattern
2858
- let arg_strings_pattern = arg_string_pattern_parts.join('')
2859
-
2860
- // converts arg strings to the appropriate and then takes the action
2861
- let seen_actions = new Set()
2862
- let seen_non_default_actions = new Set()
2863
- let extras
2864
-
2865
- let take_action = (action, argument_strings, option_string = undefined) => {
2866
- seen_actions.add(action)
2867
- let argument_values = this._get_values(action, argument_strings)
2868
-
2869
- // error if this argument is not allowed with other previously
2870
- // seen arguments, assuming that actions that use the default
2871
- // value don't really count as "present"
2872
- if (argument_values !== action.default) {
2873
- seen_non_default_actions.add(action)
2874
- for (let conflict_action of action_conflicts.get(action) || []) {
2875
- if (seen_non_default_actions.has(conflict_action)) {
2876
- let msg = 'not allowed with argument %s'
2877
- let action_name = _get_action_name(conflict_action)
2878
- throw new ArgumentError(action, sub(msg, action_name))
2879
- }
2880
- }
2881
- }
2882
-
2883
- // take the action if we didn't receive a SUPPRESS value
2884
- // (e.g. from a default)
2885
- if (argument_values !== SUPPRESS) {
2886
- action(this, namespace, argument_values, option_string)
2887
- }
2888
- }
2889
-
2890
- // function to convert arg_strings into an optional action
2891
- let consume_optional = start_index => {
2892
-
2893
- // get the optional identified at this index
2894
- let option_tuple = option_string_indices[start_index]
2895
- let [ action, option_string, explicit_arg ] = option_tuple
2896
-
2897
- // identify additional optionals in the same arg string
2898
- // (e.g. -xyz is the same as -x -y -z if no args are required)
2899
- let action_tuples = []
2900
- let stop
2901
- for (;;) {
2902
-
2903
- // if we found no optional action, skip it
2904
- if (action === undefined) {
2905
- extras.push(arg_strings[start_index])
2906
- return start_index + 1
2907
- }
2908
-
2909
- // if there is an explicit argument, try to match the
2910
- // optional's string arguments to only this
2911
- if (explicit_arg !== undefined) {
2912
- let arg_count = this._match_argument(action, 'A')
2913
-
2914
- // if the action is a single-dash option and takes no
2915
- // arguments, try to parse more single-dash options out
2916
- // of the tail of the option string
2917
- let chars = this.prefix_chars
2918
- if (arg_count === 0 && !chars.includes(option_string[1])) {
2919
- action_tuples.push([ action, [], option_string ])
2920
- let char = option_string[0]
2921
- option_string = char + explicit_arg[0]
2922
- let new_explicit_arg = explicit_arg.slice(1) || undefined
2923
- let optionals_map = this._option_string_actions
2924
- if (hasattr(optionals_map, option_string)) {
2925
- action = optionals_map[option_string]
2926
- explicit_arg = new_explicit_arg
2927
- } else {
2928
- let msg = 'ignored explicit argument %r'
2929
- throw new ArgumentError(action, sub(msg, explicit_arg))
2930
- }
2931
-
2932
- // if the action expect exactly one argument, we've
2933
- // successfully matched the option; exit the loop
2934
- } else if (arg_count === 1) {
2935
- stop = start_index + 1
2936
- let args = [ explicit_arg ]
2937
- action_tuples.push([ action, args, option_string ])
2938
- break
2939
-
2940
- // error if a double-dash option did not use the
2941
- // explicit argument
2942
- } else {
2943
- let msg = 'ignored explicit argument %r'
2944
- throw new ArgumentError(action, sub(msg, explicit_arg))
2945
- }
2946
-
2947
- // if there is no explicit argument, try to match the
2948
- // optional's string arguments with the following strings
2949
- // if successful, exit the loop
2950
- } else {
2951
- let start = start_index + 1
2952
- let selected_patterns = arg_strings_pattern.slice(start)
2953
- let arg_count = this._match_argument(action, selected_patterns)
2954
- stop = start + arg_count
2955
- let args = arg_strings.slice(start, stop)
2956
- action_tuples.push([ action, args, option_string ])
2957
- break
2958
- }
2959
- }
2960
-
2961
- // add the Optional to the list and return the index at which
2962
- // the Optional's string args stopped
2963
- assert(action_tuples.length)
2964
- for (let [ action, args, option_string ] of action_tuples) {
2965
- take_action(action, args, option_string)
2966
- }
2967
- return stop
2968
- }
2969
-
2970
- // the list of Positionals left to be parsed; this is modified
2971
- // by consume_positionals()
2972
- let positionals = this._get_positional_actions()
2973
-
2974
- // function to convert arg_strings into positional actions
2975
- let consume_positionals = start_index => {
2976
- // match as many Positionals as possible
2977
- let selected_pattern = arg_strings_pattern.slice(start_index)
2978
- let arg_counts = this._match_arguments_partial(positionals, selected_pattern)
2979
-
2980
- // slice off the appropriate arg strings for each Positional
2981
- // and add the Positional and its args to the list
2982
- for (let i = 0; i < positionals.length && i < arg_counts.length; i++) {
2983
- let action = positionals[i]
2984
- let arg_count = arg_counts[i]
2985
- let args = arg_strings.slice(start_index, start_index + arg_count)
2986
- start_index += arg_count
2987
- take_action(action, args)
2988
- }
2989
-
2990
- // slice off the Positionals that we just parsed and return the
2991
- // index at which the Positionals' string args stopped
2992
- positionals = positionals.slice(arg_counts.length)
2993
- return start_index
2994
- }
2995
-
2996
- // consume Positionals and Optionals alternately, until we have
2997
- // passed the last option string
2998
- extras = []
2999
- let start_index = 0
3000
- let max_option_string_index = Math.max(-1, ...Object.keys(option_string_indices).map(Number))
3001
- while (start_index <= max_option_string_index) {
3002
-
3003
- // consume any Positionals preceding the next option
3004
- let next_option_string_index = Math.min(
3005
- // eslint-disable-next-line no-loop-func
3006
- ...Object.keys(option_string_indices).map(Number).filter(index => index >= start_index)
3007
- )
3008
- if (start_index !== next_option_string_index) {
3009
- let positionals_end_index = consume_positionals(start_index)
3010
-
3011
- // only try to parse the next optional if we didn't consume
3012
- // the option string during the positionals parsing
3013
- if (positionals_end_index > start_index) {
3014
- start_index = positionals_end_index
3015
- continue
3016
- } else {
3017
- start_index = positionals_end_index
3018
- }
3019
- }
3020
-
3021
- // if we consumed all the positionals we could and we're not
3022
- // at the index of an option string, there were extra arguments
3023
- if (!(start_index in option_string_indices)) {
3024
- let strings = arg_strings.slice(start_index, next_option_string_index)
3025
- extras = extras.concat(strings)
3026
- start_index = next_option_string_index
3027
- }
3028
-
3029
- // consume the next optional and any arguments for it
3030
- start_index = consume_optional(start_index)
3031
- }
3032
-
3033
- // consume any positionals following the last Optional
3034
- let stop_index = consume_positionals(start_index)
3035
-
3036
- // if we didn't consume all the argument strings, there were extras
3037
- extras = extras.concat(arg_strings.slice(stop_index))
3038
-
3039
- // make sure all required actions were present and also convert
3040
- // action defaults which were not given as arguments
3041
- let required_actions = []
3042
- for (let action of this._actions) {
3043
- if (!seen_actions.has(action)) {
3044
- if (action.required) {
3045
- required_actions.push(_get_action_name(action))
3046
- } else {
3047
- // Convert action default now instead of doing it before
3048
- // parsing arguments to avoid calling convert functions
3049
- // twice (which may fail) if the argument was given, but
3050
- // only if it was defined already in the namespace
3051
- if (action.default !== undefined &&
3052
- typeof action.default === 'string' &&
3053
- hasattr(namespace, action.dest) &&
3054
- action.default === getattr(namespace, action.dest)) {
3055
- setattr(namespace, action.dest,
3056
- this._get_value(action, action.default))
3057
- }
3058
- }
3059
- }
3060
- }
3061
-
3062
- if (required_actions.length) {
3063
- this.error(sub('the following arguments are required: %s',
3064
- required_actions.join(', ')))
3065
- }
3066
-
3067
- // make sure all required groups had one option present
3068
- for (let group of this._mutually_exclusive_groups) {
3069
- if (group.required) {
3070
- let no_actions_used = true
3071
- for (let action of group._group_actions) {
3072
- if (seen_non_default_actions.has(action)) {
3073
- no_actions_used = false
3074
- break
3075
- }
3076
- }
3077
-
3078
- // if no actions were used, report the error
3079
- if (no_actions_used) {
3080
- let names = group._group_actions
3081
- .filter(action => action.help !== SUPPRESS)
3082
- .map(action => _get_action_name(action))
3083
- let msg = 'one of the arguments %s is required'
3084
- this.error(sub(msg, names.join(' ')))
3085
- }
3086
- }
3087
- }
3088
-
3089
- // return the updated namespace and the extra arguments
3090
- return [ namespace, extras ]
3091
- }
3092
-
3093
- _read_args_from_files(arg_strings) {
3094
- // expand arguments referencing files
3095
- let new_arg_strings = []
3096
- for (let arg_string of arg_strings) {
3097
-
3098
- // for regular arguments, just add them back into the list
3099
- if (!arg_string || !this.fromfile_prefix_chars.includes(arg_string[0])) {
3100
- new_arg_strings.push(arg_string)
3101
-
3102
- // replace arguments referencing files with the file content
3103
- } else {
3104
- try {
3105
- let args_file = fs.readFileSync(arg_string.slice(1), 'utf8')
3106
- let arg_strings = []
3107
- for (let arg_line of splitlines(args_file)) {
3108
- for (let arg of this.convert_arg_line_to_args(arg_line)) {
3109
- arg_strings.push(arg)
3110
- }
3111
- }
3112
- arg_strings = this._read_args_from_files(arg_strings)
3113
- new_arg_strings = new_arg_strings.concat(arg_strings)
3114
- } catch (err) {
3115
- this.error(err.message)
3116
- }
3117
- }
3118
- }
3119
-
3120
- // return the modified argument list
3121
- return new_arg_strings
3122
- }
3123
-
3124
- convert_arg_line_to_args(arg_line) {
3125
- return [arg_line]
3126
- }
3127
-
3128
- _match_argument(action, arg_strings_pattern) {
3129
- // match the pattern for this action to the arg strings
3130
- let nargs_pattern = this._get_nargs_pattern(action)
3131
- let match = arg_strings_pattern.match(new RegExp('^' + nargs_pattern))
3132
-
3133
- // raise an exception if we weren't able to find a match
3134
- if (match === null) {
3135
- let nargs_errors = {
3136
- undefined: 'expected one argument',
3137
- [OPTIONAL]: 'expected at most one argument',
3138
- [ONE_OR_MORE]: 'expected at least one argument'
3139
- }
3140
- let msg = nargs_errors[action.nargs]
3141
- if (msg === undefined) {
3142
- msg = sub(action.nargs === 1 ? 'expected %s argument' : 'expected %s arguments', action.nargs)
3143
- }
3144
- throw new ArgumentError(action, msg)
3145
- }
3146
-
3147
- // return the number of arguments matched
3148
- return match[1].length
3149
- }
3150
-
3151
- _match_arguments_partial(actions, arg_strings_pattern) {
3152
- // progressively shorten the actions list by slicing off the
3153
- // final actions until we find a match
3154
- let result = []
3155
- for (let i of range(actions.length, 0, -1)) {
3156
- let actions_slice = actions.slice(0, i)
3157
- let pattern = actions_slice.map(action => this._get_nargs_pattern(action)).join('')
3158
- let match = arg_strings_pattern.match(new RegExp('^' + pattern))
3159
- if (match !== null) {
3160
- result = result.concat(match.slice(1).map(string => string.length))
3161
- break
3162
- }
3163
- }
3164
-
3165
- // return the list of arg string counts
3166
- return result
3167
- }
3168
-
3169
- _parse_optional(arg_string) {
3170
- // if it's an empty string, it was meant to be a positional
3171
- if (!arg_string) {
3172
- return undefined
3173
- }
3174
-
3175
- // if it doesn't start with a prefix, it was meant to be positional
3176
- if (!this.prefix_chars.includes(arg_string[0])) {
3177
- return undefined
3178
- }
3179
-
3180
- // if the option string is present in the parser, return the action
3181
- if (arg_string in this._option_string_actions) {
3182
- let action = this._option_string_actions[arg_string]
3183
- return [ action, arg_string, undefined ]
3184
- }
3185
-
3186
- // if it's just a single character, it was meant to be positional
3187
- if (arg_string.length === 1) {
3188
- return undefined
3189
- }
3190
-
3191
- // if the option string before the "=" is present, return the action
3192
- if (arg_string.includes('=')) {
3193
- let [ option_string, explicit_arg ] = _string_split(arg_string, '=', 1)
3194
- if (option_string in this._option_string_actions) {
3195
- let action = this._option_string_actions[option_string]
3196
- return [ action, option_string, explicit_arg ]
3197
- }
3198
- }
3199
-
3200
- // search through all possible prefixes of the option string
3201
- // and all actions in the parser for possible interpretations
3202
- let option_tuples = this._get_option_tuples(arg_string)
3203
-
3204
- // if multiple actions match, the option string was ambiguous
3205
- if (option_tuples.length > 1) {
3206
- let options = option_tuples.map(([ /*action*/, option_string/*, explicit_arg*/ ]) => option_string).join(', ')
3207
- let args = {option: arg_string, matches: options}
3208
- let msg = 'ambiguous option: %(option)s could match %(matches)s'
3209
- this.error(sub(msg, args))
3210
-
3211
- // if exactly one action matched, this segmentation is good,
3212
- // so return the parsed action
3213
- } else if (option_tuples.length === 1) {
3214
- let [ option_tuple ] = option_tuples
3215
- return option_tuple
3216
- }
3217
-
3218
- // if it was not found as an option, but it looks like a negative
3219
- // number, it was meant to be positional
3220
- // unless there are negative-number-like options
3221
- if (this._negative_number_matcher.test(arg_string)) {
3222
- if (!this._has_negative_number_optionals.length) {
3223
- return undefined
3224
- }
3225
- }
3226
-
3227
- // if it contains a space, it was meant to be a positional
3228
- if (arg_string.includes(' ')) {
3229
- return undefined
3230
- }
3231
-
3232
- // it was meant to be an optional but there is no such option
3233
- // in this parser (though it might be a valid option in a subparser)
3234
- return [ undefined, arg_string, undefined ]
3235
- }
3236
-
3237
- _get_option_tuples(option_string) {
3238
- let result = []
3239
-
3240
- // option strings starting with two prefix characters are only
3241
- // split at the '='
3242
- let chars = this.prefix_chars
3243
- if (chars.includes(option_string[0]) && chars.includes(option_string[1])) {
3244
- if (this.allow_abbrev) {
3245
- let option_prefix, explicit_arg
3246
- if (option_string.includes('=')) {
3247
- [ option_prefix, explicit_arg ] = _string_split(option_string, '=', 1)
3248
- } else {
3249
- option_prefix = option_string
3250
- explicit_arg = undefined
3251
- }
3252
- for (let option_string of Object.keys(this._option_string_actions)) {
3253
- if (option_string.startsWith(option_prefix)) {
3254
- let action = this._option_string_actions[option_string]
3255
- let tup = [ action, option_string, explicit_arg ]
3256
- result.push(tup)
3257
- }
3258
- }
3259
- }
3260
-
3261
- // single character options can be concatenated with their arguments
3262
- // but multiple character options always have to have their argument
3263
- // separate
3264
- } else if (chars.includes(option_string[0]) && !chars.includes(option_string[1])) {
3265
- let option_prefix = option_string
3266
- let explicit_arg = undefined
3267
- let short_option_prefix = option_string.slice(0, 2)
3268
- let short_explicit_arg = option_string.slice(2)
3269
-
3270
- for (let option_string of Object.keys(this._option_string_actions)) {
3271
- if (option_string === short_option_prefix) {
3272
- let action = this._option_string_actions[option_string]
3273
- let tup = [ action, option_string, short_explicit_arg ]
3274
- result.push(tup)
3275
- } else if (option_string.startsWith(option_prefix)) {
3276
- let action = this._option_string_actions[option_string]
3277
- let tup = [ action, option_string, explicit_arg ]
3278
- result.push(tup)
3279
- }
3280
- }
3281
-
3282
- // shouldn't ever get here
3283
- } else {
3284
- this.error(sub('unexpected option string: %s', option_string))
3285
- }
3286
-
3287
- // return the collected option tuples
3288
- return result
3289
- }
3290
-
3291
- _get_nargs_pattern(action) {
3292
- // in all examples below, we have to allow for '--' args
3293
- // which are represented as '-' in the pattern
3294
- let nargs = action.nargs
3295
- let nargs_pattern
3296
-
3297
- // the default (None) is assumed to be a single argument
3298
- if (nargs === undefined) {
3299
- nargs_pattern = '(-*A-*)'
3300
-
3301
- // allow zero or one arguments
3302
- } else if (nargs === OPTIONAL) {
3303
- nargs_pattern = '(-*A?-*)'
3304
-
3305
- // allow zero or more arguments
3306
- } else if (nargs === ZERO_OR_MORE) {
3307
- nargs_pattern = '(-*[A-]*)'
3308
-
3309
- // allow one or more arguments
3310
- } else if (nargs === ONE_OR_MORE) {
3311
- nargs_pattern = '(-*A[A-]*)'
3312
-
3313
- // allow any number of options or arguments
3314
- } else if (nargs === REMAINDER) {
3315
- nargs_pattern = '([-AO]*)'
3316
-
3317
- // allow one argument followed by any number of options or arguments
3318
- } else if (nargs === PARSER) {
3319
- nargs_pattern = '(-*A[-AO]*)'
3320
-
3321
- // suppress action, like nargs=0
3322
- } else if (nargs === SUPPRESS) {
3323
- nargs_pattern = '(-*-*)'
3324
-
3325
- // all others should be integers
3326
- } else {
3327
- nargs_pattern = sub('(-*%s-*)', 'A'.repeat(nargs).split('').join('-*'))
3328
- }
3329
-
3330
- // if this is an optional action, -- is not allowed
3331
- if (action.option_strings.length) {
3332
- nargs_pattern = nargs_pattern.replace(/-\*/g, '')
3333
- nargs_pattern = nargs_pattern.replace(/-/g, '')
3334
- }
3335
-
3336
- // return the pattern
3337
- return nargs_pattern
3338
- }
3339
-
3340
- // ========================
3341
- // Alt command line argument parsing, allowing free intermix
3342
- // ========================
3343
-
3344
- parse_intermixed_args(args = undefined, namespace = undefined) {
3345
- let argv
3346
- [ args, argv ] = this.parse_known_intermixed_args(args, namespace)
3347
- if (argv.length) {
3348
- let msg = 'unrecognized arguments: %s'
3349
- this.error(sub(msg, argv.join(' ')))
3350
- }
3351
- return args
3352
- }
3353
-
3354
- parse_known_intermixed_args(args = undefined, namespace = undefined) {
3355
- // returns a namespace and list of extras
3356
- //
3357
- // positional can be freely intermixed with optionals. optionals are
3358
- // first parsed with all positional arguments deactivated. The 'extras'
3359
- // are then parsed. If the parser definition is incompatible with the
3360
- // intermixed assumptions (e.g. use of REMAINDER, subparsers) a
3361
- // TypeError is raised.
3362
- //
3363
- // positionals are 'deactivated' by setting nargs and default to
3364
- // SUPPRESS. This blocks the addition of that positional to the
3365
- // namespace
3366
-
3367
- let extras
3368
- let positionals = this._get_positional_actions()
3369
- let a = positionals.filter(action => [ PARSER, REMAINDER ].includes(action.nargs))
3370
- if (a.length) {
3371
- throw new TypeError(sub('parse_intermixed_args: positional arg' +
3372
- ' with nargs=%s', a[0].nargs))
3373
- }
3374
-
3375
- for (let group of this._mutually_exclusive_groups) {
3376
- for (let action of group._group_actions) {
3377
- if (positionals.includes(action)) {
3378
- throw new TypeError('parse_intermixed_args: positional in' +
3379
- ' mutuallyExclusiveGroup')
3380
- }
3381
- }
3382
- }
3383
-
3384
- let save_usage
3385
- try {
3386
- save_usage = this.usage
3387
- let remaining_args
3388
- try {
3389
- if (this.usage === undefined) {
3390
- // capture the full usage for use in error messages
3391
- this.usage = this.format_usage().slice(7)
3392
- }
3393
- for (let action of positionals) {
3394
- // deactivate positionals
3395
- action.save_nargs = action.nargs
3396
- // action.nargs = 0
3397
- action.nargs = SUPPRESS
3398
- action.save_default = action.default
3399
- action.default = SUPPRESS
3400
- }
3401
- [ namespace, remaining_args ] = this.parse_known_args(args,
3402
- namespace)
3403
- for (let action of positionals) {
3404
- // remove the empty positional values from namespace
3405
- let attr = getattr(namespace, action.dest)
3406
- if (Array.isArray(attr) && attr.length === 0) {
3407
- // eslint-disable-next-line no-console
3408
- console.warn(sub('Do not expect %s in %s', action.dest, namespace))
3409
- delattr(namespace, action.dest)
3410
- }
3411
- }
3412
- } finally {
3413
- // restore nargs and usage before exiting
3414
- for (let action of positionals) {
3415
- action.nargs = action.save_nargs
3416
- action.default = action.save_default
3417
- }
3418
- }
3419
- let optionals = this._get_optional_actions()
3420
- try {
3421
- // parse positionals. optionals aren't normally required, but
3422
- // they could be, so make sure they aren't.
3423
- for (let action of optionals) {
3424
- action.save_required = action.required
3425
- action.required = false
3426
- }
3427
- for (let group of this._mutually_exclusive_groups) {
3428
- group.save_required = group.required
3429
- group.required = false
3430
- }
3431
- [ namespace, extras ] = this.parse_known_args(remaining_args,
3432
- namespace)
3433
- } finally {
3434
- // restore parser values before exiting
3435
- for (let action of optionals) {
3436
- action.required = action.save_required
3437
- }
3438
- for (let group of this._mutually_exclusive_groups) {
3439
- group.required = group.save_required
3440
- }
3441
- }
3442
- } finally {
3443
- this.usage = save_usage
3444
- }
3445
- return [ namespace, extras ]
3446
- }
3447
-
3448
- // ========================
3449
- // Value conversion methods
3450
- // ========================
3451
- _get_values(action, arg_strings) {
3452
- // for everything but PARSER, REMAINDER args, strip out first '--'
3453
- if (![PARSER, REMAINDER].includes(action.nargs)) {
3454
- try {
3455
- _array_remove(arg_strings, '--')
3456
- } catch (err) {}
3457
- }
3458
-
3459
- let value
3460
- // optional argument produces a default when not present
3461
- if (!arg_strings.length && action.nargs === OPTIONAL) {
3462
- if (action.option_strings.length) {
3463
- value = action.const
3464
- } else {
3465
- value = action.default
3466
- }
3467
- if (typeof value === 'string') {
3468
- value = this._get_value(action, value)
3469
- this._check_value(action, value)
3470
- }
3471
-
3472
- // when nargs='*' on a positional, if there were no command-line
3473
- // args, use the default if it is anything other than None
3474
- } else if (!arg_strings.length && action.nargs === ZERO_OR_MORE &&
3475
- !action.option_strings.length) {
3476
- if (action.default !== undefined) {
3477
- value = action.default
3478
- } else {
3479
- value = arg_strings
3480
- }
3481
- this._check_value(action, value)
3482
-
3483
- // single argument or optional argument produces a single value
3484
- } else if (arg_strings.length === 1 && [undefined, OPTIONAL].includes(action.nargs)) {
3485
- let arg_string = arg_strings[0]
3486
- value = this._get_value(action, arg_string)
3487
- this._check_value(action, value)
3488
-
3489
- // REMAINDER arguments convert all values, checking none
3490
- } else if (action.nargs === REMAINDER) {
3491
- value = arg_strings.map(v => this._get_value(action, v))
3492
-
3493
- // PARSER arguments convert all values, but check only the first
3494
- } else if (action.nargs === PARSER) {
3495
- value = arg_strings.map(v => this._get_value(action, v))
3496
- this._check_value(action, value[0])
3497
-
3498
- // SUPPRESS argument does not put anything in the namespace
3499
- } else if (action.nargs === SUPPRESS) {
3500
- value = SUPPRESS
3501
-
3502
- // all other types of nargs produce a list
3503
- } else {
3504
- value = arg_strings.map(v => this._get_value(action, v))
3505
- for (let v of value) {
3506
- this._check_value(action, v)
3507
- }
3508
- }
3509
-
3510
- // return the converted value
3511
- return value
3512
- }
3513
-
3514
- _get_value(action, arg_string) {
3515
- let type_func = this._registry_get('type', action.type, action.type)
3516
- if (typeof type_func !== 'function') {
3517
- let msg = '%r is not callable'
3518
- throw new ArgumentError(action, sub(msg, type_func))
3519
- }
3520
-
3521
- // convert the value to the appropriate type
3522
- let result
3523
- try {
3524
- try {
3525
- result = type_func(arg_string)
3526
- } catch (err) {
3527
- // Dear TC39, why would you ever consider making es6 classes not callable?
3528
- // We had one universal interface, [[Call]], which worked for anything
3529
- // (with familiar this-instanceof guard for classes). Now we have two.
3530
- if (err instanceof TypeError &&
3531
- /Class constructor .* cannot be invoked without 'new'/.test(err.message)) {
3532
- // eslint-disable-next-line new-cap
3533
- result = new type_func(arg_string)
3534
- } else {
3535
- throw err
3536
- }
3537
- }
3538
-
3539
- } catch (err) {
3540
- // ArgumentTypeErrors indicate errors
3541
- if (err instanceof ArgumentTypeError) {
3542
- //let name = getattr(action.type, 'name', repr(action.type))
3543
- let msg = err.message
3544
- throw new ArgumentError(action, msg)
3545
-
3546
- // TypeErrors or ValueErrors also indicate errors
3547
- } else if (err instanceof TypeError) {
3548
- let name = getattr(action.type, 'name', repr(action.type))
3549
- let args = {type: name, value: arg_string}
3550
- let msg = 'invalid %(type)s value: %(value)r'
3551
- throw new ArgumentError(action, sub(msg, args))
3552
- } else {
3553
- throw err
3554
- }
3555
- }
3556
-
3557
- // return the converted value
3558
- return result
3559
- }
3560
-
3561
- _check_value(action, value) {
3562
- // converted value must be one of the choices (if specified)
3563
- if (action.choices !== undefined && !_choices_to_array(action.choices).includes(value)) {
3564
- let args = {value,
3565
- choices: _choices_to_array(action.choices).map(repr).join(', ')}
3566
- let msg = 'invalid choice: %(value)r (choose from %(choices)s)'
3567
- throw new ArgumentError(action, sub(msg, args))
3568
- }
3569
- }
3570
-
3571
- // =======================
3572
- // Help-formatting methods
3573
- // =======================
3574
- format_usage() {
3575
- let formatter = this._get_formatter()
3576
- formatter.add_usage(this.usage, this._actions,
3577
- this._mutually_exclusive_groups)
3578
- return formatter.format_help()
3579
- }
3580
-
3581
- format_help() {
3582
- let formatter = this._get_formatter()
3583
-
3584
- // usage
3585
- formatter.add_usage(this.usage, this._actions,
3586
- this._mutually_exclusive_groups)
3587
-
3588
- // description
3589
- formatter.add_text(this.description)
3590
-
3591
- // positionals, optionals and user-defined groups
3592
- for (let action_group of this._action_groups) {
3593
- formatter.start_section(action_group.title)
3594
- formatter.add_text(action_group.description)
3595
- formatter.add_arguments(action_group._group_actions)
3596
- formatter.end_section()
3597
- }
3598
-
3599
- // epilog
3600
- formatter.add_text(this.epilog)
3601
-
3602
- // determine help from format above
3603
- return formatter.format_help()
3604
- }
3605
-
3606
- _get_formatter() {
3607
- // eslint-disable-next-line new-cap
3608
- return new this.formatter_class({ prog: this.prog })
3609
- }
3610
-
3611
- // =====================
3612
- // Help-printing methods
3613
- // =====================
3614
- print_usage(file = undefined) {
3615
- if (file === undefined) file = process.stdout
3616
- this._print_message(this.format_usage(), file)
3617
- }
3618
-
3619
- print_help(file = undefined) {
3620
- if (file === undefined) file = process.stdout
3621
- this._print_message(this.format_help(), file)
3622
- }
3623
-
3624
- _print_message(message, file = undefined) {
3625
- if (message) {
3626
- if (file === undefined) file = process.stderr
3627
- file.write(message)
3628
- }
3629
- }
3630
-
3631
- // ===============
3632
- // Exiting methods
3633
- // ===============
3634
- exit(status = 0, message = undefined) {
3635
- if (message) {
3636
- this._print_message(message, process.stderr)
3637
- }
3638
- process.exit(status)
3639
- }
3640
-
3641
- error(message) {
3642
- /*
3643
- * error(message: string)
3644
- *
3645
- * Prints a usage message incorporating the message to stderr and
3646
- * exits.
3647
- *
3648
- * If you override this in a subclass, it should not return -- it
3649
- * should either exit or raise an exception.
3650
- */
3651
-
3652
- // LEGACY (v1 compatibility), debug mode
3653
- if (this.debug === true) throw new Error(message)
3654
- // end
3655
- this.print_usage(process.stderr)
3656
- let args = {prog: this.prog, message: message}
3657
- this.exit(2, sub('%(prog)s: error: %(message)s\n', args))
3658
- }
3659
- }))
3660
-
3661
-
3662
- module.exports = {
3663
- ArgumentParser,
3664
- ArgumentError,
3665
- ArgumentTypeError,
3666
- BooleanOptionalAction,
3667
- FileType,
3668
- HelpFormatter,
3669
- ArgumentDefaultsHelpFormatter,
3670
- RawDescriptionHelpFormatter,
3671
- RawTextHelpFormatter,
3672
- MetavarTypeHelpFormatter,
3673
- Namespace,
3674
- Action,
3675
- ONE_OR_MORE,
3676
- OPTIONAL,
3677
- PARSER,
3678
- REMAINDER,
3679
- SUPPRESS,
3680
- ZERO_OR_MORE
3681
- }
3682
-
3683
- // LEGACY (v1 compatibility), Const alias
3684
- Object.defineProperty(module.exports, 'Const', {
3685
- get() {
3686
- let result = {}
3687
- Object.entries({ ONE_OR_MORE, OPTIONAL, PARSER, REMAINDER, SUPPRESS, ZERO_OR_MORE }).forEach(([ n, v ]) => {
3688
- Object.defineProperty(result, n, {
3689
- get() {
3690
- deprecate(n, sub('use argparse.%s instead of argparse.Const.%s', n, n))
3691
- return v
3692
- }
3693
- })
3694
- })
3695
- Object.entries({ _UNRECOGNIZED_ARGS_ATTR }).forEach(([ n, v ]) => {
3696
- Object.defineProperty(result, n, {
3697
- get() {
3698
- deprecate(n, sub('argparse.Const.%s is an internal symbol and will no longer be available', n))
3699
- return v
3700
- }
3701
- })
3702
- })
3703
- return result
3704
- },
3705
- enumerable: false
3706
- })
3707
- // end