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
|