Apply pw format to the repository

Change-Id: I3c8e4f956dfe6c9e81d3069f72c30c5950852074
diff --git a/docs/conf.py b/docs/conf.py
index ddc7be3..229ccdc 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -41,7 +41,9 @@
 html_theme = 'sphinx_rtd_theme'
 
 # Add any paths that contain custom themes here, relative to this directory.
-html_theme_path = ['_themes',]
+html_theme_path = [
+    '_themes',
+]
 import sphinx_rtd_theme
 html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
 
@@ -73,14 +75,12 @@
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    ('index', 'pigweed', u'Pigweed', [u'Google'], 1)
-]
+man_pages = [('index', 'pigweed', u'Pigweed', [u'Google'], 1)]
 
 # Grouping the document tree into Texinfo files. List of tuples
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'Pigweed', u'Pigweed', u'Google', 'Pigweed', 'Firmware framework',
-   'Miscellaneous'),
+    ('index', 'Pigweed', u'Pigweed', u'Google', 'Pigweed',
+     'Firmware framework', 'Miscellaneous'),
 ]
diff --git a/env_setup/cipd/cipd.py b/env_setup/cipd/cipd.py
index b0e74f2..f7f8fe1 100755
--- a/env_setup/cipd/cipd.py
+++ b/env_setup/cipd/cipd.py
@@ -46,9 +46,8 @@
 
 # Get install dir from environment since args cannot be passed through this
 # script (args are passed as-is to cipd).
-INSTALL_DIR = os.environ.get(
-    'CIPD_PY_INSTALL_DIR',
-    os.path.join(SCRIPT_DIR, 'tools'))
+INSTALL_DIR = os.environ.get('CIPD_PY_INSTALL_DIR',
+                             os.path.join(SCRIPT_DIR, 'tools'))
 CLIENT = os.path.join(INSTALL_DIR, 'cipd')
 
 
@@ -131,7 +130,7 @@
     try:
         conn = httplib.HTTPSConnection(CIPD_HOST)
     except AttributeError:
-        print('='*70)
+        print('=' * 70)
         print('''
 It looks like this version of Python does not support SSL. This is common
 when using Homebrew. If using Homebrew please run the following commands.
@@ -140,10 +139,9 @@
 brew install openssl  # Probably already installed, but good to confirm.
 brew uninstall python && brew install python
 '''.strip())
-        print('='*70)
+        print('=' * 70)
         raise
 
-
     path = '/client?platform={platform}-{arch}&version={version}'.format(
         platform=platform_normalized(),
         arch=arch_normalized(),
diff --git a/env_setup/cipd/update.py b/env_setup/cipd/update.py
index 075508e..3533a99 100755
--- a/env_setup/cipd/update.py
+++ b/env_setup/cipd/update.py
@@ -32,15 +32,14 @@
     script_root = os.path.abspath(os.path.dirname(__file__))
 
     parser = argparse.ArgumentParser(description=__doc__.splitlines()[0])
-    parser.add_argument(
-        '--install-dir', default=os.path.join(script_root, 'tools'))
-    parser.add_argument(
-        '--ensure-file', default=os.path.join(script_root, 'ensure_file'))
-    parser.add_argument(
-        '--cipd', default=os.path.join(script_root, 'cipd.py'))
-    parser.add_argument(
-        '--suppress-shell-commands', action='store_false',
-        dest='print_shell_commands')
+    parser.add_argument('--install-dir',
+                        default=os.path.join(script_root, 'tools'))
+    parser.add_argument('--ensure-file',
+                        default=os.path.join(script_root, 'ensure_file'))
+    parser.add_argument('--cipd', default=os.path.join(script_root, 'cipd.py'))
+    parser.add_argument('--suppress-shell-commands',
+                        action='store_false',
+                        dest='print_shell_commands')
 
     return parser.parse_args(argv)
 
@@ -52,13 +51,14 @@
         return True
 
     except subprocess.CalledProcessError:
-        print('='*60, file=sys.stderr)
+        print('=' * 60, file=sys.stderr)
         print('ERROR: not logged into CIPD--please run this command:')
         print(cipd, 'auth-login`', file=sys.stderr)
-        print('='*60, file=sys.stderr)
+        print('=' * 60, file=sys.stderr)
 
         if print_shell_commands:
-            with tempfile.NamedTemporaryFile(mode='w', delete=False,
+            with tempfile.NamedTemporaryFile(mode='w',
+                                             delete=False,
                                              prefix='cipdsetup') as temp:
                 print('ABORT_PW_ENVSETUP=1', file=temp)
 
@@ -99,7 +99,8 @@
     paths.append(os.environ['PATH'])
 
     if args.print_shell_commands:
-        with tempfile.NamedTemporaryFile(mode='w', delete=False,
+        with tempfile.NamedTemporaryFile(mode='w',
+                                         delete=False,
                                          prefix='cipdsetup') as temp:
             print('PATH="{}"'.format(os.pathsep.join(paths)), file=temp)
             print('export PATH', file=temp)
diff --git a/env_setup/virtualenv/init.py b/env_setup/virtualenv/init.py
index 82cde9c..ee425d4 100644
--- a/env_setup/virtualenv/init.py
+++ b/env_setup/virtualenv/init.py
@@ -52,9 +52,9 @@
 
     pip_install('--upgrade', 'pip')
 
-    package_args = tuple(
-        f'--editable={os.path.dirname(path)}' for path in git_list_files(
-            'setup.py', '*/setup.py', cwd=git_repo_root()))
+    package_args = tuple(f'--editable={os.path.dirname(path)}'
+                         for path in git_list_files(
+                             'setup.py', '*/setup.py', cwd=git_repo_root()))
 
     requirement_args = tuple(f'--requirement={req}' for req in requirements)
 
diff --git a/pw_bloat/py/binary_diff.py b/pw_bloat/py/binary_diff.py
index d080ad4..6630f04 100644
--- a/pw_bloat/py/binary_diff.py
+++ b/pw_bloat/py/binary_diff.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """The binary_diff module defines a class which stores size diff information."""
 
 import collections
@@ -21,8 +20,8 @@
 
 DiffSegment = collections.namedtuple(
     'DiffSegment', ['name', 'before', 'after', 'delta', 'capacity'])
-FormattedDiff = collections.namedtuple(
-    'FormattedDiff', ['segment', 'before', 'delta', 'after'])
+FormattedDiff = collections.namedtuple('FormattedDiff',
+                                       ['segment', 'before', 'delta', 'after'])
 
 
 def format_integer(num: int, force_sign: bool = False) -> str:
@@ -39,7 +38,6 @@
 
 class BinaryDiff:
     """A size diff between two binary files."""
-
     def __init__(self, label: str):
         self.label = label
         self._segments: collections.OrderedDict = collections.OrderedDict()
@@ -52,8 +50,8 @@
         """Yields each of the segments in this diff with formatted data."""
 
         if not self._segments:
-          yield FormattedDiff('(all)', '(same)', '0', '(same)')
-          return
+            yield FormattedDiff('(all)', '(same)', '0', '(same)')
+            return
 
         for segment in self._segments.values():
             if segment.delta == 0:
@@ -67,15 +65,15 @@
             )
 
     @classmethod
-    def from_csv(cls: Type['BinaryDiff'],
-                 label: str,
+    def from_csv(cls: Type['BinaryDiff'], label: str,
                  raw_csv: List[str]) -> 'BinaryDiff':
         """Parses a BinaryDiff from bloaty's CSV output."""
 
         diff = cls(label)
         reader = csv.reader(raw_csv)
         for row in reader:
-            diff.add_segment(DiffSegment(row[0], int(
-                row[5]), int(row[7]), int(row[1]), int(row[3])))
+            diff.add_segment(
+                DiffSegment(row[0], int(row[5]), int(row[7]), int(row[1]),
+                            int(row[3])))
 
         return diff
diff --git a/pw_bloat/py/bloat_output.py b/pw_bloat/py/bloat_output.py
index 35cd49d..4fa1230 100644
--- a/pw_bloat/py/bloat_output.py
+++ b/pw_bloat/py/bloat_output.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """Module containing different output formatters for the bloat script."""
 
 import abc
@@ -24,7 +23,6 @@
 
 class Output(abc.ABC):
     """An Output produces a size report card in a specific format."""
-
     def __init__(self,
                  title: Optional[str],
                  diffs: Collection[BinaryDiff] = ()):
@@ -34,7 +32,6 @@
     @abc.abstractmethod
     def diff(self) -> str:
         """Creates a report card for a size diff between binaries and a base."""
-
     @abc.abstractmethod
     def absolute(self) -> str:
         """Creates a report card for the absolute size breakdown of binaries."""
@@ -82,14 +79,15 @@
 
     LABEL_COLUMN = 'Label'
 
-    def __init__(self,
-                 title: Optional[str],
-                 diffs: Collection[BinaryDiff] = (),
-                 charset: Union[Type[AsciiCharset],
-                                Type[LineCharset]] = AsciiCharset,
-                 preprocess: Callable[[str], str] = identity,
-                 # TODO(frolv): Make this a Literal type.
-                 justify: str = 'rjust'):
+    def __init__(
+            self,
+            title: Optional[str],
+            diffs: Collection[BinaryDiff] = (),
+            charset: Union[Type[AsciiCharset],
+                           Type[LineCharset]] = AsciiCharset,
+            preprocess: Callable[[str], str] = identity,
+            # TODO(frolv): Make this a Literal type.
+            justify: str = 'rjust'):
         self._cs = charset
         self._preprocess = preprocess
         self._justify = justify
@@ -116,10 +114,12 @@
             padding = (len(separators['top']) - len(string)) // 2
             return ' ' * padding + string
 
-        titles = [self._center_align(val.capitalize(), column_widths[i])
-                  for i, val in enumerate(FormattedDiff._fields)]
-        column_names = [self._center_align(
-            self.LABEL_COLUMN, max_label)] + titles
+        titles = [
+            self._center_align(val.capitalize(), column_widths[i])
+            for i, val in enumerate(FormattedDiff._fields)
+        ]
+        column_names = [self._center_align(self.LABEL_COLUMN, max_label)
+                        ] + titles
 
         rows: List[str] = []
 
@@ -142,14 +142,16 @@
                 subrow: List[str] = []
                 label = diff.label if not subrows else ''
                 subrow.append(getattr(label, self._justify)(max_label, ' '))
-                subrow.extend([getattr(self._preprocess(val),
-                                       self._justify)(column_widths[i], ' ')
-                               for i, val in enumerate(segment)])
+                subrow.extend([
+                    getattr(self._preprocess(val),
+                            self._justify)(column_widths[i], ' ')
+                    for i, val in enumerate(segment)
+                ])
                 subrows.append(self._table_row(subrow))
 
             rows.append('\n'.join(subrows))
-            rows.append(separators['bot' if row ==
-                                   len(self._diffs) - 1 else 'mid'])
+            rows.append(separators['bot' if row == len(self._diffs) -
+                                   1 else 'mid'])
 
         return '\n'.join(rows)
 
@@ -196,12 +198,14 @@
 
 class RstOutput(TableOutput):
     """Tabular output in ASCII format, which is also valid RST."""
-
     def __init__(self, diffs: Collection[BinaryDiff] = ()):
         # Use RST line blocks within table cells to force each value to appear
         # on a new line in the HTML output.
         def add_rst_block(val: str) -> str:
             return f'| {val}'
 
-        super().__init__(None, diffs, AsciiCharset,
-                         preprocess=add_rst_block, justify='ljust')
+        super().__init__(None,
+                         diffs,
+                         AsciiCharset,
+                         preprocess=add_rst_block,
+                         justify='ljust')
diff --git a/pw_bloat/py/setup.py b/pw_bloat/py/setup.py
index ffe0521..f639fae 100644
--- a/pw_bloat/py/setup.py
+++ b/pw_bloat/py/setup.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """pw_bloat"""
 
 import unittest
@@ -24,11 +23,11 @@
 
 
 setuptools.setup(
-        name='pw_bloat',
-        version='0.0.1',
-        author='Pigweed Authors',
-        author_email='pigweed-developers@googlegroups.com',
-        description='Tools for generating binary size report cards',
-        packages=setuptools.find_packages(),
-        test_suite='setup.test_suite',
+    name='pw_bloat',
+    version='0.0.1',
+    author='Pigweed Authors',
+    author_email='pigweed-developers@googlegroups.com',
+    description='Tools for generating binary size report cards',
+    packages=setuptools.find_packages(),
+    test_suite='setup.test_suite',
 )
diff --git a/pw_build/py/nop.py b/pw_build/py/nop.py
index aaa4e8a..ffe4a59 100644
--- a/pw_build/py/nop.py
+++ b/pw_build/py/nop.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """Does nothing.
 
 The purpose of this script is to allow for source file dependencies within GN
diff --git a/pw_cli/py/pw_cli/__main__.py b/pw_cli/py/pw_cli/__main__.py
index ed3ce40..890bd59 100644
--- a/pw_cli/py/pw_cli/__main__.py
+++ b/pw_cli/py/pw_cli/__main__.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """
 The Pigweed command line interface (CLI)
 
diff --git a/pw_cli/py/pw_cli/color.py b/pw_cli/py/pw_cli/color.py
index adea204..4cedc6d 100644
--- a/pw_cli/py/pw_cli/color.py
+++ b/pw_cli/py/pw_cli/color.py
@@ -12,6 +12,7 @@
 # License for the specific language governing permissions and limitations under
 # the License.
 
+
 def _make_color(*codes):
     # Apply all the requested ANSI color codes. Note that this is unbalanced
     # with respect to the reset, which only requires a '0' to erase all codes.
@@ -35,6 +36,4 @@
     cyan = _make_color(36, 1)
     magenta = _make_color(35, 1)
     bold_white = _make_color(37, 1)
-    black_on_white = _make_color(30, 47) # black fg white bg
-
-
+    black_on_white = _make_color(30, 47)  # black fg white bg
diff --git a/pw_cli/py/pw_cli/log.py b/pw_cli/py/pw_cli/log.py
index 0cf68f3..f4f859d 100644
--- a/pw_cli/py/pw_cli/log.py
+++ b/pw_cli/py/pw_cli/log.py
@@ -69,6 +69,7 @@
     logging.addLevelName(logging.DEBUG,    _Color.blue    ('DBG'))
     # yapf: enable
 
+
 # Note: normally this shouldn't be done at the top level without a try/catch
 # around the pw_cli.plugins registry import, since pw_cli might not be
 # installed.
@@ -78,7 +79,6 @@
     command_function=main,
 )
 
-
 if __name__ == '__main__':
     install()
     main()
diff --git a/pw_cli/py/pw_cli/plugins.py b/pw_cli/py/pw_cli/plugins.py
index 7476bf9..5de7970 100644
--- a/pw_cli/py/pw_cli/plugins.py
+++ b/pw_cli/py/pw_cli/plugins.py
@@ -18,7 +18,6 @@
 from typing import NamedTuple
 _LOG = logging.getLogger(__name__)
 
-
 DefineArgsFunction = Callable[[argparse.ArgumentParser], None]
 
 
diff --git a/pw_cli/py/pw_cli/process.py b/pw_cli/py/pw_cli/process.py
index d747f3b..04d490e 100644
--- a/pw_cli/py/pw_cli/process.py
+++ b/pw_cli/py/pw_cli/process.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """Module for running subprocesses from pw and capturing their output."""
 
 import asyncio
@@ -24,7 +23,6 @@
 
 _LOG = logging.getLogger(__name__)
 
-
 # Environment variable passed down to subprocesses to indicate that they are
 # running as a subprocess. Can be imported by other code.
 PW_SUBPROCESS_ENV = 'PW_SUBPROCESS'
@@ -44,15 +42,15 @@
 
     stdout = asyncio.subprocess.DEVNULL if silent else asyncio.subprocess.PIPE
     process = await asyncio.create_subprocess_exec(
-        *command,
-        stdout=stdout,
-        stderr=asyncio.subprocess.STDOUT,
-        env=env)
+        *command, stdout=stdout, stderr=asyncio.subprocess.STDOUT, env=env)
 
     if process.stdout is not None:
-        while line := await process.stdout.readline():
-            _LOG.log(pw_cli.log.LOGLEVEL_STDOUT,
-                     '[%s] %s',
+        while True:
+            line = await process.stdout.readline()
+            if not line:
+                break
+
+            _LOG.log(pw_cli.log.LOGLEVEL_STDOUT, '[%s] %s',
                      Color.bold_white(process.pid),
                      line.decode().rstrip())
 
diff --git a/pw_cli/py/pw_cli/watch.py b/pw_cli/py/pw_cli/watch.py
index 9fc5618..5d195a8 100755
--- a/pw_cli/py/pw_cli/watch.py
+++ b/pw_cli/py/pw_cli/watch.py
@@ -69,6 +69,7 @@
     _LOG.fatal(*args)
     sys.exit(1)
 
+
 class PigweedBuildWatcher(FileSystemEventHandler):
     def __init__(self,
                  patterns=None,
@@ -86,8 +87,8 @@
     def path_matches(self, path):
         """Returns true if path matches according to the watcher patterns"""
         pure_path = pathlib.PurePath(path)
-        return ((not any(pure_path.match(x) for x in self.ignore_patterns)) and
-                any(pure_path.match(x) for x in self.patterns))
+        return ((not any(pure_path.match(x) for x in self.ignore_patterns))
+                and any(pure_path.match(x) for x in self.patterns))
 
     def dispatch(self, event):
         # There isn't any point in triggering builds on new directory creation.
@@ -190,21 +191,23 @@
     '*.rst',
 )
 
+
 def add_parser_arguments(parser):
+    parser.add_argument('--patterns',
+                        help=(_WATCH_PATTERN_DELIMITER +
+                              '-delimited list of globs to '
+                              'watch to trigger recompile'),
+                        default=_WATCH_PATTERN_DELIMITER.join(_WATCH_PATTERNS))
+    parser.add_argument('--ignore_patterns',
+                        help=(_WATCH_PATTERN_DELIMITER +
+                              '-delimited list of globs to '
+                              'ignore events from'))
     parser.add_argument(
-            '--patterns',
-            help=(_WATCH_PATTERN_DELIMITER + '-delimited list of globs to '
-                  'watch to trigger recompile'),
-            default=_WATCH_PATTERN_DELIMITER.join(_WATCH_PATTERNS))
-    parser.add_argument(
-            '--ignore_patterns',
-            help=(_WATCH_PATTERN_DELIMITER + '-delimited list of globs to '
-                 'ignore events from'))
-    parser.add_argument(
-            '--build_dir',
-            help=('Ninja directory to build. Can be specified '
-            'multiple times to build multiple configurations'),
-            action='append')
+        '--build_dir',
+        help=('Ninja directory to build. Can be specified '
+              'multiple times to build multiple configurations'),
+        action='append')
+
 
 def watch(build_dir='', patterns=None, ignore_patterns=None):
     _LOG.info('Starting Pigweed build watcher')
@@ -255,20 +258,21 @@
 
     # We need to ignore both the user-specified patterns and also all
     # events for files in the build output directories.
-    ignore_patterns= (ignore_patterns.split(_WATCH_PATTERN_DELIMITER)
-                      if ignore_patterns else [])
-    ignore_patterns.extend([
-        f'{build_dir}/*' for build_dir in build_dirs])
+    ignore_patterns = (ignore_patterns.split(_WATCH_PATTERN_DELIMITER)
+                       if ignore_patterns else [])
+    ignore_patterns.extend([f'{build_dir}/*' for build_dir in build_dirs])
 
     event_handler = PigweedBuildWatcher(
-            patterns=patterns.split(_WATCH_PATTERN_DELIMITER),
-            ignore_patterns=ignore_patterns,
-            build_dirs=build_dirs)
+        patterns=patterns.split(_WATCH_PATTERN_DELIMITER),
+        ignore_patterns=ignore_patterns,
+        build_dirs=build_dirs)
 
     observer = Observer()
-    observer.schedule(event_handler,
-                      path_of_directory_to_watch,
-                      recursive=True,)
+    observer.schedule(
+        event_handler,
+        path_of_directory_to_watch,
+        recursive=True,
+    )
     observer.start()
 
     _LOG.info('Directory to watch: %s', path_to_log)
@@ -294,6 +298,7 @@
 
     observer.join()
 
+
 pw_cli.plugins.register(
     name='watch',
     help='Watch files for changes',
@@ -301,12 +306,13 @@
     command_function=watch,
 )
 
+
 def main():
     parser = argparse.ArgumentParser(description='Watch for changes')
     add_parser_arguments(parser)
     args = parser.parse_args()
     watch(**vars(args))
 
+
 if __name__ == '__main__':
     main()
-
diff --git a/pw_cli/py/setup.py b/pw_cli/py/setup.py
index ab83c7d..fc0c1c4 100644
--- a/pw_cli/py/setup.py
+++ b/pw_cli/py/setup.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """pw_cli"""
 
 import unittest
@@ -24,19 +23,15 @@
 
 
 setuptools.setup(
-        name='pw_cli',
-        version='0.0.1',
-        author='Pigweed Authors',
-        author_email='pigweed-developers@googlegroups.com',
-        description='Pigweed swiss-army knife',
-        packages=setuptools.find_packages(),
-        test_suite='setup.test_suite',
-        entry_points={
-            'console_scripts': [
-                'pw = pw_cli.__main__:main'
-            ]
-        },
-        install_requires=[
-            'watchdog',
-        ],
+    name='pw_cli',
+    version='0.0.1',
+    author='Pigweed Authors',
+    author_email='pigweed-developers@googlegroups.com',
+    description='Pigweed swiss-army knife',
+    packages=setuptools.find_packages(),
+    test_suite='setup.test_suite',
+    entry_points={'console_scripts': ['pw = pw_cli.__main__:main']},
+    install_requires=[
+        'watchdog',
+    ],
 )
diff --git a/pw_docgen/py/docgen.py b/pw_docgen/py/docgen.py
index b9806f0..6ef347f 100644
--- a/pw_docgen/py/docgen.py
+++ b/pw_docgen/py/docgen.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """Renders HTML documentation using Sphinx."""
 
 # TODO(frolv): Figure out a solution for installing all library dependencies
@@ -41,20 +40,28 @@
     """Parses command-line arguments."""
 
     parser = argparse.ArgumentParser(description=__doc__)
-    parser.add_argument('--sphinx-build-dir', required=True,
+    parser.add_argument('--sphinx-build-dir',
+                        required=True,
                         help='Directory in which to build docs')
-    parser.add_argument('--conf', required=True,
+    parser.add_argument('--conf',
+                        required=True,
                         help='Path to conf.py file for Sphinx')
-    parser.add_argument('--gn-root', required=True,
+    parser.add_argument('--gn-root',
+                        required=True,
                         help='Root of the GN build tree')
-    parser.add_argument('--gn-gen-root', required=True,
+    parser.add_argument('--gn-gen-root',
+                        required=True,
                         help='Root of the GN gen tree')
-    parser.add_argument('sources', nargs='+',
+    parser.add_argument('sources',
+                        nargs='+',
                         help='Paths to the root level rst source files')
-    parser.add_argument('--out-dir', required=True,
+    parser.add_argument('--out-dir',
+                        required=True,
                         help='Output directory for rendered HTML docs')
-    parser.add_argument('--metadata', required=True,
-                        type=argparse.FileType('r'), help='Metadata JSON file')
+    parser.add_argument('--metadata',
+                        required=True,
+                        type=argparse.FileType('r'),
+                        help='Metadata JSON file')
     return parser.parse_args()
 
 
@@ -63,8 +70,10 @@
 
     # TODO(frolv): Specify the Sphinx script from a prebuilts path instead of
     # requiring it in the tree.
-    command = ['sphinx-build', '-W', '-b', 'html', '-d',
-               f'{dst_dir}/help', src_dir, f'{dst_dir}/html']
+    command = [
+        'sphinx-build', '-W', '-b', 'html', '-d', f'{dst_dir}/help', src_dir,
+        f'{dst_dir}/html'
+    ]
     return subprocess.call(command)
 
 
@@ -82,7 +91,6 @@
 
 def copy_doc_tree(args: argparse.Namespace) -> None:
     """Copies doc source and input files into a build tree."""
-
     def build_path(path):
         """Converts a source path to a filename in the build directory."""
         if path.startswith(args.gn_root):
@@ -97,7 +105,7 @@
 
     mkdir(args.sphinx_build_dir)
     for path in args.sources:
-      copy(path, f'{args.sphinx_build_dir}/')
+        copy(path, f'{args.sphinx_build_dir}/')
     copy(args.conf, f'{args.sphinx_build_dir}/conf.py')
 
     # Map of directory path to list of source and destination file paths.
diff --git a/pw_module/py/setup.py b/pw_module/py/setup.py
index e0f394f..4014feb 100644
--- a/pw_module/py/setup.py
+++ b/pw_module/py/setup.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """pw_module"""
 
 import unittest
@@ -24,11 +23,11 @@
 
 
 setuptools.setup(
-        name='pw_module',
-        version='0.0.1',
-        author='Pigweed Authors',
-        author_email='pigweed-developers@googlegroups.com',
-        description='Meta-module for Pigweed',
-        packages=setuptools.find_packages(),
-        test_suite='setup.test_suite',
+    name='pw_module',
+    version='0.0.1',
+    author='Pigweed Authors',
+    author_email='pigweed-developers@googlegroups.com',
+    description='Meta-module for Pigweed',
+    packages=setuptools.find_packages(),
+    test_suite='setup.test_suite',
 )
diff --git a/pw_string/size_report/BUILD.gn b/pw_string/size_report/BUILD.gn
index 0ad86ce..6c16b3d 100644
--- a/pw_string/size_report/BUILD.gn
+++ b/pw_string/size_report/BUILD.gn
@@ -144,9 +144,7 @@
     "$dir_pw_bloat:bloat_this_binary",
     "..",
   ]
-  defines = [
-    "USE_STRING_BUILDER=0",
-  ]
+  defines = [ "USE_STRING_BUILDER=0" ]
 }
 
 pw_executable("build_string_incremental_with_string_builder") {
@@ -157,7 +155,5 @@
     "$dir_pw_bloat:bloat_this_binary",
     "..",
   ]
-  defines = [
-    "USE_STRING_BUILDER=1",
-  ]
+  defines = [ "USE_STRING_BUILDER=1" ]
 }
diff --git a/pw_toolchain/BUILD.gn b/pw_toolchain/BUILD.gn
index 4071b90..f723c13 100644
--- a/pw_toolchain/BUILD.gn
+++ b/pw_toolchain/BUILD.gn
@@ -129,9 +129,7 @@
 
 generate_toolchains("host_clang_suite") {
   toolchain_template = "host_clang"
-  common_toolchain_cflags = [
-    "-g3",
-  ]
+  common_toolchain_cflags = [ "-g3" ]
 
   toolchains = [
     {
diff --git a/pw_unit_test/py/pw_unit_test/test_runner.py b/pw_unit_test/py/pw_unit_test/test_runner.py
index 02c60d6..279c648 100644
--- a/pw_unit_test/py/pw_unit_test/test_runner.py
+++ b/pw_unit_test/py/pw_unit_test/test_runner.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """Runs Pigweed unit tests built using GN."""
 
 import argparse
@@ -35,18 +34,28 @@
 def register_arguments(parser: argparse.ArgumentParser) -> None:
     """Registers command-line arguments."""
 
-    parser.add_argument('--root', type=str, default='out',
+    parser.add_argument('--root',
+                        type=str,
+                        default='out',
                         help='Path to the root build directory')
-    parser.add_argument('-r', '--runner', type=str, required=True,
+    parser.add_argument('-r',
+                        '--runner',
+                        type=str,
+                        required=True,
                         help='Executable which runs a test on the target')
-    parser.add_argument('runner_args', nargs=argparse.REMAINDER,
+    parser.add_argument('runner_args',
+                        nargs=argparse.REMAINDER,
                         help='Arguments to forward to the test runner')
 
     # The runner script can either run binaries directly or groups.
     group = parser.add_mutually_exclusive_group()
-    group.add_argument('-g', '--group', action='append',
+    group.add_argument('-g',
+                       '--group',
+                       action='append',
                        help='Test groups to run')
-    group.add_argument('-t', '--test', action='append',
+    group.add_argument('-t',
+                       '--test',
+                       action='append',
                        help='Test binaries to run')
 
 
@@ -59,7 +68,6 @@
 
 class Test:
     """A unit test executable."""
-
     def __init__(self, name: str, file_path: str):
         self.name: str = name
         self.file_path: str = file_path
@@ -79,7 +87,6 @@
 
 class TestGroup:
     """Graph node representing a group of unit tests."""
-
     def __init__(self, name: str, tests: Iterable[Test]):
         self._name: str = name
         self._deps: Iterable['TestGroup'] = []
@@ -112,10 +119,7 @@
 
 class TestRunner:
     """Runs unit tests by calling out to a runner script."""
-
-    def __init__(self,
-                 executable: str,
-                 args: Sequence[str],
+    def __init__(self, executable: str, args: Sequence[str],
                  tests: Iterable[Test]):
         self._executable: str = executable
         self._args: Sequence[str] = args
@@ -207,7 +211,6 @@
         populated with the paths to their unit tests and references to their
         dependencies.
     """
-
     def canonicalize(path: str) -> str:
         """Removes a trailing slash from a GN target's directory.
 
@@ -242,8 +245,8 @@
                     f'{test_directory}:{entry["test_name"]}')
 
                 if test_binary not in all_tests:
-                    all_tests[test_binary] = Test(
-                        entry['test_name'], test_binary)
+                    all_tests[test_binary] = Test(entry['test_name'],
+                                                  test_binary)
 
                 tests.append(all_tests[test_binary])
 
@@ -343,6 +346,7 @@
     argv_copy = ['pw', *sys.argv[1:]]
     await find_and_run_tests(argv_copy, **kwargs)
 
+
 try:
     import pw_cli.plugins
     pw_cli.plugins.register(
@@ -363,14 +367,22 @@
 
     parser = argparse.ArgumentParser(description=__doc__)
     register_arguments(parser)
-    parser.add_argument('-v', '--verbose', action='store_true',
+    parser.add_argument('-v',
+                        '--verbose',
+                        action='store_true',
                         help='Output additional logs as the script runs')
     args = parser.parse_args()
 
     log_level = 'DEBUG' if args.verbose else 'INFO'
     coloredlogs.install(level=log_level,
-                        level_styles={'debug': {'color': 244},
-                                      'error': {'color': 'red'}},
+                        level_styles={
+                            'debug': {
+                                'color': 244
+                            },
+                            'error': {
+                                'color': 'red'
+                            }
+                        },
                         fmt='%(asctime)s | %(message)s')
 
     args_as_dict = dict(vars(args))
diff --git a/pw_unit_test/py/setup.py b/pw_unit_test/py/setup.py
index 1c4a00c..a01787a 100644
--- a/pw_unit_test/py/setup.py
+++ b/pw_unit_test/py/setup.py
@@ -11,7 +11,6 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
-
 """pw_unit_test"""
 
 import unittest
@@ -24,14 +23,14 @@
 
 
 setuptools.setup(
-        name='pw_unit_test',
-        version='0.1.0',
-        author='Pigweed Authors',
-        author_email='pigweed-developers@googlegroups.com',
-        description='Unit tests for Pigweed projects',
-        packages=setuptools.find_packages(),
-        test_suite='setup.test_suite',
-        install_requires=[
-            'coloredlogs',
-        ],
+    name='pw_unit_test',
+    version='0.1.0',
+    author='Pigweed Authors',
+    author_email='pigweed-developers@googlegroups.com',
+    description='Unit tests for Pigweed projects',
+    packages=setuptools.find_packages(),
+    test_suite='setup.test_suite',
+    install_requires=[
+        'coloredlogs',
+    ],
 )
diff --git a/targets/stm32f429i-disc1/py/setup.py b/targets/stm32f429i-disc1/py/setup.py
index 2b24a97..9455aaa 100644
--- a/targets/stm32f429i-disc1/py/setup.py
+++ b/targets/stm32f429i-disc1/py/setup.py
@@ -34,10 +34,7 @@
     entry_points={
         'console_scripts': {
             'stm32f429i_disc1_unit_test_runner = '
-                'stm32f429i_disc1_utils.unit_test_runner:main'
+            'stm32f429i_disc1_utils.unit_test_runner:main'
         }
     },
-    install_requires=[
-        'pyserial',
-        'coloredlogs'
-    ])
+    install_requires=['pyserial', 'coloredlogs'])