iotests: touch up log function signature

Representing nested, recursive data structures in mypy is notoriously
difficult; the best we can reliably do right now is denote the leaf
types as "Any" while describing the general shape of the data.

Regardless, this fully annotates the log() function.

Typing notes:

TypeVar is a Type variable that can optionally be constrained by a
sequence of possible types. This variable is bound to a specific type
per-invocation, like a Generic.

log() behaves as log<Msg>() now, where the incoming type informs the
signature it expects for any filter arguments passed in. If Msg is a
str, then filter should take and return a str.

Signed-off-by: John Snow <jsnow@redhat.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
Message-Id: <20200331000014.11581-9-jsnow@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
John Snow 2020-03-30 20:00:08 -04:00 committed by Max Reitz
parent 229fc0742a
commit 1cd0dbfc12
1 changed files with 11 additions and 3 deletions

View File

@ -28,6 +28,7 @@ import signal
import struct
import subprocess
import sys
from typing import (Any, Callable, Dict, Iterable, List, Optional, TypeVar)
import unittest
# pylint: disable=import-error, wrong-import-position
@ -354,9 +355,16 @@ def filter_qmp_imgfmt(qmsg):
return value
return filter_qmp(qmsg, _filter)
def log(msg, filters=(), indent=None):
'''Logs either a string message or a JSON serializable message (like QMP).
If indent is provided, JSON serializable messages are pretty-printed.'''
Msg = TypeVar('Msg', Dict[str, Any], List[Any], str)
def log(msg: Msg,
filters: Iterable[Callable[[Msg], Msg]] = (),
indent: Optional[int] = None) -> None:
"""
Logs either a string message or a JSON serializable message (like QMP).
If indent is provided, JSON serializable messages are pretty-printed.
"""
for flt in filters:
msg = flt(msg)
if isinstance(msg, (dict, list)):