style: use .format() in various places instead of "%" formatting
diff --git a/serial/__init__.py b/serial/__init__.py
index 2d2237b..049cff1 100644
--- a/serial/__init__.py
+++ b/serial/__init__.py
@@ -30,7 +30,7 @@
     elif os.name == 'java':
         from serial.serialjava import Serial
     else:
-        raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
+        raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name))
 
 
 protocol_handler_packages = [
@@ -66,7 +66,7 @@
         # if it is an URL, try to import the handler module from the list of possible packages
         if '://' in url_lowercase:
             protocol = url_lowercase.split('://', 1)[0]
-            module_name = '.protocol_%s' % (protocol,)
+            module_name = '.protocol_{}'.format(protocol)
             for package_name in protocol_handler_packages:
                 try:
                     importlib.import_module(package_name)
@@ -80,7 +80,7 @@
                         klass = handler_module.Serial
                     break
             else:
-                raise ValueError('invalid URL, protocol %r not known' % (protocol,))
+                raise ValueError('invalid URL, protocol {!r} not known'.format(protocol))
     # instantiate and open when desired
     instance = klass(None, *args, **kwargs)
     instance.port = url
diff --git a/serial/tools/hexlify_codec.py b/serial/tools/hexlify_codec.py
index 635f7d3..1371da2 100644
--- a/serial/tools/hexlify_codec.py
+++ b/serial/tools/hexlify_codec.py
@@ -91,7 +91,7 @@
                 state = 0
             else:
                 if self.errors == 'strict':
-                    raise UnicodeError('non-hex digit found: %r' % c)
+                    raise UnicodeError('non-hex digit found: {!r}'.format(c))
         self.state = state
         return serial.to_bytes(encoded)
 
diff --git a/serial/tools/list_ports.py b/serial/tools/list_ports.py
index 8041c70..2271dd1 100644
--- a/serial/tools/list_ports.py
+++ b/serial/tools/list_ports.py
@@ -29,7 +29,7 @@
     from serial.tools.list_ports_posix import comports
 #~ elif os.name == 'java':
 else:
-    raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
+    raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name))
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 
@@ -79,7 +79,7 @@
     # get iteraror w/ or w/o filter
     if args.regexp:
         if not args.quiet:
-            sys.stderr.write("Filtered list with regexp: %r\n" % (args.regexp,))
+            sys.stderr.write("Filtered list with regexp: {!r}\n".format(args.regexp))
         iterator = sorted(grep(args.regexp))
     else:
         iterator = sorted(comports())
diff --git a/serial/tools/list_ports_linux.py b/serial/tools/list_ports_linux.py
index f957efe..567df6d 100644
--- a/serial/tools/list_ports_linux.py
+++ b/serial/tools/list_ports_linux.py
@@ -20,8 +20,8 @@
         super(SysFS, self).__init__(device)
         self.name = os.path.basename(device)
         self.usb_device_path = None
-        if os.path.exists('/sys/class/tty/%s/device' % (self.name,)):
-            self.device_path = os.path.realpath('/sys/class/tty/%s/device' % (self.name,))
+        if os.path.exists('/sys/class/tty/{}/device'.format(self.name)):
+            self.device_path = os.path.realpath('/sys/class/tty/{}/device'.format(self.name))
             self.subsystem = os.path.basename(os.path.realpath(os.path.join(self.device_path, 'subsystem')))
         else:
             self.device_path = None
@@ -81,4 +81,4 @@
 # test
 if __name__ == '__main__':
     for port, desc, hwid in sorted(comports()):
-        print("%s: %s [%s]" % (port, desc, hwid))
+        print("{}: {} [{}]".format(port, desc, hwid))
diff --git a/serial/tools/list_ports_osx.py b/serial/tools/list_ports_osx.py
index 55ef7f4..1d57b96 100644
--- a/serial/tools/list_ports_osx.py
+++ b/serial/tools/list_ports_osx.py
@@ -256,4 +256,4 @@
 # test
 if __name__ == '__main__':
     for port, desc, hwid in sorted(comports()):
-        print("%s: %s [%s]" % (port, desc, hwid))
+        print("{}: {} [{}]".format(port, desc, hwid))
diff --git a/serial/tools/list_ports_posix.py b/serial/tools/list_ports_posix.py
index 1901e60..6ea4db9 100644
--- a/serial/tools/list_ports_posix.py
+++ b/serial/tools/list_ports_posix.py
@@ -86,16 +86,16 @@
 ! I you know how the serial ports are named send this information to
 ! the author of this module:
 
-sys.platform = %r
-os.name = %r
-pySerial version = %s
+sys.platform = {!r}
+os.name = {!r}
+pySerial version = {}
 
 also add the naming scheme of the serial ports and with a bit luck you can get
 this module running...
-""" % (sys.platform, os.name, serial.VERSION))
-    raise ImportError("Sorry: no implementation for your platform ('%s') available" % (os.name,))
+""".format(sys.platform, os.name, serial.VERSION))
+    raise ImportError("Sorry: no implementation for your platform ('{}') available".format(os.name))
 
 # test
 if __name__ == '__main__':
     for port, desc, hwid in sorted(comports()):
-        print("%s: %s [%s]" % (port, desc, hwid))
+        print("{}: {} [{}]".format(port, desc, hwid))
diff --git a/serial/tools/list_ports_windows.py b/serial/tools/list_ports_windows.py
index 89f3db7..a2922f8 100644
--- a/serial/tools/list_ports_windows.py
+++ b/serial/tools/list_ports_windows.py
@@ -66,12 +66,12 @@
     ]
 
     def __str__(self):
-        return "{%08x-%04x-%04x-%s-%s}" % (
+        return "{{{:08x}-{:04x}-{:04x}-{}-{}}}".format(
             self.Data1,
             self.Data2,
             self.Data3,
-            ''.join(["%02x" % d for d in self.Data4[:2]]),
-            ''.join(["%02x" % d for d in self.Data4[2:]]),
+            ''.join(["{:02x}".format(d) for d in self.Data4[:2]]),
+            ''.join(["{:02x}".format(d) for d in self.Data4[2:]]),
         )
 
 
@@ -84,7 +84,7 @@
     ]
 
     def __str__(self):
-        return "ClassGuid:%s DevInst:%s" % (self.ClassGuid, self.DevInst)
+        return "ClassGuid:{} DevInst:{}".format(self.ClassGuid, self.DevInst)
 
 PSP_DEVINFO_DATA = ctypes.POINTER(SP_DEVINFO_DATA)
 
@@ -246,7 +246,7 @@
                     location = []
                     for g in m:
                         if g.group(1):
-                            location.append('%d' % (int(g.group(1)) + 1))
+                            location.append('{:d}'.format(int(g.group(1)) + 1))
                         else:
                             if len(location) > 1:
                                 location.append('.')
@@ -297,4 +297,4 @@
 # test
 if __name__ == '__main__':
     for port, desc, hwid in sorted(comports()):
-        print("%s: %s [%s]" % (port, desc, hwid))
+        print("{}: {} [{}]".format(port, desc, hwid))
diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py
index 420bf12..145996f 100644
--- a/serial/tools/miniterm.py
+++ b/serial/tools/miniterm.py
@@ -32,7 +32,7 @@
     """generate a readable description for a key"""
     ascii_code = ord(character)
     if ascii_code < 32:
-        return 'Ctrl+%c' % (ord('@') + ascii_code)
+        return 'Ctrl+{:c}'.format(ord('@') + ascii_code)
     else:
         return repr(character)
 
@@ -322,7 +322,6 @@
     sys.stderr.write('\n--- Available ports:\n')
     ports = []
     for n, (port, desc, hwid) in enumerate(sorted(comports()), 1):
-        #~ sys.stderr.write('--- %-20s %s [%s]\n' % (port, desc, hwid))
         sys.stderr.write('--- {:2}: {:20} {}\n'.format(n, port, desc))
         ports.append(port)
     while True:
diff --git a/serial/urlhandler/protocol_alt.py b/serial/urlhandler/protocol_alt.py
index e33144e..c14a87e 100644
--- a/serial/urlhandler/protocol_alt.py
+++ b/serial/urlhandler/protocol_alt.py
@@ -30,23 +30,23 @@
     if parts.scheme != 'alt':
         raise serial.SerialException(
             'expected a string in the form "alt://port[?option[=value][&option[=value]]]": '
-            'not starting with alt:// (%r)' % (parts.scheme,))
+            'not starting with alt:// ({!r})'.format(parts.scheme))
     class_name = 'Serial'
     try:
         for option, values in urlparse.parse_qs(parts.query, True).items():
             if option == 'class':
                 class_name = values[0]
             else:
-                raise ValueError('unknown option: %r' % (option,))
+                raise ValueError('unknown option: {!r}'.format(option))
     except ValueError as e:
         raise serial.SerialException(
             'expected a string in the form '
-            '"alt://port[?option[=value][&option[=value]]]": %s' % e)
+            '"alt://port[?option[=value][&option[=value]]]": {!r}'.format(e))
     if not hasattr(serial, class_name):
-        raise ValueError('unknown class: %r' % (class_name,))
+        raise ValueError('unknown class: {!r}'.format(class_name))
     cls = getattr(serial, class_name)
     if not issubclass(cls, serial.Serial):
-        raise ValueError('class %r is not an instance of Serial' % (class_name,))
+        raise ValueError('class {!r} is not an instance of Serial'.format(class_name))
     return (''.join([parts.netloc, parts.path]), cls)
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/serial/urlhandler/protocol_hwgrep.py b/serial/urlhandler/protocol_hwgrep.py
index 9b3a082..49bbebe 100644
--- a/serial/urlhandler/protocol_hwgrep.py
+++ b/serial/urlhandler/protocol_hwgrep.py
@@ -59,12 +59,12 @@
                 # pick n'th element
                 n = int(value) - 1
                 if n < 1:
-                    raise ValueError('option "n" expects a positive integer larger than 1: %r' % (value,))
+                    raise ValueError('option "n" expects a positive integer larger than 1: {!r}'.format(value))
             elif option == 'skip_busy':
                 # open to test if port is available. not the nicest way..
                 test_open = True
             else:
-                raise ValueError('unknown option: %r' % (option,))
+                raise ValueError('unknown option: {!r}'.format(option))
         # use a for loop to get the 1st element from the generator
         for port, desc, hwid in sorted(serial.tools.list_ports.grep(regexp)):
             if test_open:
@@ -80,7 +80,7 @@
                 continue
             return port
         else:
-            raise serial.SerialException('no ports found matching regexp %r' % (url,))
+            raise serial.SerialException('no ports found matching regexp {!r}'.format(url))
 
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 if __name__ == '__main__':
diff --git a/serial/urlhandler/protocol_loop.py b/serial/urlhandler/protocol_loop.py
index daf2415..819da77 100644
--- a/serial/urlhandler/protocol_loop.py
+++ b/serial/urlhandler/protocol_loop.py
@@ -91,7 +91,7 @@
         """
         # not that's it of any real use, but it helps in the unit tests
         if not isinstance(self._baudrate, numbers.Integral) or not 0 < self._baudrate < 2 ** 32:
-            raise ValueError("invalid baudrate: %r" % (self._baudrate))
+            raise ValueError("invalid baudrate: {!r}".format(self._baudrate))
         if self.logger:
             self.logger.info('_reconfigure_port()')
 
@@ -102,7 +102,7 @@
             raise SerialException(
                 'expected a string in the form '
                 '"loop://[?logging={debug|info|warning|error}]": not starting '
-                'with loop:// (%r)' % (parts.scheme,))
+                'with loop:// ({!r})'.format(parts.scheme))
         try:
             # process options now, directly altering self
             for option, values in urlparse.parse_qs(parts.query, True).items():
@@ -112,11 +112,11 @@
                     self.logger.setLevel(LOGGER_LEVELS[values[0]])
                     self.logger.debug('enabled logging')
                 else:
-                    raise ValueError('unknown option: %r' % (option,))
+                    raise ValueError('unknown option: {!r}'.format(option))
         except ValueError as e:
             raise SerialException(
                 'expected a string in the form '
-                '"loop://[?logging={debug|info|warning|error}]": %s' % e)
+                '"loop://[?logging={debug|info|warning|error}]": {}'.format(e))
 
     #  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
 
@@ -128,7 +128,7 @@
         if self.logger:
             # attention the logged value can differ from return value in
             # threaded environments...
-            self.logger.debug('in_waiting -> %d' % (self.queue.qsize(),))
+            self.logger.debug('in_waiting -> {:d}'.format(self.queue.qsize()))
         return self.queue.qsize()
 
     def read(self, size=1):
@@ -217,17 +217,17 @@
         possible.
         """
         if self.logger:
-            self.logger.info('_update_break_state(%r)' % (self._break_state,))
+            self.logger.info('_update_break_state({!r})'.format(self._break_state))
 
     def _update_rts_state(self):
         """Set terminal status line: Request To Send"""
         if self.logger:
-            self.logger.info('_update_rts_state(%r) -> state of CTS' % (self._rts_state,))
+            self.logger.info('_update_rts_state({!r}) -> state of CTS'.format(self._rts_state))
 
     def _update_dtr_state(self):
         """Set terminal status line: Data Terminal Ready"""
         if self.logger:
-            self.logger.info('_update_dtr_state(%r) -> state of DSR' % (self._dtr_state,))
+            self.logger.info('_update_dtr_state({!r}) -> state of DSR'.format(self._dtr_state))
 
     @property
     def cts(self):
@@ -235,14 +235,14 @@
         if not self.is_open:
             raise portNotOpenError
         if self.logger:
-            self.logger.info('CTS -> state of RTS (%r)' % (self._rts_state,))
+            self.logger.info('CTS -> state of RTS ({!r})'.format(self._rts_state))
         return self._rts_state
 
     @property
     def dsr(self):
         """Read terminal status line: Data Set Ready"""
         if self.logger:
-            self.logger.info('DSR -> state of DTR (%r)' % (self._dtr_state,))
+            self.logger.info('DSR -> state of DTR ({!r})'.format(self._dtr_state))
         return self._dtr_state
 
     @property
@@ -271,11 +271,11 @@
 if __name__ == '__main__':
     import sys
     s = Serial('loop://')
-    sys.stdout.write('%s\n' % s)
+    sys.stdout.write('{}\n'.format(s))
 
     sys.stdout.write("write...\n")
     s.write("hello\n")
     s.flush()
-    sys.stdout.write("read: %s\n" % s.read(5))
+    sys.stdout.write("read: {!r}\n".format(s.read(5)))
 
     s.close()
diff --git a/serial/urlhandler/protocol_spy.py b/serial/urlhandler/protocol_spy.py
index 939d5aa..3479010 100644
--- a/serial/urlhandler/protocol_spy.py
+++ b/serial/urlhandler/protocol_spy.py
@@ -173,7 +173,7 @@
             raise serial.SerialException(
                 'expected a string in the form '
                 '"spy://port[?option[=value][&option[=value]]]": '
-                'not starting with spy:// (%r)' % (parts.scheme,))
+                'not starting with spy:// ({!r})'.format(parts.scheme))
         # process options now, directly altering self
         formatter = FormatHexdump
         color = False
@@ -189,11 +189,11 @@
                 elif option == 'all':
                     self.show_all = True
                 else:
-                    raise ValueError('unknown option: %r' % (option,))
+                    raise ValueError('unknown option: {!r}'.format(option))
         except ValueError as e:
             raise serial.SerialException(
                 'expected a string in the form '
-                '"spy://port[?option[=value][&option[=value]]]": %s' % e)
+                '"spy://port[?option[=value][&option[=value]]]": {}'.format(e))
         self.formatter = formatter(output, color)
         return ''.join([parts.netloc, parts.path])