Brunobkr/llama.cpp_AlgMor24_github
ΩFFFΣLLIa • llama.cpp • AlgMor24 ██████╗ ███████╗███████╗███████╗██╗ ██╗ ██╗ █████╗ ██╔═══██╗██╔════╝██╔════╝██╔════╝██║ ██║ ██║██╔══██╗ ██║ ██║█████╗ █████╗ █████╗ ██║ ██║ ██║███████║ ██║ ██║██╔══╝ ██╔══╝ ██╔══╝ ██║ ██║ ██║██╔══██║ ╚██████╔╝██║ ██║ ███████╗███████╗███████╗██║██║ ██║ ╚═════╝ ╚═╝ ╚═╝ ╚══════╝╚══════╝╚══════╝╚═╝╚═╝ ╚═╝ High-Performance LLM / VLM Inference & Autonomous Agentic Ecosystem… See the full description on the dataset page: https://huggingface.co/datasets/Brunobkr/llama.cpp_AlgMor24_github.
03k
1// Port of python's argparse module, version 3.9.0:2// https://github.com/python/cpython/blob/v3.9.0rc1/Lib/argparse.py3 4'use strict'5 6// Copyright (C) 2010-2020 Python Software Foundation.7// Copyright (C) 2020 argparse.js authors8 9/*10 * Command-line parsing library11 *12 * This module is an optparse-inspired command-line parsing library that:13 *14 * - handles both optional and positional arguments15 * - produces highly informative usage messages16 * - supports parsers that dispatch to sub-parsers17 *18 * The following is a simple usage example that sums integers from the19 * command-line and writes the result to a file::20 *21 * parser = argparse.ArgumentParser(22 * description='sum the integers at the command line')23 * parser.add_argument(24 * 'integers', metavar='int', nargs='+', type=int,25 * help='an integer to be summed')26 * parser.add_argument(27 * '--log', default=sys.stdout, type=argparse.FileType('w'),28 * help='the file where the sum should be written')29 * args = parser.parse_args()30 * args.log.write('%s' % sum(args.integers))31 * args.log.close()32 *33 * The module contains the following public classes:34 *35 * - ArgumentParser -- The main entry point for command-line parsing. As the36 * example above shows, the add_argument() method is used to populate37 * the parser with actions for optional and positional arguments. Then38 * the parse_args() method is invoked to convert the args at the39 * command-line into an object with attributes.40 *41 * - ArgumentError -- The exception raised by ArgumentParser objects when42 * there are errors with the parser's actions. Errors raised while43 * parsing the command-line are caught by ArgumentParser and emitted44 * as command-line messages.45 *46 * - FileType -- A factory for defining types of files to be created. As the47 * example above shows, instances of FileType are typically passed as48 * the type= argument of add_argument() calls.49 *50 * - Action -- The base class for parser actions. Typically actions are51 * selected by passing strings like 'store_true' or 'append_const' to52 * the action= argument of add_argument(). However, for greater53 * customization of ArgumentParser actions, subclasses of Action may54 * be defined and passed as the action= argument.55 *56 * - HelpFormatter, RawDescriptionHelpFormatter, RawTextHelpFormatter,57 * ArgumentDefaultsHelpFormatter -- Formatter classes which58 * may be passed as the formatter_class= argument to the59 * ArgumentParser constructor. HelpFormatter is the default,60 * RawDescriptionHelpFormatter and RawTextHelpFormatter tell the parser61 * not to change the formatting for help text, and62 * ArgumentDefaultsHelpFormatter adds information about argument defaults63 * to the help.64 *65 * All other classes in this module are considered implementation details.66 * (Also note that HelpFormatter and RawDescriptionHelpFormatter are only67 * considered public as object names -- the API of the formatter objects is68 * still considered an implementation detail.)69 */70 71const SUPPRESS = '==SUPPRESS=='72 73const OPTIONAL = '?'74const ZERO_OR_MORE = '*'75const ONE_OR_MORE = '+'76const PARSER = 'A...'77const REMAINDER = '...'78const _UNRECOGNIZED_ARGS_ATTR = '_unrecognized_args'79 80 81// ==================================82// Utility functions used for porting83// ==================================84const assert = require('assert')85const util = require('util')86const fs = require('fs')87const sub = require('./lib/sub')88const path = require('path')89const repr = util.inspect90 91function get_argv() {92 // omit first argument (which is assumed to be interpreter - `node`, `coffee`, `ts-node`, etc.)93 return process.argv.slice(1)94}95 96function get_terminal_size() {97 return {98 columns: +process.env.COLUMNS || process.stdout.columns || 8099 }100}101 102function hasattr(object, name) {103 return Object.prototype.hasOwnProperty.call(object, name)104}105 106function getattr(object, name, value) {107 return hasattr(object, name) ? object[name] : value108}109 110function setattr(object, name, value) {111 object[name] = value112}113 114function setdefault(object, name, value) {115 if (!hasattr(object, name)) object[name] = value116 return object[name]117}118 119function delattr(object, name) {120 delete object[name]121}122 123function range(from, to, step=1) {124 // range(10) is equivalent to range(0, 10)125 if (arguments.length === 1) [ to, from ] = [ from, 0 ]126 if (typeof from !== 'number' || typeof to !== 'number' || typeof step !== 'number') {127 throw new TypeError('argument cannot be interpreted as an integer')128 }129 if (step === 0) throw new TypeError('range() arg 3 must not be zero')130 131 let result = []132 if (step > 0) {133 for (let i = from; i < to; i += step) result.push(i)134 } else {135 for (let i = from; i > to; i += step) result.push(i)136 }137 return result138}139 140function splitlines(str, keepends = false) {141 let result142 if (!keepends) {143 result = str.split(/\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029]/)144 } else {145 result = []146 let parts = str.split(/(\r\n|[\n\r\v\f\x1c\x1d\x1e\x85\u2028\u2029])/)147 for (let i = 0; i < parts.length; i += 2) {148 result.push(parts[i] + (i + 1 < parts.length ? parts[i + 1] : ''))149 }150 }151 if (!result[result.length - 1]) result.pop()152 return result153}154 155function _string_lstrip(string, prefix_chars) {156 let idx = 0157 while (idx < string.length && prefix_chars.includes(string[idx])) idx++158 return idx ? string.slice(idx) : string159}160 161function _string_split(string, sep, maxsplit) {162 let result = string.split(sep)163 if (result.length > maxsplit) {164 result = result.slice(0, maxsplit).concat([ result.slice(maxsplit).join(sep) ])165 }166 return result167}168 169function _array_equal(array1, array2) {170 if (array1.length !== array2.length) return false171 for (let i = 0; i < array1.length; i++) {172 if (array1[i] !== array2[i]) return false173 }174 return true175}176 177function _array_remove(array, item) {178 let idx = array.indexOf(item)179 if (idx === -1) throw new TypeError(sub('%r not in list', item))180 array.splice(idx, 1)181}182 183// normalize choices to array;184// this isn't required in python because `in` and `map` operators work with anything,185// but in js dealing with multiple types here is too clunky186function _choices_to_array(choices) {187 if (choices === undefined) {188 return []189 } else if (Array.isArray(choices)) {190 return choices191 } else if (choices !== null && typeof choices[Symbol.iterator] === 'function') {192 return Array.from(choices)193 } else if (typeof choices === 'object' && choices !== null) {194 return Object.keys(choices)195 } else {196 throw new Error(sub('invalid choices value: %r', choices))197 }198}199 200// decorator that allows a class to be called without new201function _callable(cls) {202 let result = { // object is needed for inferred class name203 [cls.name]: function (...args) {204 let this_class = new.target === result || !new.target205 return Reflect.construct(cls, args, this_class ? cls : new.target)206 }207 }208 result[cls.name].prototype = cls.prototype209 // fix default tag for toString, e.g. [object Action] instead of [object Object]210 cls.prototype[Symbol.toStringTag] = cls.name211 return result[cls.name]212}213 214function _alias(object, from, to) {215 try {216 let name = object.constructor.name217 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: false221 })222 } catch {}223}224 225// decorator that allows snake_case class methods to be called with camelCase and vice versa226function _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 _class232}233 234function _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 key239}240 241function _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 key246}247 248// parse options249let no_default = Symbol('no_default_value')250function _parse_opts(args, descriptor) {251 function get_name() {252 let stack = new Error().stack.split('\n')253 .map(x => x.match(/^ at (.*) \(.*\)$/))254 .filter(Boolean)255 .map(m => m[1])256 .map(fn => fn.match(/[^ .]*$/)[0])257 258 if (stack.length && stack[0] === get_name.name) stack.shift()259 if (stack.length && stack[0] === _parse_opts.name) stack.shift()260 return stack.length ? stack[0] : ''261 }262 263 args = Array.from(args)264 let kwargs = {}265 let result = []266 let last_opt = args.length && args[args.length - 1]267 268 if (typeof last_opt === 'object' && last_opt !== null && !Array.isArray(last_opt) &&269 (!last_opt.constructor || last_opt.constructor.name === 'Object')) {270 kwargs = Object.assign({}, args.pop())271 }272 273 // LEGACY (v1 compatibility): camelcase274 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 tests280 //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 // end294 295 let missing_positionals = []296 let positional_count = args.length297 298 for (let [ key, def ] of Object.entries(descriptor)) {299 if (key[0] === '*') {300 if (key.length > 0 && key[1] === '*') {301 // LEGACY (v1 compatibility): camelcase302 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 tests308 //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 // end322 result.push(kwargs)323 kwargs = {}324 } else {325 result.push(args)326 args = []327 }328 } else if (key in kwargs && args.length > 0) {329 throw new TypeError(sub('%s() got multiple values for argument %r', get_name(), key))330 } else if (key in kwargs) {331 result.push(kwargs[key])332 delete kwargs[key]333 } else if (args.length > 0) {334 result.push(args.shift())335 } else if (def !== no_default) {336 result.push(def)337 } else {338 missing_positionals.push(key)339 }340 }341 342 if (Object.keys(kwargs).length) {343 throw new TypeError(sub('%s() got an unexpected keyword argument %r',344 get_name(), Object.keys(kwargs)[0]))345 }346 347 if (args.length) {348 let from = Object.entries(descriptor).filter(([ k, v ]) => k[0] !== '*' && v !== no_default).length349 let to = Object.entries(descriptor).filter(([ k ]) => k[0] !== '*').length350 throw new TypeError(sub('%s() takes %s positional argument%s but %s %s given',351 get_name(),352 from === to ? sub('from %s to %s', from, to) : to,353 from === to && to === 1 ? '' : 's',354 positional_count,355 positional_count === 1 ? 'was' : 'were'))356 }357 358 if (missing_positionals.length) {359 let strs = missing_positionals.map(repr)360 if (strs.length > 1) strs[strs.length - 1] = 'and ' + strs[strs.length - 1]361 let str_joined = strs.join(strs.length === 2 ? '' : ', ')362 throw new TypeError(sub('%s() missing %i required positional argument%s: %s',363 get_name(), strs.length, strs.length === 1 ? '' : 's', str_joined))364 }365 366 return result367}368 369let _deprecations = {}370function deprecate(id, string) {371 _deprecations[id] = _deprecations[id] || util.deprecate(() => {}, string)372 _deprecations[id]()373}374 375 376// =============================377// Utility functions and classes378// =============================379function _AttributeHolder(cls = Object) {380 /*381 * Abstract base class that provides __repr__.382 *383 * The __repr__ method returns a string in the format::384 * ClassName(attr=name, attr=name, ...)385 * The attributes are determined either by a class-level attribute,386 * '_kwarg_names', or by inspecting the instance __dict__.387 */388 389 return class _AttributeHolder extends cls {390 [util.inspect.custom]() {391 let type_name = this.constructor.name392 let arg_strings = []393 let star_args = {}394 for (let arg of this._get_args()) {395 arg_strings.push(repr(arg))396 }397 for (let [ name, value ] of this._get_kwargs()) {398 if (/^[a-z_][a-z0-9_$]*$/i.test(name)) {399 arg_strings.push(sub('%s=%r', name, value))400 } else {401 star_args[name] = value402 }403 }404 if (Object.keys(star_args).length) {405 arg_strings.push(sub('**%s', repr(star_args)))406 }407 return sub('%s(%s)', type_name, arg_strings.join(', '))408 }409 410 toString() {411 return this[util.inspect.custom]()412 }413 414 _get_kwargs() {415 return Object.entries(this)416 }417 418 _get_args() {419 return []420 }421 }422}423 424 425function _copy_items(items) {426 if (items === undefined) {427 return []428 }429 return items.slice(0)430}431 432 433// ===============434// Formatting Help435// ===============436const HelpFormatter = _camelcase_alias(_callable(class HelpFormatter {437 /*438 * Formatter for generating usage messages and argument help strings.439 *440 * Only the name of this class is considered a public API. All the methods441 * provided by the class are considered an implementation detail.442 */443 444 constructor() {445 let [446 prog,447 indent_increment,448 max_help_position,449 width450 ] = _parse_opts(arguments, {451 prog: no_default,452 indent_increment: 2,453 max_help_position: 24,454 width: undefined455 })456 457 // default setting for width458 if (width === undefined) {459 width = get_terminal_size().columns460 width -= 2461 }462 463 this._prog = prog464 this._indent_increment = indent_increment465 this._max_help_position = Math.min(max_help_position,466 Math.max(width - 20, indent_increment * 2))467 this._width = width468 469 this._current_indent = 0470 this._level = 0471 this._action_max_length = 0472 473 this._root_section = this._Section(this, undefined)474 this._current_section = this._root_section475 476 this._whitespace_matcher = /[ \t\n\r\f\v]+/g // equivalent to python /\s+/ with ASCII flag477 this._long_break_matcher = /\n\n\n+/g478 }479 480 // ===============================481 // Section and indentation methods482 // ===============================483 _indent() {484 this._current_indent += this._indent_increment485 this._level += 1486 }487 488 _dedent() {489 this._current_indent -= this._indent_increment490 assert(this._current_indent >= 0, 'Indent decreased below 0.')491 this._level -= 1492 }493 494 _add_item(func, args) {495 this._current_section.items.push([ func, args ])496 }497 498 // ========================499 // Message building methods500 // ========================501 start_section(heading) {502 this._indent()503 let section = this._Section(this, this._current_section, heading)504 this._add_item(section.format_help.bind(section), [])505 this._current_section = section506 }507 508 end_section() {509 this._current_section = this._current_section.parent510 this._dedent()511 }512 513 add_text(text) {514 if (text !== SUPPRESS && text !== undefined) {515 this._add_item(this._format_text.bind(this), [text])516 }517 }518 519 add_usage(usage, actions, groups, prefix = undefined) {520 if (usage !== SUPPRESS) {521 let args = [ usage, actions, groups, prefix ]522 this._add_item(this._format_usage.bind(this), args)523 }524 }525 526 add_argument(action) {527 if (action.help !== SUPPRESS) {528 529 // find all invocations530 let invocations = [this._format_action_invocation(action)]531 for (let subaction of this._iter_indented_subactions(action)) {532 invocations.push(this._format_action_invocation(subaction))533 }534 535 // update the maximum item length536 let invocation_length = Math.max(...invocations.map(invocation => invocation.length))537 let action_length = invocation_length + this._current_indent538 this._action_max_length = Math.max(this._action_max_length,539 action_length)540 541 // add the item to the list542 this._add_item(this._format_action.bind(this), [action])543 }544 }545 546 add_arguments(actions) {547 for (let action of actions) {548 this.add_argument(action)549 }550 }551 552 // =======================553 // Help-formatting methods554 // =======================555 format_help() {556 let help = this._root_section.format_help()557 if (help) {558 help = help.replace(this._long_break_matcher, '\n\n')559 help = help.replace(/^\n+|\n+$/g, '') + '\n'560 }561 return help562 }563 564 _join_parts(part_strings) {565 return part_strings.filter(part => part && part !== SUPPRESS).join('')566 }567 568 _format_usage(usage, actions, groups, prefix) {569 if (prefix === undefined) {570 prefix = 'usage: '571 }572 573 // if usage is specified, use that574 if (usage !== undefined) {575 usage = sub(usage, { prog: this._prog })576 577 // if no optionals or positionals are available, usage is just prog578 } else if (usage === undefined && !actions.length) {579 usage = sub('%(prog)s', { prog: this._prog })580 581 // if optionals and positionals are available, calculate usage582 } else if (usage === undefined) {583 let prog = sub('%(prog)s', { prog: this._prog })584 585 // split optionals from positionals586 let optionals = []587 let positionals = []588 for (let action of actions) {589 if (action.option_strings.length) {590 optionals.push(action)591 } else {592 positionals.push(action)593 }594 }595 596 // build full usage string597 let action_usage = this._format_actions_usage([].concat(optionals).concat(positionals), groups)598 usage = [ prog, action_usage ].map(String).join(' ')599 600 // wrap the usage parts if it's too long601 let text_width = this._width - this._current_indent602 if (prefix.length + usage.length > text_width) {603 604 // break usage into wrappable parts605 let part_regexp = /\(.*?\)+(?=\s|$)|\[.*?\]+(?=\s|$)|\S+/g606 let opt_usage = this._format_actions_usage(optionals, groups)607 let pos_usage = this._format_actions_usage(positionals, groups)608 let opt_parts = opt_usage.match(part_regexp) || []609 let pos_parts = pos_usage.match(part_regexp) || []610 assert(opt_parts.join(' ') === opt_usage)611 assert(pos_parts.join(' ') === pos_usage)612 613 // helper for wrapping lines614 let get_lines = (parts, indent, prefix = undefined) => {615 let lines = []616 let line = []617 let line_len618 if (prefix !== undefined) {619 line_len = prefix.length - 1620 } else {621 line_len = indent.length - 1622 }623 for (let part of parts) {624 if (line_len + 1 + part.length > text_width && line) {625 lines.push(indent + line.join(' '))626 line = []627 line_len = indent.length - 1628 }629 line.push(part)630 line_len += part.length + 1631 }632 if (line.length) {633 lines.push(indent + line.join(' '))634 }635 if (prefix !== undefined) {636 lines[0] = lines[0].slice(indent.length)637 }638 return lines639 }640 641 let lines642 643 // if prog is short, follow it with optionals or positionals644 if (prefix.length + prog.length <= 0.75 * text_width) {645 let indent = ' '.repeat(prefix.length + prog.length + 1)646 if (opt_parts.length) {647 lines = get_lines([prog].concat(opt_parts), indent, prefix)648 lines = lines.concat(get_lines(pos_parts, indent))649 } else if (pos_parts.length) {650 lines = get_lines([prog].concat(pos_parts), indent, prefix)651 } else {652 lines = [prog]653 }654 655 // if prog is long, put it on its own line656 } else {657 let indent = ' '.repeat(prefix.length)658 let parts = [].concat(opt_parts).concat(pos_parts)659 lines = get_lines(parts, indent)660 if (lines.length > 1) {661 lines = []662 lines = lines.concat(get_lines(opt_parts, indent))663 lines = lines.concat(get_lines(pos_parts, indent))664 }665 lines = [prog].concat(lines)666 }667 668 // join lines into usage669 usage = lines.join('\n')670 }671 }672 673 // prefix with 'usage:'674 return sub('%s%s\n\n', prefix, usage)675 }676 677 _format_actions_usage(actions, groups) {678 // find group indices and identify actions in groups679 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 continue685 } else {686 let end = start + group._group_actions.length687 if (_array_equal(actions.slice(start, end), group._group_actions)) {688 for (let action of group._group_actions) {689 group_actions.add(action)690 }691 if (!group.required) {692 if (start in inserts) {693 inserts[start] += ' ['694 } else {695 inserts[start] = '['696 }697 if (end in inserts) {698 inserts[end] += ']'699 } else {700 inserts[end] = ']'701 }702 } else {703 if (start in inserts) {704 inserts[start] += ' ('705 } else {706 inserts[start] = '('707 }708 if (end in inserts) {709 inserts[end] += ')'710 } else {711 inserts[end] = ')'712 }713 }714 for (let i of range(start + 1, end)) {715 inserts[i] = '|'716 }717 }718 }719 }720 721 // collect all actions format strings722 let parts = []723 for (let [ i, action ] of Object.entries(actions)) {724 725 // suppressed arguments are marked with None726 // remove | separators for suppressed arguments727 if (action.help === SUPPRESS) {728 parts.push(undefined)729 if (inserts[+i] === '|') {730 delete inserts[+i]731 } else if (inserts[+i + 1] === '|') {732 delete inserts[+i + 1]733 }734 735 // produce all arg strings736 } else if (!action.option_strings.length) {737 let default_value = this._get_default_metavar_for_positional(action)738 let part = this._format_args(action, default_value)739 740 // if it's in a group, strip the outer []741 if (group_actions.has(action)) {742 if (part[0] === '[' && part[part.length - 1] === ']') {743 part = part.slice(1, -1)744 }745 }746 747 // add the action string to the list748 parts.push(part)749 750 // produce the first way to invoke the option in brackets751 } else {752 let option_string = action.option_strings[0]753 let part754 755 // if the Optional doesn't take a value, format is:756 // -s or --long757 if (action.nargs === 0) {758 part = action.format_usage()759 760 // if the Optional takes a value, format is:761 // -s ARGS or --long ARGS762 } else {763 let default_value = this._get_default_metavar_for_optional(action)764 let args_string = this._format_args(action, default_value)765 part = sub('%s %s', option_string, args_string)766 }767 768 // make it look optional if it's not required or in a group769 if (!action.required && !group_actions.has(action)) {770 part = sub('[%s]', part)771 }772 773 // add the action string to the list774 parts.push(part)775 }776 }777 778 // insert things at the necessary indices779 for (let i of Object.keys(inserts).map(Number).sort((a, b) => b - a)) {780 parts.splice(+i, 0, inserts[+i])781 }782 783 // join all the action items with spaces784 let text = parts.filter(Boolean).join(' ')785 786 // clean up separators for mutually exclusive groups787 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 text794 return text795 }796 797 _format_text(text) {798 if (text.includes('%(prog)')) {799 text = sub(text, { prog: this._prog })800 }801 let text_width = Math.max(this._width - this._current_indent, 11)802 let indent = ' '.repeat(this._current_indent)803 return this._fill_text(text, text_width, indent) + '\n\n'804 }805 806 _format_action(action) {807 // determine the required width and the entry label808 let help_position = Math.min(this._action_max_length + 2,809 this._max_help_position)810 let help_width = Math.max(this._width - help_position, 11)811 let action_width = help_position - this._current_indent - 2812 let action_header = this._format_action_invocation(action)813 let indent_first814 815 // no help; start on same line and add a final newline816 if (!action.help) {817 let tup = [ this._current_indent, '', action_header ]818 action_header = sub('%*s%s\n', ...tup)819 820 // short action name; start on the same line and pad two spaces821 } else if (action_header.length <= action_width) {822 let tup = [ this._current_indent, '', action_width, action_header ]823 action_header = sub('%*s%-*s ', ...tup)824 indent_first = 0825 826 // long action name; start on the next line827 } else {828 let tup = [ this._current_indent, '', action_header ]829 action_header = sub('%*s%s\n', ...tup)830 indent_first = help_position831 }832 833 // collect the pieces of the action help834 let parts = [action_header]835 836 // if there was help for the action, add lines of help text837 if (action.help) {838 let help_text = this._expand_help(action)839 let help_lines = this._split_lines(help_text, help_width)840 parts.push(sub('%*s%s\n', indent_first, '', help_lines[0]))841 for (let line of help_lines.slice(1)) {842 parts.push(sub('%*s%s\n', help_position, '', line))843 }844 845 // or add a newline if the description doesn't end with one846 } else if (!action_header.endsWith('\n')) {847 parts.push('\n')848 }849 850 // if there are any sub-actions, add their help as well851 for (let subaction of this._iter_indented_subactions(action)) {852 parts.push(this._format_action(subaction))853 }854 855 // return a single string856 return this._join_parts(parts)857 }858 859 _format_action_invocation(action) {860 if (!action.option_strings.length) {861 let default_value = this._get_default_metavar_for_positional(action)862 let metavar = this._metavar_formatter(action, default_value)(1)[0]863 return metavar864 865 } else {866 let parts = []867 868 // if the Optional doesn't take a value, format is:869 // -s, --long870 if (action.nargs === 0) {871 parts = parts.concat(action.option_strings)872 873 // if the Optional takes a value, format is:874 // -s ARGS, --long ARGS875 } else {876 let default_value = this._get_default_metavar_for_optional(action)877 let args_string = this._format_args(action, default_value)878 for (let option_string of action.option_strings) {879 parts.push(sub('%s %s', option_string, args_string))880 }881 }882 883 return parts.join(', ')884 }885 }886 887 _metavar_formatter(action, default_metavar) {888 let result889 if (action.metavar !== undefined) {890 result = action.metavar891 } else if (action.choices !== undefined) {892 let choice_strs = _choices_to_array(action.choices).map(String)893 result = sub('{%s}', choice_strs.join(','))894 } else {895 result = default_metavar896 }897 898 function format(tuple_size) {899 if (Array.isArray(result)) {900 return result901 } else {902 return Array(tuple_size).fill(result)903 }904 }905 return format906 }907 908 _format_args(action, default_metavar) {909 let get_metavar = this._metavar_formatter(action, default_metavar)910 let result911 if (action.nargs === undefined) {912 result = sub('%s', ...get_metavar(1))913 } else if (action.nargs === OPTIONAL) {914 result = sub('[%s]', ...get_metavar(1))915 } else if (action.nargs === ZERO_OR_MORE) {916 let metavar = get_metavar(1)917 if (metavar.length === 2) {918 result = sub('[%s [%s ...]]', ...metavar)919 } else {920 result = sub('[%s ...]', ...metavar)921 }922 } else if (action.nargs === ONE_OR_MORE) {923 result = sub('%s [%s ...]', ...get_metavar(2))924 } else if (action.nargs === REMAINDER) {925 result = '...'926 } else if (action.nargs === PARSER) {927 result = sub('%s ...', ...get_metavar(1))928 } else if (action.nargs === SUPPRESS) {929 result = ''930 } else {931 let formats932 try {933 formats = range(action.nargs).map(() => '%s')934 } catch (err) {935 throw new TypeError('invalid nargs value')936 }937 result = sub(formats.join(' '), ...get_metavar(action.nargs))938 }939 return result940 }941 942 _expand_help(action) {943 let params = Object.assign({ prog: this._prog }, action)944 for (let name of Object.keys(params)) {945 if (params[name] === SUPPRESS) {946 delete params[name]947 }948 }949 for (let name of Object.keys(params)) {950 if (params[name] && params[name].name) {951 params[name] = params[name].name952 }953 }954 if (params.choices !== undefined) {955 let choices_str = _choices_to_array(params.choices).map(String).join(', ')956 params.choices = choices_str957 }958 // LEGACY (v1 compatibility): camelcase959 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 // end966 return sub(this._get_help_string(action), params)967 }968 969 * _iter_indented_subactions(action) {970 if (typeof action._get_subactions === 'function') {971 this._indent()972 yield* action._get_subactions()973 this._dedent()974 }975 }976 977 _split_lines(text, width) {978 text = text.replace(this._whitespace_matcher, ' ').trim()979 // The textwrap module is used only for formatting help.980 // Delay its import for speeding up the common usage of argparse.981 let textwrap = require('./lib/textwrap')982 return textwrap.wrap(text, { width })983 }984 985 _fill_text(text, width, indent) {986 text = text.replace(this._whitespace_matcher, ' ').trim()987 let textwrap = require('./lib/textwrap')988 return textwrap.fill(text, { width,989 initial_indent: indent,990 subsequent_indent: indent })991 }992 993 _get_help_string(action) {994 return action.help995 }996 997 _get_default_metavar_for_optional(action) {998 return action.dest.toUpperCase()999 }1000 1001 _get_default_metavar_for_positional(action) {1002 return action.dest1003 }1004}))1005 1006HelpFormatter.prototype._Section = _callable(class _Section {1007 1008 constructor(formatter, parent, heading = undefined) {1009 this.formatter = formatter1010 this.parent = parent1011 this.heading = heading1012 this.items = []1013 }1014 1015 format_help() {1016 // format the indented section1017 if (this.parent !== undefined) {1018 this.formatter._indent()1019 }1020 let item_help = this.formatter._join_parts(this.items.map(([ func, args ]) => func.apply(null, args)))1021 if (this.parent !== undefined) {1022 this.formatter._dedent()1023 }1024 1025 // return nothing if the section was empty1026 if (!item_help) {1027 return ''1028 }1029 1030 // add the heading if the section was non-empty1031 let heading1032 if (this.heading !== SUPPRESS && this.heading !== undefined) {1033 let current_indent = this.formatter._current_indent1034 heading = sub('%*s%s:\n', current_indent, '', this.heading)1035 } else {1036 heading = ''1037 }1038 1039 // join the section-initial newline, the heading and the help1040 return this.formatter._join_parts(['\n', heading, item_help, '\n'])1041 }1042})1043 1044 1045const RawDescriptionHelpFormatter = _camelcase_alias(_callable(class RawDescriptionHelpFormatter extends HelpFormatter {1046 /*1047 * Help message formatter which retains any formatting in descriptions.1048 *1049 * Only the name of this class is considered a public API. All the methods1050 * provided by the class are considered an implementation detail.1051 */1052 1053 _fill_text(text, width, indent) {1054 return splitlines(text, true).map(line => indent + line).join('')1055 }1056}))1057 1058 1059const RawTextHelpFormatter = _camelcase_alias(_callable(class RawTextHelpFormatter extends RawDescriptionHelpFormatter {1060 /*1061 * Help message formatter which retains formatting of all help text.1062 *1063 * Only the name of this class is considered a public API. All the methods1064 * provided by the class are considered an implementation detail.1065 */1066 1067 _split_lines(text/*, width*/) {1068 return splitlines(text)1069 }1070}))1071 1072 1073const ArgumentDefaultsHelpFormatter = _camelcase_alias(_callable(class ArgumentDefaultsHelpFormatter extends HelpFormatter {1074 /*1075 * Help message formatter which adds default values to argument help.1076 *1077 * Only the name of this class is considered a public API. All the methods1078 * provided by the class are considered an implementation detail.1079 */1080 1081 _get_help_string(action) {1082 let help = action.help1083 // LEGACY (v1 compatibility): additional check for defaultValue needed1084 if (!action.help.includes('%(default)') && !action.help.includes('%(defaultValue)')) {1085 if (action.default !== SUPPRESS) {1086 let defaulting_nargs = [OPTIONAL, ZERO_OR_MORE]1087 if (action.option_strings.length || defaulting_nargs.includes(action.nargs)) {1088 help += ' (default: %(default)s)'1089 }1090 }1091 }1092 return help1093 }1094}))1095 1096 1097const MetavarTypeHelpFormatter = _camelcase_alias(_callable(class MetavarTypeHelpFormatter extends HelpFormatter {1098 /*1099 * Help message formatter which uses the argument 'type' as the default1100 * metavar value (instead of the argument 'dest')1101 *1102 * Only the name of this class is considered a public API. All the methods1103 * provided by the class are considered an implementation detail.1104 */1105 1106 _get_default_metavar_for_optional(action) {1107 return typeof action.type === 'function' ? action.type.name : action.type1108 }1109 1110 _get_default_metavar_for_positional(action) {1111 return typeof action.type === 'function' ? action.type.name : action.type1112 }1113}))1114 1115 1116// =====================1117// Options and Arguments1118// =====================1119function _get_action_name(argument) {1120 if (argument === undefined) {1121 return undefined1122 } else if (argument.option_strings.length) {1123 return argument.option_strings.join('/')1124 } else if (![ undefined, SUPPRESS ].includes(argument.metavar)) {1125 return argument.metavar1126 } else if (![ undefined, SUPPRESS ].includes(argument.dest)) {1127 return argument.dest1128 } else {1129 return undefined1130 }1131}1132 1133 1134const ArgumentError = _callable(class ArgumentError extends Error {1135 /*1136 * An error from creating or using an argument (optional or positional).1137 *1138 * The string value of this exception is the message, augmented with1139 * information about the argument that caused it.1140 */1141 1142 constructor(argument, message) {1143 super()1144 this.name = 'ArgumentError'1145 this._argument_name = _get_action_name(argument)1146 this._message = message1147 this.message = this.str()1148 }1149 1150 str() {1151 let format1152 if (this._argument_name === undefined) {1153 format = '%(message)s'1154 } else {1155 format = 'argument %(argument_name)s: %(message)s'1156 }1157 return sub(format, { message: this._message,1158 argument_name: this._argument_name })1159 }1160})1161 1162 1163const ArgumentTypeError = _callable(class ArgumentTypeError extends Error {1164 /*1165 * An error from trying to convert a command line string to a type.1166 */1167 1168 constructor(message) {1169 super(message)1170 this.name = 'ArgumentTypeError'1171 }1172})1173 1174 1175// ==============1176// Action classes1177// ==============1178const Action = _camelcase_alias(_callable(class Action extends _AttributeHolder(Function) {1179 /*1180 * Information about how to convert command line strings to Python objects.1181 *1182 * Action objects are used by an ArgumentParser to represent the information1183 * needed to parse a single argument from one or more strings from the1184 * command line. The keyword arguments to the Action constructor are also1185 * all attributes of Action instances.1186 *1187 * Keyword Arguments:1188 *1189 * - option_strings -- A list of command-line option strings which1190 * should be associated with this action.1191 *1192 * - dest -- The name of the attribute to hold the created object(s)1193 *1194 * - nargs -- The number of command-line arguments that should be1195 * consumed. By default, one argument will be consumed and a single1196 * value will be produced. Other values include:1197 * - N (an integer) consumes N arguments (and produces a list)1198 * - '?' consumes zero or one arguments1199 * - '*' consumes zero or more arguments (and produces a list)1200 * - '+' consumes one or more arguments (and produces a list)