Skip to content

Commit

Permalink
Merge b932026 into 11a2133
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-maier committed Jun 27, 2020
2 parents 11a2133 + b932026 commit 3ea3975
Show file tree
Hide file tree
Showing 6 changed files with 152 additions and 22 deletions.
4 changes: 4 additions & 0 deletions docs/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ Released: not yet
of the DMTF pull operations. It tests for all of the operations and
reports success or failure on each operation.

* Added value-mapped strings to properties in instance table output.
For integer-typed (scalar or array) properties that have a ValueMap qualifier,
the output of instances in table format now includes the value of the Values
qualifier in parenthesis, in addition to the integer value. (See issue #634)

**Cleanup**

Expand Down
15 changes: 13 additions & 2 deletions pywbemtools/pywbemcli/_cimvalueformatter.py
Original file line number Diff line number Diff line change
Expand Up @@ -438,14 +438,19 @@ def _mofstr(value, indent, maxline, line_pos, end_space, avoid_splits=False,

def cimvalue_to_fmtd_string(value, type, indent=0,
maxline=DEFAULT_MAX_CELL_WIDTH,
line_pos=0, end_space=0, avoid_splits=False):
line_pos=0, end_space=0, avoid_splits=False,
valuemapping=None):
# pylint: disable=redefined-builtin
"""
Return a MOF string representing a CIM-typed value (scalar or array).
In case of an array, the array items are separated by comma, but the
surrounding curly braces are not added.
In case a value mapping is provided, each value is followed by the
Values qualifier string in parenthesis. For example, "4" may become
"4 (Enabled)".
Parameters:
value (CIM-typed value or list of CIM-typed values): The value.
Expand All @@ -464,6 +469,9 @@ def cimvalue_to_fmtd_string(value, type, indent=0,
avoid_splits (bool): Avoid splits at the price of starting a new line
instead of using the current line.
valuemapping (:class:`pywbem.ValueMapping`): None or a value mapping
defining a string for the integer-typed property value(s).
Returns:
tuple of
Expand All @@ -483,6 +491,8 @@ def cimvalue_to_fmtd_string(value, type, indent=0,

val_str, line_pos = _scalar_value_tomof(
v, type, indent, maxline, line_pos, end_space + 2, avoid_splits)
if valuemapping:
val_str = "{} ({})".format(val_str, valuemapping.tovalues(v))

if i > 0:
# Add the actual separator
Expand All @@ -500,5 +510,6 @@ def cimvalue_to_fmtd_string(value, type, indent=0,
else:
mof_str, line_pos = _scalar_value_tomof(
value, type, indent, maxline, line_pos, end_space, avoid_splits)

if valuemapping:
mof_str = "{} ({})".format(mof_str, valuemapping.tovalues(value))
return mof_str, line_pos
77 changes: 61 additions & 16 deletions pywbemtools/pywbemcli/_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

from pywbem import CIMInstanceName, CIMInstance, CIMClass, \
CIMQualifierDeclaration, CIMProperty, CIMClassName, \
cimvalue
cimvalue, ValueMapping

from .config import USE_TERMINAL_WIDTH, DEFAULT_TABLE_WIDTH

Expand All @@ -50,6 +50,8 @@

DEFAULT_MAX_CELL_WIDTH = 100

INT_TYPE_PATTERN = re.compile(r'^[su]int(8|16|32|64)$')

##############################################################
#
# General option output format definitions and support for
Expand Down Expand Up @@ -1057,19 +1059,18 @@ def display_cim_objects(context, cim_objects, output_format, summary=False,
if isinstance(cim_objects, (list, tuple)):
# Table format output is processed as a group
if output_format_is_table(output_format):
_print_objects_as_table(cim_objects, output_format)
_print_objects_as_table(cim_objects, output_format, context=context)
else:
# Call to display each object
for obj in cim_objects:
display_cim_objects(context, obj,
output_format=output_format)
display_cim_objects(context, obj, output_format=output_format)
return

# Display a single item.
object_ = cim_objects
# This allows passing single objects to the table formatter (i.e. not lists)
if output_format_is_table(output_format):
_print_objects_as_table([object_], output_format)
_print_objects_as_table([object_], output_format, context=context)
elif output_format == 'mof':
try:
click.echo(object_.tomof())
Expand Down Expand Up @@ -1403,7 +1404,7 @@ def _print_qual_decls_as_table(qual_decls, table_width, table_format):


def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
include_classes=False):
include_classes=False, context=None):
"""
Format the list of instances properties into as a list of the property
values for each instance( a row of the table) gathered into a list of
Expand All @@ -1415,7 +1416,10 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
max_width if not None folds col entries longer than the defined
max_cell_width. If max_width is None, the data length is ignored.
Formatting is consistent with mof output for each value.
The property values are formatted similar to MOF output. Properties that
have a ValueMap qualifier (effectively, in the creation class of the
instance) are shown with both the actual property value and the mapped
value in parenthesis.
NOTE: This is a separate function to allow testing of the table formatting
independently of print output.
Expand All @@ -1431,11 +1435,21 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
prop_names = []

# find instance with max number of properties

# TODO: The following code misses properties if there are instances with
# different sets of properties where no instance has all of them.
# See issue #650.

for inst in insts:
pn = inst.keys()
if len(pn) > len(prop_names):
prop_names = pn

# Cache of ValueMapping objects for integer-typed properties.
# Key: classname.propertyname, both in lower case.
# A value of None indicates the property does not have a value mapping.
valuemappings = {}

for inst in insts:
if not isinstance(inst, CIMInstance):
raise ValueError('Only accepts CIMInstance; not type {}'
Expand All @@ -1446,6 +1460,7 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,

# get value for each property in this object
for name in prop_names:

# Account for possible instances without all properties
# Outputs empty string. Note that instance with no value
# results in same output as not instance name.
Expand All @@ -1454,27 +1469,55 @@ def _format_instances_as_rows(insts, max_cell_width=DEFAULT_MAX_CELL_WIDTH,
else:
value = inst.get(name)
p = inst.properties[name]

# Cache value mappings for integer-typed properties
if INT_TYPE_PATTERN.match(p.type) and context:
vm_key = '{}.{}'.format(
inst.classname.lower(), name.lower())
try:
valuemapping = valuemappings[vm_key]
except KeyError:
try:
valuemapping = ValueMapping.for_property(
context.conn,
context.conn.default_namespace,
inst.classname,
name)
except ValueError:
# Property does not have a value mapping.
valuemapping = None
valuemappings[vm_key] = valuemapping
else:
valuemapping = None

if value is None:
val_str = u''
else:
val_str, _ = cimvalue_to_fmtd_string(
p.value, p.type, indent=0, maxline=max_cell_width,
line_pos=0, end_space=0, avoid_splits=False)
line_pos=0, end_space=0, avoid_splits=False,
valuemapping=valuemapping)

line.append(val_str)
lines.append(line)

return lines


def _print_instances_as_table(insts, table_width, table_format,
include_classes=False):
include_classes=False, context=None):
"""
Print the properties of the instances defined in insts as a table where
each row is an instance and each column is a property value. The properties
are formatted similar to mof output. All properties in the instance are
included.
each row is an instance and each column is a property value.
All properties in the instance are included.
The header line consists of the property names.
The header line consists of property names.
The property values are formatted similar to MOF output. Properties that
have a ValueMap qualifier (effectively, in the creation class of the
instance) are shown with both the actual property value and the mapped
value in parenthesis.
"""

if table_width is None:
Expand Down Expand Up @@ -1517,14 +1560,15 @@ def _print_instances_as_table(insts, table_width, table_format,
raise ValueError('Only CIMInstance display allows table output')

rows = _format_instances_as_rows(insts, max_cell_width=max_cell_width,
include_classes=include_classes)
include_classes=include_classes,
context=context)

title = 'Instances: {}'.format(insts[0].classname)
click.echo(format_table(rows, new_header_line, title=title,
table_format=table_format))


def _print_objects_as_table(objects, output_format):
def _print_objects_as_table(objects, output_format, context=None):
"""
Call the method for each type of object to print that object type
information as a table.
Expand All @@ -1538,7 +1582,8 @@ def _print_objects_as_table(objects, output_format):

if objects:
if isinstance(objects[0], CIMInstance):
_print_instances_as_table(objects, table_width, output_format)
_print_instances_as_table(objects, table_width, output_format,
context=context)
elif isinstance(objects[0], CIMClass):
_print_classes_as_table(objects, table_width, output_format)
elif isinstance(objects[0], CIMQualifierDeclaration):
Expand Down
42 changes: 38 additions & 4 deletions tests/unit/simple_assoc_mock_model.mof
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,21 @@ Qualifier Out : boolean = false,
Scope(parameter),
Flavor(DisableOverride, ToSubclass);

Qualifier ValueMap : string[],
Scope(property, method, parameter);

Qualifier Values : string[],
Scope(property, method, parameter),
Flavor(EnableOverride, ToSubclass, Translatable);

class TST_Person{
[Key, Description ("This is key prop")]
string name;
string extraProperty = "defaultvalue";
[ValueMap {"1", "2"}, Values {"female", "male"}]
uint16 gender;
[ValueMap {"1", "2"}, Values {"books", "movies"}]
uint16 likes[];
};

// NOTE: classname uses lower case s in sub. Instance names use upper case
Expand Down Expand Up @@ -57,25 +68,48 @@ class TST_FamilyCollection {

// Define instances of TST_Person

instance of TST_Person as $Mike { name = "Mike"; };
instance of TST_Person as $Saara { name = "Saara"; };
instance of TST_Person as $Sofi { name = "Sofi"; };
instance of TST_Person as $Gabi{ name = "Gabi"; };
instance of TST_Person as $Mike {
name = "Mike";
gender = 2;
likes = {1, 2};
};
instance of TST_Person as $Saara {
name = "Saara";
gender = 1;
likes = {1};
};
instance of TST_Person as $Sofi {
name = "Sofi";
gender = 1;
likes = NULL;
};
instance of TST_Person as $Gabi{
name = "Gabi";
gender = 1;
likes = {};
};

// Define instances of the TST_PersonSub
instance of TST_PersonSub as $Mikesub{ name = "Mikesub";
gender = 2;
likes = {1, 2};
secondProperty = "one" ;
counter = 1; };

instance of TST_PersonSub as $Saarasub { name = "Saarasub";
gender = 1;
likes = {2};
secondProperty = "two" ;
counter = 2; };

instance of TST_PersonSub as $Sofisub{ name = "Sofisub";
gender = 1;
likes = NULL;
secondProperty = "three" ;
counter = 3; };

instance of TST_PersonSub as $Gabisub{ name = "Gabisub";
gender = 1;
secondProperty = "four" ;
counter = 4; };

Expand Down
32 changes: 32 additions & 0 deletions tests/unit/test_class_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
' [ValueMap { "1", "2" },',
' Values { "books", "movies" }]',
' uint16 likes[];',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1203,6 +1211,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
' [ValueMap { "1", "2" },',
' Values { "books", "movies" }]',
' uint16 likes[];',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1223,6 +1239,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
' [ValueMap { "1", "2" },',
' Values { "books", "movies" }]',
' uint16 likes[];',
'',
'};',
''],
'test': 'lines'},
Expand All @@ -1243,6 +1267,14 @@ class CIM_Foo_sub_sub : CIM_Foo_sub {
'',
' string extraProperty = "defaultvalue";',
'',
' [ValueMap { "1", "2" },',
' Values { "female", "male" }]',
' uint16 gender;',
'',
' [ValueMap { "1", "2" },',
' Values { "books", "movies" }]',
' uint16 likes[];',
'',
'};',
''],
'test': 'lines'},
Expand Down
4 changes: 4 additions & 0 deletions tests/unit/test_instance_cmds.py
Original file line number Diff line number Diff line change
Expand Up @@ -380,10 +380,14 @@
instance of TST_Person {
name = "Gabi";
gender = 1;
likes = { };
};
instance of TST_Person {
name = "Sofi";
gender = 1;
likes = NULL;
};
"""
Expand Down

0 comments on commit 3ea3975

Please sign in to comment.