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
 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:
 
 try:
     import VppTransport
 except ModuleNotFoundError:
+
     class V:
         """placeholder for VppTransport as the implementation is dependent on
         VPPAPIClient's initialization values
     class V:
         """placeholder for VppTransport as the implementation is dependent on
         VPPAPIClient's initialization values
@@ -44,15 +45,22 @@ except ModuleNotFoundError:
 
     VppTransport = V
 
 
     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())
 
 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):
 
 
 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:
     """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()
 
 
         vpp_instance.disconnect()
 
 
@@ -98,9 +106,9 @@ def add_convenience_methods():
 
     def _vapi_af_name(self):
         if 6 == self._version:
 
     def _vapi_af_name(self):
         if 6 == self._version:
-            return 'ip6'
+            return "ip6"
         if 4 == self._version:
         if 4 == self._version:
-            return 'ip4'
+            return "ip4"
         raise ValueError("Invalid _version.")
 
     ipaddress._IPAddressBase.vapi_af = property(_vapi_af)
         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 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):
 
 
 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
         # 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:
             # 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"""
 
         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
 
             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.
             '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
 
         srcdir = None
-        if dmatch('src/scripts'):
+        if dmatch("src/scripts"):
             srcdir = os.path.sep.join(localdir_s[:-2])
             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])
             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.
             # 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
 
         # 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])
             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])
             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
 
         # 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:
 
         # check the directories for existence; first one wins
         for dir in dirs:
@@ -226,7 +237,7 @@ class VPPApiJSONFiles:
         return None
 
     @classmethod
         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
         """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):
                 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:
         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):
 
         api_files = []
         for root, dirnames, files in os.walk(api_dir):
@@ -281,39 +292,39 @@ class VPPApiJSONFiles:
         services = {}
         messages = {}
         try:
         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:
         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:
         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:
         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:
         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:
         except KeyError:
             pass
 
         try:
-            services.update(api['services'])
+            services.update(api["services"])
         except KeyError:
             pass
 
         except KeyError:
             pass
 
@@ -321,30 +332,30 @@ class VPPApiJSONFiles:
         while True:
             unresolved = {}
             for k, v in types.items():
         while True:
             unresolved = {}
             for k, v in types.items():
-                t = v['data']
+                t = v["data"]
                 if not vpp_get_type(k):
                 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):
                         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
                         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
                         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
                         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:
                         try:
                             VPPTypeAlias(k, t)
                         except ValueError:
@@ -352,17 +363,16 @@ class VPPApiJSONFiles:
             if len(unresolved) == 0:
                 break
             if i > 3:
             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:
             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
                 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
         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.
     """
     provides a means to register a callback function to receive
     these messages in a background thread.
     """
+
     apidir = None
     VPPApiError = VPPApiError
     VPPRuntimeError = VPPRuntimeError
     apidir = None
     VPPApiError = VPPApiError
     VPPRuntimeError = VPPRuntimeError
@@ -387,11 +398,18 @@ class VPPApiClient:
     VPPNotImplementedError = VPPNotImplementedError
     VPPIOError = VPPIOError
 
     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
         """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(
         """
         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
             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.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()
         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:
 
         # 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))
 
         # 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."""
 
     class ContextId:
         """Multiprocessing-safe provider of unique context IDs."""
+
         def __init__(self):
             self.context = mp.Value(ctypes.c_uint, 0)
             self.lock = mp.Lock()
         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
             with self.lock:
                 self.context.value += 1
                 return self.context.value
+
     get_context = ContextId()
 
     def get_type(self, name):
     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):
         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)
             def f(**kwargs):
                 return self._call_vpp_async(i, msg, **kwargs)
+
         else:
         else:
+
             def f(**kwargs):
                 return self._call_vpp(i, msg, multipart, **kwargs)
 
         f.__name__ = str(msg.name)
             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
         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():
         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
             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:
                     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:
         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
         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(
         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:
         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:
             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)
         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.
 
     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.
         """
 
         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."""
 
     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 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:
             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
 
 
     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)
 
         (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]
             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:
             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)
             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
 
         #
             return
 
         #
@@ -633,7 +654,7 @@ class VPPApiClient:
         #
         msgobj = self.id_msgdef[i]
         if not msgobj:
         #
         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
 
         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."""
 
     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:
 
     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:
 
     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:
         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):
 
     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:
         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):
                 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()
         no response within the timeout window.
         """
         ts = time.time()
-        if 'context' not in kwargs:
+        if "context" not in kwargs:
             context = self.get_context()
             context = self.get_context()
-            kwargs['context'] = context
+            kwargs["context"] = context
         else:
         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:
 
         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)
 
         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)
         self.logger.debug(s)
 
         b = msgdef.pack(kwargs)
@@ -733,17 +753,17 @@ class VPPApiClient:
 
         self.transport.write(b)
 
 
         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:
-            if 'stream_msg' in service:
+            if "stream_msg" in service:
                 # New service['reply'] = _reply and service['stream_message'] = _details
                 # 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
             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.
                 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 = []
 
         # Block until we get a reply.
         rl = []
-        while (True):
+        while True:
             r = self.read_blocking(no_type_conversion, timeout)
             if r is None:
             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)):
             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 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
 
                     rl = r, rl
                 break
 
@@ -774,7 +794,7 @@ class VPPApiClient:
 
         self.transport.resume()
 
 
         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)
         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.
         """
         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()
             context = self.get_context()
-            kwargs['context'] = context
+            kwargs["context"] = context
         else:
         else:
-            context = kwargs['context']
+            context = kwargs["context"]
         try:
             if self.transport.socket_index:
         try:
             if self.transport.socket_index:
-                kwargs['client_index'] = self.transport.socket_index
+                kwargs["client_index"] = self.transport.socket_index
         except AttributeError:
         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)
         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."""
 
         """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:
         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):
                 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:
 
     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
             rv, details = f(**kwargs)
             for d in details:
                 yield d