Revision 8bc17ebb

b/lib/opcodes.py
434 434
    slots = mcs._GetSlots(attrs)
435 435
    assert "OP_DSC_FIELD" not in attrs or attrs["OP_DSC_FIELD"] in slots, \
436 436
      "Class '%s' uses unknown field in OP_DSC_FIELD" % name
437
    assert ("OP_DSC_FORMATTER" not in attrs or
438
            callable(attrs["OP_DSC_FORMATTER"])), \
439
      ("Class '%s' uses non-callable in OP_DSC_FORMATTER (%s)" %
440
       (name, type(attrs["OP_DSC_FORMATTER"])))
437 441

  
438 442
    attrs["OP_ID"] = _NameToId(name)
439 443

  
......
598 602
  @cvar OP_DSC_FIELD: The name of a field whose value will be included in the
599 603
                      string returned by Summary(); see the docstring of that
600 604
                      method for details).
605
  @cvar OP_DSC_FORMATTER: A callable that should format the OP_DSC_FIELD; if
606
                          not present, then the field will be simply converted
607
                          to string
601 608
  @cvar OP_PARAMS: List of opcode attributes, the default values they should
602 609
                   get if not already defined, and types they must match.
603 610
  @cvar OP_RESULT: Callable to verify opcode result
......
685 692
    field_name = getattr(self, "OP_DSC_FIELD", None)
686 693
    if field_name:
687 694
      field_value = getattr(self, field_name, None)
688
      if isinstance(field_value, (list, tuple)):
695
      field_formatter = getattr(self, "OP_DSC_FORMATTER", None)
696
      if callable(field_formatter):
697
        field_value = field_formatter(field_value)
698
      elif isinstance(field_value, (list, tuple)):
689 699
        field_value = ",".join(str(i) for i in field_value)
690 700
      txt = "%s(%s)" % (txt, field_value)
691 701
    return txt
......
1958 1968
    ("repeat", 0, ht.TNonNegativeInt, None),
1959 1969
    ]
1960 1970

  
1971
  def OP_DSC_FORMATTER(self, value): # pylint: disable=C0103,R0201
1972
    """Custom formatter for duration.
1973

  
1974
    """
1975
    try:
1976
      v = float(value)
1977
    except TypeError:
1978
      v = value
1979
    return str(v)
1980

  
1961 1981

  
1962 1982
class OpTestAllocator(OpCode):
1963 1983
  """Allocator framework testing.
b/test/ganeti.opcodes_unittest.py
121 121
    self.assertEqual(OpTest(data="node1.example.com").Summary(),
122 122
                     "TEST(node1.example.com)")
123 123

  
124
  def testSummaryFormatter(self):
125
    class OpTest(opcodes.OpCode):
126
      OP_DSC_FIELD = "data"
127
      OP_DSC_FORMATTER = lambda _, v: "a"
128
      OP_PARAMS = [
129
        ("data", ht.NoDefault, ht.TString, None),
130
        ]
131
    self.assertEqual(OpTest(data="").Summary(), "TEST(a)")
132
    self.assertEqual(OpTest(data="b").Summary(), "TEST(a)")
133

  
124 134
  def testTinySummary(self):
125 135
    self.assertFalse(utils.FindDuplicates(opcodes._SUMMARY_PREFIX.values()))
126 136
    self.assertTrue(compat.all(prefix.endswith("_") and supplement.endswith("_")

Also available in: Unified diff