tests: replace pycodestyle with black
[vpp.git] / src / vpp-api / python / vpp_papi / vpp_papi.py
index 3465f50..1e5d23e 100644 (file)
@@ -30,13 +30,14 @@ import fnmatch
 import weakref
 import atexit
 import time
-from . vpp_format import verify_enum_hint
-from . vpp_serializer import VPPType, VPPEnumType, VPPEnumFlagType, VPPUnionType
-from . vpp_serializer import VPPMessage, vpp_get_type, VPPTypeAlias
+from .vpp_format import verify_enum_hint
+from .vpp_serializer import VPPType, VPPEnumType, VPPEnumFlagType, VPPUnionType
+from .vpp_serializer import VPPMessage, vpp_get_type, VPPTypeAlias
 
 try:
     import VppTransport
 except ModuleNotFoundError:
+
     class V:
         """placeholder for VppTransport as the implementation is dependent on
         VPPAPIClient's initialization values
@@ -44,15 +45,22 @@ except ModuleNotFoundError:
 
     VppTransport = V
 
-from . vpp_transport_socket import VppTransport
+from .vpp_transport_socket import VppTransport
 
-logger = logging.getLogger('vpp_papi')
+logger = logging.getLogger("vpp_papi")
 logger.addHandler(logging.NullHandler())
 
-__all__ = ('FuncWrapper', 'VppApiDynamicMethodHolder',
-           'VppEnum', 'VppEnumType', 'VppEnumFlag',
-           'VPPIOError', 'VPPRuntimeError', 'VPPValueError',
-           'VPPApiClient', )
+__all__ = (
+    "FuncWrapper",
+    "VppApiDynamicMethodHolder",
+    "VppEnum",
+    "VppEnumType",
+    "VppEnumFlag",
+    "VPPIOError",
+    "VPPRuntimeError",
+    "VPPValueError",
+    "VPPApiClient",
+)
 
 
 def metaclass(metaclass):
@@ -83,7 +91,7 @@ def vpp_atexit(vpp_weakref):
     """Clean up VPP connection on shutdown."""
     vpp_instance = vpp_weakref()
     if vpp_instance and vpp_instance.transport.connected:
-        logger.debug('Cleaning up VPP on exit')
+        logger.debug("Cleaning up VPP on exit")
         vpp_instance.disconnect()
 
 
@@ -98,9 +106,9 @@ def add_convenience_methods():
 
     def _vapi_af_name(self):
         if 6 == self._version:
-            return 'ip6'
+            return "ip6"
         if 4 == self._version:
-            return 'ip4'
+            return "ip4"
         raise ValueError("Invalid _version.")
 
     ipaddress._IPAddressBase.vapi_af = property(_vapi_af)
@@ -121,7 +129,7 @@ class FuncWrapper:
         return self._func(**kwargs)
 
     def __repr__(self):
-        return '<FuncWrapper(func=<%s(%s)>)>' % (self.__name__, self.__doc__)
+        return "<FuncWrapper(func=<%s(%s)>)>" % (self.__name__, self.__doc__)
 
 
 class VPPApiError(Exception):
@@ -161,7 +169,8 @@ class VPPApiJSONFiles:
         # perhaps we're in the 'src/scripts' or 'src/vpp-api/python' dir;
         # in which case, plot a course to likely places in the src tree
         import __main__ as main
-        if hasattr(main, '__file__'):
+
+        if hasattr(main, "__file__"):
             # get the path of the calling script
             localdir = os.path.dirname(os.path.realpath(main.__file__))
         else:
@@ -171,7 +180,7 @@ class VPPApiJSONFiles:
 
         def dmatch(dir):
             """Match dir against right-hand components of the script dir"""
-            d = dir.split('/')  # param 'dir' assumes a / separator
+            d = dir.split("/")  # param 'dir' assumes a / separator
             length = len(d)
             return len(localdir_s) > length and localdir_s[-length:] == d
 
@@ -180,43 +189,45 @@ class VPPApiJSONFiles:
             'variant'  (typically '' or '_debug')"""
             # Since 'core' and 'plugin' files are staged
             # in separate directories, we target the parent dir.
-            return os.path.sep.join((
-                srcdir,
-                'build-root',
-                'install-vpp%s-native' % variant,
-                'vpp',
-                'share',
-                'vpp',
-                'api',
-            ))
+            return os.path.sep.join(
+                (
+                    srcdir,
+                    "build-root",
+                    "install-vpp%s-native" % variant,
+                    "vpp",
+                    "share",
+                    "vpp",
+                    "api",
+                )
+            )
 
         srcdir = None
-        if dmatch('src/scripts'):
+        if dmatch("src/scripts"):
             srcdir = os.path.sep.join(localdir_s[:-2])
-        elif dmatch('src/vpp-api/python'):
+        elif dmatch("src/vpp-api/python"):
             srcdir = os.path.sep.join(localdir_s[:-3])
-        elif dmatch('test'):
+        elif dmatch("test"):
             # we're apparently running tests
             srcdir = os.path.sep.join(localdir_s[:-1])
 
         if srcdir:
             # we're in the source tree, try both the debug and release
             # variants.
-            dirs.append(sdir(srcdir, '_debug'))
-            dirs.append(sdir(srcdir, ''))
+            dirs.append(sdir(srcdir, "_debug"))
+            dirs.append(sdir(srcdir, ""))
 
         # Test for staged copies of the scripts
         # For these, since we explicitly know if we're running a debug versus
         # release variant, target only the relevant directory
-        if dmatch('build-root/install-vpp_debug-native/vpp/bin'):
+        if dmatch("build-root/install-vpp_debug-native/vpp/bin"):
             srcdir = os.path.sep.join(localdir_s[:-4])
-            dirs.append(sdir(srcdir, '_debug'))
-        if dmatch('build-root/install-vpp-native/vpp/bin'):
+            dirs.append(sdir(srcdir, "_debug"))
+        if dmatch("build-root/install-vpp-native/vpp/bin"):
             srcdir = os.path.sep.join(localdir_s[:-4])
-            dirs.append(sdir(srcdir, ''))
+            dirs.append(sdir(srcdir, ""))
 
         # finally, try the location system packages typically install into
-        dirs.append(os.path.sep.join(('', 'usr', 'share', 'vpp', 'api')))
+        dirs.append(os.path.sep.join(("", "usr", "share", "vpp", "api")))
 
         # check the directories for existence; first one wins
         for dir in dirs:
@@ -226,7 +237,7 @@ class VPPApiJSONFiles:
         return None
 
     @classmethod
-    def find_api_files(cls, api_dir=None, patterns='*'):  # -> list
+    def find_api_files(cls, api_dir=None, patterns="*"):  # -> list
         """Find API definition files from the given directory tree with the
         given pattern. If no directory is given then find_api_dir() is used
         to locate one. If no pattern is given then all definition files found
@@ -252,9 +263,9 @@ class VPPApiJSONFiles:
                 raise VPPApiError("api_dir cannot be located")
 
         if isinstance(patterns, list) or isinstance(patterns, tuple):
-            patterns = [p.strip() + '.api.json' for p in patterns]
+            patterns = [p.strip() + ".api.json" for p in patterns]
         else:
-            patterns = [p.strip() + '.api.json' for p in patterns.split(",")]
+            patterns = [p.strip() + ".api.json" for p in patterns.split(",")]
 
         api_files = []
         for root, dirnames, files in os.walk(api_dir):
@@ -281,39 +292,39 @@ class VPPApiJSONFiles:
         services = {}
         messages = {}
         try:
-            for t in api['enums']:
-                t[0] = 'vl_api_' + t[0] + '_t'
-                types[t[0]] = {'type': 'enum', 'data': t}
+            for t in api["enums"]:
+                t[0] = "vl_api_" + t[0] + "_t"
+                types[t[0]] = {"type": "enum", "data": t}
         except KeyError:
             pass
         try:
-            for t in api['enumflags']:
-                t[0] = 'vl_api_' + t[0] + '_t'
-                types[t[0]] = {'type': 'enum', 'data': t}
+            for t in api["enumflags"]:
+                t[0] = "vl_api_" + t[0] + "_t"
+                types[t[0]] = {"type": "enum", "data": t}
         except KeyError:
             pass
         try:
-            for t in api['unions']:
-                t[0] = 'vl_api_' + t[0] + '_t'
-                types[t[0]] = {'type': 'union', 'data': t}
+            for t in api["unions"]:
+                t[0] = "vl_api_" + t[0] + "_t"
+                types[t[0]] = {"type": "union", "data": t}
         except KeyError:
             pass
 
         try:
-            for t in api['types']:
-                t[0] = 'vl_api_' + t[0] + '_t'
-                types[t[0]] = {'type': 'type', 'data': t}
+            for t in api["types"]:
+                t[0] = "vl_api_" + t[0] + "_t"
+                types[t[0]] = {"type": "type", "data": t}
         except KeyError:
             pass
 
         try:
-            for t, v in api['aliases'].items():
-                types['vl_api_' + t + '_t'] = {'type': 'alias', 'data': v}
+            for t, v in api["aliases"].items():
+                types["vl_api_" + t + "_t"] = {"type": "alias", "data": v}
         except KeyError:
             pass
 
         try:
-            services.update(api['services'])
+            services.update(api["services"])
         except KeyError:
             pass
 
@@ -321,30 +332,30 @@ class VPPApiJSONFiles:
         while True:
             unresolved = {}
             for k, v in types.items():
-                t = v['data']
+                t = v["data"]
                 if not vpp_get_type(k):
-                    if v['type'] == 'enum':
+                    if v["type"] == "enum":
                         try:
                             VPPEnumType(t[0], t[1:])
                         except ValueError:
                             unresolved[k] = v
                 if not vpp_get_type(k):
-                    if v['type'] == 'enumflag':
+                    if v["type"] == "enumflag":
                         try:
                             VPPEnumFlagType(t[0], t[1:])
                         except ValueError:
                             unresolved[k] = v
-                    elif v['type'] == 'union':
+                    elif v["type"] == "union":
                         try:
                             VPPUnionType(t[0], t[1:])
                         except ValueError:
                             unresolved[k] = v
-                    elif v['type'] == 'type':
+                    elif v["type"] == "type":
                         try:
                             VPPType(t[0], t[1:])
                         except ValueError:
                             unresolved[k] = v
-                    elif v['type'] == 'alias':
+                    elif v["type"] == "alias":
                         try:
                             VPPTypeAlias(k, t)
                         except ValueError:
@@ -352,17 +363,16 @@ class VPPApiJSONFiles:
             if len(unresolved) == 0:
                 break
             if i > 3:
-                raise VPPValueError('Unresolved type definitions {}'
-                                    .format(unresolved))
+                raise VPPValueError("Unresolved type definitions {}".format(unresolved))
             types = unresolved
             i += 1
         try:
-            for m in api['messages']:
+            for m in api["messages"]:
                 try:
                     messages[m[0]] = VPPMessage(m[0], m[1:])
                 except VPPNotImplementedError:
                     ### OLE FIXME
-                    logger.error('Not implemented error for {}'.format(m[0]))
+                    logger.error("Not implemented error for {}".format(m[0]))
         except KeyError:
             pass
         return messages, services
@@ -380,6 +390,7 @@ class VPPApiClient:
     provides a means to register a callback function to receive
     these messages in a background thread.
     """
+
     apidir = None
     VPPApiError = VPPApiError
     VPPRuntimeError = VPPRuntimeError
@@ -387,11 +398,18 @@ class VPPApiClient:
     VPPNotImplementedError = VPPNotImplementedError
     VPPIOError = VPPIOError
 
-
-    def __init__(self, *, apifiles=None, testmode=False, async_thread=True,
-                 logger=None, loglevel=None,
-                 read_timeout=5, use_socket=True,
-                 server_address='/run/vpp/api.sock'):
+    def __init__(
+        self,
+        *,
+        apifiles=None,
+        testmode=False,
+        async_thread=True,
+        logger=None,
+        loglevel=None,
+        read_timeout=5,
+        use_socket=True,
+        server_address="/run/vpp/api.sock",
+    ):
         """Create a VPP API object.
 
         apifiles is a list of files containing API
@@ -406,7 +424,8 @@ class VPPApiClient:
         """
         if logger is None:
             logger = logging.getLogger(
-                "{}.{}".format(__name__, self.__class__.__name__))
+                "{}.{}".format(__name__, self.__class__.__name__)
+            )
             if loglevel is not None:
                 logger.setLevel(loglevel)
         self.logger = logger
@@ -415,8 +434,7 @@ class VPPApiClient:
         self.services = {}
         self.id_names = []
         self.id_msgdef = []
-        self.header = VPPType('header', [['u16', 'msgid'],
-                                         ['u32', 'client_index']])
+        self.header = VPPType("header", [["u16", "msgid"], ["u32", "client_index"]])
         self.apifiles = []
         self.event_callback = None
         self.message_queue = queue.Queue()
@@ -449,13 +467,13 @@ class VPPApiClient:
 
         # Basic sanity check
         if len(self.messages) == 0 and not testmode:
-            raise VPPValueError(1, 'Missing JSON message definitions')
-        if not(verify_enum_hint(VppEnum.vl_api_address_family_t)):
-            raise VPPRuntimeError("Invalid address family hints. "
-                                  "Cannot continue.")
+            raise VPPValueError(1, "Missing JSON message definitions")
+        if not (verify_enum_hint(VppEnum.vl_api_address_family_t)):
+            raise VPPRuntimeError("Invalid address family hints. " "Cannot continue.")
 
-        self.transport = VppTransport(self, read_timeout=read_timeout,
-                                      server_address=server_address)
+        self.transport = VppTransport(
+            self, read_timeout=read_timeout, server_address=server_address
+        )
         # Make sure we allow VPP to clean up the message rings.
         atexit.register(vpp_atexit, weakref.ref(self))
 
@@ -466,6 +484,7 @@ class VPPApiClient:
 
     class ContextId:
         """Multiprocessing-safe provider of unique context IDs."""
+
         def __init__(self):
             self.context = mp.Value(ctypes.c_uint, 0)
             self.lock = mp.Lock()
@@ -475,6 +494,7 @@ class VPPApiClient:
             with self.lock:
                 self.context.value += 1
                 return self.context.value
+
     get_context = ContextId()
 
     def get_type(self, name):
@@ -487,17 +507,20 @@ class VPPApiClient:
         return self._api
 
     def make_function(self, msg, i, multipart, do_async):
-        if (do_async):
+        if do_async:
+
             def f(**kwargs):
                 return self._call_vpp_async(i, msg, **kwargs)
+
         else:
+
             def f(**kwargs):
                 return self._call_vpp(i, msg, multipart, **kwargs)
 
         f.__name__ = str(msg.name)
-        f.__doc__ = ", ".join(["%s %s" %
-                               (msg.fieldtypes[j], k)
-                               for j, k in enumerate(msg.fields)])
+        f.__doc__ = ", ".join(
+            ["%s %s" % (msg.fieldtypes[j], k) for j, k in enumerate(msg.fields)]
+        )
         f.msg = msg
 
         return f
@@ -507,7 +530,7 @@ class VPPApiClient:
         self.id_msgdef = [None] * (self.vpp_dictionary_maxid + 1)
         self._api = VppApiDynamicMethodHolder()
         for name, msg in self.messages.items():
-            n = name + '_' + msg.crc[2:]
+            n = name + "_" + msg.crc[2:]
             i = self.transport.get_msg_index(n)
             if i > 0:
                 self.id_msgdef[i] = msg
@@ -518,28 +541,25 @@ class VPPApiClient:
                     f = self.make_function(msg, i, self.services[name], do_async)
                     setattr(self._api, name, FuncWrapper(f))
             else:
-                self.logger.debug(
-                    'No such message type or failed CRC checksum: %s', n)
+                self.logger.debug("No such message type or failed CRC checksum: %s", n)
 
-    def connect_internal(self, name, msg_handler, chroot_prefix, rx_qlen,
-                         do_async):
-        pfx = chroot_prefix.encode('utf-8') if chroot_prefix else None
+    def connect_internal(self, name, msg_handler, chroot_prefix, rx_qlen, do_async):
+        pfx = chroot_prefix.encode("utf-8") if chroot_prefix else None
 
-        rv = self.transport.connect(name, pfx,
-                                    msg_handler, rx_qlen)
+        rv = self.transport.connect(name, pfx, msg_handler, rx_qlen)
         if rv != 0:
-            raise VPPIOError(2, 'Connect failed')
+            raise VPPIOError(2, "Connect failed")
         self.vpp_dictionary_maxid = self.transport.msg_table_max_index()
         self._register_functions(do_async=do_async)
 
         # Initialise control ping
-        crc = self.messages['control_ping'].crc
+        crc = self.messages["control_ping"].crc
         self.control_ping_index = self.transport.get_msg_index(
-            ('control_ping' + '_' + crc[2:]))
-        self.control_ping_msgdef = self.messages['control_ping']
+            ("control_ping" + "_" + crc[2:])
+        )
+        self.control_ping_msgdef = self.messages["control_ping"]
         if self.async_thread:
-            self.event_thread = threading.Thread(
-                target=self.thread_msg_handler)
+            self.event_thread = threading.Thread(target=self.thread_msg_handler)
             self.event_thread.daemon = True
             self.event_thread.start()
         else:
@@ -556,8 +576,9 @@ class VPPApiClient:
         client and server.
         """
         msg_handler = self.transport.get_callback(do_async)
-        return self.connect_internal(name, msg_handler, chroot_prefix, rx_qlen,
-                                     do_async)
+        return self.connect_internal(
+            name, msg_handler, chroot_prefix, rx_qlen, do_async
+        )
 
     def connect_sync(self, name, chroot_prefix=None, rx_qlen=32):
         """Attach to VPP in synchronous mode. Application must poll for events.
@@ -568,8 +589,7 @@ class VPPApiClient:
         client and server.
         """
 
-        return self.connect_internal(name, None, chroot_prefix, rx_qlen,
-                                     do_async=False)
+        return self.connect_internal(name, None, chroot_prefix, rx_qlen, do_async=False)
 
     def disconnect(self):
         """Detach from VPP."""
@@ -590,42 +610,43 @@ class VPPApiClient:
         # If we have a context, then use the context to find any
         # request waiting for a reply
         context = 0
-        if hasattr(r, 'context') and r.context > 0:
+        if hasattr(r, "context") and r.context > 0:
             context = r.context
 
         if context == 0:
             # No context -> async notification that we feed to the callback
             self.message_queue.put_nowait(r)
         else:
-            raise VPPIOError(2, 'RPC reply message received in event handler')
+            raise VPPIOError(2, "RPC reply message received in event handler")
 
     def has_context(self, msg):
         if len(msg) < 10:
             return False
 
-        header = VPPType('header_with_context', [['u16', 'msgid'],
-                                                 ['u32', 'client_index'],
-                                                 ['u32', 'context']])
+        header = VPPType(
+            "header_with_context",
+            [["u16", "msgid"], ["u32", "client_index"], ["u32", "context"]],
+        )
 
         (i, ci, context), size = header.unpack(msg, 0)
-        if self.id_names[i] == 'rx_thread_exit':
+        if self.id_names[i] == "rx_thread_exit":
             return
 
         #
         # Decode message and returns a tuple.
         #
         msgobj = self.id_msgdef[i]
-        if 'context' in msgobj.field_by_name and context >= 0:
+        if "context" in msgobj.field_by_name and context >= 0:
             return True
         return False
 
     def decode_incoming_msg(self, msg, no_type_conversion=False):
         if not msg:
-            logger.warning('vpp_api.read failed')
+            logger.warning("vpp_api.read failed")
             return
 
         (i, ci), size = self.header.unpack(msg, 0)
-        if self.id_names[i] == 'rx_thread_exit':
+        if self.id_names[i] == "rx_thread_exit":
             return
 
         #
@@ -633,7 +654,7 @@ class VPPApiClient:
         #
         msgobj = self.id_msgdef[i]
         if not msgobj:
-            raise VPPIOError(2, 'Reply message undefined')
+            raise VPPIOError(2, "Reply message undefined")
 
         r, size = msgobj.unpack(msg, ntc=no_type_conversion)
         return r
@@ -654,41 +675,39 @@ class VPPApiClient:
 
     def _control_ping(self, context):
         """Send a ping command."""
-        self._call_vpp_async(self.control_ping_index,
-                             self.control_ping_msgdef,
-                             context=context)
+        self._call_vpp_async(
+            self.control_ping_index, self.control_ping_msgdef, context=context
+        )
 
     def validate_args(self, msg, kwargs):
         d = set(kwargs.keys()) - set(msg.field_by_name.keys())
         if d:
-            raise VPPValueError('Invalid argument {} to {}'
-                                .format(list(d), msg.name))
+            raise VPPValueError("Invalid argument {} to {}".format(list(d), msg.name))
 
     def _add_stat(self, name, ms):
         if not name in self.stats:
-            self.stats[name] = {'max': ms, 'count': 1, 'avg': ms}
+            self.stats[name] = {"max": ms, "count": 1, "avg": ms}
         else:
-            if ms > self.stats[name]['max']:
-                self.stats[name]['max'] = ms
-            self.stats[name]['count'] += 1
-            n = self.stats[name]['count']
-            self.stats[name]['avg'] = self.stats[name]['avg'] * (n - 1) / n + ms / n
+            if ms > self.stats[name]["max"]:
+                self.stats[name]["max"] = ms
+            self.stats[name]["count"] += 1
+            n = self.stats[name]["count"]
+            self.stats[name]["avg"] = self.stats[name]["avg"] * (n - 1) / n + ms / n
 
     def get_stats(self):
-        s = '\n=== API PAPI STATISTICS ===\n'
-        s += '{:<30} {:>4} {:>6} {:>6}\n'.format('message', 'cnt', 'avg', 'max')
-        for n in sorted(self.stats.items(), key=lambda v: v[1]['avg'], reverse=True):
-            s += '{:<30} {:>4} {:>6.2f} {:>6.2f}\n'.format(n[0], n[1]['count'],
-                                                           n[1]['avg'], n[1]['max'])
+        s = "\n=== API PAPI STATISTICS ===\n"
+        s += "{:<30} {:>4} {:>6} {:>6}\n".format("message", "cnt", "avg", "max")
+        for n in sorted(self.stats.items(), key=lambda v: v[1]["avg"], reverse=True):
+            s += "{:<30} {:>4} {:>6.2f} {:>6.2f}\n".format(
+                n[0], n[1]["count"], n[1]["avg"], n[1]["max"]
+            )
         return s
 
     def get_field_options(self, msg, fld_name):
         # when there is an option, the msgdef has 3 elements.
         # ['u32', 'ring_size', {'default': 1024}]
         for _def in self.messages[msg].msgdef:
-            if isinstance(_def, list) and \
-                    len(_def) == 3 and \
-                    _def[1] == fld_name:
+            if isinstance(_def, list) and len(_def) == 3 and _def[1] == fld_name:
                 return _def[2]
 
     def _call_vpp(self, i, msgdef, service, **kwargs):
@@ -707,25 +726,26 @@ class VPPApiClient:
         no response within the timeout window.
         """
         ts = time.time()
-        if 'context' not in kwargs:
+        if "context" not in kwargs:
             context = self.get_context()
-            kwargs['context'] = context
+            kwargs["context"] = context
         else:
-            context = kwargs['context']
-        kwargs['_vl_msg_id'] = i
+            context = kwargs["context"]
+        kwargs["_vl_msg_id"] = i
 
-        no_type_conversion = kwargs.pop('_no_type_conversion', False)
-        timeout = kwargs.pop('_timeout', None)
+        no_type_conversion = kwargs.pop("_no_type_conversion", False)
+        timeout = kwargs.pop("_timeout", None)
 
         try:
             if self.transport.socket_index:
-                kwargs['client_index'] = self.transport.socket_index
+                kwargs["client_index"] = self.transport.socket_index
         except AttributeError:
             pass
         self.validate_args(msgdef, kwargs)
 
-        s = 'Calling {}({})'.format(msgdef.name,
-            ','.join(['{!r}:{!r}'.format(k, v) for k, v in kwargs.items()]))
+        s = "Calling {}({})".format(
+            msgdef.name, ",".join(["{!r}:{!r}".format(k, v) for k, v in kwargs.items()])
+        )
         self.logger.debug(s)
 
         b = msgdef.pack(kwargs)
@@ -733,17 +753,17 @@ class VPPApiClient:
 
         self.transport.write(b)
 
-        msgreply = service['reply']
-        stream = True if 'stream' in service else False
+        msgreply = service["reply"]
+        stream = True if "stream" in service else False
         if stream:
-            if 'stream_msg' in service:
+            if "stream_msg" in service:
                 # New service['reply'] = _reply and service['stream_message'] = _details
-                stream_message = service['stream_msg']
-                modern =True
+                stream_message = service["stream_msg"]
+                modern = True
             else:
                 # Old  service['reply'] = _details
                 stream_message = msgreply
-                msgreply = 'control_ping_reply'
+                msgreply = "control_ping_reply"
                 modern = False
                 # Send a ping after the request - we use its response
                 # to detect that we have seen all results.
@@ -751,22 +771,22 @@ class VPPApiClient:
 
         # Block until we get a reply.
         rl = []
-        while (True):
+        while True:
             r = self.read_blocking(no_type_conversion, timeout)
             if r is None:
-                raise VPPIOError(2, 'VPP API client: read failed')
+                raise VPPIOError(2, "VPP API client: read failed")
             msgname = type(r).__name__
             if context not in r or r.context == 0 or context != r.context:
                 # Message being queued
                 self.message_queue.put_nowait(r)
                 continue
             if msgname != msgreply and (stream and (msgname != stream_message)):
-                print('REPLY MISMATCH', msgreply, msgname, stream_message, stream)
+                print("REPLY MISMATCH", msgreply, msgname, stream_message, stream)
             if not stream:
                 rl = r
                 break
             if msgname == msgreply:
-                if modern: # Return both reply and list
+                if modern:  # Return both reply and list
                     rl = r, rl
                 break
 
@@ -774,7 +794,7 @@ class VPPApiClient:
 
         self.transport.resume()
 
-        s = 'Return value: {!r}'.format(r)
+        s = "Return value: {!r}".format(r)
         if len(s) > 80:
             s = s[:80] + "..."
         self.logger.debug(s)
@@ -795,17 +815,17 @@ class VPPApiClient:
         The returned context will help with assigning which call
         the reply belongs to.
         """
-        if 'context' not in kwargs:
+        if "context" not in kwargs:
             context = self.get_context()
-            kwargs['context'] = context
+            kwargs["context"] = context
         else:
-            context = kwargs['context']
+            context = kwargs["context"]
         try:
             if self.transport.socket_index:
-                kwargs['client_index'] = self.transport.socket_index
+                kwargs["client_index"] = self.transport.socket_index
         except AttributeError:
-            kwargs['client_index'] = 0
-        kwargs['_vl_msg_id'] = i
+            kwargs["client_index"] = 0
+        kwargs["_vl_msg_id"] = i
         b = msg.pack(kwargs)
 
         self.transport.write(b)
@@ -891,26 +911,34 @@ class VPPApiClient:
         """Return VPPs API message table as name_crc dictionary,
         filtered by message name list."""
 
-        replies = [self.services[n]['reply'] for n in msglist]
+        replies = [self.services[n]["reply"] for n in msglist]
         message_table_filtered = {}
         for name in msglist + replies:
-            for k,v in self.transport.message_table.items():
+            for k, v in self.transport.message_table.items():
                 if k.startswith(name):
                     message_table_filtered[k] = v
                     break
         return message_table_filtered
 
     def __repr__(self):
-        return "<VPPApiClient apifiles=%s, testmode=%s, async_thread=%s, " \
-               "logger=%s, read_timeout=%s, " \
-               "server_address='%s'>" % (
-                   self._apifiles, self.testmode, self.async_thread,
-                   self.logger, self.read_timeout, self.server_address)
+        return (
+            "<VPPApiClient apifiles=%s, testmode=%s, async_thread=%s, "
+            "logger=%s, read_timeout=%s, "
+            "server_address='%s'>"
+            % (
+                self._apifiles,
+                self.testmode,
+                self.async_thread,
+                self.logger,
+                self.read_timeout,
+                self.server_address,
+            )
+        )
 
     def details_iter(self, f, **kwargs):
         cursor = 0
         while True:
-            kwargs['cursor'] = cursor
+            kwargs["cursor"] = cursor
             rv, details = f(**kwargs)
             for d in details:
                 yield d