Revision 726ae450 lib/cli.py
b/lib/cli.py | ||
---|---|---|
563 | 563 |
raise OptionValueError("option %s: %s" % (opt, err)) |
564 | 564 |
|
565 | 565 |
|
566 |
def _SplitKeyVal(opt, data): |
|
566 |
def _SplitKeyVal(opt, data, parse_prefixes):
|
|
567 | 567 |
"""Convert a KeyVal string into a dict. |
568 | 568 |
|
569 | 569 |
This function will convert a key=val[,...] string into a dict. Empty |
570 | 570 |
values will be converted specially: keys which have the prefix 'no_' |
571 |
will have the value=False and the prefix stripped, the others will |
|
571 |
will have the value=False and the prefix stripped, keys with the prefix |
|
572 |
"-" will have value=None and the prefix stripped, and the others will |
|
572 | 573 |
have value=True. |
573 | 574 |
|
574 | 575 |
@type opt: string |
... | ... | |
576 | 577 |
data, used in building error messages |
577 | 578 |
@type data: string |
578 | 579 |
@param data: a string of the format key=val,key=val,... |
580 |
@type parse_prefixes: bool |
|
581 |
@param parse_prefixes: whether to handle prefixes specially |
|
579 | 582 |
@rtype: dict |
580 | 583 |
@return: {key=val, key=val} |
581 | 584 |
@raises errors.ParameterError: if there are duplicate keys |
... | ... | |
586 | 589 |
for elem in utils.UnescapeAndSplit(data, sep=","): |
587 | 590 |
if "=" in elem: |
588 | 591 |
key, val = elem.split("=", 1) |
589 |
else:
|
|
592 |
elif parse_prefixes:
|
|
590 | 593 |
if elem.startswith(NO_PREFIX): |
591 | 594 |
key, val = elem[len(NO_PREFIX):], False |
592 | 595 |
elif elem.startswith(UN_PREFIX): |
593 | 596 |
key, val = elem[len(UN_PREFIX):], None |
594 | 597 |
else: |
595 | 598 |
key, val = elem, True |
599 |
else: |
|
600 |
raise errors.ParameterError("Missing value for key '%s' in option %s" % |
|
601 |
(elem, opt)) |
|
596 | 602 |
if key in kv_dict: |
597 | 603 |
raise errors.ParameterError("Duplicate key '%s' in option %s" % |
598 | 604 |
(key, opt)) |
... | ... | |
600 | 606 |
return kv_dict |
601 | 607 |
|
602 | 608 |
|
603 |
def check_ident_key_val(option, opt, value): # pylint: disable=W0613
|
|
604 |
"""Custom parser for ident:key=val,key=val options.
|
|
609 |
def _SplitIdentKeyVal(opt, value, parse_prefixes):
|
|
610 |
"""Helper function to parse "ident:key=val,key=val" options.
|
|
605 | 611 |
|
606 |
This will store the parsed values as a tuple (ident, {key: val}). As such, |
|
607 |
multiple uses of this option via action=append is possible. |
|
612 |
@type opt: string |
|
613 |
@param opt: option name, used in error messages |
|
614 |
@type value: string |
|
615 |
@param value: expected to be in the format "ident:key=val,key=val,..." |
|
616 |
@type parse_prefixes: bool |
|
617 |
@param parse_prefixes: whether to handle prefixes specially (see |
|
618 |
L{_SplitKeyVal}) |
|
619 |
@rtype: tuple |
|
620 |
@return: (ident, {key=val, key=val}) |
|
621 |
@raises errors.ParameterError: in case of duplicates or other parsing errors |
|
608 | 622 |
|
609 | 623 |
""" |
610 | 624 |
if ":" not in value: |
... | ... | |
612 | 626 |
else: |
613 | 627 |
ident, rest = value.split(":", 1) |
614 | 628 |
|
615 |
if ident.startswith(NO_PREFIX): |
|
629 |
if parse_prefixes and ident.startswith(NO_PREFIX):
|
|
616 | 630 |
if rest: |
617 | 631 |
msg = "Cannot pass options when removing parameter groups: %s" % value |
618 | 632 |
raise errors.ParameterError(msg) |
619 | 633 |
retval = (ident[len(NO_PREFIX):], False) |
620 |
elif (ident.startswith(UN_PREFIX) and |
|
621 |
(len(ident) <= len(UN_PREFIX) or |
|
622 |
not ident[len(UN_PREFIX)][0].isdigit())): |
|
634 |
elif (parse_prefixes and ident.startswith(UN_PREFIX) and |
|
635 |
(len(ident) <= len(UN_PREFIX) or not ident[len(UN_PREFIX)].isdigit())): |
|
623 | 636 |
if rest: |
624 | 637 |
msg = "Cannot pass options when removing parameter groups: %s" % value |
625 | 638 |
raise errors.ParameterError(msg) |
626 | 639 |
retval = (ident[len(UN_PREFIX):], None) |
627 | 640 |
else: |
628 |
kv_dict = _SplitKeyVal(opt, rest) |
|
641 |
kv_dict = _SplitKeyVal(opt, rest, parse_prefixes)
|
|
629 | 642 |
retval = (ident, kv_dict) |
630 | 643 |
return retval |
631 | 644 |
|
632 | 645 |
|
646 |
def check_ident_key_val(option, opt, value): # pylint: disable=W0613 |
|
647 |
"""Custom parser for ident:key=val,key=val options. |
|
648 |
|
|
649 |
This will store the parsed values as a tuple (ident, {key: val}). As such, |
|
650 |
multiple uses of this option via action=append is possible. |
|
651 |
|
|
652 |
""" |
|
653 |
return _SplitIdentKeyVal(opt, value, True) |
|
654 |
|
|
655 |
|
|
633 | 656 |
def check_key_val(option, opt, value): # pylint: disable=W0613 |
634 | 657 |
"""Custom parser class for key=val,key=val options. |
635 | 658 |
|
636 | 659 |
This will store the parsed values as a dict {key: val}. |
637 | 660 |
|
638 | 661 |
""" |
639 |
return _SplitKeyVal(opt, value) |
|
662 |
return _SplitKeyVal(opt, value, True) |
|
663 |
|
|
664 |
|
|
665 |
def _SplitListKeyVal(opt, value): |
|
666 |
retval = {} |
|
667 |
for elem in value.split("/"): |
|
668 |
if not elem: |
|
669 |
raise errors.ParameterError("Empty section in option '%s'" % opt) |
|
670 |
(ident, valdict) = _SplitIdentKeyVal(opt, elem, False) |
|
671 |
if ident in retval: |
|
672 |
msg = ("Duplicated parameter '%s' in parsing %s: %s" % |
|
673 |
(ident, opt, elem)) |
|
674 |
raise errors.ParameterError(msg) |
|
675 |
retval[ident] = valdict |
|
676 |
return retval |
|
677 |
|
|
678 |
|
|
679 |
def check_list_ident_key_val(_, opt, value): |
|
680 |
"""Custom parser for "ident:key=val,key=val/ident:key=val" options. |
|
681 |
|
|
682 |
@rtype: list of dictionary |
|
683 |
@return: {ident: {key: val, key: val}, ident: {key: val}} |
|
684 |
|
|
685 |
""" |
|
686 |
return _SplitListKeyVal(opt, value) |
|
640 | 687 |
|
641 | 688 |
|
642 | 689 |
def check_bool(option, opt, value): # pylint: disable=W0613 |
... | ... | |
711 | 758 |
"completion_suggest", |
712 | 759 |
] |
713 | 760 |
TYPES = Option.TYPES + ( |
761 |
"listidentkeyval", |
|
714 | 762 |
"identkeyval", |
715 | 763 |
"keyval", |
716 | 764 |
"unit", |
... | ... | |
719 | 767 |
"maybefloat", |
720 | 768 |
) |
721 | 769 |
TYPE_CHECKER = Option.TYPE_CHECKER.copy() |
770 |
TYPE_CHECKER["listidentkeyval"] = check_list_ident_key_val |
|
722 | 771 |
TYPE_CHECKER["identkeyval"] = check_ident_key_val |
723 | 772 |
TYPE_CHECKER["keyval"] = check_key_val |
724 | 773 |
TYPE_CHECKER["unit"] = check_unit |
Also available in: Unified diff