Row stringification happens a lot in client logs and it is far
more useful to have the logged Row's uuid printed. This also
adds converting referenced Row objects, and references within
set and map columns to UUIDs.

Signed-off-by: Terry Wilson <twil...@redhat.com>
---
 python/ovs/db/idl.py | 32 ++++++++++++++++++++++++++++----
 tests/test-ovsdb.py  |  3 +++
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
index f01e21b5e..7e538c225 100644
--- a/python/ovs/db/idl.py
+++ b/python/ovs/db/idl.py
@@ -1229,6 +1229,29 @@ def _row_to_uuid(value):
         return value
 
 
+def _rows_to_uuid_str(value):
+    if isinstance(value, collections.abc.Mapping):
+        try:
+            k, v = next(iter(value.items()))
+            # Pass through early without iterating if not Rows.
+            if isinstance(k, Row) or isinstance(v, Row):
+                return {str(_row_to_uuid(x)): str(_row_to_uuid(y))
+                        for x, y in value.items()}
+        except StopIteration:
+            # Empty, return default.
+            pass
+    elif (isinstance(value, collections.abc.Iterable)
+        and not isinstance(value, str)):
+        try:
+            # Pass through early without iterating if not Rows.
+            if value and isinstance(value[0], Row):
+                return type(value)(str(_row_to_uuid(x)) for x in value)
+        except TypeError:
+            # Weird Iterable, pass through.
+            pass
+    return str(_row_to_uuid(value))
+
+
 @functools.total_ordering
 class Row(object):
     """A row within an IDL.
@@ -1334,11 +1357,12 @@ class Row(object):
         return int(self.__dict__['uuid'])
 
     def __str__(self):
-        return "{table}({data})".format(
+        return "{table}(uuid={uuid}, {data})".format(
             table=self._table.name,
-            data=", ".join("{col}={val}".format(col=c, val=getattr(self, c))
-                           for c in sorted(self._table.columns)
-                           if hasattr(self, c)))
+            uuid=self.uuid,
+            data=", ".join("{col}={val}".format(
+                col=c, val=_rows_to_uuid_str(getattr(self, c)))
+                for c in sorted(self._table.columns) if hasattr(self, c)))
 
     def _uuid_to_row(self, atom, base):
         if base.ref_table:
diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py
index b690b4f07..f184052de 100644
--- a/tests/test-ovsdb.py
+++ b/tests/test-ovsdb.py
@@ -214,6 +214,9 @@ def do_parse_schema(schema_string):
 
 
 def get_simple_printable_row_string(row, columns):
+    # NOTE(twilson):This turns out to be a particularly good place to test that
+    # Row object stringification doesn't crash on a large variety of row types
+    assert str(row)
     s = ""
     for column in columns:
         if hasattr(row, column) and not (type(getattr(row, column))
-- 
2.49.0

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to