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