@openclaw/matrix 2026.7.2-beta.7 → 2026.7.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (368) hide show
  1. package/README.md +1 -1
  2. package/dist/{account-selection-kqquRzCf.js → .setup/account-selection-BOQeTqax.mjs} +18 -17
  3. package/dist/{approval-handler.runtime-DSeaIsGa.js → .setup/approval-handler.runtime-CEXm9_-p.mjs} +18 -28
  4. package/dist/{approval-ids-BdJGPAJT.js → .setup/approval-ids-DdFnDB3h.mjs} +1 -1
  5. package/dist/{approval-reaction-auth-BjOpELxu.js → .setup/approval-reaction-auth-CREvd7S7.mjs} +2 -2
  6. package/dist/.setup/approval-reactions-Cltyp8nL.mjs +113 -0
  7. package/dist/.setup/async-lock-BcLS4KOc.mjs +19 -0
  8. package/dist/{channel-vj788dNZ.js → .setup/channel-an4umty1.mjs} +186 -144
  9. package/dist/{channel.runtime-CLoF2S9T.js → .setup/channel.runtime-GHcIBJ7H.mjs} +51 -45
  10. package/dist/{cli-DMqfDE-q.js → .setup/cli-B3WYmv5U.mjs} +882 -901
  11. package/dist/{cli-metadata-C7D53SND.js → .setup/cli-metadata-RUKCn0wJ.mjs} +1 -1
  12. package/dist/{client-6eRENr7k.js → .setup/client-Ct0bUHCo.mjs} +5 -5
  13. package/dist/{shared-CUMWxcMz.js → .setup/client-DFBQtzCe.mjs} +422 -179
  14. package/dist/.setup/client-bootstrap-Be8jvNle.mjs +74 -0
  15. package/dist/{config-schema-Djxw3C6b.js → .setup/config-schema-D9J_vUF6.mjs} +89 -70
  16. package/dist/.setup/credentials-BhZlA0kL.mjs +56 -0
  17. package/dist/.setup/credentials-read-CRHg6XPm.mjs +114 -0
  18. package/dist/{credentials-write.runtime-Be9zNSUw.js → .setup/credentials-write.runtime-dWuLafsk.mjs} +1 -1
  19. package/dist/{crypto-runtime-D9_6J5tZ.js → .setup/crypto-runtime-D-cZa8P0.mjs} +81 -35
  20. package/dist/.setup/crypto-state-store-B43k3z3W.mjs +352 -0
  21. package/dist/{deps-CcVJfvRM.js → .setup/deps-Dy6yreL4.mjs} +92 -25
  22. package/dist/{device-health-B4-YXtJR.js → .setup/device-health-D4LBxuPq.mjs} +1 -6
  23. package/dist/{directory-live-C8dVBiCc.js → .setup/directory-live-BTEYxMwy.mjs} +10 -9
  24. package/dist/.setup/doctor-BGnvMzOR.mjs +169 -0
  25. package/dist/.setup/doctor-contract-DNJw0fdq.mjs +246 -0
  26. package/dist/{draft-stream-CtvOXq0Z.js → .setup/draft-stream-C-_OhpE8.mjs} +1 -6
  27. package/dist/{encryption-guidance-CbEFe38F.js → .setup/encryption-guidance-CpuuwmjL.mjs} +4 -3
  28. package/dist/{env-auth-CQsYbz-p.js → .setup/env-auth-CYJL1jNl.mjs} +2 -2
  29. package/dist/{env-vars-B0NxQnPk.js → .setup/env-vars-KzaYveuy.mjs} +1 -3
  30. package/dist/{exec-approval-resolver-BCgqRtZS.js → .setup/exec-approval-resolver-f9j6staN.mjs} +1 -2
  31. package/dist/{file-sync-store-DiiFsayX.js → .setup/file-sync-store-DU0cnYAz.mjs} +30 -25
  32. package/dist/{http-client-CycYxU9-.js → .setup/http-client-C954In2D.mjs} +45 -25
  33. package/dist/{idb-persistence-B6x7dMsF.js → .setup/idb-persistence-_HKTXkVC.mjs} +76 -78
  34. package/dist/{idb-persistence-lock-DAJ49nZX.js → .setup/idb-persistence-lock-B3fZXyF_.mjs} +1 -1
  35. package/dist/.setup/legacy-crypto-inspector-Byp8LCys.mjs +42 -0
  36. package/dist/.setup/legacy-crypto-restore-YQVoK1B2.mjs +93 -0
  37. package/dist/{logger-D0GCSDQq.js → .setup/logger-DpoogOgz.mjs} +1 -1
  38. package/dist/{logging-DV-p52N0.js → .setup/logging-CgxQOJJP.mjs} +2 -9
  39. package/dist/.setup/matrix-migration.runtime-BDH5c3fN.mjs +530 -0
  40. package/dist/{media-text-BTwzADS_.js → .setup/media-text-Cib-dxkn.mjs} +1 -1
  41. package/dist/{messages-DxQJkhxs.js → .setup/messages-D4DYGHYX.mjs} +15 -67
  42. package/dist/.setup/migration-snapshot-backup-CpgYhiUp.mjs +70 -0
  43. package/dist/.setup/migration-snapshot.runtime-O8qkMVaC.mjs +2 -0
  44. package/dist/{monitor-VyWlSLwo.js → .setup/monitor-DNcW_oAN.mjs} +2525 -2361
  45. package/dist/.setup/probe.runtime-CMPh0mFk.mjs +2 -0
  46. package/dist/{profile-update-CffmyW_4.js → .setup/profile-update-DzOL3Wiw.mjs} +5 -4
  47. package/dist/{reaction-events-B00WSi98.js → .setup/reaction-events-BcvgXxHb.mjs} +14 -64
  48. package/dist/{resolve-targets-nm2L48sh.js → .setup/resolve-targets-Bq80X9Sn.mjs} +3 -3
  49. package/dist/{resolver.runtime-DS6uPaEe.js → .setup/resolver.runtime-CeBHR9-T.mjs} +1 -1
  50. package/dist/{runtime-api-D1xI_cvh.js → .setup/runtime-api-CEsWNdil.mjs} +4 -4
  51. package/dist/.setup/runtime-setter-api-DGMubGUq.mjs +3 -0
  52. package/dist/{sdk-bUytQHx7.js → .setup/sdk-He1quVAq.mjs} +592 -261
  53. package/dist/.setup/secret-contract-api-CiTJ7pd5.mjs +3 -0
  54. package/dist/{secret-contract-M3hRmGO-.js → .setup/secret-contract-phPvlNfV.mjs} +53 -28
  55. package/dist/{send-BldGYG8g.js → .setup/send-CGgl0uTn.mjs} +133 -660
  56. package/dist/{setup-bootstrap-Deleiibz.js → .setup/setup-bootstrap-DUXBC8X2.mjs} +4 -4
  57. package/dist/{setup-core-BVfBv2ai.js → .setup/setup-core-bhdcEo7v.mjs} +239 -189
  58. package/dist/.setup/setup-plugin-api-CAwZ_Bi7.mjs +43 -0
  59. package/dist/.setup/setup-plugin-api-DIFVsOs3.mjs +2 -0
  60. package/dist/{setup-surface-BBq3WeqX.js → .setup/setup-surface-05_G-MnT.mjs} +149 -92
  61. package/dist/{startup-verification-wm3_i88s.js → .setup/startup-verification-BTwIGu1J.mjs} +7 -6
  62. package/dist/.setup/storage-NGZq5zet.mjs +432 -0
  63. package/dist/{storage-paths-gUmSydsW.js → .setup/storage-paths-BWo_ZEMC.mjs} +13 -2
  64. package/dist/{subagent-hooks-dkPAF6Et.js → .setup/subagent-hooks-BSWPJEmo.mjs} +2 -2
  65. package/dist/{thread-binding-api-DRbBZlhS.js → .setup/thread-binding-api-B7UaOoKv.mjs} +1 -1
  66. package/dist/{thread-bindings-DGbl3vDW.js → .setup/thread-bindings-DqmjG2on.mjs} +8 -8
  67. package/dist/{tool-actions.runtime-uu9blSqO.js → .setup/tool-actions.runtime-CXDLk2jg.mjs} +196 -332
  68. package/dist/{verification-DYMQ1QpI.js → .setup/verification-DeWOtZJr.mjs} +4 -3
  69. package/dist/api.js +9 -9
  70. package/dist/auth-presence.js +21 -13
  71. package/dist/channel-plugin-api.js +1 -1
  72. package/dist/cli-metadata.js +1 -1
  73. package/dist/contract-api.js +2 -2
  74. package/dist/doctor-contract-api.js +99 -524
  75. package/dist/helper-api.js +4 -4
  76. package/dist/index.js +1 -1
  77. package/dist/plugin-entry.handlers.runtime.js +2 -2
  78. package/dist/runtime-api.js +8 -8
  79. package/dist/runtime-heavy-api.js +3 -0
  80. package/dist/runtime-setter-api.js +1 -1
  81. package/dist/secret-contract-api.js +1 -1
  82. package/dist/session-binding-contract-api.js +3 -3
  83. package/dist/setup-entry.js +4 -3
  84. package/dist/setup-plugin-api.js +1 -44
  85. package/dist/subagent-hooks-api.js +1 -1
  86. package/dist/thread-binding-api.js +1 -1
  87. package/dist/thread-bindings-runtime.js +1 -1
  88. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/package.json +1 -1
  89. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm.d.ts +2 -14
  90. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.cjs +384 -409
  91. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.js +224 -246
  92. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm +0 -0
  93. package/node_modules/@matrix-org/matrix-sdk-crypto-wasm/pkg/matrix_sdk_crypto_wasm_bg.wasm.d.ts +58 -59
  94. package/node_modules/markdown-it/README.md +18 -294
  95. package/node_modules/markdown-it/bin/markdown-it.mjs +2 -2
  96. package/node_modules/markdown-it/dist/browser/markdown-it.esm.min.mjs +3013 -0
  97. package/node_modules/markdown-it/dist/browser/markdown-it.esm.min.mjs.map +1 -0
  98. package/node_modules/markdown-it/dist/browser/markdown-it.umd.min.js +14 -0
  99. package/node_modules/markdown-it/dist/browser/markdown-it.umd.min.js.map +1 -0
  100. package/node_modules/markdown-it/dist/markdown-it.cjs.js +4420 -0
  101. package/node_modules/markdown-it/dist/markdown-it.cjs.js.map +1 -0
  102. package/node_modules/markdown-it/dist/markdown-it.d.cts +19 -0
  103. package/node_modules/markdown-it/dist/markdown-it.d.mts +950 -0
  104. package/node_modules/markdown-it/dist/{index.cjs.js → markdown-it.mjs} +1504 -1525
  105. package/node_modules/markdown-it/dist/markdown-it.mjs.map +1 -0
  106. package/node_modules/markdown-it/node_modules/argparse/LICENSE +1 -208
  107. package/node_modules/markdown-it/node_modules/argparse/README.md +46 -41
  108. package/node_modules/markdown-it/node_modules/argparse/lib/_colorize.js +72 -0
  109. package/node_modules/markdown-it/node_modules/argparse/lib/argparse.d.ts +292 -0
  110. package/node_modules/markdown-it/node_modules/argparse/{argparse.js → lib/argparse.js} +1142 -1029
  111. package/node_modules/markdown-it/node_modules/argparse/lib/difflib.js +190 -0
  112. package/node_modules/markdown-it/node_modules/argparse/lib/sub.js +4 -4
  113. package/node_modules/markdown-it/node_modules/argparse/lib/textwrap.js +28 -28
  114. package/node_modules/markdown-it/node_modules/argparse/package.json +18 -11
  115. package/node_modules/markdown-it/node_modules/entities/dist/decode-codepoint.d.ts +8 -0
  116. package/node_modules/markdown-it/node_modules/entities/dist/decode-codepoint.d.ts.map +1 -0
  117. package/node_modules/markdown-it/node_modules/entities/dist/decode-codepoint.js +46 -0
  118. package/node_modules/markdown-it/node_modules/entities/dist/decode-codepoint.js.map +1 -0
  119. package/node_modules/markdown-it/node_modules/entities/{lib → dist}/decode.d.ts +28 -45
  120. package/node_modules/markdown-it/node_modules/entities/dist/decode.d.ts.map +1 -0
  121. package/node_modules/markdown-it/node_modules/entities/{lib/esm → dist}/decode.js +189 -141
  122. package/node_modules/markdown-it/node_modules/entities/dist/decode.js.map +1 -0
  123. package/node_modules/markdown-it/node_modules/entities/{lib/esm → dist}/encode.d.ts +4 -2
  124. package/node_modules/markdown-it/node_modules/entities/dist/encode.d.ts.map +1 -0
  125. package/node_modules/markdown-it/node_modules/entities/dist/encode.js +90 -0
  126. package/node_modules/markdown-it/node_modules/entities/dist/encode.js.map +1 -0
  127. package/node_modules/markdown-it/node_modules/entities/{lib → dist}/escape.d.ts +15 -10
  128. package/node_modules/markdown-it/node_modules/entities/dist/escape.d.ts.map +1 -0
  129. package/node_modules/markdown-it/node_modules/entities/dist/escape.js +132 -0
  130. package/node_modules/markdown-it/node_modules/entities/dist/escape.js.map +1 -0
  131. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-html.d.ts +3 -0
  132. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-html.d.ts.map +1 -0
  133. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-html.js +5 -0
  134. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-html.js.map +1 -0
  135. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-xml.d.ts +3 -0
  136. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-xml.d.ts.map +1 -0
  137. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-xml.js +5 -0
  138. package/node_modules/markdown-it/node_modules/entities/dist/generated/decode-data-xml.js.map +1 -0
  139. package/node_modules/markdown-it/node_modules/entities/dist/generated/encode-html.d.ts +5 -0
  140. package/node_modules/markdown-it/node_modules/entities/dist/generated/encode-html.d.ts.map +1 -0
  141. package/node_modules/markdown-it/node_modules/entities/dist/generated/encode-html.js +12 -0
  142. package/node_modules/markdown-it/node_modules/entities/dist/generated/encode-html.js.map +1 -0
  143. package/node_modules/markdown-it/node_modules/entities/{lib/esm → dist}/index.d.ts +14 -21
  144. package/node_modules/markdown-it/node_modules/entities/dist/index.d.ts.map +1 -0
  145. package/node_modules/markdown-it/node_modules/entities/dist/index.js +91 -0
  146. package/node_modules/markdown-it/node_modules/entities/dist/index.js.map +1 -0
  147. package/node_modules/markdown-it/node_modules/entities/dist/internal/bin-trie-flags.d.ts +17 -0
  148. package/node_modules/markdown-it/node_modules/entities/dist/internal/bin-trie-flags.d.ts.map +1 -0
  149. package/node_modules/markdown-it/node_modules/entities/dist/internal/bin-trie-flags.js +18 -0
  150. package/node_modules/markdown-it/node_modules/entities/dist/internal/bin-trie-flags.js.map +1 -0
  151. package/node_modules/markdown-it/node_modules/entities/dist/internal/decode-shared.d.ts +7 -0
  152. package/node_modules/markdown-it/node_modules/entities/dist/internal/decode-shared.d.ts.map +1 -0
  153. package/node_modules/markdown-it/node_modules/entities/dist/internal/decode-shared.js +17 -0
  154. package/node_modules/markdown-it/node_modules/entities/dist/internal/decode-shared.js.map +1 -0
  155. package/node_modules/markdown-it/node_modules/entities/dist/internal/encode-shared.d.ts +33 -0
  156. package/node_modules/markdown-it/node_modules/entities/dist/internal/encode-shared.d.ts.map +1 -0
  157. package/node_modules/markdown-it/node_modules/entities/dist/internal/encode-shared.js +93 -0
  158. package/node_modules/markdown-it/node_modules/entities/dist/internal/encode-shared.js.map +1 -0
  159. package/node_modules/markdown-it/node_modules/entities/package.json +63 -70
  160. package/node_modules/markdown-it/node_modules/entities/readme.md +54 -45
  161. package/node_modules/markdown-it/node_modules/entities/src/decode-codepoint.ts +50 -0
  162. package/node_modules/markdown-it/node_modules/entities/src/decode.ts +671 -0
  163. package/node_modules/markdown-it/node_modules/entities/src/encode.ts +95 -0
  164. package/node_modules/markdown-it/node_modules/entities/src/escape.ts +160 -0
  165. package/node_modules/markdown-it/node_modules/entities/src/generated/decode-data-html.ts +7 -0
  166. package/node_modules/markdown-it/node_modules/entities/src/generated/decode-data-xml.ts +7 -0
  167. package/node_modules/markdown-it/node_modules/entities/src/generated/encode-html.ts +18 -0
  168. package/node_modules/markdown-it/node_modules/entities/src/index.ts +162 -0
  169. package/node_modules/markdown-it/node_modules/entities/src/internal/bin-trie-flags.ts +16 -0
  170. package/node_modules/markdown-it/node_modules/entities/src/internal/decode-shared.ts +18 -0
  171. package/node_modules/markdown-it/node_modules/entities/src/internal/encode-shared.ts +123 -0
  172. package/node_modules/markdown-it/node_modules/linkify-it/README.md +49 -86
  173. package/node_modules/markdown-it/node_modules/linkify-it/build/index.cjs.js +636 -825
  174. package/node_modules/markdown-it/node_modules/linkify-it/build/index.cjs.js.map +1 -0
  175. package/node_modules/markdown-it/node_modules/linkify-it/build/index.d.ts +236 -0
  176. package/node_modules/markdown-it/node_modules/linkify-it/build/index.mjs +538 -0
  177. package/node_modules/markdown-it/node_modules/linkify-it/build/index.mjs.map +1 -0
  178. package/node_modules/markdown-it/node_modules/linkify-it/package.json +23 -20
  179. package/node_modules/markdown-it/node_modules/uc.micro/README.md +18 -1
  180. package/node_modules/markdown-it/node_modules/uc.micro/build/index.cjs.js +13 -18
  181. package/node_modules/markdown-it/node_modules/uc.micro/build/index.d.ts +6 -0
  182. package/node_modules/markdown-it/node_modules/uc.micro/build/index.mjs +8 -0
  183. package/node_modules/markdown-it/node_modules/uc.micro/package.json +12 -17
  184. package/node_modules/markdown-it/package.json +47 -30
  185. package/node_modules/matrix-js-sdk/CHANGELOG.md +0 -11
  186. package/node_modules/matrix-js-sdk/package.json +1 -1
  187. package/node_modules/music-metadata/lib/common/Util.d.ts +1 -1
  188. package/node_modules/music-metadata/lib/common/Util.js +1 -7
  189. package/node_modules/music-metadata/lib/id3v2/FrameHeader.js +3 -23
  190. package/node_modules/music-metadata/lib/id3v2/FrameParser.js +2 -2
  191. package/node_modules/music-metadata/lib/id3v2/ID3v2Token.js +1 -1
  192. package/node_modules/music-metadata/lib/mp4/AtomToken.js +13 -38
  193. package/node_modules/music-metadata/lib/mpeg/MpegParser.js +1 -1
  194. package/node_modules/music-metadata/package.json +6 -6
  195. package/node_modules/typebox/build/compile/validator.d.mts +4 -1
  196. package/node_modules/typebox/build/guard/guard.d.mts +1 -1
  197. package/node_modules/typebox/build/guard/guard.mjs +2 -5
  198. package/node_modules/typebox/build/guard/string.mjs +4 -16
  199. package/node_modules/typebox/build/schema/engine/_functions.mjs +15 -34
  200. package/node_modules/typebox/build/type/action/readonly_object.d.mts +0 -5
  201. package/node_modules/typebox/build/type/action/readonly_object.mjs +0 -8
  202. package/node_modules/typebox/build/typebox.d.mts +1 -1
  203. package/node_modules/typebox/build/typebox.mjs +1 -1
  204. package/node_modules/typebox/package.json +1 -1
  205. package/node_modules/typebox/readme.md +32 -29
  206. package/openclaw.plugin.json +146 -152
  207. package/package.json +31 -114
  208. package/dist/accounts-DfngqebB.js +0 -130
  209. package/dist/active-client-DXvz2gCo.js +0 -20
  210. package/dist/approval-reactions-D-BxBK_L.js +0 -202
  211. package/dist/client-Dbso3-0V.js +0 -30
  212. package/dist/client-bootstrap-XsIkHNt0.js +0 -110
  213. package/dist/create-client-BmSU-q-D.js +0 -61
  214. package/dist/credentials-W2EmwRhu.js +0 -65
  215. package/dist/credentials-read-DVmFCm7X.js +0 -77
  216. package/dist/doctor-CM8ijNpW.js +0 -64
  217. package/dist/doctor-contract-BMSJkkAE.js +0 -167
  218. package/dist/inbound-dedupe-CaBLblef.js +0 -48
  219. package/dist/probe.runtime-BuieqmS3.js +0 -3
  220. package/dist/record-shared-CWWx6fvI.js +0 -2
  221. package/dist/recovery-key-store-BNnHvXdk.js +0 -275
  222. package/dist/room-info-CAFZ3Z9J.js +0 -87
  223. package/dist/route-DY6at4qJ.js +0 -161
  224. package/dist/storage-BvAkgzvT.js +0 -685
  225. package/node_modules/markdown-it/dist/index.cjs.js.map +0 -1
  226. package/node_modules/markdown-it/dist/markdown-it.js +0 -3975
  227. package/node_modules/markdown-it/dist/markdown-it.js.map +0 -1
  228. package/node_modules/markdown-it/dist/markdown-it.min.js +0 -3
  229. package/node_modules/markdown-it/dist/markdown-it.min.js.map +0 -1
  230. package/node_modules/markdown-it/index.mjs +0 -1
  231. package/node_modules/markdown-it/lib/common/html_blocks.mjs +0 -67
  232. package/node_modules/markdown-it/lib/common/html_re.mjs +0 -25
  233. package/node_modules/markdown-it/lib/common/utils.mjs +0 -324
  234. package/node_modules/markdown-it/lib/helpers/index.mjs +0 -11
  235. package/node_modules/markdown-it/lib/helpers/parse_link_destination.mjs +0 -77
  236. package/node_modules/markdown-it/lib/helpers/parse_link_label.mjs +0 -49
  237. package/node_modules/markdown-it/lib/helpers/parse_link_title.mjs +0 -66
  238. package/node_modules/markdown-it/lib/index.mjs +0 -565
  239. package/node_modules/markdown-it/lib/parser_block.mjs +0 -134
  240. package/node_modules/markdown-it/lib/parser_core.mjs +0 -62
  241. package/node_modules/markdown-it/lib/parser_inline.mjs +0 -197
  242. package/node_modules/markdown-it/lib/presets/commonmark.mjs +0 -88
  243. package/node_modules/markdown-it/lib/presets/default.mjs +0 -47
  244. package/node_modules/markdown-it/lib/presets/zero.mjs +0 -70
  245. package/node_modules/markdown-it/lib/renderer.mjs +0 -322
  246. package/node_modules/markdown-it/lib/ruler.mjs +0 -340
  247. package/node_modules/markdown-it/lib/rules_block/blockquote.mjs +0 -209
  248. package/node_modules/markdown-it/lib/rules_block/code.mjs +0 -30
  249. package/node_modules/markdown-it/lib/rules_block/fence.mjs +0 -94
  250. package/node_modules/markdown-it/lib/rules_block/heading.mjs +0 -51
  251. package/node_modules/markdown-it/lib/rules_block/hr.mjs +0 -40
  252. package/node_modules/markdown-it/lib/rules_block/html_block.mjs +0 -80
  253. package/node_modules/markdown-it/lib/rules_block/lheading.mjs +0 -85
  254. package/node_modules/markdown-it/lib/rules_block/list.mjs +0 -331
  255. package/node_modules/markdown-it/lib/rules_block/paragraph.mjs +0 -48
  256. package/node_modules/markdown-it/lib/rules_block/reference.mjs +0 -212
  257. package/node_modules/markdown-it/lib/rules_block/state_block.mjs +0 -220
  258. package/node_modules/markdown-it/lib/rules_block/table.mjs +0 -228
  259. package/node_modules/markdown-it/lib/rules_core/block.mjs +0 -13
  260. package/node_modules/markdown-it/lib/rules_core/inline.mjs +0 -11
  261. package/node_modules/markdown-it/lib/rules_core/linkify.mjs +0 -134
  262. package/node_modules/markdown-it/lib/rules_core/normalize.mjs +0 -17
  263. package/node_modules/markdown-it/lib/rules_core/replacements.mjs +0 -101
  264. package/node_modules/markdown-it/lib/rules_core/smartquotes.mjs +0 -209
  265. package/node_modules/markdown-it/lib/rules_core/state_core.mjs +0 -17
  266. package/node_modules/markdown-it/lib/rules_core/text_join.mjs +0 -43
  267. package/node_modules/markdown-it/lib/rules_inline/autolink.mjs +0 -72
  268. package/node_modules/markdown-it/lib/rules_inline/backticks.mjs +0 -60
  269. package/node_modules/markdown-it/lib/rules_inline/balance_pairs.mjs +0 -124
  270. package/node_modules/markdown-it/lib/rules_inline/emphasis.mjs +0 -123
  271. package/node_modules/markdown-it/lib/rules_inline/entity.mjs +0 -51
  272. package/node_modules/markdown-it/lib/rules_inline/escape.mjs +0 -83
  273. package/node_modules/markdown-it/lib/rules_inline/fragments_join.mjs +0 -38
  274. package/node_modules/markdown-it/lib/rules_inline/html_inline.mjs +0 -50
  275. package/node_modules/markdown-it/lib/rules_inline/image.mjs +0 -138
  276. package/node_modules/markdown-it/lib/rules_inline/link.mjs +0 -139
  277. package/node_modules/markdown-it/lib/rules_inline/linkify.mjs +0 -63
  278. package/node_modules/markdown-it/lib/rules_inline/newline.mjs +0 -42
  279. package/node_modules/markdown-it/lib/rules_inline/state_inline.mjs +0 -154
  280. package/node_modules/markdown-it/lib/rules_inline/strikethrough.mjs +0 -127
  281. package/node_modules/markdown-it/lib/rules_inline/text.mjs +0 -86
  282. package/node_modules/markdown-it/lib/token.mjs +0 -191
  283. package/node_modules/markdown-it/node_modules/argparse/CHANGELOG.md +0 -216
  284. package/node_modules/markdown-it/node_modules/entities/lib/decode.d.ts.map +0 -1
  285. package/node_modules/markdown-it/node_modules/entities/lib/decode.js +0 -536
  286. package/node_modules/markdown-it/node_modules/entities/lib/decode.js.map +0 -1
  287. package/node_modules/markdown-it/node_modules/entities/lib/decode_codepoint.d.ts +0 -19
  288. package/node_modules/markdown-it/node_modules/entities/lib/decode_codepoint.d.ts.map +0 -1
  289. package/node_modules/markdown-it/node_modules/entities/lib/decode_codepoint.js +0 -76
  290. package/node_modules/markdown-it/node_modules/entities/lib/decode_codepoint.js.map +0 -1
  291. package/node_modules/markdown-it/node_modules/entities/lib/encode.d.ts +0 -22
  292. package/node_modules/markdown-it/node_modules/entities/lib/encode.d.ts.map +0 -1
  293. package/node_modules/markdown-it/node_modules/entities/lib/encode.js +0 -77
  294. package/node_modules/markdown-it/node_modules/entities/lib/encode.js.map +0 -1
  295. package/node_modules/markdown-it/node_modules/entities/lib/escape.d.ts.map +0 -1
  296. package/node_modules/markdown-it/node_modules/entities/lib/escape.js +0 -122
  297. package/node_modules/markdown-it/node_modules/entities/lib/escape.js.map +0 -1
  298. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode.d.ts +0 -211
  299. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode.d.ts.map +0 -1
  300. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode.js.map +0 -1
  301. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode_codepoint.d.ts +0 -19
  302. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode_codepoint.d.ts.map +0 -1
  303. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode_codepoint.js +0 -71
  304. package/node_modules/markdown-it/node_modules/entities/lib/esm/decode_codepoint.js.map +0 -1
  305. package/node_modules/markdown-it/node_modules/entities/lib/esm/encode.d.ts.map +0 -1
  306. package/node_modules/markdown-it/node_modules/entities/lib/esm/encode.js +0 -69
  307. package/node_modules/markdown-it/node_modules/entities/lib/esm/encode.js.map +0 -1
  308. package/node_modules/markdown-it/node_modules/entities/lib/esm/escape.d.ts +0 -43
  309. package/node_modules/markdown-it/node_modules/entities/lib/esm/escape.d.ts.map +0 -1
  310. package/node_modules/markdown-it/node_modules/entities/lib/esm/escape.js +0 -116
  311. package/node_modules/markdown-it/node_modules/entities/lib/esm/escape.js.map +0 -1
  312. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-html.d.ts +0 -3
  313. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-html.d.ts.map +0 -1
  314. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-html.js +0 -7
  315. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-html.js.map +0 -1
  316. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts +0 -3
  317. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-xml.d.ts.map +0 -1
  318. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-xml.js +0 -7
  319. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/decode-data-xml.js.map +0 -1
  320. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/encode-html.d.ts +0 -8
  321. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/encode-html.d.ts.map +0 -1
  322. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/encode-html.js +0 -10
  323. package/node_modules/markdown-it/node_modules/entities/lib/esm/generated/encode-html.js.map +0 -1
  324. package/node_modules/markdown-it/node_modules/entities/lib/esm/index.d.ts.map +0 -1
  325. package/node_modules/markdown-it/node_modules/entities/lib/esm/index.js +0 -99
  326. package/node_modules/markdown-it/node_modules/entities/lib/esm/index.js.map +0 -1
  327. package/node_modules/markdown-it/node_modules/entities/lib/esm/package.json +0 -1
  328. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-html.d.ts +0 -3
  329. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-html.d.ts.map +0 -1
  330. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-html.js +0 -9
  331. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-html.js.map +0 -1
  332. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-xml.d.ts +0 -3
  333. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-xml.d.ts.map +0 -1
  334. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-xml.js +0 -9
  335. package/node_modules/markdown-it/node_modules/entities/lib/generated/decode-data-xml.js.map +0 -1
  336. package/node_modules/markdown-it/node_modules/entities/lib/generated/encode-html.d.ts +0 -8
  337. package/node_modules/markdown-it/node_modules/entities/lib/generated/encode-html.d.ts.map +0 -1
  338. package/node_modules/markdown-it/node_modules/entities/lib/generated/encode-html.js +0 -12
  339. package/node_modules/markdown-it/node_modules/entities/lib/generated/encode-html.js.map +0 -1
  340. package/node_modules/markdown-it/node_modules/entities/lib/index.d.ts +0 -96
  341. package/node_modules/markdown-it/node_modules/entities/lib/index.d.ts.map +0 -1
  342. package/node_modules/markdown-it/node_modules/entities/lib/index.js +0 -126
  343. package/node_modules/markdown-it/node_modules/entities/lib/index.js.map +0 -1
  344. package/node_modules/markdown-it/node_modules/linkify-it/index.mjs +0 -646
  345. package/node_modules/markdown-it/node_modules/linkify-it/lib/re.mjs +0 -193
  346. package/node_modules/markdown-it/node_modules/uc.micro/categories/Cc/regex.mjs +0 -1
  347. package/node_modules/markdown-it/node_modules/uc.micro/categories/Cf/regex.mjs +0 -1
  348. package/node_modules/markdown-it/node_modules/uc.micro/categories/P/regex.mjs +0 -1
  349. package/node_modules/markdown-it/node_modules/uc.micro/categories/S/regex.mjs +0 -1
  350. package/node_modules/markdown-it/node_modules/uc.micro/categories/Z/regex.mjs +0 -1
  351. package/node_modules/markdown-it/node_modules/uc.micro/index.mjs +0 -8
  352. package/node_modules/markdown-it/node_modules/uc.micro/properties/Any/regex.mjs +0 -1
  353. /package/dist/{account-config-BZWN9tGS.js → .setup/account-config-BZWN9tGS.mjs} +0 -0
  354. /package/dist/{backup-health-Dm_YMVFT.js → .setup/backup-health-Dm_YMVFT.mjs} +0 -0
  355. /package/dist/{config-paths-CnREYb1Y.js → .setup/config-paths-CnREYb1Y.mjs} +0 -0
  356. /package/dist/{config-secret-input.runtime-CwsP3--c.js → .setup/config-secret-input.runtime-CwsP3--c.mjs} +0 -0
  357. /package/dist/{crypto-node.runtime-6Aj_ltHQ.js → .setup/crypto-node.runtime-6Aj_ltHQ.mjs} +0 -0
  358. /package/dist/{errors-C47hvAF8.js → .setup/errors-C47hvAF8.mjs} +0 -0
  359. /package/dist/{preflight-audio.runtime-BZxxQsxY.js → .setup/preflight-audio.runtime-BZxxQsxY.mjs} +0 -0
  360. /package/dist/{reaction-common-DkrQdBSZ.js → .setup/reaction-common-DkrQdBSZ.mjs} +0 -0
  361. /package/dist/{rolldown-runtime-8H4AJuhK.js → .setup/rolldown-runtime-8H4AJuhK.mjs} +0 -0
  362. /package/dist/{runtime-6S3DNFNv.js → .setup/runtime-6S3DNFNv.mjs} +0 -0
  363. /package/dist/{runtime-BefyhPWv.js → .setup/runtime-BefyhPWv.mjs} +0 -0
  364. /package/dist/{sync-state-CWbp0QSY.js → .setup/sync-state-CWbp0QSY.mjs} +0 -0
  365. /package/dist/{target-ids-B-5aQxwn.js → .setup/target-ids-B-5aQxwn.mjs} +0 -0
  366. /package/dist/{thread-bindings-shared-CKnY4LSd.js → .setup/thread-bindings-shared-CKnY4LSd.mjs} +0 -0
  367. /package/dist/{timeout-abort-signal-DMrgRFIy.js → .setup/timeout-abort-signal-DMrgRFIy.mjs} +0 -0
  368. /package/dist/{url-validation-GRHde6lq.js → .setup/url-validation-GRHde6lq.mjs} +0 -0
@@ -1,5 +1,5 @@
1
- // Port of python's argparse module, version 3.9.0:
2
- // https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py
1
+ // Port of python's argparse module, version 3.14.6:
2
+ // https://github.com/python/cpython/blob/v3.14.6/Lib/argparse.py
3
3
 
4
4
  'use strict'
5
5
 
@@ -24,11 +24,12 @@
24
24
  * 'integers', metavar='int', nargs='+', type=int,
25
25
  * help='an integer to be summed')
26
26
  * parser.add_argument(
27
- * '--log', default=sys.stdout, type=argparse.FileType('w'),
27
+ * '--log',
28
28
  * help='the file where the sum should be written')
29
29
  * args = parser.parse_args()
30
- * args.log.write('%s' % sum(args.integers))
31
- * args.log.close()
30
+ * with (open(args.log, 'w') if args.log is not None
31
+ * else contextlib.nullcontext(sys.stdout)) as log:
32
+ * log.write('%s' % sum(args.integers))
32
33
  *
33
34
  * The module contains the following public classes:
34
35
  *
@@ -84,51 +85,51 @@ const _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'
84
85
  const assert = require('assert')
85
86
  const util = require('util')
86
87
  const fs = require('fs')
87
- const sub = require('./lib/sub')
88
+ const sub = require('./sub')
88
89
  const path = require('path')
89
90
  const repr = util.inspect
90
91
 
91
- function get_argv() {
92
+ function get_argv () {
92
93
  // omit first argument (which is assumed to be interpreter - `node`, `coffee`, `ts-node`, etc.)
93
94
  return process.argv.slice(1)
94
95
  }
95
96
 
96
- function get_terminal_size() {
97
+ function get_terminal_size () {
97
98
  return {
98
99
  columns: +process.env.COLUMNS || process.stdout.columns || 80
99
100
  }
100
101
  }
101
102
 
102
- function hasattr(object, name) {
103
+ function hasattr (object, name) {
103
104
  return Object.prototype.hasOwnProperty.call(object, name)
104
105
  }
105
106
 
106
- function getattr(object, name, value) {
107
+ function getattr (object, name, value) {
107
108
  return hasattr(object, name) ? object[name] : value
108
109
  }
109
110
 
110
- function setattr(object, name, value) {
111
+ function setattr (object, name, value) {
111
112
  object[name] = value
112
113
  }
113
114
 
114
- function setdefault(object, name, value) {
115
+ function setdefault (object, name, value) {
115
116
  if (!hasattr(object, name)) object[name] = value
116
117
  return object[name]
117
118
  }
118
119
 
119
- function delattr(object, name) {
120
+ function delattr (object, name) {
120
121
  delete object[name]
121
122
  }
122
123
 
123
- function range(from, to, step=1) {
124
+ function range (from, to, step = 1) {
124
125
  // range(10) is equivalent to range(0, 10)
125
- if (arguments.length === 1) [ to, from ] = [ from, 0 ]
126
+ if (arguments.length === 1) [to, from] = [from, 0]
126
127
  if (typeof from !== 'number' || typeof to !== 'number' || typeof step !== 'number') {
127
128
  throw new TypeError('argument cannot be interpreted as an integer')
128
129
  }
129
130
  if (step === 0) throw new TypeError('range() arg 3 must not be zero')
130
131
 
131
- let result = []
132
+ const result = []
132
133
  if (step > 0) {
133
134
  for (let i = from; i < to; i += step) result.push(i)
134
135
  } else {
@@ -137,13 +138,13 @@ function range(from, to, step=1) {
137
138
  return result
138
139
  }
139
140
 
140
- function splitlines(str, keepends = false) {
141
+ function splitlines (str, keepends = false) {
141
142
  let result
142
143
  if (!keepends) {
143
144
  result = str.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]/)
144
145
  } else {
145
146
  result = []
146
- let parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/)
147
+ const parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/)
147
148
  for (let i = 0; i < parts.length; i += 2) {
148
149
  result.push(parts[i] + (i + 1 < parts.length ? parts[i + 1] : ''))
149
150
  }
@@ -152,30 +153,29 @@ function splitlines(str, keepends = false) {
152
153
  return result
153
154
  }
154
155
 
155
- function _string_lstrip(string, prefix_chars) {
156
+ function _string_lstrip (string, prefix_chars) {
156
157
  let idx = 0
157
158
  while (idx < string.length && prefix_chars.includes(string[idx])) idx++
158
159
  return idx ? string.slice(idx) : string
159
160
  }
160
161
 
161
- function _string_split(string, sep, maxsplit) {
162
+ function _string_split (string, sep, maxsplit) {
162
163
  let result = string.split(sep)
163
164
  if (result.length > maxsplit) {
164
- result = result.slice(0, maxsplit).concat([ result.slice(maxsplit).join(sep) ])
165
+ result = result.slice(0, maxsplit).concat([result.slice(maxsplit).join(sep)])
165
166
  }
166
167
  return result
167
168
  }
168
169
 
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
170
+ function _string_to_number (string) {
171
+ if (typeof string === 'string' && !/(?:^|\D)_|_(?:\D|$)/.test(string)) {
172
+ string = string.replace(/_/g, '')
173
173
  }
174
- return true
174
+ return Number(string)
175
175
  }
176
176
 
177
- function _array_remove(array, item) {
178
- let idx = array.indexOf(item)
177
+ function _array_remove (array, item) {
178
+ const idx = array.indexOf(item)
179
179
  if (idx === -1) throw new TypeError(sub('%r not in list', item))
180
180
  array.splice(idx, 1)
181
181
  }
@@ -183,11 +183,13 @@ function _array_remove(array, item) {
183
183
  // normalize choices to array;
184
184
  // this isn't required in python because `in` and `map` operators work with anything,
185
185
  // but in js dealing with multiple types here is too clunky
186
- function _choices_to_array(choices) {
186
+ function _choices_to_array (choices) {
187
187
  if (choices === undefined) {
188
188
  return []
189
189
  } else if (Array.isArray(choices)) {
190
190
  return choices
191
+ } else if (choices instanceof Map) {
192
+ return Array.from(choices.keys())
191
193
  } else if (choices !== null && typeof choices[Symbol.iterator] === 'function') {
192
194
  return Array.from(choices)
193
195
  } else if (typeof choices === 'object' && choices !== null) {
@@ -198,10 +200,10 @@ function _choices_to_array(choices) {
198
200
  }
199
201
 
200
202
  // 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
+ function _callable (cls) {
204
+ const result = { // object is needed for inferred class name
203
205
  [cls.name]: function (...args) {
204
- let this_class = new.target === result || !new.target
206
+ const this_class = new.target === result || !new.target
205
207
  return Reflect.construct(cls, args, this_class ? cls : new.target)
206
208
  }
207
209
  }
@@ -211,45 +213,11 @@ function _callable(cls) {
211
213
  return result[cls.name]
212
214
  }
213
215
 
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
216
  // 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')
217
+ const no_default = Symbol('no_default_value')
218
+ function _parse_opts (args, descriptor) {
219
+ function get_name () {
220
+ const stack = new Error().stack.split('\n')
253
221
  .map(x => x.match(/^ at (.*) \(.*\)$/))
254
222
  .filter(Boolean)
255
223
  .map(m => m[1])
@@ -262,63 +230,23 @@ function _parse_opts(args, descriptor) {
262
230
 
263
231
  args = Array.from(args)
264
232
  let kwargs = {}
265
- let result = []
266
- let last_opt = args.length && args[args.length - 1]
233
+ const result = []
234
+ const last_opt = args.length && args[args.length - 1]
267
235
 
268
236
  if (typeof last_opt === 'object' && last_opt !== null && !Array.isArray(last_opt) &&
269
237
  (!last_opt.constructor || last_opt.constructor.name === 'Object')) {
270
238
  kwargs = Object.assign({}, args.pop())
271
239
  }
272
240
 
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
241
+ const missing_positionals = []
242
+ const positional_count = args.length
243
+ let keyword_only = false
297
244
 
298
- for (let [ key, def ] of Object.entries(descriptor)) {
299
- if (key[0] === '*') {
245
+ for (const [key, def] of Object.entries(descriptor)) {
246
+ if (key === '*') {
247
+ keyword_only = true
248
+ } else if (key[0] === '*') {
300
249
  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
250
  result.push(kwargs)
323
251
  kwargs = {}
324
252
  } else {
@@ -330,7 +258,7 @@ function _parse_opts(args, descriptor) {
330
258
  } else if (key in kwargs) {
331
259
  result.push(kwargs[key])
332
260
  delete kwargs[key]
333
- } else if (args.length > 0) {
261
+ } else if (args.length > 0 && !keyword_only) {
334
262
  result.push(args.shift())
335
263
  } else if (def !== no_default) {
336
264
  result.push(def)
@@ -345,8 +273,12 @@ function _parse_opts(args, descriptor) {
345
273
  }
346
274
 
347
275
  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
276
+ const entries = Object.entries(descriptor)
277
+ const marker = entries.findIndex(([k]) => k === '*')
278
+ const positional_entries = (marker === -1 ? entries : entries.slice(0, marker))
279
+ .filter(([k]) => k[0] !== '*')
280
+ const from = positional_entries.filter(([, v]) => v !== no_default).length
281
+ const to = positional_entries.length
350
282
  throw new TypeError(sub('%s() takes %s positional argument%s but %s %s given',
351
283
  get_name(),
352
284
  from === to ? sub('from %s to %s', from, to) : to,
@@ -356,9 +288,9 @@ function _parse_opts(args, descriptor) {
356
288
  }
357
289
 
358
290
  if (missing_positionals.length) {
359
- let strs = missing_positionals.map(repr)
291
+ const strs = missing_positionals.map(repr)
360
292
  if (strs.length > 1) strs[strs.length - 1] = 'and ' + strs[strs.length - 1]
361
- let str_joined = strs.join(strs.length === 2 ? '' : ', ')
293
+ const str_joined = strs.join(strs.length === 2 ? '' : ', ')
362
294
  throw new TypeError(sub('%s() missing %i required positional argument%s: %s',
363
295
  get_name(), strs.length, strs.length === 1 ? '' : 's', str_joined))
364
296
  }
@@ -366,17 +298,10 @@ function _parse_opts(args, descriptor) {
366
298
  return result
367
299
  }
368
300
 
369
- let _deprecations = {}
370
- function deprecate(id, string) {
371
- _deprecations[id] = _deprecations[id] || util.deprecate(() => {}, string)
372
- _deprecations[id]()
373
- }
374
-
375
-
376
301
  // =============================
377
302
  // Utility functions and classes
378
303
  // =============================
379
- function _AttributeHolder(cls = Object) {
304
+ function _AttributeHolder (cls = Object) {
380
305
  /*
381
306
  * Abstract base class that provides __repr__.
382
307
  *
@@ -387,14 +312,14 @@ function _AttributeHolder(cls = Object) {
387
312
  */
388
313
 
389
314
  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()) {
315
+ [util.inspect.custom] () {
316
+ const type_name = this.constructor.name
317
+ const arg_strings = []
318
+ const star_args = {}
319
+ for (const arg of this._get_args()) {
395
320
  arg_strings.push(repr(arg))
396
321
  }
397
- for (let [ name, value ] of this._get_kwargs()) {
322
+ for (const [name, value] of this._get_kwargs()) {
398
323
  if (/^[a-z_][a-z0-9_$]*$/i.test(name)) {
399
324
  arg_strings.push(sub('%s=%r', name, value))
400
325
  } else {
@@ -407,33 +332,37 @@ function _AttributeHolder(cls = Object) {
407
332
  return sub('%s(%s)', type_name, arg_strings.join(', '))
408
333
  }
409
334
 
410
- toString() {
335
+ toString () {
411
336
  return this[util.inspect.custom]()
412
337
  }
413
338
 
414
- _get_kwargs() {
339
+ _get_kwargs () {
415
340
  return Object.entries(this)
416
341
  }
417
342
 
418
- _get_args() {
343
+ _get_args () {
419
344
  return []
420
345
  }
421
346
  }
422
347
  }
423
348
 
424
349
 
425
- function _copy_items(items) {
426
- if (items === undefined) {
350
+ function _copy_items (items) {
351
+ if (items === undefined || items === null) {
427
352
  return []
428
353
  }
429
354
  return items.slice(0)
430
355
  }
431
356
 
357
+ function _identity (value) {
358
+ return value
359
+ }
360
+
432
361
 
433
362
  // ===============
434
363
  // Formatting Help
435
364
  // ===============
436
- const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
365
+ const HelpFormatter = _callable(class HelpFormatter {
437
366
  /*
438
367
  * Formatter for generating usage messages and argument help strings.
439
368
  *
@@ -441,17 +370,19 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
441
370
  * provided by the class are considered an implementation detail.
442
371
  */
443
372
 
444
- constructor() {
373
+ constructor () {
445
374
  let [
446
375
  prog,
447
376
  indent_increment,
448
377
  max_help_position,
449
- width
378
+ width,
379
+ color
450
380
  ] = _parse_opts(arguments, {
451
381
  prog: no_default,
452
382
  indent_increment: 2,
453
383
  max_help_position: 24,
454
- width: undefined
384
+ width: undefined,
385
+ color: true
455
386
  })
456
387
 
457
388
  // default setting for width
@@ -460,6 +391,7 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
460
391
  width -= 2
461
392
  }
462
393
 
394
+ this._set_color(color)
463
395
  this._prog = prog
464
396
  this._indent_increment = indent_increment
465
397
  this._max_help_position = Math.min(max_help_position,
@@ -477,64 +409,80 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
477
409
  this._long_break_matcher = /\n\n\n+/g
478
410
  }
479
411
 
412
+ _set_color (color) {
413
+ const { can_colorize, decolor, get_theme } = require('./_colorize')
414
+
415
+ if (color && can_colorize()) {
416
+ this._theme = get_theme({ force_color: true }).argparse
417
+ this._decolor = decolor
418
+ } else {
419
+ this._theme = get_theme({ force_no_color: true }).argparse
420
+ this._decolor = _identity
421
+ }
422
+ }
423
+
480
424
  // ===============================
481
425
  // Section and indentation methods
482
426
  // ===============================
483
- _indent() {
427
+ _indent () {
484
428
  this._current_indent += this._indent_increment
485
429
  this._level += 1
486
430
  }
487
431
 
488
- _dedent() {
432
+ _dedent () {
489
433
  this._current_indent -= this._indent_increment
490
434
  assert(this._current_indent >= 0, 'Indent decreased below 0.')
491
435
  this._level -= 1
492
436
  }
493
437
 
494
- _add_item(func, args) {
495
- this._current_section.items.push([ func, args ])
438
+ _add_item (func, args) {
439
+ this._current_section.items.push([func, args])
496
440
  }
497
441
 
498
442
  // ========================
499
443
  // Message building methods
500
444
  // ========================
501
- start_section(heading) {
445
+ start_section (heading) {
502
446
  this._indent()
503
- let section = this._Section(this, this._current_section, heading)
447
+ const section = this._Section(this, this._current_section, heading)
504
448
  this._add_item(section.format_help.bind(section), [])
505
449
  this._current_section = section
506
450
  }
507
451
 
508
- end_section() {
452
+ end_section () {
509
453
  this._current_section = this._current_section.parent
510
454
  this._dedent()
511
455
  }
512
456
 
513
- add_text(text) {
457
+ add_text (text) {
514
458
  if (text !== SUPPRESS && text !== undefined) {
515
459
  this._add_item(this._format_text.bind(this), [text])
516
460
  }
517
461
  }
518
462
 
519
- add_usage(usage, actions, groups, prefix = undefined) {
463
+ add_usage (usage, actions, groups, prefix = undefined) {
520
464
  if (usage !== SUPPRESS) {
521
- let args = [ usage, actions, groups, prefix ]
465
+ const args = [usage, actions, groups, prefix]
522
466
  this._add_item(this._format_usage.bind(this), args)
523
467
  }
524
468
  }
525
469
 
526
- add_argument(action) {
470
+ add_argument (action) {
527
471
  if (action.help !== SUPPRESS) {
528
472
 
529
473
  // 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))
474
+ const get_invocation = action => this._decolor(this._format_action_invocation(action))
475
+ const invocation_lengths = [
476
+ get_invocation(action).length + this._current_indent
477
+ ]
478
+ for (const subaction of this._iter_indented_subactions(action)) {
479
+ invocation_lengths.push(
480
+ get_invocation(subaction).length + this._current_indent
481
+ )
533
482
  }
534
483
 
535
484
  // 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
485
+ const action_length = Math.max(...invocation_lengths)
538
486
  this._action_max_length = Math.max(this._action_max_length,
539
487
  action_length)
540
488
 
@@ -543,8 +491,8 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
543
491
  }
544
492
  }
545
493
 
546
- add_arguments(actions) {
547
- for (let action of actions) {
494
+ add_arguments (actions) {
495
+ for (const action of actions) {
548
496
  this.add_argument(action)
549
497
  }
550
498
  }
@@ -552,7 +500,7 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
552
500
  // =======================
553
501
  // Help-formatting methods
554
502
  // =======================
555
- format_help() {
503
+ format_help () {
556
504
  let help = this._root_section.format_help()
557
505
  if (help) {
558
506
  help = help.replace(this._long_break_matcher, '\n\n')
@@ -561,79 +509,69 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
561
509
  return help
562
510
  }
563
511
 
564
- _join_parts(part_strings) {
512
+ _join_parts (part_strings) {
565
513
  return part_strings.filter(part => part && part !== SUPPRESS).join('')
566
514
  }
567
515
 
568
- _format_usage(usage, actions, groups, prefix) {
516
+ _format_usage (usage, actions, groups, prefix) {
517
+ const t = this._theme
518
+
569
519
  if (prefix === undefined) {
570
520
  prefix = 'usage: '
571
521
  }
572
522
 
573
523
  // if usage is specified, use that
574
524
  if (usage !== undefined) {
575
- usage = sub(usage, { prog: this._prog })
525
+ usage = t.prog_extra + sub(usage, {
526
+ prog: t.prog + this._prog + t.reset + t.prog_extra
527
+ }) + t.reset
576
528
 
577
529
  // if no optionals or positionals are available, usage is just prog
578
530
  } else if (usage === undefined && !actions.length) {
579
- usage = sub('%(prog)s', { prog: this._prog })
531
+ usage = t.prog + this._prog + t.reset
580
532
 
581
533
  // if optionals and positionals are available, calculate usage
582
534
  } 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
- }
535
+ const prog = sub('%(prog)s', { prog: this._prog })
595
536
 
537
+ const [parts, pos_start] = this._get_actions_usage_parts(actions, groups)
596
538
  // 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(' ')
539
+ usage = [prog].concat(parts).filter(Boolean).join(' ')
599
540
 
600
541
  // 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) {
542
+ const text_width = this._width - this._current_indent
543
+ if (prefix.length + this._decolor(usage).length > text_width) {
603
544
 
604
545
  // 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)
546
+ const opt_parts = parts.slice(0, pos_start)
547
+ const pos_parts = parts.slice(pos_start)
612
548
 
613
549
  // helper for wrapping lines
614
- let get_lines = (parts, indent, prefix = undefined) => {
615
- let lines = []
550
+ const get_lines = (parts, indent, prefix = undefined) => {
551
+ const lines = []
616
552
  let line = []
553
+ const indent_length = indent.length
617
554
  let line_len
618
555
  if (prefix !== undefined) {
619
556
  line_len = prefix.length - 1
620
557
  } else {
621
- line_len = indent.length - 1
558
+ line_len = indent_length - 1
622
559
  }
623
- for (let part of parts) {
624
- if (line_len + 1 + part.length > text_width && line) {
560
+ for (const part of parts) {
561
+ const part_len = this._decolor(part).length
562
+ if (line_len + 1 + part_len > text_width && line.length) {
625
563
  lines.push(indent + line.join(' '))
626
564
  line = []
627
- line_len = indent.length - 1
565
+ line_len = indent_length - 1
628
566
  }
629
567
  line.push(part)
630
- line_len += part.length + 1
568
+ line_len += part_len + 1
631
569
  }
632
570
  if (line.length) {
633
571
  lines.push(indent + line.join(' '))
634
572
  }
635
573
  if (prefix !== undefined) {
636
- lines[0] = lines[0].slice(indent.length)
574
+ lines[0] = lines[0].slice(indent_length)
637
575
  }
638
576
  return lines
639
577
  }
@@ -641,8 +579,9 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
641
579
  let lines
642
580
 
643
581
  // 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)
582
+ const prog_len = this._decolor(prog).length
583
+ if (prefix.length + prog_len <= 0.75 * text_width) {
584
+ const indent = ' '.repeat(prefix.length + prog_len + 1)
646
585
  if (opt_parts.length) {
647
586
  lines = get_lines([prog].concat(opt_parts), indent, prefix)
648
587
  lines = lines.concat(get_lines(pos_parts, indent))
@@ -654,8 +593,8 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
654
593
 
655
594
  // if prog is long, put it on its own line
656
595
  } else {
657
- let indent = ' '.repeat(prefix.length)
658
- let parts = [].concat(opt_parts).concat(pos_parts)
596
+ const indent = ' '.repeat(prefix.length)
597
+ const parts = [].concat(opt_parts).concat(pos_parts)
659
598
  lines = get_lines(parts, indent)
660
599
  if (lines.length > 1) {
661
600
  lines = []
@@ -668,178 +607,214 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
668
607
  // join lines into usage
669
608
  usage = lines.join('\n')
670
609
  }
610
+
611
+ if (usage.startsWith(prog)) usage = usage.slice(prog.length)
612
+ usage = t.prog + prog + t.reset + usage
671
613
  }
672
614
 
673
615
  // prefix with 'usage:'
674
- return sub('%s%s\n\n', prefix, usage)
616
+ return t.usage + prefix + t.reset + usage + '\n\n'
675
617
  }
676
618
 
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] = ')'
619
+ _is_long_option (string) {
620
+ return string.length > 2
621
+ }
622
+
623
+ _get_actions_usage_parts (actions, groups) {
624
+ /* Get usage parts with split index for optionals/positionals.
625
+
626
+ * Returns [parts, pos_start] where pos_start is the index in parts
627
+ * where positionals begin. This preserves mutually exclusive group
628
+ * formatting across the optionals/positionals boundary (gh-75949).
629
+ */
630
+ actions = actions.filter(action => action.help !== SUPPRESS)
631
+
632
+ // group actions by mutually exclusive groups
633
+ const action_groups = new Map(actions.map(action => [action, undefined]))
634
+ for (const group of groups) {
635
+ for (const action of group._group_actions) {
636
+ if (action_groups.has(action)) {
637
+ action_groups.set(action, group)
638
+ }
639
+ }
640
+ }
641
+
642
+ // positional arguments keep their position
643
+ const positionals = []
644
+ for (const action of actions) {
645
+ if (!action.option_strings.length) {
646
+ const group = action_groups.get(action)
647
+ action_groups.delete(action)
648
+ if (group) {
649
+ const group_actions = []
650
+ for (const action2 of group._group_actions) {
651
+ if (action2.option_strings.length && action_groups.has(action2)) {
652
+ const action_group = action_groups.get(action2)
653
+ action_groups.delete(action2)
654
+ if (action_group) {
655
+ group_actions.push(action2)
656
+ }
712
657
  }
713
658
  }
714
- for (let i of range(start + 1, end)) {
715
- inserts[i] = '|'
659
+ group_actions.push(action)
660
+ positionals.push([group.required, group_actions])
661
+ } else {
662
+ positionals.push([undefined, [action]])
663
+ }
664
+ }
665
+ }
666
+
667
+ // the remaining optional arguments are sorted by the position of
668
+ // the first option in the group
669
+ const optionals = []
670
+ for (const action of actions) {
671
+ if (action.option_strings.length && action_groups.has(action)) {
672
+ const group = action_groups.get(action)
673
+ action_groups.delete(action)
674
+ if (group) {
675
+ const group_actions = [action]
676
+ for (const action2 of group._group_actions) {
677
+ if (action2.option_strings.length && action_groups.has(action2)) {
678
+ const action_group = action_groups.get(action2)
679
+ action_groups.delete(action2)
680
+ if (action_group) {
681
+ group_actions.push(action2)
682
+ }
683
+ }
716
684
  }
685
+ optionals.push([group.required, group_actions])
686
+ } else {
687
+ optionals.push([undefined, [action]])
717
688
  }
718
689
  }
719
690
  }
720
691
 
721
692
  // 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
- }
693
+ const parts = []
694
+ const t = this._theme
695
+ let pos_start
696
+ const action_sets = optionals.concat(positionals)
697
+ for (let i = 0; i < action_sets.length; i++) {
698
+ const [required, group] = action_sets[i]
699
+ const start = parts.length
700
+ if (i === optionals.length) {
701
+ pos_start = start
702
+ }
703
+ const in_group = group.length > 1
704
+ for (const action of group) {
705
+ let part
734
706
 
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)
707
+ // produce all arg strings
708
+ if (!action.option_strings.length) {
709
+ const default_value = this._get_default_metavar_for_positional(action)
710
+ part = this._format_args(action, default_value)
739
711
 
740
- // if it's in a group, strip the outer []
741
- if (group_actions.has(action)) {
742
- if (part[0] === '[' && part[part.length - 1] === ']') {
712
+ // if it's in a group, strip the outer []
713
+ if (in_group && part[0] === '[' && part[part.length - 1] === ']') {
743
714
  part = part.slice(1, -1)
744
715
  }
745
- }
746
-
747
- // add the action string to the list
748
- parts.push(part)
716
+ part = t.summary_action + part + t.reset
749
717
 
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
718
+ // produce the first way to invoke the option in brackets
762
719
  } 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
- }
720
+ const option_string = action.option_strings[0]
721
+ const option_color = this._is_long_option(option_string)
722
+ ? t.summary_long_option
723
+ : t.summary_short_option
724
+
725
+ // if the Optional doesn't take a value, format is:
726
+ // -s or --long
727
+ if (action.nargs === 0) {
728
+ part = action.format_usage()
729
+ part = option_color + part + t.reset
730
+
731
+ // if the Optional takes a value, format is:
732
+ // -s ARGS or --long ARGS
733
+ } else {
734
+ const default_value = this._get_default_metavar_for_optional(action)
735
+ const args_string = this._format_args(action, default_value)
736
+ part = option_color + option_string + ' ' +
737
+ t.summary_label + args_string + t.reset
738
+ }
767
739
 
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)
740
+ // make it look optional if it's not required or in a group
741
+ if (!(action.required || required || in_group)) {
742
+ part = sub('[%s]', part)
743
+ }
771
744
  }
772
745
 
773
746
  // add the action string to the list
774
747
  parts.push(part)
775
748
  }
776
- }
777
749
 
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])
750
+ if (in_group) {
751
+ parts[start] = (required ? '(' : '[') + parts[start]
752
+ for (let i = start; i < parts.length - 1; i++) {
753
+ parts[i] += ' |'
754
+ }
755
+ parts[parts.length - 1] += required ? ')' : ']'
756
+ }
781
757
  }
782
758
 
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
759
+ if (pos_start === undefined) {
760
+ pos_start = parts.length
761
+ }
762
+ return [parts, pos_start]
795
763
  }
796
764
 
797
- _format_text(text) {
765
+ _format_text (text) {
798
766
  if (text.includes('%(prog)')) {
799
767
  text = sub(text, { prog: this._prog })
800
768
  }
801
- let text_width = Math.max(this._width - this._current_indent, 11)
802
- let indent = ' '.repeat(this._current_indent)
769
+ const text_width = Math.max(this._width - this._current_indent, 11)
770
+ const indent = ' '.repeat(this._current_indent)
803
771
  return this._fill_text(text, text_width, indent) + '\n\n'
804
772
  }
805
773
 
806
- _format_action(action) {
774
+ _format_action (action) {
807
775
  // determine the required width and the entry label
808
- let help_position = Math.min(this._action_max_length + 2,
776
+ const help_position = Math.min(this._action_max_length + 2,
809
777
  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
778
+ const help_width = Math.max(this._width - help_position, 11)
779
+ const action_width = help_position - this._current_indent - 2
812
780
  let action_header = this._format_action_invocation(action)
781
+ const action_header_no_color = this._decolor(action_header)
813
782
  let indent_first
814
783
 
815
784
  // no help; start on same line and add a final newline
816
785
  if (!action.help) {
817
- let tup = [ this._current_indent, '', action_header ]
786
+ const tup = [this._current_indent, '', action_header]
818
787
  action_header = sub('%*s%s\n', ...tup)
819
788
 
820
789
  // 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 ]
790
+ } else if (action_header_no_color.length <= action_width) {
791
+ // calculate widths without color codes
792
+ const action_header_color = action_header
793
+ const tup = [this._current_indent, '', action_width, action_header_no_color]
823
794
  action_header = sub('%*s%-*s ', ...tup)
795
+ // swap in the colored header
796
+ action_header = action_header.replace(action_header_no_color, action_header_color)
824
797
  indent_first = 0
825
798
 
826
799
  // long action name; start on the next line
827
800
  } else {
828
- let tup = [ this._current_indent, '', action_header ]
801
+ const tup = [this._current_indent, '', action_header]
829
802
  action_header = sub('%*s%s\n', ...tup)
830
803
  indent_first = help_position
831
804
  }
832
805
 
833
806
  // collect the pieces of the action help
834
- let parts = [action_header]
807
+ const parts = [action_header]
835
808
 
836
809
  // 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))
810
+ if (action.help && action.help.trim()) {
811
+ const help_text = this._expand_help(action)
812
+ if (help_text) {
813
+ const help_lines = this._split_lines(help_text, help_width)
814
+ parts.push(sub('%*s%s\n', indent_first, '', help_lines[0]))
815
+ for (const line of help_lines.slice(1)) {
816
+ parts.push(sub('%*s%s\n', help_position, '', line))
817
+ }
843
818
  }
844
819
 
845
820
  // or add a newline if the description doesn't end with one
@@ -848,7 +823,7 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
848
823
  }
849
824
 
850
825
  // if there are any sub-actions, add their help as well
851
- for (let subaction of this._iter_indented_subactions(action)) {
826
+ for (const subaction of this._iter_indented_subactions(action)) {
852
827
  parts.push(this._format_action(subaction))
853
828
  }
854
829
 
@@ -856,46 +831,49 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
856
831
  return this._join_parts(parts)
857
832
  }
858
833
 
859
- _format_action_invocation(action) {
834
+ _format_action_invocation (action) {
835
+ const t = this._theme
836
+
860
837
  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
838
+ const default_value = this._get_default_metavar_for_positional(action)
839
+ return t.action +
840
+ this._metavar_formatter(action, default_value)(1).join(' ') +
841
+ t.reset
864
842
 
865
843
  } else {
866
- let parts = []
844
+ const color_option_strings = strings => strings.map(string => {
845
+ const color = this._is_long_option(string) ? t.long_option : t.short_option
846
+ return color + string + t.reset
847
+ })
867
848
 
868
849
  // if the Optional doesn't take a value, format is:
869
850
  // -s, --long
870
851
  if (action.nargs === 0) {
871
- parts = parts.concat(action.option_strings)
852
+ return color_option_strings(action.option_strings).join(', ')
872
853
 
873
854
  // if the Optional takes a value, format is:
874
- // -s ARGS, --long ARGS
855
+ // -s, --long ARGS
875
856
  } 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
- }
857
+ const default_value = this._get_default_metavar_for_optional(action)
858
+ const option_strings = color_option_strings(action.option_strings)
859
+ const args_string = t.label + this._format_args(action, default_value) + t.reset
860
+ return option_strings.join(', ') + ' ' + args_string
881
861
  }
882
-
883
- return parts.join(', ')
884
862
  }
885
863
  }
886
864
 
887
- _metavar_formatter(action, default_metavar) {
865
+ _metavar_formatter (action, default_metavar) {
888
866
  let result
889
867
  if (action.metavar !== undefined) {
890
868
  result = action.metavar
891
869
  } else if (action.choices !== undefined) {
892
- let choice_strs = _choices_to_array(action.choices).map(String)
870
+ const choice_strs = _choices_to_array(action.choices).map(String)
893
871
  result = sub('{%s}', choice_strs.join(','))
894
872
  } else {
895
873
  result = default_metavar
896
874
  }
897
875
 
898
- function format(tuple_size) {
876
+ function format (tuple_size) {
899
877
  if (Array.isArray(result)) {
900
878
  return result
901
879
  } else {
@@ -905,15 +883,15 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
905
883
  return format
906
884
  }
907
885
 
908
- _format_args(action, default_metavar) {
909
- let get_metavar = this._metavar_formatter(action, default_metavar)
886
+ _format_args (action, default_metavar) {
887
+ const get_metavar = this._metavar_formatter(action, default_metavar)
910
888
  let result
911
889
  if (action.nargs === undefined) {
912
890
  result = sub('%s', ...get_metavar(1))
913
891
  } else if (action.nargs === OPTIONAL) {
914
892
  result = sub('[%s]', ...get_metavar(1))
915
893
  } else if (action.nargs === ZERO_OR_MORE) {
916
- let metavar = get_metavar(1)
894
+ const metavar = get_metavar(1)
917
895
  if (metavar.length === 2) {
918
896
  result = sub('[%s [%s ...]]', ...metavar)
919
897
  } else {
@@ -939,85 +917,79 @@ const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {
939
917
  return result
940
918
  }
941
919
 
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
- }
920
+ _expand_help (action) {
921
+ const help_string = this._get_help_string(action)
922
+ if (!help_string.includes('%')) {
923
+ return help_string
948
924
  }
949
- for (let name of Object.keys(params)) {
950
- if (params[name] && params[name].name) {
951
- params[name] = params[name].name
925
+ const params = Object.assign({}, action, { prog: this._prog })
926
+ for (const name of Object.keys(params)) {
927
+ const value = params[name]
928
+ if (value === SUPPRESS) {
929
+ delete params[name]
930
+ } else if (value !== undefined && value !== null && 'name' in Object(value)) {
931
+ params[name] = value.name
952
932
  }
953
933
  }
954
934
  if (params.choices !== undefined) {
955
- let choices_str = _choices_to_array(params.choices).map(String).join(', ')
935
+ const choices_str = _choices_to_array(params.choices).map(String).join(', ')
956
936
  params.choices = choices_str
957
937
  }
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)
938
+ return sub(help_string, params)
967
939
  }
968
940
 
969
- * _iter_indented_subactions(action) {
941
+ * _iter_indented_subactions (action) {
970
942
  if (typeof action._get_subactions === 'function') {
971
943
  this._indent()
972
- yield* action._get_subactions()
944
+ yield * action._get_subactions()
973
945
  this._dedent()
974
946
  }
975
947
  }
976
948
 
977
- _split_lines(text, width) {
949
+ _split_lines (text, width) {
978
950
  text = text.replace(this._whitespace_matcher, ' ').trim()
979
951
  // The textwrap module is used only for formatting help.
980
952
  // Delay its import for speeding up the common usage of argparse.
981
- let textwrap = require('./lib/textwrap')
953
+ const textwrap = require('./textwrap')
982
954
  return textwrap.wrap(text, { width })
983
955
  }
984
956
 
985
- _fill_text(text, width, indent) {
957
+ _fill_text (text, width, indent) {
986
958
  text = text.replace(this._whitespace_matcher, ' ').trim()
987
- let textwrap = require('./lib/textwrap')
959
+ const textwrap = require('./textwrap')
988
960
  return textwrap.fill(text, { width,
989
961
  initial_indent: indent,
990
962
  subsequent_indent: indent })
991
963
  }
992
964
 
993
- _get_help_string(action) {
965
+ _get_help_string (action) {
994
966
  return action.help
995
967
  }
996
968
 
997
- _get_default_metavar_for_optional(action) {
969
+ _get_default_metavar_for_optional (action) {
998
970
  return action.dest.toUpperCase()
999
971
  }
1000
972
 
1001
- _get_default_metavar_for_positional(action) {
973
+ _get_default_metavar_for_positional (action) {
1002
974
  return action.dest
1003
975
  }
1004
- }))
976
+ })
1005
977
 
1006
978
  HelpFormatter.prototype._Section = _callable(class _Section {
1007
979
 
1008
- constructor(formatter, parent, heading = undefined) {
980
+ constructor (formatter, parent, heading = undefined) {
1009
981
  this.formatter = formatter
1010
982
  this.parent = parent
1011
983
  this.heading = heading
1012
984
  this.items = []
1013
985
  }
1014
986
 
1015
- format_help() {
987
+ format_help () {
1016
988
  // format the indented section
1017
989
  if (this.parent !== undefined) {
1018
990
  this.formatter._indent()
1019
991
  }
1020
- let item_help = this.formatter._join_parts(this.items.map(([ func, args ]) => func.apply(null, args)))
992
+ const item_help = this.formatter._join_parts(this.items.map(([func, args]) => func.apply(null, args)))
1021
993
  if (this.parent !== undefined) {
1022
994
  this.formatter._dedent()
1023
995
  }
@@ -1030,8 +1002,10 @@ HelpFormatter.prototype._Section = _callable(class _Section {
1030
1002
  // add the heading if the section was non-empty
1031
1003
  let heading
1032
1004
  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)
1005
+ const current_indent = this.formatter._current_indent
1006
+ const t = this.formatter._theme
1007
+ const heading_text = this.heading + ':'
1008
+ heading = ' '.repeat(current_indent) + t.heading + heading_text + t.reset + '\n'
1035
1009
  } else {
1036
1010
  heading = ''
1037
1011
  }
@@ -1042,7 +1016,7 @@ HelpFormatter.prototype._Section = _callable(class _Section {
1042
1016
  })
1043
1017
 
1044
1018
 
1045
- const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescriptionHelpFormatter extends HelpFormatter {
1019
+ const RawDescriptionHelpFormatter = _callable(class RawDescriptionHelpFormatter extends HelpFormatter {
1046
1020
  /*
1047
1021
  * Help message formatter which retains any formatting in descriptions.
1048
1022
  *
@@ -1050,13 +1024,13 @@ const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescript
1050
1024
  * provided by the class are considered an implementation detail.
1051
1025
  */
1052
1026
 
1053
- _fill_text(text, width, indent) {
1027
+ _fill_text (text, width, indent) {
1054
1028
  return splitlines(text, true).map(line => indent + line).join('')
1055
1029
  }
1056
- }))
1030
+ })
1057
1031
 
1058
1032
 
1059
- const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter {
1033
+ const RawTextHelpFormatter = _callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter {
1060
1034
  /*
1061
1035
  * Help message formatter which retains formatting of all help text.
1062
1036
  *
@@ -1064,13 +1038,13 @@ const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatt
1064
1038
  * provided by the class are considered an implementation detail.
1065
1039
  */
1066
1040
 
1067
- _split_lines(text/*, width*/) {
1041
+ _split_lines (text/*, width */) {
1068
1042
  return splitlines(text)
1069
1043
  }
1070
- }))
1044
+ })
1071
1045
 
1072
1046
 
1073
- const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter {
1047
+ const ArgumentDefaultsHelpFormatter = _callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter {
1074
1048
  /*
1075
1049
  * Help message formatter which adds default values to argument help.
1076
1050
  *
@@ -1078,23 +1052,26 @@ const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentD
1078
1052
  * provided by the class are considered an implementation detail.
1079
1053
  */
1080
1054
 
1081
- _get_help_string(action) {
1055
+ _get_help_string (action) {
1082
1056
  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
- }
1057
+ if (help === undefined) {
1058
+ help = ''
1059
+ }
1060
+
1061
+ if (!help.includes('%(default)') &&
1062
+ action.default !== SUPPRESS &&
1063
+ !action.required) {
1064
+ const defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]
1065
+ if (action.option_strings.length || defaulting_nargs.includes(action.nargs)) {
1066
+ help += ' (default: %(default)s)'
1090
1067
  }
1091
1068
  }
1092
1069
  return help
1093
1070
  }
1094
- }))
1071
+ })
1095
1072
 
1096
1073
 
1097
- const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHelpFormatter extends HelpFormatter {
1074
+ const MetavarTypeHelpFormatter = _callable(class MetavarTypeHelpFormatter extends HelpFormatter {
1098
1075
  /*
1099
1076
  * Help message formatter which uses the argument 'type' as the default
1100
1077
  * metavar value (instead of the argument 'dest')
@@ -1103,31 +1080,45 @@ const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHel
1103
1080
  * provided by the class are considered an implementation detail.
1104
1081
  */
1105
1082
 
1106
- _get_default_metavar_for_optional(action) {
1083
+ _get_default_metavar_for_optional (action) {
1107
1084
  return typeof action.type === 'function' ? action.type.name : action.type
1108
1085
  }
1109
1086
 
1110
- _get_default_metavar_for_positional(action) {
1087
+ _get_default_metavar_for_positional (action) {
1111
1088
  return typeof action.type === 'function' ? action.type.name : action.type
1112
1089
  }
1113
- }))
1090
+ })
1114
1091
 
1115
1092
 
1116
1093
  // =====================
1117
1094
  // Options and Arguments
1118
1095
  // =====================
1119
- function _get_action_name(argument) {
1096
+ function _get_action_name (argument) {
1120
1097
  if (argument === undefined) {
1121
1098
  return undefined
1122
1099
  } else if (argument.option_strings.length) {
1123
1100
  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)) {
1101
+ } else if (![undefined, SUPPRESS].includes(argument.metavar)) {
1102
+ const metavar = argument.metavar
1103
+ if (!Array.isArray(metavar)) {
1104
+ return metavar
1105
+ }
1106
+ if (argument.nargs === ZERO_OR_MORE && metavar.length === 2) {
1107
+ return sub('%s[, %s]', ...metavar)
1108
+ } else if (argument.nargs === ONE_OR_MORE) {
1109
+ return sub('%s[, %s]', ...metavar)
1110
+ } else {
1111
+ return metavar.join(', ')
1112
+ }
1113
+ } else if (![undefined, SUPPRESS].includes(argument.dest)) {
1127
1114
  return argument.dest
1128
- } else {
1129
- return undefined
1115
+ } else if (argument.choices) {
1116
+ const choices = _choices_to_array(argument.choices)
1117
+ if (choices.length) {
1118
+ return sub('{%s}', choices.map(String).join(','))
1119
+ }
1130
1120
  }
1121
+ return undefined
1131
1122
  }
1132
1123
 
1133
1124
 
@@ -1139,7 +1130,7 @@ const ArgumentError = _callable(class ArgumentError extends Error {
1139
1130
  * information about the argument that caused it.
1140
1131
  */
1141
1132
 
1142
- constructor(argument, message) {
1133
+ constructor (argument, message) {
1143
1134
  super()
1144
1135
  this.name = 'ArgumentError'
1145
1136
  this._argument_name = _get_action_name(argument)
@@ -1147,7 +1138,7 @@ const ArgumentError = _callable(class ArgumentError extends Error {
1147
1138
  this.message = this.str()
1148
1139
  }
1149
1140
 
1150
- str() {
1141
+ str () {
1151
1142
  let format
1152
1143
  if (this._argument_name === undefined) {
1153
1144
  format = '%(message)s'
@@ -1165,7 +1156,7 @@ const ArgumentTypeError = _callable(class ArgumentTypeError extends Error {
1165
1156
  * An error from trying to convert a command line string to a type.
1166
1157
  */
1167
1158
 
1168
- constructor(message) {
1159
+ constructor (message) {
1169
1160
  super(message)
1170
1161
  this.name = 'ArgumentTypeError'
1171
1162
  }
@@ -1175,7 +1166,7 @@ const ArgumentTypeError = _callable(class ArgumentTypeError extends Error {
1175
1166
  // ==============
1176
1167
  // Action classes
1177
1168
  // ==============
1178
- const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(Function) {
1169
+ const Action = _callable(class Action extends _AttributeHolder(Function) {
1179
1170
  /*
1180
1171
  * Information about how to convert command line strings to Python objects.
1181
1172
  *
@@ -1227,8 +1218,8 @@ const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(
1227
1218
  * help string. If None, the 'dest' value will be used as the name.
1228
1219
  */
1229
1220
 
1230
- constructor() {
1231
- let [
1221
+ constructor () {
1222
+ const [
1232
1223
  option_strings,
1233
1224
  dest,
1234
1225
  nargs,
@@ -1238,7 +1229,8 @@ const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(
1238
1229
  choices,
1239
1230
  required,
1240
1231
  help,
1241
- metavar
1232
+ metavar,
1233
+ deprecated
1242
1234
  ] = _parse_opts(arguments, {
1243
1235
  option_strings: no_default,
1244
1236
  dest: no_default,
@@ -1249,7 +1241,8 @@ const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(
1249
1241
  choices: undefined,
1250
1242
  required: false,
1251
1243
  help: undefined,
1252
- metavar: undefined
1244
+ metavar: undefined,
1245
+ deprecated: false
1253
1246
  })
1254
1247
 
1255
1248
  // when this class is called as a function, redirect it to .call() method of itself
@@ -1265,10 +1258,11 @@ const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(
1265
1258
  this.required = required
1266
1259
  this.help = help
1267
1260
  this.metavar = metavar
1261
+ this.deprecated = deprecated
1268
1262
  }
1269
1263
 
1270
- _get_kwargs() {
1271
- let names = [
1264
+ _get_kwargs () {
1265
+ const names = [
1272
1266
  'option_strings',
1273
1267
  'dest',
1274
1268
  'nargs',
@@ -1276,88 +1270,84 @@ const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(
1276
1270
  'default',
1277
1271
  'type',
1278
1272
  'choices',
1273
+ 'required',
1279
1274
  'help',
1280
- 'metavar'
1275
+ 'metavar',
1276
+ 'deprecated'
1281
1277
  ]
1282
- return names.map(name => [ name, getattr(this, name) ])
1278
+ return names.map(name => [name, getattr(this, name)])
1283
1279
  }
1284
1280
 
1285
- format_usage() {
1281
+ format_usage () {
1286
1282
  return this.option_strings[0]
1287
1283
  }
1288
1284
 
1289
- call(/*parser, namespace, values, option_string = undefined*/) {
1285
+ call (/* parser, namespace, values, option_string = undefined */) {
1290
1286
  throw new Error('.call() not defined')
1291
1287
  }
1292
- }))
1288
+ })
1293
1289
 
1294
1290
 
1295
- const BooleanOptionalAction = _camelcase_alias(_callable(class BooleanOptionalAction extends Action {
1291
+ const BooleanOptionalAction = _callable(class BooleanOptionalAction extends Action {
1296
1292
 
1297
- constructor() {
1298
- let [
1293
+ constructor () {
1294
+ const [
1299
1295
  option_strings,
1300
1296
  dest,
1301
1297
  default_value,
1302
- type,
1303
- choices,
1304
1298
  required,
1305
1299
  help,
1306
- metavar
1300
+ deprecated
1307
1301
  ] = _parse_opts(arguments, {
1308
1302
  option_strings: no_default,
1309
1303
  dest: no_default,
1310
1304
  default: undefined,
1311
- type: undefined,
1312
- choices: undefined,
1313
1305
  required: false,
1314
1306
  help: undefined,
1315
- metavar: undefined
1307
+ deprecated: false
1316
1308
  })
1317
1309
 
1318
- let _option_strings = []
1310
+ const _option_strings = []
1319
1311
  for (let option_string of option_strings) {
1320
1312
  _option_strings.push(option_string)
1321
1313
 
1322
1314
  if (option_string.startsWith('--')) {
1315
+ if (option_string.startsWith('--no-')) {
1316
+ throw new TypeError(sub('invalid option name %r ' +
1317
+ 'for BooleanOptionalAction', option_string))
1318
+ }
1323
1319
  option_string = '--no-' + option_string.slice(2)
1324
1320
  _option_strings.push(option_string)
1325
1321
  }
1326
1322
  }
1327
1323
 
1328
- if (help !== undefined && default_value !== undefined) {
1329
- help += ` (default: ${default_value})`
1330
- }
1331
-
1332
1324
  super({
1333
1325
  option_strings: _option_strings,
1334
1326
  dest,
1335
1327
  nargs: 0,
1336
1328
  default: default_value,
1337
- type,
1338
- choices,
1339
1329
  required,
1340
1330
  help,
1341
- metavar
1331
+ deprecated
1342
1332
  })
1343
1333
  }
1344
1334
 
1345
- call(parser, namespace, values, option_string = undefined) {
1335
+ call (parser, namespace, values, option_string = undefined) {
1346
1336
  if (this.option_strings.includes(option_string)) {
1347
1337
  setattr(namespace, this.dest, !option_string.startsWith('--no-'))
1348
1338
  }
1349
1339
  }
1350
1340
 
1351
- format_usage() {
1341
+ format_usage () {
1352
1342
  return this.option_strings.join(' | ')
1353
1343
  }
1354
- }))
1344
+ })
1355
1345
 
1356
1346
 
1357
1347
  const _StoreAction = _callable(class _StoreAction extends Action {
1358
1348
 
1359
- constructor() {
1360
- let [
1349
+ constructor () {
1350
+ const [
1361
1351
  option_strings,
1362
1352
  dest,
1363
1353
  nargs,
@@ -1367,7 +1357,8 @@ const _StoreAction = _callable(class _StoreAction extends Action {
1367
1357
  choices,
1368
1358
  required,
1369
1359
  help,
1370
- metavar
1360
+ metavar,
1361
+ deprecated
1371
1362
  ] = _parse_opts(arguments, {
1372
1363
  option_strings: no_default,
1373
1364
  dest: no_default,
@@ -1378,7 +1369,8 @@ const _StoreAction = _callable(class _StoreAction extends Action {
1378
1369
  choices: undefined,
1379
1370
  required: false,
1380
1371
  help: undefined,
1381
- metavar: undefined
1372
+ metavar: undefined,
1373
+ deprecated: false
1382
1374
  })
1383
1375
 
1384
1376
  if (nargs === 0) {
@@ -1399,11 +1391,12 @@ const _StoreAction = _callable(class _StoreAction extends Action {
1399
1391
  choices,
1400
1392
  required,
1401
1393
  help,
1402
- metavar
1394
+ metavar,
1395
+ deprecated
1403
1396
  })
1404
1397
  }
1405
1398
 
1406
- call(parser, namespace, values/*, option_string = undefined*/) {
1399
+ call (parser, namespace, values/*, option_string = undefined */) {
1407
1400
  setattr(namespace, this.dest, values)
1408
1401
  }
1409
1402
  })
@@ -1411,22 +1404,23 @@ const _StoreAction = _callable(class _StoreAction extends Action {
1411
1404
 
1412
1405
  const _StoreConstAction = _callable(class _StoreConstAction extends Action {
1413
1406
 
1414
- constructor() {
1415
- let [
1407
+ constructor () {
1408
+ const [
1416
1409
  option_strings,
1417
1410
  dest,
1418
1411
  const_value,
1419
1412
  default_value,
1420
1413
  required,
1421
- help
1422
- //, metavar
1414
+ help,
1415
+ deprecated
1423
1416
  ] = _parse_opts(arguments, {
1424
1417
  option_strings: no_default,
1425
1418
  dest: no_default,
1426
- const: no_default,
1419
+ const: undefined,
1427
1420
  default: undefined,
1428
1421
  required: false,
1429
1422
  help: undefined,
1423
+ deprecated: false,
1430
1424
  metavar: undefined
1431
1425
  })
1432
1426
 
@@ -1437,11 +1431,12 @@ const _StoreConstAction = _callable(class _StoreConstAction extends Action {
1437
1431
  const: const_value,
1438
1432
  default: default_value,
1439
1433
  required,
1440
- help
1434
+ help,
1435
+ deprecated
1441
1436
  })
1442
1437
  }
1443
1438
 
1444
- call(parser, namespace/*, values, option_string = undefined*/) {
1439
+ call (parser, namespace/*, values, option_string = undefined */) {
1445
1440
  setattr(namespace, this.dest, this.const)
1446
1441
  }
1447
1442
  })
@@ -1449,19 +1444,21 @@ const _StoreConstAction = _callable(class _StoreConstAction extends Action {
1449
1444
 
1450
1445
  const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAction {
1451
1446
 
1452
- constructor() {
1453
- let [
1447
+ constructor () {
1448
+ const [
1454
1449
  option_strings,
1455
1450
  dest,
1456
1451
  default_value,
1457
1452
  required,
1458
- help
1453
+ help,
1454
+ deprecated
1459
1455
  ] = _parse_opts(arguments, {
1460
1456
  option_strings: no_default,
1461
1457
  dest: no_default,
1462
1458
  default: false,
1463
1459
  required: false,
1464
- help: undefined
1460
+ help: undefined,
1461
+ deprecated: false
1465
1462
  })
1466
1463
 
1467
1464
  super({
@@ -1470,7 +1467,8 @@ const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAct
1470
1467
  const: true,
1471
1468
  default: default_value,
1472
1469
  required,
1473
- help
1470
+ help,
1471
+ deprecated
1474
1472
  })
1475
1473
  }
1476
1474
  })
@@ -1478,19 +1476,21 @@ const _StoreTrueAction = _callable(class _StoreTrueAction extends _StoreConstAct
1478
1476
 
1479
1477
  const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstAction {
1480
1478
 
1481
- constructor() {
1482
- let [
1479
+ constructor () {
1480
+ const [
1483
1481
  option_strings,
1484
1482
  dest,
1485
1483
  default_value,
1486
1484
  required,
1487
- help
1485
+ help,
1486
+ deprecated
1488
1487
  ] = _parse_opts(arguments, {
1489
1488
  option_strings: no_default,
1490
1489
  dest: no_default,
1491
1490
  default: true,
1492
1491
  required: false,
1493
- help: undefined
1492
+ help: undefined,
1493
+ deprecated: false
1494
1494
  })
1495
1495
 
1496
1496
  super({
@@ -1499,7 +1499,8 @@ const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstA
1499
1499
  const: false,
1500
1500
  default: default_value,
1501
1501
  required,
1502
- help
1502
+ help,
1503
+ deprecated
1503
1504
  })
1504
1505
  }
1505
1506
  })
@@ -1507,8 +1508,8 @@ const _StoreFalseAction = _callable(class _StoreFalseAction extends _StoreConstA
1507
1508
 
1508
1509
  const _AppendAction = _callable(class _AppendAction extends Action {
1509
1510
 
1510
- constructor() {
1511
- let [
1511
+ constructor () {
1512
+ const [
1512
1513
  option_strings,
1513
1514
  dest,
1514
1515
  nargs,
@@ -1518,7 +1519,8 @@ const _AppendAction = _callable(class _AppendAction extends Action {
1518
1519
  choices,
1519
1520
  required,
1520
1521
  help,
1521
- metavar
1522
+ metavar,
1523
+ deprecated
1522
1524
  ] = _parse_opts(arguments, {
1523
1525
  option_strings: no_default,
1524
1526
  dest: no_default,
@@ -1529,7 +1531,8 @@ const _AppendAction = _callable(class _AppendAction extends Action {
1529
1531
  choices: undefined,
1530
1532
  required: false,
1531
1533
  help: undefined,
1532
- metavar: undefined
1534
+ metavar: undefined,
1535
+ deprecated: false
1533
1536
  })
1534
1537
 
1535
1538
  if (nargs === 0) {
@@ -1550,11 +1553,12 @@ const _AppendAction = _callable(class _AppendAction extends Action {
1550
1553
  choices,
1551
1554
  required,
1552
1555
  help,
1553
- metavar
1556
+ metavar,
1557
+ deprecated
1554
1558
  })
1555
1559
  }
1556
1560
 
1557
- call(parser, namespace, values/*, option_string = undefined*/) {
1561
+ call (parser, namespace, values/*, option_string = undefined */) {
1558
1562
  let items = getattr(namespace, this.dest, undefined)
1559
1563
  items = _copy_items(items)
1560
1564
  items.push(values)
@@ -1565,23 +1569,25 @@ const _AppendAction = _callable(class _AppendAction extends Action {
1565
1569
 
1566
1570
  const _AppendConstAction = _callable(class _AppendConstAction extends Action {
1567
1571
 
1568
- constructor() {
1569
- let [
1572
+ constructor () {
1573
+ const [
1570
1574
  option_strings,
1571
1575
  dest,
1572
1576
  const_value,
1573
1577
  default_value,
1574
1578
  required,
1575
1579
  help,
1576
- metavar
1580
+ metavar,
1581
+ deprecated
1577
1582
  ] = _parse_opts(arguments, {
1578
1583
  option_strings: no_default,
1579
1584
  dest: no_default,
1580
- const: no_default,
1585
+ const: undefined,
1581
1586
  default: undefined,
1582
1587
  required: false,
1583
1588
  help: undefined,
1584
- metavar: undefined
1589
+ metavar: undefined,
1590
+ deprecated: false
1585
1591
  })
1586
1592
 
1587
1593
  super({
@@ -1592,11 +1598,12 @@ const _AppendConstAction = _callable(class _AppendConstAction extends Action {
1592
1598
  default: default_value,
1593
1599
  required,
1594
1600
  help,
1595
- metavar
1601
+ metavar,
1602
+ deprecated
1596
1603
  })
1597
1604
  }
1598
1605
 
1599
- call(parser, namespace/*, values, option_string = undefined*/) {
1606
+ call (parser, namespace/*, values, option_string = undefined */) {
1600
1607
  let items = getattr(namespace, this.dest, undefined)
1601
1608
  items = _copy_items(items)
1602
1609
  items.push(this.const)
@@ -1607,19 +1614,21 @@ const _AppendConstAction = _callable(class _AppendConstAction extends Action {
1607
1614
 
1608
1615
  const _CountAction = _callable(class _CountAction extends Action {
1609
1616
 
1610
- constructor() {
1611
- let [
1617
+ constructor () {
1618
+ const [
1612
1619
  option_strings,
1613
1620
  dest,
1614
1621
  default_value,
1615
1622
  required,
1616
- help
1623
+ help,
1624
+ deprecated
1617
1625
  ] = _parse_opts(arguments, {
1618
1626
  option_strings: no_default,
1619
1627
  dest: no_default,
1620
1628
  default: undefined,
1621
1629
  required: false,
1622
- help: undefined
1630
+ help: undefined,
1631
+ deprecated: false
1623
1632
  })
1624
1633
 
1625
1634
  super({
@@ -1628,11 +1637,12 @@ const _CountAction = _callable(class _CountAction extends Action {
1628
1637
  nargs: 0,
1629
1638
  default: default_value,
1630
1639
  required,
1631
- help
1640
+ help,
1641
+ deprecated
1632
1642
  })
1633
1643
  }
1634
1644
 
1635
- call(parser, namespace/*, values, option_string = undefined*/) {
1645
+ call (parser, namespace/*, values, option_string = undefined */) {
1636
1646
  let count = getattr(namespace, this.dest, undefined)
1637
1647
  if (count === undefined) {
1638
1648
  count = 0
@@ -1644,17 +1654,19 @@ const _CountAction = _callable(class _CountAction extends Action {
1644
1654
 
1645
1655
  const _HelpAction = _callable(class _HelpAction extends Action {
1646
1656
 
1647
- constructor() {
1648
- let [
1657
+ constructor () {
1658
+ const [
1649
1659
  option_strings,
1650
1660
  dest,
1651
1661
  default_value,
1652
- help
1662
+ help,
1663
+ deprecated
1653
1664
  ] = _parse_opts(arguments, {
1654
1665
  option_strings: no_default,
1655
1666
  dest: SUPPRESS,
1656
1667
  default: SUPPRESS,
1657
- help: undefined
1668
+ help: undefined,
1669
+ deprecated: false
1658
1670
  })
1659
1671
 
1660
1672
  super({
@@ -1662,11 +1674,12 @@ const _HelpAction = _callable(class _HelpAction extends Action {
1662
1674
  dest,
1663
1675
  default: default_value,
1664
1676
  nargs: 0,
1665
- help
1677
+ help,
1678
+ deprecated
1666
1679
  })
1667
1680
  }
1668
1681
 
1669
- call(parser/*, namespace, values, option_string = undefined*/) {
1682
+ call (parser/*, namespace, values, option_string = undefined */) {
1670
1683
  parser.print_help()
1671
1684
  parser.exit()
1672
1685
  }
@@ -1675,7 +1688,7 @@ const _HelpAction = _callable(class _HelpAction extends Action {
1675
1688
 
1676
1689
  const _VersionAction = _callable(class _VersionAction extends Action {
1677
1690
 
1678
- constructor() {
1691
+ constructor () {
1679
1692
  let [
1680
1693
  option_strings,
1681
1694
  version,
@@ -1687,9 +1700,14 @@ const _VersionAction = _callable(class _VersionAction extends Action {
1687
1700
  version: undefined,
1688
1701
  dest: SUPPRESS,
1689
1702
  default: SUPPRESS,
1690
- help: "show program's version number and exit"
1703
+ help: "show program's version number and exit",
1704
+ deprecated: false
1691
1705
  })
1692
1706
 
1707
+ if (help === undefined || help === null) {
1708
+ help = "show program's version number and exit"
1709
+ }
1710
+
1693
1711
  super({
1694
1712
  option_strings,
1695
1713
  dest,
@@ -1700,12 +1718,12 @@ const _VersionAction = _callable(class _VersionAction extends Action {
1700
1718
  this.version = version
1701
1719
  }
1702
1720
 
1703
- call(parser/*, namespace, values, option_string = undefined*/) {
1721
+ call (parser/*, namespace, values, option_string = undefined */) {
1704
1722
  let version = this.version
1705
1723
  if (version === undefined) {
1706
1724
  version = parser.version
1707
1725
  }
1708
- let formatter = parser._get_formatter()
1726
+ const formatter = parser._get_formatter()
1709
1727
  formatter.add_text(version)
1710
1728
  parser._print_message(formatter.format_help(), process.stdout)
1711
1729
  parser.exit()
@@ -1713,10 +1731,10 @@ const _VersionAction = _callable(class _VersionAction extends Action {
1713
1731
  })
1714
1732
 
1715
1733
 
1716
- const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction extends Action {
1734
+ const _SubParsersAction = _callable(class _SubParsersAction extends Action {
1717
1735
 
1718
- constructor() {
1719
- let [
1736
+ constructor () {
1737
+ const [
1720
1738
  option_strings,
1721
1739
  prog,
1722
1740
  parser_class,
@@ -1734,7 +1752,7 @@ const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction ext
1734
1752
  metavar: undefined
1735
1753
  })
1736
1754
 
1737
- let name_parser_map = {}
1755
+ const name_parser_map = Object.create(null)
1738
1756
 
1739
1757
  super({
1740
1758
  option_strings,
@@ -1750,10 +1768,12 @@ const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction ext
1750
1768
  this._parser_class = parser_class
1751
1769
  this._name_parser_map = name_parser_map
1752
1770
  this._choices_actions = []
1771
+ this._deprecated = new Set()
1772
+ this._color = true
1753
1773
  }
1754
1774
 
1755
- add_parser() {
1756
- let [
1775
+ add_parser () {
1776
+ const [
1757
1777
  name,
1758
1778
  kwargs
1759
1779
  ] = _parse_opts(arguments, {
@@ -1766,35 +1786,62 @@ const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction ext
1766
1786
  kwargs.prog = sub('%s %s', this._prog_prefix, name)
1767
1787
  }
1768
1788
 
1769
- let aliases = getattr(kwargs, 'aliases', [])
1789
+ // set color
1790
+ if (kwargs.color === undefined) {
1791
+ kwargs.color = this._color
1792
+ }
1793
+
1794
+ const aliases = getattr(kwargs, 'aliases', [])
1770
1795
  delete kwargs.aliases
1796
+ const deprecated = getattr(kwargs, 'deprecated', false)
1797
+ delete kwargs.deprecated
1798
+
1799
+ if (hasattr(this._name_parser_map, name)) {
1800
+ throw new TypeError(sub('conflicting subparser: %s', name))
1801
+ }
1802
+ for (const alias of aliases) {
1803
+ if (hasattr(this._name_parser_map, alias)) {
1804
+ throw new TypeError(sub('conflicting subparser alias: %s', alias))
1805
+ }
1806
+ }
1771
1807
 
1772
1808
  // create a pseudo-action to hold the choice help
1809
+ let choice_action
1773
1810
  if ('help' in kwargs) {
1774
- let help = kwargs.help
1811
+ const help = kwargs.help
1775
1812
  delete kwargs.help
1776
- let choice_action = this._ChoicesPseudoAction(name, aliases, help)
1813
+ choice_action = this._ChoicesPseudoAction(name, aliases, help)
1777
1814
  this._choices_actions.push(choice_action)
1778
1815
  }
1779
1816
 
1780
1817
  // create the parser and add it to the map
1781
- let parser = new this._parser_class(kwargs)
1818
+ const parser = new this._parser_class(kwargs)
1819
+ if (choice_action !== undefined) {
1820
+ parser._check_help(choice_action)
1821
+ }
1782
1822
  this._name_parser_map[name] = parser
1783
1823
 
1784
1824
  // make parser available under aliases also
1785
- for (let alias of aliases) {
1825
+ for (const alias of aliases) {
1786
1826
  this._name_parser_map[alias] = parser
1787
1827
  }
1788
1828
 
1829
+ if (deprecated) {
1830
+ this._deprecated.add(name)
1831
+ for (const alias of aliases) {
1832
+ this._deprecated.add(alias)
1833
+ }
1834
+ }
1835
+
1789
1836
  return parser
1790
1837
  }
1791
1838
 
1792
- _get_subactions() {
1839
+ _get_subactions () {
1793
1840
  return this._choices_actions
1794
1841
  }
1795
1842
 
1796
- call(parser, namespace, values/*, option_string = undefined*/) {
1797
- let parser_name = values[0]
1843
+ call (parser, namespace, values/*, option_string = undefined */) {
1844
+ const parser_name = values[0]
1798
1845
  let arg_strings = values.slice(1)
1799
1846
 
1800
1847
  // set the parser name if requested
@@ -1803,15 +1850,20 @@ const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction ext
1803
1850
  }
1804
1851
 
1805
1852
  // select the parser
1853
+ let subparser
1806
1854
  if (hasattr(this._name_parser_map, parser_name)) {
1807
- parser = this._name_parser_map[parser_name]
1855
+ subparser = this._name_parser_map[parser_name]
1808
1856
  } 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)
1857
+ const args = {parser_name,
1858
+ choices: Object.keys(this._name_parser_map).join(', ')}
1859
+ const msg = sub('unknown parser %(parser_name)r (choices: %(choices)s)', args)
1812
1860
  throw new ArgumentError(this, msg)
1813
1861
  }
1814
1862
 
1863
+ if (this._deprecated.has(parser_name)) {
1864
+ parser._warning(sub("command '%(parser_name)s' is deprecated", { parser_name }))
1865
+ }
1866
+
1815
1867
  // parse all the remaining options into the namespace
1816
1868
  // store any unrecognized options on the object, so that the top
1817
1869
  // level parser can decide what to do with them
@@ -1820,22 +1872,25 @@ const _SubParsersAction = _camelcase_alias(_callable(class _SubParsersAction ext
1820
1872
  // in a new namespace object and then update the original
1821
1873
  // namespace for the relevant parts.
1822
1874
  let subnamespace
1823
- [ subnamespace, arg_strings ] = parser.parse_known_args(arg_strings, undefined)
1824
- for (let [ key, value ] of Object.entries(subnamespace)) {
1875
+ [subnamespace, arg_strings] = subparser.parse_known_args(arg_strings, undefined)
1876
+ for (const [key, value] of Object.entries(subnamespace)) {
1825
1877
  setattr(namespace, key, value)
1826
1878
  }
1827
1879
 
1828
1880
  if (arg_strings.length) {
1829
- setdefault(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
1881
+ if (!hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) {
1882
+ setattr(namespace, _UNRECOGNIZED_ARGS_ATTR, [])
1883
+ }
1830
1884
  getattr(namespace, _UNRECOGNIZED_ARGS_ATTR).push(...arg_strings)
1831
1885
  }
1832
1886
  }
1833
- }))
1887
+ })
1834
1888
 
1835
1889
 
1836
1890
  _SubParsersAction.prototype._ChoicesPseudoAction = _callable(class _ChoicesPseudoAction extends Action {
1837
- constructor(name, aliases, help) {
1838
- let metavar = name, dest = name
1891
+ constructor (name, aliases, help) {
1892
+ let metavar = name
1893
+ const dest = name
1839
1894
  if (aliases.length) {
1840
1895
  metavar += sub(' (%s)', aliases.join(', '))
1841
1896
  }
@@ -1845,10 +1900,12 @@ _SubParsersAction.prototype._ChoicesPseudoAction = _callable(class _ChoicesPseud
1845
1900
 
1846
1901
 
1847
1902
  const _ExtendAction = _callable(class _ExtendAction extends _AppendAction {
1848
- call(parser, namespace, values/*, option_string = undefined*/) {
1903
+ call (parser, namespace, values/*, option_string = undefined */) {
1849
1904
  let items = getattr(namespace, this.dest, undefined)
1850
1905
  items = _copy_items(items)
1851
- items = items.concat(values)
1906
+ for (const value of values) {
1907
+ items.push(value)
1908
+ }
1852
1909
  setattr(namespace, this.dest, items)
1853
1910
  }
1854
1911
  })
@@ -1859,7 +1916,7 @@ const _ExtendAction = _callable(class _ExtendAction extends _AppendAction {
1859
1916
  // ==============
1860
1917
  const FileType = _callable(class FileType extends Function {
1861
1918
  /*
1862
- * Factory for creating file object types
1919
+ * Deprecated factory for creating file object types
1863
1920
  *
1864
1921
  * Instances of FileType are typically passed as type= arguments to the
1865
1922
  * ArgumentParser add_argument() method.
@@ -1875,8 +1932,8 @@ const FileType = _callable(class FileType extends Function {
1875
1932
  * be handled. Accepts the same value as the builtin open() function.
1876
1933
  */
1877
1934
 
1878
- constructor() {
1879
- let [
1935
+ constructor () {
1936
+ const [
1880
1937
  flags,
1881
1938
  encoding,
1882
1939
  mode,
@@ -1898,11 +1955,15 @@ const FileType = _callable(class FileType extends Function {
1898
1955
  fs: undefined
1899
1956
  })
1900
1957
 
1958
+ process.emitWarning(
1959
+ 'FileType is deprecated. Simply open files after parsing arguments.',
1960
+ 'PendingDeprecationWarning')
1961
+
1901
1962
  // when this class is called as a function, redirect it to .call() method of itself
1902
1963
  super('return arguments.callee.call.apply(arguments.callee, arguments)')
1903
1964
 
1904
1965
  Object.defineProperty(this, 'name', {
1905
- get() {
1966
+ get () {
1906
1967
  return sub('FileType(%r)', flags)
1907
1968
  }
1908
1969
  })
@@ -1918,15 +1979,15 @@ const FileType = _callable(class FileType extends Function {
1918
1979
  if (fs !== undefined) this._options.fs = fs
1919
1980
  }
1920
1981
 
1921
- call(string) {
1982
+ call (string) {
1922
1983
  // the special argument "-" means sys.std{in,out}
1923
1984
  if (string === '-') {
1924
1985
  if (this._flags.includes('r')) {
1925
1986
  return process.stdin
1926
- } else if (this._flags.includes('w')) {
1987
+ } else if ([...'wax'].some(flag => this._flags.includes(flag))) {
1927
1988
  return process.stdout
1928
1989
  } else {
1929
- let msg = sub('argument "-" with mode %r', this._flags)
1990
+ const msg = sub('argument "-" with mode %r', this._flags)
1930
1991
  throw new TypeError(msg)
1931
1992
  }
1932
1993
  }
@@ -1936,37 +1997,45 @@ const FileType = _callable(class FileType extends Function {
1936
1997
  try {
1937
1998
  fd = fs.openSync(string, this._flags, this._options.mode)
1938
1999
  } catch (e) {
1939
- let args = { filename: string, error: e.message }
1940
- let message = "can't open '%(filename)s': %(error)s"
2000
+ if (e instanceof TypeError) {
2001
+ throw e
2002
+ }
2003
+ const args = { filename: string, error: e.message }
2004
+ const message = "can't open '%(filename)s': %(error)s"
1941
2005
  throw new ArgumentTypeError(sub(message, args))
1942
2006
  }
1943
2007
 
1944
- let options = Object.assign({ fd, flags: this._flags }, this._options)
2008
+ const options = Object.assign({ fd, flags: this._flags }, this._options)
1945
2009
  if (this._flags.includes('r')) {
1946
- return fs.createReadStream(undefined, options)
2010
+ const file = fs.createReadStream(string, options)
2011
+ file.path = string
2012
+ return file
1947
2013
  } else if (this._flags.includes('w')) {
1948
- return fs.createWriteStream(undefined, options)
2014
+ const file = fs.createWriteStream(string, options)
2015
+ file.path = string
2016
+ return file
1949
2017
  } else {
1950
- let msg = sub('argument "%s" with mode %r', string, this._flags)
2018
+ fs.closeSync(fd)
2019
+ const msg = sub('argument "%s" with mode %r', string, this._flags)
1951
2020
  throw new TypeError(msg)
1952
2021
  }
1953
2022
  }
1954
2023
 
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 ]
2024
+ [util.inspect.custom] () {
2025
+ const args = [this._flags]
2026
+ const kwargs = Object.entries(this._options).map(([k, v]) => {
2027
+ if (k === 'mode') v = { value: v, [util.inspect.custom] () { return '0o' + this.value.toString(8) } }
2028
+ return [k, v]
1960
2029
  })
1961
- let args_str = []
2030
+ const args_str = []
1962
2031
  .concat(args.filter(arg => arg !== -1).map(repr))
1963
- .concat(kwargs.filter(([/*kw*/, arg]) => arg !== undefined)
2032
+ .concat(kwargs.filter(([/* kw */, arg]) => arg !== undefined)
1964
2033
  .map(([kw, arg]) => sub('%s=%r', kw, arg)))
1965
2034
  .join(', ')
1966
2035
  return sub('%s(%s)', this.constructor.name, args_str)
1967
2036
  }
1968
2037
 
1969
- toString() {
2038
+ toString () {
1970
2039
  return this[util.inspect.custom]()
1971
2040
  }
1972
2041
  })
@@ -1982,7 +2051,7 @@ const Namespace = _callable(class Namespace extends _AttributeHolder() {
1982
2051
  * string representation.
1983
2052
  */
1984
2053
 
1985
- constructor(options = {}) {
2054
+ constructor (options = {}) {
1986
2055
  super()
1987
2056
  Object.assign(this, options)
1988
2057
  }
@@ -1992,10 +2061,10 @@ const Namespace = _callable(class Namespace extends _AttributeHolder() {
1992
2061
  Namespace.prototype[Symbol.toStringTag] = undefined
1993
2062
 
1994
2063
 
1995
- const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2064
+ const _ActionsContainer = _callable(class _ActionsContainer {
1996
2065
 
1997
- constructor() {
1998
- let [
2066
+ constructor () {
2067
+ const [
1999
2068
  description,
2000
2069
  prefix_chars,
2001
2070
  argument_default,
@@ -2013,7 +2082,7 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2013
2082
  this.conflict_handler = conflict_handler
2014
2083
 
2015
2084
  // set up registries
2016
- this._registries = {}
2085
+ this._registries = Object.create(null)
2017
2086
 
2018
2087
  // register actions
2019
2088
  this.register('action', undefined, _StoreAction)
@@ -2028,30 +2097,22 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2028
2097
  this.register('action', 'version', _VersionAction)
2029
2098
  this.register('action', 'parsers', _SubParsersAction)
2030
2099
  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
2100
  // raise an exception if the conflict handler is invalid
2040
2101
  this._get_handler()
2041
2102
 
2042
2103
  // action storage
2043
2104
  this._actions = []
2044
- this._option_string_actions = {}
2105
+ this._option_string_actions = Object.create(null)
2045
2106
 
2046
2107
  // groups
2047
2108
  this._action_groups = []
2048
2109
  this._mutually_exclusive_groups = []
2049
2110
 
2050
2111
  // defaults storage
2051
- this._defaults = {}
2112
+ this._defaults = Object.create(null)
2052
2113
 
2053
2114
  // determines whether an "option" looks like a negative number
2054
- this._negative_number_matcher = /^-\d+$|^-\d*\.\d+$/
2115
+ this._negative_number_matcher = /^-\.?\d/
2055
2116
 
2056
2117
  // whether or not there are any optionals that look like negative
2057
2118
  // numbers -- uses a list so it can be shared and edited
@@ -2061,32 +2122,32 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2061
2122
  // ====================
2062
2123
  // Registration methods
2063
2124
  // ====================
2064
- register(registry_name, value, object) {
2065
- let registry = setdefault(this._registries, registry_name, {})
2125
+ register (registry_name, value, object) {
2126
+ const registry = setdefault(this._registries, registry_name, Object.create(null))
2066
2127
  registry[value] = object
2067
2128
  }
2068
2129
 
2069
- _registry_get(registry_name, value, default_value = undefined) {
2130
+ _registry_get (registry_name, value, default_value = undefined) {
2070
2131
  return getattr(this._registries[registry_name], value, default_value)
2071
2132
  }
2072
2133
 
2073
2134
  // ==================================
2074
2135
  // Namespace default accessor methods
2075
2136
  // ==================================
2076
- set_defaults(kwargs) {
2137
+ set_defaults (kwargs) {
2077
2138
  Object.assign(this._defaults, kwargs)
2078
2139
 
2079
2140
  // if these defaults match any existing arguments, replace
2080
2141
  // the previous default on the object with the new one
2081
- for (let action of this._actions) {
2142
+ for (const action of this._actions) {
2082
2143
  if (action.dest in kwargs) {
2083
2144
  action.default = kwargs[action.dest]
2084
2145
  }
2085
2146
  }
2086
2147
  }
2087
2148
 
2088
- get_default(dest) {
2089
- for (let action of this._actions) {
2149
+ get_default (dest) {
2150
+ for (const action of this._actions) {
2090
2151
  if (action.dest === dest && action.default !== undefined) {
2091
2152
  return action.default
2092
2153
  }
@@ -2098,7 +2159,7 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2098
2159
  // =======================
2099
2160
  // Adding argument actions
2100
2161
  // =======================
2101
- add_argument() {
2162
+ add_argument () {
2102
2163
  /*
2103
2164
  * add_argument(dest, ..., name=value, ...)
2104
2165
  * add_argument(option_string, option_string, ..., name=value, ...)
@@ -2110,23 +2171,23 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2110
2171
  '*args': no_default,
2111
2172
  '**kwargs': no_default
2112
2173
  })
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
- }))
2174
+ // argparse v1 accepted an array of argument names here. Python argparse
2175
+ // accepts only individual string names and rejects a list; reject it
2176
+ // explicitly because JS would otherwise coerce the array to a string.
2177
+ if (args.some(arg => typeof arg !== 'string')) {
2178
+ throw new TypeError('argument name must be a string')
2179
+ }
2180
+ if (args.some(arg => !arg.length)) {
2181
+ throw new TypeError('argument name must not be empty')
2120
2182
  }
2121
- // end
2122
-
2123
2183
  // if no positional args are supplied or only one is supplied and
2124
2184
  // it doesn't look like an option string, parse a positional
2125
2185
  // argument
2126
- let chars = this.prefix_chars
2186
+ const chars = this.prefix_chars
2127
2187
  if (!args.length || args.length === 1 && !chars.includes(args[0][0])) {
2128
2188
  if (args.length && 'dest' in kwargs) {
2129
- throw new TypeError('dest supplied twice for positional argument')
2189
+ throw new TypeError('dest supplied twice for positional argument,' +
2190
+ ' did you mean metavar?')
2130
2191
  }
2131
2192
  kwargs = this._get_positional_kwargs(...args, kwargs)
2132
2193
 
@@ -2137,7 +2198,7 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2137
2198
 
2138
2199
  // if no default was supplied, use the parser-level default
2139
2200
  if (!('default' in kwargs)) {
2140
- let dest = kwargs.dest
2201
+ const dest = kwargs.dest
2141
2202
  if (dest in this._defaults) {
2142
2203
  kwargs.default = this._defaults[dest]
2143
2204
  } else if (this.argument_default !== undefined) {
@@ -2146,15 +2207,22 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2146
2207
  }
2147
2208
 
2148
2209
  // create the action object, and add it to the parser
2149
- let action_class = this._pop_action_class(kwargs)
2210
+ const action_name = kwargs.action
2211
+ const action_class = this._pop_action_class(kwargs)
2150
2212
  if (typeof action_class !== 'function') {
2151
- throw new TypeError(sub('unknown action "%s"', action_class))
2213
+ throw new TypeError(sub('unknown action %r', action_class))
2152
2214
  }
2153
2215
  // eslint-disable-next-line new-cap
2154
- let action = new action_class(kwargs)
2216
+ const action = new action_class(kwargs)
2217
+
2218
+ // raise an error if action for positional argument does not
2219
+ // consume arguments
2220
+ if (!action.option_strings.length && action.nargs === 0) {
2221
+ throw new TypeError(sub('action %r is not valid for positional arguments', action_name))
2222
+ }
2155
2223
 
2156
2224
  // raise an error if the action type is not callable
2157
- let type_func = this._registry_get('type', action.type, action.type)
2225
+ const type_func = this._registry_get('type', action.type, action.type)
2158
2226
  if (typeof type_func !== 'function') {
2159
2227
  throw new TypeError(sub('%r is not callable', type_func))
2160
2228
  }
@@ -2165,9 +2233,10 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2165
2233
  }
2166
2234
 
2167
2235
  // raise an error if the metavar does not match the type
2168
- if ('_get_formatter' in this) {
2236
+ if ('_get_validation_formatter' in this) {
2237
+ const formatter = this._get_validation_formatter()
2169
2238
  try {
2170
- this._get_formatter()._format_args(action, undefined)
2239
+ formatter._format_args(action, undefined)
2171
2240
  } catch (err) {
2172
2241
  // check for 'invalid nargs value' is an artifact of TypeError and ValueError in js being the same
2173
2242
  if (err instanceof TypeError && err.message !== 'invalid nargs value') {
@@ -2178,23 +2247,25 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2178
2247
  }
2179
2248
  }
2180
2249
 
2250
+ this._check_help(action)
2251
+
2181
2252
  return this._add_action(action)
2182
2253
  }
2183
2254
 
2184
- add_argument_group() {
2185
- let group = _ArgumentGroup(this, ...arguments)
2255
+ add_argument_group () {
2256
+ const group = _ArgumentGroup(this, ...arguments)
2186
2257
  this._action_groups.push(group)
2187
2258
  return group
2188
2259
  }
2189
2260
 
2190
- add_mutually_exclusive_group() {
2191
- // eslint-disable-next-line no-use-before-define
2192
- let group = _MutuallyExclusiveGroup(this, ...arguments)
2261
+ add_mutually_exclusive_group () {
2262
+
2263
+ const group = _MutuallyExclusiveGroup(this, ...arguments)
2193
2264
  this._mutually_exclusive_groups.push(group)
2194
2265
  return group
2195
2266
  }
2196
2267
 
2197
- _add_action(action) {
2268
+ _add_action (action) {
2198
2269
  // resolve any conflicts
2199
2270
  this._check_conflict(action)
2200
2271
 
@@ -2203,12 +2274,12 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2203
2274
  action.container = this
2204
2275
 
2205
2276
  // index the action by any option strings it has
2206
- for (let option_string of action.option_strings) {
2277
+ for (const option_string of action.option_strings) {
2207
2278
  this._option_string_actions[option_string] = action
2208
2279
  }
2209
2280
 
2210
2281
  // set the flag if any option strings look like negative numbers
2211
- for (let option_string of action.option_strings) {
2282
+ for (const option_string of action.option_strings) {
2212
2283
  if (this._negative_number_matcher.test(option_string)) {
2213
2284
  if (!this._has_negative_number_optionals.length) {
2214
2285
  this._has_negative_number_optionals.push(true)
@@ -2220,24 +2291,26 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2220
2291
  return action
2221
2292
  }
2222
2293
 
2223
- _remove_action(action) {
2294
+ _remove_action (action) {
2224
2295
  _array_remove(this._actions, action)
2225
2296
  }
2226
2297
 
2227
- _add_container_actions(container) {
2298
+ _add_container_actions (container) {
2228
2299
  // collect groups by titles
2229
- let title_group_map = {}
2230
- for (let group of this._action_groups) {
2300
+ const title_group_map = Object.create(null)
2301
+ for (const group of this._action_groups) {
2231
2302
  if (group.title in title_group_map) {
2232
- let msg = 'cannot merge actions - two groups are named %r'
2303
+ // This branch could happen if a derived class added
2304
+ // groups with duplicated titles in constructor.
2305
+ const msg = 'cannot merge actions - two groups are named %r'
2233
2306
  throw new TypeError(sub(msg, group.title))
2234
2307
  }
2235
2308
  title_group_map[group.title] = group
2236
2309
  }
2237
2310
 
2238
2311
  // map each action to its group
2239
- let group_map = new Map()
2240
- for (let group of container._action_groups) {
2312
+ const group_map = new Map()
2313
+ for (const group of container._action_groups) {
2241
2314
 
2242
2315
  // if a group with the title exists, use that, otherwise
2243
2316
  // create a new group matching the container's group
@@ -2250,7 +2323,7 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2250
2323
  }
2251
2324
 
2252
2325
  // map the actions to their new group
2253
- for (let action of group._group_actions) {
2326
+ for (const action of group._group_actions) {
2254
2327
  group_map.set(action, title_group_map[group.title])
2255
2328
  }
2256
2329
  }
@@ -2258,25 +2331,32 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2258
2331
  // add container's mutually exclusive groups
2259
2332
  // NOTE: if add_mutually_exclusive_group ever gains title= and
2260
2333
  // 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({
2334
+ for (const group of container._mutually_exclusive_groups) {
2335
+ let cont
2336
+ if (group._container === container) {
2337
+ cont = this
2338
+ } else {
2339
+ cont = title_group_map[group._container.title]
2340
+ }
2341
+ const mutex_group = cont.add_mutually_exclusive_group({
2263
2342
  required: group.required
2264
2343
  })
2265
2344
 
2266
2345
  // map the actions to their new mutex group
2267
- for (let action of group._group_actions) {
2346
+ for (const action of group._group_actions) {
2268
2347
  group_map.set(action, mutex_group)
2269
2348
  }
2270
2349
  }
2271
2350
 
2272
2351
  // add all actions to this container or their group
2273
- for (let action of container._actions) {
2274
- group_map.get(action)._add_action(action)
2352
+ for (const action of container._actions) {
2353
+ const action_group = group_map.get(action) || this
2354
+ action_group._add_action(action)
2275
2355
  }
2276
2356
  }
2277
2357
 
2278
- _get_positional_kwargs() {
2279
- let [
2358
+ _get_positional_kwargs () {
2359
+ const [
2280
2360
  dest,
2281
2361
  kwargs
2282
2362
  ] = _parse_opts(arguments, {
@@ -2286,16 +2366,17 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2286
2366
 
2287
2367
  // make sure required is not specified
2288
2368
  if ('required' in kwargs) {
2289
- let msg = "'required' is an invalid argument for positionals"
2369
+ const msg = "'required' is an invalid argument for positionals"
2290
2370
  throw new TypeError(msg)
2291
2371
  }
2292
2372
 
2293
2373
  // mark positional arguments as required if at least one is
2294
2374
  // always required
2295
- if (![OPTIONAL, ZERO_OR_MORE].includes(kwargs.nargs)) {
2296
- kwargs.required = true
2375
+ const nargs = kwargs.nargs
2376
+ if (nargs === 0) {
2377
+ throw new TypeError('nargs for positionals must be != 0')
2297
2378
  }
2298
- if (kwargs.nargs === ZERO_OR_MORE && !('default' in kwargs)) {
2379
+ if (![OPTIONAL, ZERO_OR_MORE, REMAINDER, SUPPRESS].includes(nargs)) {
2299
2380
  kwargs.required = true
2300
2381
  }
2301
2382
 
@@ -2303,8 +2384,8 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2303
2384
  return Object.assign(kwargs, { dest, option_strings: [] })
2304
2385
  }
2305
2386
 
2306
- _get_optional_kwargs() {
2307
- let [
2387
+ _get_optional_kwargs () {
2388
+ const [
2308
2389
  args,
2309
2390
  kwargs
2310
2391
  ] = _parse_opts(arguments, {
@@ -2313,15 +2394,15 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2313
2394
  })
2314
2395
 
2315
2396
  // determine short and long option strings
2316
- let option_strings = []
2317
- let long_option_strings = []
2397
+ const option_strings = []
2398
+ const long_option_strings = []
2318
2399
  let option_string
2319
2400
  for (option_string of args) {
2320
2401
  // error on strings that don't start with an appropriate prefix
2321
2402
  if (!this.prefix_chars.includes(option_string[0])) {
2322
- let args = {option: option_string,
2403
+ const args = {option: option_string,
2323
2404
  prefix_chars: this.prefix_chars}
2324
- let msg = 'invalid option string %(option)r: ' +
2405
+ const msg = 'invalid option string %(option)r: ' +
2325
2406
  'must start with a character %(prefix_chars)r'
2326
2407
  throw new TypeError(sub(msg, args))
2327
2408
  }
@@ -2345,7 +2426,7 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2345
2426
  }
2346
2427
  dest = _string_lstrip(dest_option_string, this.prefix_chars)
2347
2428
  if (!dest) {
2348
- let msg = 'dest= is required for options like %r'
2429
+ const msg = 'dest= is required for options like %r'
2349
2430
  throw new TypeError(sub(msg, option_string))
2350
2431
  }
2351
2432
  dest = dest.replace(/-/g, '_')
@@ -2355,53 +2436,53 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2355
2436
  return Object.assign(kwargs, { dest, option_strings })
2356
2437
  }
2357
2438
 
2358
- _pop_action_class(kwargs, default_value = undefined) {
2359
- let action = getattr(kwargs, 'action', default_value)
2439
+ _pop_action_class (kwargs, default_value = undefined) {
2440
+ const action = getattr(kwargs, 'action', default_value)
2360
2441
  delete kwargs.action
2361
2442
  return this._registry_get('action', action, action)
2362
2443
  }
2363
2444
 
2364
- _get_handler() {
2445
+ _get_handler () {
2365
2446
  // determine function from conflict handler string
2366
- let handler_func_name = sub('_handle_conflict_%s', this.conflict_handler)
2447
+ const handler_func_name = sub('_handle_conflict_%s', this.conflict_handler)
2367
2448
  if (typeof this[handler_func_name] === 'function') {
2368
2449
  return this[handler_func_name]
2369
2450
  } else {
2370
- let msg = 'invalid conflict_resolution value: %r'
2451
+ const msg = 'invalid conflict_resolution value: %r'
2371
2452
  throw new TypeError(sub(msg, this.conflict_handler))
2372
2453
  }
2373
2454
  }
2374
2455
 
2375
- _check_conflict(action) {
2456
+ _check_conflict (action) {
2376
2457
 
2377
2458
  // find all options that conflict with this option
2378
- let confl_optionals = []
2379
- for (let option_string of action.option_strings) {
2459
+ const confl_optionals = []
2460
+ for (const option_string of action.option_strings) {
2380
2461
  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 ])
2462
+ const confl_optional = this._option_string_actions[option_string]
2463
+ confl_optionals.push([option_string, confl_optional])
2383
2464
  }
2384
2465
  }
2385
2466
 
2386
2467
  // resolve any conflicts
2387
2468
  if (confl_optionals.length) {
2388
- let conflict_handler = this._get_handler()
2469
+ const conflict_handler = this._get_handler()
2389
2470
  conflict_handler.call(this, action, confl_optionals)
2390
2471
  }
2391
2472
  }
2392
2473
 
2393
- _handle_conflict_error(action, conflicting_actions) {
2394
- let message = conflicting_actions.length === 1 ?
2474
+ _handle_conflict_error (action, conflicting_actions) {
2475
+ const message = conflicting_actions.length === 1 ?
2395
2476
  'conflicting option string: %s' :
2396
2477
  'conflicting option strings: %s'
2397
- let conflict_string = conflicting_actions.map(([ option_string/*, action*/ ]) => option_string).join(', ')
2478
+ const conflict_string = conflicting_actions.map(([option_string]) => option_string).join(', ')
2398
2479
  throw new ArgumentError(action, sub(message, conflict_string))
2399
2480
  }
2400
2481
 
2401
- _handle_conflict_resolve(action, conflicting_actions) {
2482
+ _handle_conflict_resolve (action, conflicting_actions) {
2402
2483
 
2403
2484
  // remove all conflicting options
2404
- for (let [ option_string, action ] of conflicting_actions) {
2485
+ for (const [option_string, action] of conflicting_actions) {
2405
2486
 
2406
2487
  // remove the conflicting option
2407
2488
  _array_remove(action.option_strings, option_string)
@@ -2414,13 +2495,27 @@ const _ActionsContainer = _camelcase_alias(_callable(class _ActionsContainer {
2414
2495
  }
2415
2496
  }
2416
2497
  }
2417
- }))
2498
+
2499
+ _check_help (action) {
2500
+ if (action.help && '_get_validation_formatter' in this) {
2501
+ const formatter = this._get_validation_formatter()
2502
+ try {
2503
+ formatter._expand_help(action)
2504
+ } catch (err) {
2505
+ if (err instanceof TypeError) {
2506
+ throw new TypeError('badly formed help string', { cause: err })
2507
+ }
2508
+ throw err
2509
+ }
2510
+ }
2511
+ }
2512
+ })
2418
2513
 
2419
2514
 
2420
2515
  const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer {
2421
2516
 
2422
- constructor() {
2423
- let [
2517
+ constructor () {
2518
+ const [
2424
2519
  container,
2425
2520
  title,
2426
2521
  description,
@@ -2432,6 +2527,13 @@ const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer
2432
2527
  '**kwargs': no_default
2433
2528
  })
2434
2529
 
2530
+ if ('prefix_chars' in kwargs) {
2531
+ const depr_msg =
2532
+ "The use of the undocumented 'prefix_chars' parameter in " +
2533
+ 'ArgumentParser.add_argument_group() is deprecated.'
2534
+ process.emitWarning(depr_msg, 'DeprecationWarning')
2535
+ }
2536
+
2435
2537
  // add any missing keyword arguments by checking the container
2436
2538
  setdefault(kwargs, 'conflict_handler', container.conflict_handler)
2437
2539
  setdefault(kwargs, 'prefix_chars', container.prefix_chars)
@@ -2452,23 +2554,27 @@ const _ArgumentGroup = _callable(class _ArgumentGroup extends _ActionsContainer
2452
2554
  this._mutually_exclusive_groups = container._mutually_exclusive_groups
2453
2555
  }
2454
2556
 
2455
- _add_action(action) {
2557
+ _add_action (action) {
2456
2558
  action = super._add_action(action)
2457
2559
  this._group_actions.push(action)
2458
2560
  return action
2459
2561
  }
2460
2562
 
2461
- _remove_action(action) {
2563
+ _remove_action (action) {
2462
2564
  super._remove_action(action)
2463
2565
  _array_remove(this._group_actions, action)
2464
2566
  }
2567
+
2568
+ add_argument_group () {
2569
+ throw new TypeError('argument groups cannot be nested')
2570
+ }
2465
2571
  })
2466
2572
 
2467
2573
 
2468
2574
  const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends _ArgumentGroup {
2469
2575
 
2470
- constructor() {
2471
- let [
2576
+ constructor () {
2577
+ const [
2472
2578
  container,
2473
2579
  required
2474
2580
  ] = _parse_opts(arguments, {
@@ -2481,9 +2587,9 @@ const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends
2481
2587
  this._container = container
2482
2588
  }
2483
2589
 
2484
- _add_action(action) {
2590
+ _add_action (action) {
2485
2591
  if (action.required) {
2486
- let msg = 'mutually exclusive arguments must be optional'
2592
+ const msg = 'mutually exclusive arguments must be optional'
2487
2593
  throw new TypeError(msg)
2488
2594
  }
2489
2595
  action = this._container._add_action(action)
@@ -2491,14 +2597,18 @@ const _MutuallyExclusiveGroup = _callable(class _MutuallyExclusiveGroup extends
2491
2597
  return action
2492
2598
  }
2493
2599
 
2494
- _remove_action(action) {
2600
+ _remove_action (action) {
2495
2601
  this._container._remove_action(action)
2496
2602
  _array_remove(this._group_actions, action)
2497
2603
  }
2604
+
2605
+ add_mutually_exclusive_group () {
2606
+ throw new TypeError('mutually exclusive groups cannot be nested')
2607
+ }
2498
2608
  })
2499
2609
 
2500
2610
 
2501
- const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _AttributeHolder(_ActionsContainer) {
2611
+ const ArgumentParser = _callable(class ArgumentParser extends _AttributeHolder(_ActionsContainer) {
2502
2612
  /*
2503
2613
  * Object for parsing command line strings into Python objects.
2504
2614
  *
@@ -2518,9 +2628,12 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2518
2628
  * - allow_abbrev -- Allow long options to be abbreviated unambiguously
2519
2629
  * - exit_on_error -- Determines whether or not ArgumentParser exits with
2520
2630
  * error info when an error occurs
2631
+ * - suggest_on_error - Enables suggestions for mistyped argument choices
2632
+ * and subparser names. (default: false)
2633
+ * - color - Allow color output in help messages (default: true)
2521
2634
  */
2522
2635
 
2523
- constructor() {
2636
+ constructor () {
2524
2637
  let [
2525
2638
  prog,
2526
2639
  usage,
@@ -2535,8 +2648,8 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2535
2648
  add_help,
2536
2649
  allow_abbrev,
2537
2650
  exit_on_error,
2538
- debug, // LEGACY (v1 compatibility), debug mode
2539
- version // LEGACY (v1 compatibility), version
2651
+ suggest_on_error,
2652
+ color
2540
2653
  ] = _parse_opts(arguments, {
2541
2654
  prog: undefined,
2542
2655
  usage: undefined,
@@ -2551,26 +2664,11 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2551
2664
  add_help: true,
2552
2665
  allow_abbrev: true,
2553
2666
  exit_on_error: true,
2554
- debug: undefined, // LEGACY (v1 compatibility), debug mode
2555
- version: undefined // LEGACY (v1 compatibility), version
2667
+ '*': no_default,
2668
+ suggest_on_error: false,
2669
+ color: true
2556
2670
  })
2557
2671
 
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
2672
  super({
2575
2673
  description,
2576
2674
  prefix_chars,
@@ -2591,44 +2689,58 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2591
2689
  this.add_help = add_help
2592
2690
  this.allow_abbrev = allow_abbrev
2593
2691
  this.exit_on_error = exit_on_error
2594
- // LEGACY (v1 compatibility), debug mode
2595
- this.debug = debug
2596
- // end
2692
+ this.suggest_on_error = suggest_on_error
2693
+ this.color = color
2694
+
2695
+ // Cached formatter for validation (avoids repeated _set_color calls)
2696
+ this._cached_formatter = undefined
2597
2697
 
2598
2698
  this._positionals = this.add_argument_group('positional arguments')
2599
- this._optionals = this.add_argument_group('optional arguments')
2699
+ this._optionals = this.add_argument_group('options')
2600
2700
  this._subparsers = undefined
2601
2701
 
2602
2702
  // register types
2603
- function identity(string) {
2703
+ function identity (string) {
2604
2704
  return string
2605
2705
  }
2606
2706
  this.register('type', undefined, identity)
2607
2707
  this.register('type', null, identity)
2608
- this.register('type', 'auto', identity)
2609
2708
  this.register('type', 'int', function (x) {
2610
- let result = Number(x)
2709
+ if (typeof x === 'string' && !/^[+-]?\d+(?:_?\d+)*$/.test(x.trim())) {
2710
+ throw new TypeError(sub('could not convert string to int: %r', x))
2711
+ }
2712
+ const result = _string_to_number(x)
2611
2713
  if (!Number.isInteger(result)) {
2612
2714
  throw new TypeError(sub('could not convert string to int: %r', x))
2613
2715
  }
2614
- return result
2716
+ // python integers have no negative zero
2717
+ return result === 0 ? 0 : result
2615
2718
  })
2616
2719
  this.register('type', 'float', function (x) {
2617
- let result = Number(x)
2720
+ if (typeof x === 'string') {
2721
+ const value = x.trim().toLowerCase()
2722
+ // Number() knows neither spelling
2723
+ if (/^[+-]?nan$/.test(value)) return NaN
2724
+ if (/^[+-]?inf(?:inity)?$/.test(value)) {
2725
+ return value[0] === '-' ? -Infinity : Infinity
2726
+ }
2727
+ // python's float() grammar: PEP 515 underscores, optional exponent
2728
+ const number = /^[+-]?(\d+(_\d+)*(\.(\d+(_\d+)*)?)?|\.\d+(_\d+)*)(e[+-]?\d+(_\d+)*)?$/
2729
+ if (!number.test(value)) {
2730
+ throw new TypeError(sub('could not convert string to float: %r', x))
2731
+ }
2732
+ }
2733
+ const result = _string_to_number(x)
2618
2734
  if (isNaN(result)) {
2619
2735
  throw new TypeError(sub('could not convert string to float: %r', x))
2620
2736
  }
2621
2737
  return result
2622
2738
  })
2623
2739
  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
2740
 
2629
2741
  // add help argument if necessary
2630
2742
  // (using explicit default to override global argument_default)
2631
- let default_prefix = prefix_chars.includes('-') ? '-' : prefix_chars[0]
2743
+ const default_prefix = prefix_chars.includes('-') ? '-' : prefix_chars[0]
2632
2744
  if (this.add_help) {
2633
2745
  this.add_argument(
2634
2746
  default_prefix + 'h',
@@ -2640,23 +2752,11 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2640
2752
  }
2641
2753
  )
2642
2754
  }
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
2755
  // add parent arguments and defaults
2659
- for (let parent of parents) {
2756
+ for (const parent of parents) {
2757
+ if (!(parent instanceof ArgumentParser)) {
2758
+ throw new TypeError('parents must be a list of ArgumentParser')
2759
+ }
2660
2760
  this._add_container_actions(parent)
2661
2761
  Object.assign(this._defaults, parent._defaults)
2662
2762
  }
@@ -2665,8 +2765,8 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2665
2765
  // =======================
2666
2766
  // Pretty __repr__ methods
2667
2767
  // =======================
2668
- _get_kwargs() {
2669
- let names = [
2768
+ _get_kwargs () {
2769
+ const names = [
2670
2770
  'prog',
2671
2771
  'usage',
2672
2772
  'description',
@@ -2674,29 +2774,29 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2674
2774
  'conflict_handler',
2675
2775
  'add_help'
2676
2776
  ]
2677
- return names.map(name => [ name, getattr(this, name) ])
2777
+ return names.map(name => [name, getattr(this, name)])
2678
2778
  }
2679
2779
 
2680
2780
  // ==================================
2681
2781
  // Optional/Positional adding methods
2682
2782
  // ==================================
2683
- add_subparsers() {
2684
- let [
2783
+ add_subparsers () {
2784
+ const [
2685
2785
  kwargs
2686
2786
  ] = _parse_opts(arguments, {
2687
2787
  '**kwargs': no_default
2688
2788
  })
2689
2789
 
2690
2790
  if (this._subparsers !== undefined) {
2691
- this.error('cannot have multiple subparser arguments')
2791
+ throw new TypeError('cannot have multiple subparser arguments')
2692
2792
  }
2693
2793
 
2694
2794
  // add the parser class to the arguments if it's not present
2695
2795
  setdefault(kwargs, 'parser_class', this.constructor)
2696
2796
 
2697
2797
  if ('title' in kwargs || 'description' in kwargs) {
2698
- let title = getattr(kwargs, 'title', 'subcommands')
2699
- let description = getattr(kwargs, 'description', undefined)
2798
+ const title = getattr(kwargs, 'title', 'subcommands')
2799
+ const description = getattr(kwargs, 'description', undefined)
2700
2800
  delete kwargs.title
2701
2801
  delete kwargs.description
2702
2802
  this._subparsers = this.add_argument_group(title, description)
@@ -2707,24 +2807,32 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2707
2807
  // prog defaults to the usage message of this parser, skipping
2708
2808
  // optional arguments and with no "usage:" prefix
2709
2809
  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, '')
2810
+ // Create formatter without color to avoid storing ANSI codes in prog
2811
+ // eslint-disable-next-line new-cap
2812
+ const formatter = new this.formatter_class({ prog: this.prog })
2813
+ formatter._set_color(false)
2814
+ const positionals = this._get_positional_actions()
2815
+ const groups = this._mutually_exclusive_groups
2816
+ formatter.add_usage(undefined, positionals, groups, '')
2714
2817
  kwargs.prog = formatter.format_help().trim()
2715
2818
  }
2716
2819
 
2717
2820
  // create the parsers action and add it to the positionals list
2718
- let parsers_class = this._pop_action_class(kwargs, 'parsers')
2821
+ const parsers_class = this._pop_action_class(kwargs, 'parsers')
2822
+ if (hasattr(kwargs, 'option_strings')) {
2823
+ throw new TypeError("add_subparsers() got multiple values for argument 'option_strings'")
2824
+ }
2719
2825
  // eslint-disable-next-line new-cap
2720
- let action = new parsers_class(Object.assign({ option_strings: [] }, kwargs))
2826
+ const action = new parsers_class(Object.assign({ option_strings: [] }, kwargs))
2827
+ action._color = this.color
2828
+ this._check_help(action)
2721
2829
  this._subparsers._add_action(action)
2722
2830
 
2723
2831
  // return the created parsers action
2724
2832
  return action
2725
2833
  }
2726
2834
 
2727
- _add_action(action) {
2835
+ _add_action (action) {
2728
2836
  if (action.option_strings.length) {
2729
2837
  this._optionals._add_action(action)
2730
2838
  } else {
@@ -2733,30 +2841,40 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2733
2841
  return action
2734
2842
  }
2735
2843
 
2736
- _get_optional_actions() {
2844
+ _get_optional_actions () {
2737
2845
  return this._actions.filter(action => action.option_strings.length)
2738
2846
  }
2739
2847
 
2740
- _get_positional_actions() {
2848
+ _get_positional_actions () {
2741
2849
  return this._actions.filter(action => !action.option_strings.length)
2742
2850
  }
2743
2851
 
2744
2852
  // =====================================
2745
2853
  // Command line argument parsing methods
2746
2854
  // =====================================
2747
- parse_args(args = undefined, namespace = undefined) {
2855
+ parse_args (args = undefined, namespace = undefined) {
2748
2856
  let argv
2749
- [ args, argv ] = this.parse_known_args(args, namespace)
2857
+ [args, argv] = this.parse_known_args(args, namespace)
2750
2858
  if (argv && argv.length > 0) {
2751
- let msg = 'unrecognized arguments: %s'
2752
- this.error(sub(msg, argv.join(' ')))
2859
+ const msg = sub('unrecognized arguments: %s', argv.join(' '))
2860
+ if (this.exit_on_error) {
2861
+ this.error(msg)
2862
+ } else {
2863
+ throw new ArgumentError(undefined, msg)
2864
+ }
2753
2865
  }
2754
2866
  return args
2755
2867
  }
2756
2868
 
2757
- parse_known_args(args = undefined, namespace = undefined) {
2869
+ parse_known_args (args = undefined, namespace = undefined) {
2870
+ return this._parse_known_args2(args, namespace, false)
2871
+ }
2872
+
2873
+ _parse_known_args2 (args, namespace, intermixed) {
2758
2874
  if (args === undefined) {
2759
2875
  args = get_argv().slice(1)
2876
+ } else {
2877
+ args = Array.from(args)
2760
2878
  }
2761
2879
 
2762
2880
  // default Namespace built from parser defaults
@@ -2765,7 +2883,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2765
2883
  }
2766
2884
 
2767
2885
  // add any action defaults that aren't present
2768
- for (let action of this._actions) {
2886
+ for (const action of this._actions) {
2769
2887
  if (action.dest !== SUPPRESS) {
2770
2888
  if (!hasattr(namespace, action.dest)) {
2771
2889
  if (action.default !== SUPPRESS) {
@@ -2776,7 +2894,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2776
2894
  }
2777
2895
 
2778
2896
  // add any parser defaults that aren't present
2779
- for (let dest of Object.keys(this._defaults)) {
2897
+ for (const dest of Object.keys(this._defaults)) {
2780
2898
  if (!hasattr(namespace, dest)) {
2781
2899
  setattr(namespace, dest, this._defaults[dest])
2782
2900
  }
@@ -2785,7 +2903,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2785
2903
  // parse the arguments and exit if there are any errors
2786
2904
  if (this.exit_on_error) {
2787
2905
  try {
2788
- [ namespace, args ] = this._parse_known_args(args, namespace)
2906
+ [namespace, args] = this._parse_known_args(args, namespace, intermixed)
2789
2907
  } catch (err) {
2790
2908
  if (err instanceof ArgumentError) {
2791
2909
  this.error(err.message)
@@ -2794,7 +2912,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2794
2912
  }
2795
2913
  }
2796
2914
  } else {
2797
- [ namespace, args ] = this._parse_known_args(args, namespace)
2915
+ [namespace, args] = this._parse_known_args(args, namespace, intermixed)
2798
2916
  }
2799
2917
 
2800
2918
  if (hasattr(namespace, _UNRECOGNIZED_ARGS_ATTR)) {
@@ -2802,10 +2920,10 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2802
2920
  delattr(namespace, _UNRECOGNIZED_ARGS_ATTR)
2803
2921
  }
2804
2922
 
2805
- return [ namespace, args ]
2923
+ return [namespace, args]
2806
2924
  }
2807
2925
 
2808
- _parse_known_args(arg_strings, namespace) {
2926
+ _parse_known_args (arg_strings, namespace, intermixed) {
2809
2927
  // replace arg strings that are file references
2810
2928
  if (this.fromfile_prefix_chars !== undefined) {
2811
2929
  arg_strings = this._read_args_from_files(arg_strings)
@@ -2813,10 +2931,10 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2813
2931
 
2814
2932
  // map all mutually exclusive arguments to the other arguments
2815
2933
  // 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)) {
2934
+ const action_conflicts = new Map()
2935
+ for (const mutex_group of this._mutually_exclusive_groups) {
2936
+ const group_actions = mutex_group._group_actions
2937
+ for (const [i, mutex_action] of Object.entries(mutex_group._group_actions)) {
2820
2938
  let conflicts = action_conflicts.get(mutex_action) || []
2821
2939
  conflicts = conflicts.concat(group_actions.slice(0, +i))
2822
2940
  conflicts = conflicts.concat(group_actions.slice(+i + 1))
@@ -2827,27 +2945,27 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2827
2945
  // find all option indices, and determine the arg_string_pattern
2828
2946
  // which has an 'O' if there is an option at an index,
2829
2947
  // 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) {
2948
+ const option_string_indices = {}
2949
+ const arg_string_pattern_parts = []
2950
+ const arg_strings_iter = Object.entries(arg_strings)[Symbol.iterator]()
2951
+ for (let [i, arg_string] of arg_strings_iter) {
2834
2952
 
2835
2953
  // all args after -- are non-options
2836
2954
  if (arg_string === '--') {
2837
2955
  arg_string_pattern_parts.push('-')
2838
- for ([ i, arg_string ] of arg_strings_iter) {
2956
+ for ([i, arg_string] of arg_strings_iter) {
2839
2957
  arg_string_pattern_parts.push('A')
2840
2958
  }
2841
2959
 
2842
2960
  // otherwise, add the arg to the arg strings
2843
2961
  // and note the index if it was an option
2844
2962
  } else {
2845
- let option_tuple = this._parse_optional(arg_string)
2963
+ const option_tuples = this._parse_optional(arg_string)
2846
2964
  let pattern
2847
- if (option_tuple === undefined) {
2965
+ if (option_tuples === undefined) {
2848
2966
  pattern = 'A'
2849
2967
  } else {
2850
- option_string_indices[i] = option_tuple
2968
+ option_string_indices[i] = option_tuples
2851
2969
  pattern = 'O'
2852
2970
  }
2853
2971
  arg_string_pattern_parts.push(pattern)
@@ -2858,23 +2976,23 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2858
2976
  let arg_strings_pattern = arg_string_pattern_parts.join('')
2859
2977
 
2860
2978
  // 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()
2979
+ const seen_actions = new Set()
2980
+ const seen_non_default_actions = new Set()
2981
+ const warned = new Set()
2863
2982
  let extras
2864
2983
 
2865
- let take_action = (action, argument_strings, option_string = undefined) => {
2984
+ const take_action = (action, argument_strings, option_string = undefined) => {
2866
2985
  seen_actions.add(action)
2867
- let argument_values = this._get_values(action, argument_strings)
2986
+ const argument_values = this._get_values(action, argument_strings)
2868
2987
 
2869
2988
  // 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) {
2989
+ // seen arguments
2990
+ if (action.option_strings.length || argument_strings.length) {
2873
2991
  seen_non_default_actions.add(action)
2874
- for (let conflict_action of action_conflicts.get(action) || []) {
2992
+ for (const conflict_action of action_conflicts.get(action) || []) {
2875
2993
  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)
2994
+ const msg = 'not allowed with argument %s'
2995
+ const action_name = _get_action_name(conflict_action)
2878
2996
  throw new ArgumentError(action, sub(msg, action_name))
2879
2997
  }
2880
2998
  }
@@ -2888,59 +3006,81 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2888
3006
  }
2889
3007
 
2890
3008
  // function to convert arg_strings into an optional action
2891
- let consume_optional = start_index => {
3009
+ const consume_optional = start_index => {
2892
3010
 
2893
3011
  // 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
3012
+ const option_tuples = option_string_indices[start_index]
3013
+ if (option_tuples.length > 1) {
3014
+ const options = option_tuples.map(([, option_string]) => option_string).join(', ')
3015
+ const args = {option: arg_strings[start_index], matches: options}
3016
+ const msg = 'ambiguous option: %(option)s could match %(matches)s'
3017
+ throw new ArgumentError(undefined, sub(msg, args))
3018
+ }
3019
+ let [action, option_string, sep, explicit_arg] = option_tuples[0]
2896
3020
 
2897
3021
  // identify additional optionals in the same arg string
2898
3022
  // (e.g. -xyz is the same as -x -y -z if no args are required)
2899
- let action_tuples = []
3023
+ const action_tuples = []
2900
3024
  let stop
2901
3025
  for (;;) {
2902
3026
 
2903
3027
  // if we found no optional action, skip it
2904
3028
  if (action === undefined) {
2905
3029
  extras.push(arg_strings[start_index])
3030
+ extras_pattern.push('O')
2906
3031
  return start_index + 1
2907
3032
  }
2908
3033
 
2909
3034
  // if there is an explicit argument, try to match the
2910
3035
  // optional's string arguments to only this
2911
3036
  if (explicit_arg !== undefined) {
2912
- let arg_count = this._match_argument(action, 'A')
3037
+ const arg_count = this._match_argument(action, 'A')
2913
3038
 
2914
3039
  // if the action is a single-dash option and takes no
2915
3040
  // arguments, try to parse more single-dash options out
2916
3041
  // 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]
3042
+ const chars = this.prefix_chars
3043
+ if (arg_count === 0 &&
3044
+ !chars.includes(option_string[1]) &&
3045
+ explicit_arg !== '') {
3046
+ if (sep || chars.includes(explicit_arg[0])) {
3047
+ const msg = 'ignored explicit argument %r'
3048
+ throw new ArgumentError(action, sub(msg, explicit_arg))
3049
+ }
3050
+ action_tuples.push([action, [], option_string])
3051
+ const char = option_string[0]
2921
3052
  option_string = char + explicit_arg[0]
2922
- let new_explicit_arg = explicit_arg.slice(1) || undefined
2923
- let optionals_map = this._option_string_actions
3053
+ const optionals_map = this._option_string_actions
2924
3054
  if (hasattr(optionals_map, option_string)) {
2925
3055
  action = optionals_map[option_string]
2926
- explicit_arg = new_explicit_arg
3056
+ explicit_arg = explicit_arg.slice(1)
3057
+ if (!explicit_arg) {
3058
+ sep = explicit_arg = undefined
3059
+ } else if (explicit_arg[0] === '=') {
3060
+ sep = '='
3061
+ explicit_arg = explicit_arg.slice(1)
3062
+ } else {
3063
+ sep = ''
3064
+ }
2927
3065
  } else {
2928
- let msg = 'ignored explicit argument %r'
2929
- throw new ArgumentError(action, sub(msg, explicit_arg))
3066
+ extras.push(char + explicit_arg)
3067
+ extras_pattern.push('O')
3068
+ stop = start_index + 1
3069
+ break
2930
3070
  }
2931
3071
 
2932
3072
  // if the action expect exactly one argument, we've
2933
3073
  // successfully matched the option; exit the loop
2934
3074
  } else if (arg_count === 1) {
2935
3075
  stop = start_index + 1
2936
- let args = [ explicit_arg ]
2937
- action_tuples.push([ action, args, option_string ])
3076
+ const args = [explicit_arg]
3077
+ action_tuples.push([action, args, option_string])
2938
3078
  break
2939
3079
 
2940
3080
  // error if a double-dash option did not use the
2941
3081
  // explicit argument
2942
3082
  } else {
2943
- let msg = 'ignored explicit argument %r'
3083
+ const msg = 'ignored explicit argument %r'
2944
3084
  throw new ArgumentError(action, sub(msg, explicit_arg))
2945
3085
  }
2946
3086
 
@@ -2948,12 +3088,12 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2948
3088
  // optional's string arguments with the following strings
2949
3089
  // if successful, exit the loop
2950
3090
  } 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)
3091
+ const start = start_index + 1
3092
+ const selected_patterns = arg_strings_pattern.slice(start)
3093
+ const arg_count = this._match_argument(action, selected_patterns)
2954
3094
  stop = start + arg_count
2955
- let args = arg_strings.slice(start, stop)
2956
- action_tuples.push([ action, args, option_string ])
3095
+ const args = arg_strings.slice(start, stop)
3096
+ action_tuples.push([action, args, option_string])
2957
3097
  break
2958
3098
  }
2959
3099
  }
@@ -2961,7 +3101,13 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2961
3101
  // add the Optional to the list and return the index at which
2962
3102
  // the Optional's string args stopped
2963
3103
  assert(action_tuples.length)
2964
- for (let [ action, args, option_string ] of action_tuples) {
3104
+ for (const [action, args, option_string] of action_tuples) {
3105
+ if (action.deprecated && !warned.has(option_string)) {
3106
+ this._warning(sub("option '%(option)s' is deprecated", {
3107
+ option: option_string
3108
+ }))
3109
+ warned.add(option_string)
3110
+ }
2965
3111
  take_action(action, args, option_string)
2966
3112
  }
2967
3113
  return stop
@@ -2972,18 +3118,35 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2972
3118
  let positionals = this._get_positional_actions()
2973
3119
 
2974
3120
  // function to convert arg_strings into positional actions
2975
- let consume_positionals = start_index => {
3121
+ const consume_positionals = start_index => {
2976
3122
  // 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)
3123
+ const selected_pattern = arg_strings_pattern.slice(start_index)
3124
+ const arg_counts = this._match_arguments_partial(positionals, selected_pattern)
2979
3125
 
2980
3126
  // slice off the appropriate arg strings for each Positional
2981
3127
  // and add the Positional and its args to the list
2982
3128
  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)
3129
+ const action = positionals[i]
3130
+ const arg_count = arg_counts[i]
3131
+ const args = arg_strings.slice(start_index, start_index + arg_count)
3132
+ // Strip out the first '--' if it is not in REMAINDER arg.
3133
+ if (action.nargs === PARSER) {
3134
+ if (arg_strings_pattern[start_index] === '-') {
3135
+ assert(args[0] === '--')
3136
+ _array_remove(args, '--')
3137
+ }
3138
+ } else if (action.nargs !== REMAINDER) {
3139
+ if (arg_strings_pattern.slice(start_index, start_index + arg_count).includes('-')) {
3140
+ _array_remove(args, '--')
3141
+ }
3142
+ }
2986
3143
  start_index += arg_count
3144
+ if (args.length && action.deprecated && !warned.has(action.dest)) {
3145
+ this._warning(sub("argument '%(argument_name)s' is deprecated", {
3146
+ argument_name: action.dest
3147
+ }))
3148
+ warned.add(action.dest)
3149
+ }
2987
3150
  take_action(action, args)
2988
3151
  }
2989
3152
 
@@ -2996,17 +3159,21 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
2996
3159
  // consume Positionals and Optionals alternately, until we have
2997
3160
  // passed the last option string
2998
3161
  extras = []
3162
+ let extras_pattern = []
2999
3163
  let start_index = 0
3000
- let max_option_string_index = Math.max(-1, ...Object.keys(option_string_indices).map(Number))
3164
+ const max_option_string_index = Math.max(-1, ...Object.keys(option_string_indices).map(Number))
3001
3165
  while (start_index <= max_option_string_index) {
3002
3166
 
3003
3167
  // 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)
3168
+ let next_option_string_index = start_index
3169
+ while (next_option_string_index <= max_option_string_index) {
3170
+ if (next_option_string_index in option_string_indices) {
3171
+ break
3172
+ }
3173
+ next_option_string_index += 1
3174
+ }
3175
+ if (!intermixed && start_index !== next_option_string_index) {
3176
+ const positionals_end_index = consume_positionals(start_index)
3010
3177
 
3011
3178
  // only try to parse the next optional if we didn't consume
3012
3179
  // the option string during the positionals parsing
@@ -3021,8 +3188,10 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3021
3188
  // if we consumed all the positionals we could and we're not
3022
3189
  // at the index of an option string, there were extra arguments
3023
3190
  if (!(start_index in option_string_indices)) {
3024
- let strings = arg_strings.slice(start_index, next_option_string_index)
3191
+ const strings = arg_strings.slice(start_index, next_option_string_index)
3025
3192
  extras = extras.concat(strings)
3193
+ extras_pattern = extras_pattern.concat(
3194
+ arg_strings_pattern.slice(start_index, next_option_string_index).split(''))
3026
3195
  start_index = next_option_string_index
3027
3196
  }
3028
3197
 
@@ -3030,16 +3199,37 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3030
3199
  start_index = consume_optional(start_index)
3031
3200
  }
3032
3201
 
3033
- // consume any positionals following the last Optional
3034
- let stop_index = consume_positionals(start_index)
3202
+ if (!intermixed) {
3203
+ // consume any positionals following the last Optional
3204
+ const stop_index = consume_positionals(start_index)
3035
3205
 
3036
- // if we didn't consume all the argument strings, there were extras
3037
- extras = extras.concat(arg_strings.slice(stop_index))
3206
+ // if we didn't consume all the argument strings, there were extras
3207
+ extras = extras.concat(arg_strings.slice(stop_index))
3208
+ } else {
3209
+ extras = extras.concat(arg_strings.slice(start_index))
3210
+ extras_pattern = extras_pattern.concat(
3211
+ arg_strings_pattern.slice(start_index).split(''))
3212
+ extras_pattern = extras_pattern.join('')
3213
+ assert(extras_pattern.length === extras.length)
3214
+ // consume all positionals
3215
+ arg_strings = extras.filter((string, i) => extras_pattern[i] !== 'O')
3216
+ arg_strings_pattern = extras_pattern.replace(/O/g, '')
3217
+ let stop_index = consume_positionals(0)
3218
+ // leave unknown optionals and non-consumed positionals in extras
3219
+ for (let i = 0; i < extras_pattern.length; i++) {
3220
+ if (!stop_index) break
3221
+ if (extras_pattern[i] !== 'O') {
3222
+ stop_index -= 1
3223
+ extras[i] = undefined
3224
+ }
3225
+ }
3226
+ extras = extras.filter(string => string !== undefined)
3227
+ }
3038
3228
 
3039
3229
  // make sure all required actions were present and also convert
3040
3230
  // action defaults which were not given as arguments
3041
- let required_actions = []
3042
- for (let action of this._actions) {
3231
+ const required_actions = []
3232
+ for (const action of this._actions) {
3043
3233
  if (!seen_actions.has(action)) {
3044
3234
  if (action.required) {
3045
3235
  required_actions.push(_get_action_name(action))
@@ -3060,15 +3250,15 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3060
3250
  }
3061
3251
 
3062
3252
  if (required_actions.length) {
3063
- this.error(sub('the following arguments are required: %s',
3064
- required_actions.join(', ')))
3253
+ throw new ArgumentError(undefined,
3254
+ sub('the following arguments are required: %s', required_actions.join(', ')))
3065
3255
  }
3066
3256
 
3067
3257
  // make sure all required groups had one option present
3068
- for (let group of this._mutually_exclusive_groups) {
3258
+ for (const group of this._mutually_exclusive_groups) {
3069
3259
  if (group.required) {
3070
3260
  let no_actions_used = true
3071
- for (let action of group._group_actions) {
3261
+ for (const action of group._group_actions) {
3072
3262
  if (seen_non_default_actions.has(action)) {
3073
3263
  no_actions_used = false
3074
3264
  break
@@ -3077,23 +3267,23 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3077
3267
 
3078
3268
  // if no actions were used, report the error
3079
3269
  if (no_actions_used) {
3080
- let names = group._group_actions
3270
+ const names = group._group_actions
3081
3271
  .filter(action => action.help !== SUPPRESS)
3082
3272
  .map(action => _get_action_name(action))
3083
- let msg = 'one of the arguments %s is required'
3084
- this.error(sub(msg, names.join(' ')))
3273
+ const msg = 'one of the arguments %s is required'
3274
+ throw new ArgumentError(undefined, sub(msg, names.join(' ')))
3085
3275
  }
3086
3276
  }
3087
3277
  }
3088
3278
 
3089
3279
  // return the updated namespace and the extra arguments
3090
- return [ namespace, extras ]
3280
+ return [namespace, extras]
3091
3281
  }
3092
3282
 
3093
- _read_args_from_files(arg_strings) {
3283
+ _read_args_from_files (arg_strings) {
3094
3284
  // expand arguments referencing files
3095
3285
  let new_arg_strings = []
3096
- for (let arg_string of arg_strings) {
3286
+ for (const arg_string of arg_strings) {
3097
3287
 
3098
3288
  // for regular arguments, just add them back into the list
3099
3289
  if (!arg_string || !this.fromfile_prefix_chars.includes(arg_string[0])) {
@@ -3101,19 +3291,20 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3101
3291
 
3102
3292
  // replace arguments referencing files with the file content
3103
3293
  } else {
3294
+ let args_file
3104
3295
  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)
3296
+ args_file = fs.readFileSync(arg_string.slice(1), 'utf8')
3114
3297
  } catch (err) {
3115
- this.error(err.message)
3298
+ throw new ArgumentError(undefined, err.message)
3116
3299
  }
3300
+ let arg_strings = []
3301
+ for (const arg_line of splitlines(args_file)) {
3302
+ for (const arg of this.convert_arg_line_to_args(arg_line)) {
3303
+ arg_strings.push(arg)
3304
+ }
3305
+ }
3306
+ arg_strings = this._read_args_from_files(arg_strings)
3307
+ new_arg_strings = new_arg_strings.concat(arg_strings)
3117
3308
  }
3118
3309
  }
3119
3310
 
@@ -3121,18 +3312,18 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3121
3312
  return new_arg_strings
3122
3313
  }
3123
3314
 
3124
- convert_arg_line_to_args(arg_line) {
3315
+ convert_arg_line_to_args (arg_line) {
3125
3316
  return [arg_line]
3126
3317
  }
3127
3318
 
3128
- _match_argument(action, arg_strings_pattern) {
3319
+ _match_argument (action, arg_strings_pattern) {
3129
3320
  // 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))
3321
+ const nargs_pattern = this._get_nargs_pattern(action)
3322
+ const match = arg_strings_pattern.match(new RegExp('^' + nargs_pattern))
3132
3323
 
3133
3324
  // raise an exception if we weren't able to find a match
3134
3325
  if (match === null) {
3135
- let nargs_errors = {
3326
+ const nargs_errors = {
3136
3327
  undefined: 'expected one argument',
3137
3328
  [OPTIONAL]: 'expected at most one argument',
3138
3329
  [ONE_OR_MORE]: 'expected at least one argument'
@@ -3148,25 +3339,28 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3148
3339
  return match[1].length
3149
3340
  }
3150
3341
 
3151
- _match_arguments_partial(actions, arg_strings_pattern) {
3342
+ _match_arguments_partial (actions, arg_strings_pattern) {
3152
3343
  // progressively shorten the actions list by slicing off the
3153
3344
  // 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))
3345
+ for (const i of range(actions.length, 0, -1)) {
3346
+ const actions_slice = actions.slice(0, i)
3347
+ const pattern = actions_slice.map(action => this._get_nargs_pattern(action)).join('')
3348
+ const match = arg_strings_pattern.match(new RegExp('^' + pattern))
3159
3349
  if (match !== null) {
3160
- result = result.concat(match.slice(1).map(string => string.length))
3161
- break
3350
+ const result = match.slice(1).map(string => string.length)
3351
+ if (match[0].length < arg_strings_pattern.length &&
3352
+ arg_strings_pattern[match[0].length] === 'O') {
3353
+ while (result.length && !result[result.length - 1]) {
3354
+ result.pop()
3355
+ }
3356
+ }
3357
+ return result
3162
3358
  }
3163
3359
  }
3164
-
3165
- // return the list of arg string counts
3166
- return result
3360
+ return []
3167
3361
  }
3168
3362
 
3169
- _parse_optional(arg_string) {
3363
+ _parse_optional (arg_string) {
3170
3364
  // if it's an empty string, it was meant to be a positional
3171
3365
  if (!arg_string) {
3172
3366
  return undefined
@@ -3179,8 +3373,8 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3179
3373
 
3180
3374
  // if the option string is present in the parser, return the action
3181
3375
  if (arg_string in this._option_string_actions) {
3182
- let action = this._option_string_actions[arg_string]
3183
- return [ action, arg_string, undefined ]
3376
+ const action = this._option_string_actions[arg_string]
3377
+ return [[action, arg_string, undefined, undefined]]
3184
3378
  }
3185
3379
 
3186
3380
  // if it's just a single character, it was meant to be positional
@@ -3190,29 +3384,20 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3190
3384
 
3191
3385
  // if the option string before the "=" is present, return the action
3192
3386
  if (arg_string.includes('=')) {
3193
- let [ option_string, explicit_arg ] = _string_split(arg_string, '=', 1)
3387
+ const [option_string, explicit_arg] = _string_split(arg_string, '=', 1)
3194
3388
  if (option_string in this._option_string_actions) {
3195
- let action = this._option_string_actions[option_string]
3196
- return [ action, option_string, explicit_arg ]
3389
+ const action = this._option_string_actions[option_string]
3390
+ return [[action, option_string, '=', explicit_arg]]
3197
3391
  }
3198
3392
  }
3199
3393
 
3200
3394
  // search through all possible prefixes of the option string
3201
3395
  // 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))
3396
+ const option_tuples = this._get_option_tuples(arg_string)
3210
3397
 
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
3398
+ // if at least one action matched, return the options
3399
+ if (option_tuples.length) {
3400
+ return option_tuples
3216
3401
  }
3217
3402
 
3218
3403
  // if it was not found as an option, but it looks like a negative
@@ -3231,28 +3416,30 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3231
3416
 
3232
3417
  // it was meant to be an optional but there is no such option
3233
3418
  // in this parser (though it might be a valid option in a subparser)
3234
- return [ undefined, arg_string, undefined ]
3419
+ return [[undefined, arg_string, undefined, undefined]]
3235
3420
  }
3236
3421
 
3237
- _get_option_tuples(option_string) {
3238
- let result = []
3422
+ _get_option_tuples (option_string) {
3423
+ const result = []
3239
3424
 
3240
3425
  // option strings starting with two prefix characters are only
3241
3426
  // split at the '='
3242
- let chars = this.prefix_chars
3427
+ const chars = this.prefix_chars
3243
3428
  if (chars.includes(option_string[0]) && chars.includes(option_string[1])) {
3244
3429
  if (this.allow_abbrev) {
3245
- let option_prefix, explicit_arg
3430
+ let option_prefix, sep, explicit_arg
3246
3431
  if (option_string.includes('=')) {
3247
- [ option_prefix, explicit_arg ] = _string_split(option_string, '=', 1)
3432
+ [option_prefix, explicit_arg] = _string_split(option_string, '=', 1)
3433
+ sep = '='
3248
3434
  } else {
3249
3435
  option_prefix = option_string
3436
+ sep = undefined
3250
3437
  explicit_arg = undefined
3251
3438
  }
3252
- for (let option_string of Object.keys(this._option_string_actions)) {
3439
+ for (const option_string of Object.keys(this._option_string_actions)) {
3253
3440
  if (option_string.startsWith(option_prefix)) {
3254
- let action = this._option_string_actions[option_string]
3255
- let tup = [ action, option_string, explicit_arg ]
3441
+ const action = this._option_string_actions[option_string]
3442
+ const tup = [action, option_string, sep, explicit_arg]
3256
3443
  result.push(tup)
3257
3444
  }
3258
3445
  }
@@ -3262,75 +3449,78 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3262
3449
  // but multiple character options always have to have their argument
3263
3450
  // separate
3264
3451
  } 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)
3452
+ let option_prefix, sep, explicit_arg
3453
+ if (option_string.includes('=')) {
3454
+ [option_prefix, explicit_arg] = _string_split(option_string, '=', 1)
3455
+ sep = '='
3456
+ } else {
3457
+ option_prefix = option_string
3458
+ sep = explicit_arg = undefined
3459
+ }
3460
+ const short_option_prefix = option_string.slice(0, 2)
3461
+ const short_explicit_arg = option_string.slice(2)
3269
3462
 
3270
- for (let option_string of Object.keys(this._option_string_actions)) {
3463
+ for (const option_string of Object.keys(this._option_string_actions)) {
3271
3464
  if (option_string === short_option_prefix) {
3272
- let action = this._option_string_actions[option_string]
3273
- let tup = [ action, option_string, short_explicit_arg ]
3465
+ const action = this._option_string_actions[option_string]
3466
+ const tup = [action, option_string, '', short_explicit_arg]
3274
3467
  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 ]
3468
+ } else if (this.allow_abbrev && option_string.startsWith(option_prefix)) {
3469
+ const action = this._option_string_actions[option_string]
3470
+ const tup = [action, option_string, sep, explicit_arg]
3278
3471
  result.push(tup)
3279
3472
  }
3280
3473
  }
3281
3474
 
3282
3475
  // shouldn't ever get here
3283
3476
  } else {
3284
- this.error(sub('unexpected option string: %s', option_string))
3477
+ throw new ArgumentError(undefined, sub('unexpected option string: %s', option_string))
3285
3478
  }
3286
3479
 
3287
3480
  // return the collected option tuples
3288
3481
  return result
3289
3482
  }
3290
3483
 
3291
- _get_nargs_pattern(action) {
3484
+ _get_nargs_pattern (action) {
3292
3485
  // in all examples below, we have to allow for '--' args
3293
3486
  // which are represented as '-' in the pattern
3294
- let nargs = action.nargs
3487
+ const nargs = action.nargs
3488
+ const option = action.option_strings.length
3295
3489
  let nargs_pattern
3296
3490
 
3297
3491
  // the default (None) is assumed to be a single argument
3298
3492
  if (nargs === undefined) {
3299
- nargs_pattern = '(-*A-*)'
3493
+ nargs_pattern = option ? '([A])' : '(-*A-*)'
3300
3494
 
3301
3495
  // allow zero or one arguments
3302
3496
  } else if (nargs === OPTIONAL) {
3303
- nargs_pattern = '(-*A?-*)'
3497
+ nargs_pattern = option ? '(A?)' : '(-*A?-*)'
3304
3498
 
3305
3499
  // allow zero or more arguments
3306
3500
  } else if (nargs === ZERO_OR_MORE) {
3307
- nargs_pattern = '(-*[A-]*)'
3501
+ nargs_pattern = option ? '(A*)' : '(-*[A-]*)'
3308
3502
 
3309
3503
  // allow one or more arguments
3310
3504
  } else if (nargs === ONE_OR_MORE) {
3311
- nargs_pattern = '(-*A[A-]*)'
3505
+ nargs_pattern = option ? '(A+)' : '(-*A[A-]*)'
3312
3506
 
3313
3507
  // allow any number of options or arguments
3314
3508
  } else if (nargs === REMAINDER) {
3315
- nargs_pattern = '([-AO]*)'
3509
+ nargs_pattern = option ? '([AO]*)' : '(.*)'
3316
3510
 
3317
3511
  // allow one argument followed by any number of options or arguments
3318
3512
  } else if (nargs === PARSER) {
3319
- nargs_pattern = '(-*A[-AO]*)'
3513
+ nargs_pattern = option ? '(A[AO]*)' : '(-*A[-AO]*)'
3320
3514
 
3321
3515
  // suppress action, like nargs=0
3322
3516
  } else if (nargs === SUPPRESS) {
3323
- nargs_pattern = '(-*-*)'
3517
+ nargs_pattern = option ? '()' : '(-*)'
3324
3518
 
3325
3519
  // all others should be integers
3326
3520
  } 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, '')
3521
+ nargs_pattern = option
3522
+ ? sub('([AO]{%s})', nargs)
3523
+ : sub('((?:-*A){%s}-*)', nargs)
3334
3524
  }
3335
3525
 
3336
3526
  // return the pattern
@@ -3341,17 +3531,21 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3341
3531
  // Alt command line argument parsing, allowing free intermix
3342
3532
  // ========================
3343
3533
 
3344
- parse_intermixed_args(args = undefined, namespace = undefined) {
3534
+ parse_intermixed_args (args = undefined, namespace = undefined) {
3345
3535
  let argv
3346
- [ args, argv ] = this.parse_known_intermixed_args(args, namespace)
3536
+ [args, argv] = this.parse_known_intermixed_args(args, namespace)
3347
3537
  if (argv.length) {
3348
- let msg = 'unrecognized arguments: %s'
3349
- this.error(sub(msg, argv.join(' ')))
3538
+ const msg = sub('unrecognized arguments: %s', argv.join(' '))
3539
+ if (this.exit_on_error) {
3540
+ this.error(msg)
3541
+ } else {
3542
+ throw new ArgumentError(undefined, msg)
3543
+ }
3350
3544
  }
3351
3545
  return args
3352
3546
  }
3353
3547
 
3354
- parse_known_intermixed_args(args = undefined, namespace = undefined) {
3548
+ parse_known_intermixed_args (args = undefined, namespace = undefined) {
3355
3549
  // returns a namespace and list of extras
3356
3550
  //
3357
3551
  // positional can be freely intermixed with optionals. optionals are
@@ -3359,103 +3553,21 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3359
3553
  // are then parsed. If the parser definition is incompatible with the
3360
3554
  // intermixed assumptions (e.g. use of REMAINDER, subparsers) a
3361
3555
  // 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
3556
 
3367
- let extras
3368
- let positionals = this._get_positional_actions()
3369
- let a = positionals.filter(action => [ PARSER, REMAINDER ].includes(action.nargs))
3557
+ const positionals = this._get_positional_actions()
3558
+ const a = positionals.filter(action => [PARSER, REMAINDER].includes(action.nargs))
3370
3559
  if (a.length) {
3371
3560
  throw new TypeError(sub('parse_intermixed_args: positional arg' +
3372
3561
  ' with nargs=%s', a[0].nargs))
3373
3562
  }
3374
3563
 
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 ]
3564
+ return this._parse_known_args2(args, namespace, true)
3446
3565
  }
3447
3566
 
3448
3567
  // ========================
3449
3568
  // Value conversion methods
3450
3569
  // ========================
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
-
3570
+ _get_values (action, arg_strings) {
3459
3571
  let value
3460
3572
  // optional argument produces a default when not present
3461
3573
  if (!arg_strings.length && action.nargs === OPTIONAL) {
@@ -3464,9 +3576,8 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3464
3576
  } else {
3465
3577
  value = action.default
3466
3578
  }
3467
- if (typeof value === 'string') {
3579
+ if (typeof value === 'string' && value !== SUPPRESS) {
3468
3580
  value = this._get_value(action, value)
3469
- this._check_value(action, value)
3470
3581
  }
3471
3582
 
3472
3583
  // when nargs='*' on a positional, if there were no command-line
@@ -3476,13 +3587,12 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3476
3587
  if (action.default !== undefined) {
3477
3588
  value = action.default
3478
3589
  } else {
3479
- value = arg_strings
3590
+ value = []
3480
3591
  }
3481
- this._check_value(action, value)
3482
3592
 
3483
3593
  // single argument or optional argument produces a single value
3484
3594
  } else if (arg_strings.length === 1 && [undefined, OPTIONAL].includes(action.nargs)) {
3485
- let arg_string = arg_strings[0]
3595
+ const arg_string = arg_strings[0]
3486
3596
  value = this._get_value(action, arg_string)
3487
3597
  this._check_value(action, value)
3488
3598
 
@@ -3502,7 +3612,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3502
3612
  // all other types of nargs produce a list
3503
3613
  } else {
3504
3614
  value = arg_strings.map(v => this._get_value(action, v))
3505
- for (let v of value) {
3615
+ for (const v of value) {
3506
3616
  this._check_value(action, v)
3507
3617
  }
3508
3618
  }
@@ -3511,11 +3621,10 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3511
3621
  return value
3512
3622
  }
3513
3623
 
3514
- _get_value(action, arg_string) {
3515
- let type_func = this._registry_get('type', action.type, action.type)
3624
+ _get_value (action, arg_string) {
3625
+ const type_func = this._registry_get('type', action.type, action.type)
3516
3626
  if (typeof type_func !== 'function') {
3517
- let msg = '%r is not callable'
3518
- throw new ArgumentError(action, sub(msg, type_func))
3627
+ throw new TypeError(sub('%r is not callable', type_func))
3519
3628
  }
3520
3629
 
3521
3630
  // convert the value to the appropriate type
@@ -3539,15 +3648,14 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3539
3648
  } catch (err) {
3540
3649
  // ArgumentTypeErrors indicate errors
3541
3650
  if (err instanceof ArgumentTypeError) {
3542
- //let name = getattr(action.type, 'name', repr(action.type))
3543
- let msg = err.message
3651
+ const msg = err.message
3544
3652
  throw new ArgumentError(action, msg)
3545
3653
 
3546
3654
  // TypeErrors or ValueErrors also indicate errors
3547
3655
  } 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'
3656
+ const name = getattr(action.type, 'name', repr(action.type))
3657
+ const args = {type: name, value: arg_string}
3658
+ const msg = 'invalid %(type)s value: %(value)r'
3551
3659
  throw new ArgumentError(action, sub(msg, args))
3552
3660
  } else {
3553
3661
  throw err
@@ -3558,28 +3666,44 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3558
3666
  return result
3559
3667
  }
3560
3668
 
3561
- _check_value(action, value) {
3669
+ _check_value (action, value) {
3562
3670
  // 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))
3671
+ if (action.choices === undefined) return
3672
+
3673
+ const choices = _choices_to_array(action.choices)
3674
+ if (choices.includes(value)) return
3675
+
3676
+ const args = {value: String(value),
3677
+ choices: choices.map(choice => repr(String(choice))).join(', ')}
3678
+ let msg = 'invalid choice: %(value)r (choose from %(choices)s)'
3679
+
3680
+ if (this.suggest_on_error && typeof value === 'string') {
3681
+ if (choices.every(choice => typeof choice === 'string')) {
3682
+ const { get_close_matches } = require('./difflib')
3683
+ const suggestions = get_close_matches(value, choices, 1)
3684
+ if (suggestions.length) {
3685
+ args.closest = suggestions[0]
3686
+ msg = 'invalid choice: %(value)r, maybe you meant %(closest)r? ' +
3687
+ '(choose from %(choices)s)'
3688
+ }
3689
+ }
3568
3690
  }
3691
+
3692
+ throw new ArgumentError(action, sub(msg, args))
3569
3693
  }
3570
3694
 
3571
3695
  // =======================
3572
3696
  // Help-formatting methods
3573
3697
  // =======================
3574
- format_usage() {
3575
- let formatter = this._get_formatter()
3698
+ format_usage () {
3699
+ const formatter = this._get_formatter()
3576
3700
  formatter.add_usage(this.usage, this._actions,
3577
3701
  this._mutually_exclusive_groups)
3578
3702
  return formatter.format_help()
3579
3703
  }
3580
3704
 
3581
- format_help() {
3582
- let formatter = this._get_formatter()
3705
+ format_help () {
3706
+ const formatter = this._get_formatter()
3583
3707
 
3584
3708
  // usage
3585
3709
  formatter.add_usage(this.usage, this._actions,
@@ -3589,7 +3713,7 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3589
3713
  formatter.add_text(this.description)
3590
3714
 
3591
3715
  // positionals, optionals and user-defined groups
3592
- for (let action_group of this._action_groups) {
3716
+ for (const action_group of this._action_groups) {
3593
3717
  formatter.start_section(action_group.title)
3594
3718
  formatter.add_text(action_group.description)
3595
3719
  formatter.add_arguments(action_group._group_actions)
@@ -3603,42 +3727,55 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3603
3727
  return formatter.format_help()
3604
3728
  }
3605
3729
 
3606
- _get_formatter() {
3730
+ _get_formatter () {
3607
3731
  // eslint-disable-next-line new-cap
3608
- return new this.formatter_class({ prog: this.prog })
3732
+ const formatter = new this.formatter_class({ prog: this.prog })
3733
+ formatter._set_color(this.color)
3734
+ return formatter
3735
+ }
3736
+
3737
+ _get_validation_formatter () {
3738
+ // Return cached formatter for read-only validation operations
3739
+ // (_expand_help and _format_args). Avoids repeated slow _set_color calls.
3740
+ if (this._cached_formatter === undefined) {
3741
+ this._cached_formatter = this._get_formatter()
3742
+ }
3743
+ return this._cached_formatter
3609
3744
  }
3610
3745
 
3611
3746
  // =====================
3612
3747
  // Help-printing methods
3613
3748
  // =====================
3614
- print_usage(file = undefined) {
3749
+ print_usage (file = undefined) {
3615
3750
  if (file === undefined) file = process.stdout
3616
3751
  this._print_message(this.format_usage(), file)
3617
3752
  }
3618
3753
 
3619
- print_help(file = undefined) {
3754
+ print_help (file = undefined) {
3620
3755
  if (file === undefined) file = process.stdout
3621
3756
  this._print_message(this.format_help(), file)
3622
3757
  }
3623
3758
 
3624
- _print_message(message, file = undefined) {
3759
+ _print_message (message, file = undefined) {
3625
3760
  if (message) {
3626
- if (file === undefined) file = process.stderr
3627
- file.write(message)
3761
+ file = file || process.stderr
3762
+ if (file && typeof file.write === 'function') {
3763
+ file.write(message)
3764
+ }
3628
3765
  }
3629
3766
  }
3630
3767
 
3631
3768
  // ===============
3632
3769
  // Exiting methods
3633
3770
  // ===============
3634
- exit(status = 0, message = undefined) {
3771
+ exit (status = 0, message = undefined) {
3635
3772
  if (message) {
3636
3773
  this._print_message(message, process.stderr)
3637
3774
  }
3638
3775
  process.exit(status)
3639
3776
  }
3640
3777
 
3641
- error(message) {
3778
+ error (message) {
3642
3779
  /*
3643
3780
  * error(message: string)
3644
3781
  *
@@ -3649,14 +3786,16 @@ const ArgumentParser = _camelcase_alias(_callable(class ArgumentParser extends _
3649
3786
  * should either exit or raise an exception.
3650
3787
  */
3651
3788
 
3652
- // LEGACY (v1 compatibility), debug mode
3653
- if (this.debug === true) throw new Error(message)
3654
- // end
3655
3789
  this.print_usage(process.stderr)
3656
- let args = {prog: this.prog, message: message}
3790
+ const args = {prog: this.prog, message}
3657
3791
  this.exit(2, sub('%(prog)s: error: %(message)s\n', args))
3658
3792
  }
3659
- }))
3793
+
3794
+ _warning (message) {
3795
+ const args = { prog: this.prog, message }
3796
+ this._print_message(sub('%(prog)s: warning: %(message)s\n', args), process.stderr)
3797
+ }
3798
+ })
3660
3799
 
3661
3800
 
3662
3801
  module.exports = {
@@ -3679,29 +3818,3 @@ module.exports = {
3679
3818
  SUPPRESS,
3680
3819
  ZERO_OR_MORE
3681
3820
  }
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