Fix pylint warnings.

Change-Id: I8ef482776bcb5ec89afde39f215bd52c950a4b1b
diff --git a/pw_cli/py/pw_cli/__init__.py b/pw_cli/py/pw_cli/__init__.py
index e0c7f08..2740eab 100644
--- a/pw_cli/py/pw_cli/__init__.py
+++ b/pw_cli/py/pw_cli/__init__.py
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
+"""Auto-load default plugins for pw_cli."""
 
 # Note that these imports will trigger plugin registrations.
 import pw_cli.log
diff --git a/pw_cli/py/pw_cli/__main__.py b/pw_cli/py/pw_cli/__main__.py
index 890bd59..eb4277f 100644
--- a/pw_cli/py/pw_cli/__main__.py
+++ b/pw_cli/py/pw_cli/__main__.py
@@ -41,6 +41,8 @@
 
 
 def main(raw_args=None):
+    """Entry point for pw command."""
+
     if raw_args is None:
         raw_args = sys.argv[1:]
 
@@ -79,7 +81,7 @@
     for module in pkgutil.iter_modules():
         if module.name.startswith('pw_'):
             _LOG.debug('Found module that may have plugins: %s', module.name)
-            plugin = importlib.__import__(module.name)
+            unused_plugin = importlib.__import__(module.name)
 
     # Pull plugins out of the registry and set them up with the parser.
     subparsers = parser.add_subparsers(help='pw subcommand to run')
@@ -105,10 +107,12 @@
         del args_as_dict['loglevel']
 
     # Run the command and exit with the appropriate status.
+    # pylint: disable=protected-access
     if args._run_async:
         sys.exit(asyncio.run(args._command(**args_as_dict)))
     else:
         sys.exit(args._command(**args_as_dict))
+    # pylint: enable=protected-access
 
 
 if __name__ == "__main__":
diff --git a/pw_cli/py/pw_cli/color.py b/pw_cli/py/pw_cli/color.py
index 4cedc6d..87e0329 100644
--- a/pw_cli/py/pw_cli/color.py
+++ b/pw_cli/py/pw_cli/color.py
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
+"""Color codes for use by rest of pw_cli."""
 
 
 def _make_color(*codes):
@@ -24,6 +25,7 @@
 
 # TODO(keir): Totally replace this Color object with something more complete
 # like the 'colorful' module.
+# pylint: disable=too-few-public-methods
 class Color:
     """Helpers to surround text with ASCII color escapes"""
     red = _make_color(31, 1)
@@ -37,3 +39,6 @@
     magenta = _make_color(35, 1)
     bold_white = _make_color(37, 1)
     black_on_white = _make_color(30, 47)  # black fg white bg
+
+
+# pylint: enable=too-few-public-methods
diff --git a/pw_cli/py/pw_cli/log.py b/pw_cli/py/pw_cli/log.py
index f4f859d..e5094b5 100644
--- a/pw_cli/py/pw_cli/log.py
+++ b/pw_cli/py/pw_cli/log.py
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
+"""Configure the system logger for the default pw command log format."""
 
 import logging
 import os
@@ -40,19 +41,19 @@
 def install():
     """Configure the system logger for the default pw command log format."""
 
-    PW_SUBPROCESS = os.getenv('PW_SUBPROCESS')
-    if PW_SUBPROCESS is None:
+    pw_subprocess = os.getenv('PW_SUBPROCESS')
+    if pw_subprocess is None:
         # This applies a gray background to the time to make the log lines
         # distinct from other input, in a way that's easier to see than plain
         # colored text.
         timestamp_fmt = _Color.black_on_white('%(asctime)s') + ' '
-    elif PW_SUBPROCESS == '1':
+    elif pw_subprocess == '1':
         # If the logger is being run in the context of a pw subprocess, the
         # time and date are omitted (since pw_cli.process will provide them).
         timestamp_fmt = ''
     else:
         raise ValueError(
-            f'Invalid environment variable PW_SUBPROCESS={PW_SUBPROCESS}')
+            f'Invalid environment variable PW_SUBPROCESS={pw_subprocess}')
 
     logging.basicConfig(format=timestamp_fmt + '%(levelname)s %(message)s',
                         datefmt='%Y%m%d %H:%M:%S',
@@ -60,6 +61,7 @@
 
     # Shorten all the log levels to 3 characters for column-aligned logs.
     # Color the logs using ANSI codes.
+    # pylint: disable=bad-whitespace
     # yapf: disable
     logging.addLevelName(logging.CRITICAL, _Color.bold_red('CRT'))
     logging.addLevelName(logging.ERROR,    _Color.red     ('ERR'))
@@ -68,6 +70,7 @@
     logging.addLevelName(LOGLEVEL_STDOUT,  _Color.cyan    ('OUT'))
     logging.addLevelName(logging.DEBUG,    _Color.blue    ('DBG'))
     # yapf: enable
+    # pylint: enable=bad-whitespace
 
 
 # Note: normally this shouldn't be done at the top level without a try/catch
diff --git a/pw_cli/py/pw_cli/plugins.py b/pw_cli/py/pw_cli/plugins.py
index 5de7970..5b5a4cf 100644
--- a/pw_cli/py/pw_cli/plugins.py
+++ b/pw_cli/py/pw_cli/plugins.py
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
+"""Registry for plugins."""
 
 import argparse
 import logging
@@ -35,7 +36,7 @@
 def register(
         name: str,
         command_function: Callable,
-        help: str = '',
+        help: str = '',  # pylint: disable=redefined-builtin
         define_args_function: DefineArgsFunction = lambda _: None,
 ) -> None:
     registry.append(
diff --git a/pw_cli/py/pw_cli/watch.py b/pw_cli/py/pw_cli/watch.py
index 5d195a8..2c81990 100755
--- a/pw_cli/py/pw_cli/watch.py
+++ b/pw_cli/py/pw_cli/watch.py
@@ -11,6 +11,7 @@
 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 # License for the specific language governing permissions and limitations under
 # the License.
+"""Rebuild every time a file is chanegd."""
 
 import argparse
 import enum
@@ -30,7 +31,6 @@
 import pw_cli.plugins
 from pw_cli.color import Color as _Color
 
-import logging
 _LOG = logging.getLogger(__name__)
 
 _PASS_MESSAGE = """
@@ -70,19 +70,24 @@
     sys.exit(1)
 
 
+# pylint: disable=logging-format-interpolation
+
+
 class PigweedBuildWatcher(FileSystemEventHandler):
+    """Process filesystem events and launch builds if necessary."""
     def __init__(self,
                  patterns=None,
                  ignore_patterns=None,
                  case_sensitive=False,
-                 build_dirs=[]):
+                 build_dirs=None):
         super().__init__()
 
         self.patterns = patterns
         self.ignore_patterns = ignore_patterns
         self.case_sensitive = case_sensitive
         self.state = _State.WAITING_FOR_FILE_CHANGE_EVENT
-        self.build_dirs = build_dirs
+        self.build_dirs = build_dirs or []
+        self.cooldown_finish_time = None
 
     def path_matches(self, path):
         """Returns true if path matches according to the watcher patterns"""
@@ -109,10 +114,10 @@
         for path in paths:
             if self.path_matches(path):
                 _LOG.debug('Match for path: %s', path)
-                self.on_any_event()
+                self.on_any_event(event)
 
     def run_builds(self):
-        # Run all the builds in serial and capture pass/fail for each.
+        """Run all the builds in serial and capture pass/fail for each."""
         builds_succeeded = []
         num_builds = len(self.build_dirs)
         _LOG.info(f'Starting build with {num_builds} directories')
@@ -158,7 +163,7 @@
         else:
             print(_Color.red(_FAIL_MESSAGE))
 
-    def on_any_event(self):
+    def on_any_event(self, unused_event=None):
         if self.state == _State.WAITING_FOR_FILE_CHANGE_EVENT:
             self.run_builds()
 
@@ -210,6 +215,8 @@
 
 
 def watch(build_dir='', patterns=None, ignore_patterns=None):
+    """TODO(keir) docstring"""
+
     _LOG.info('Starting Pigweed build watcher')
 
     # If no build directory was specified, search the tree for GN build
@@ -230,11 +237,13 @@
         _die("No build dirs found. Did you forget to 'gn gen out'?")
 
     # Verify that the build output directories exist.
+    # pylint: disable=redefined-argument-from-local
     for i, build_dir in enumerate(build_dirs, 1):
         if not os.path.isdir(build_dir):
             _die("Build directory doesn't exist: %s", build_dir)
         else:
             _LOG.info(f'Will build [{i}/{len(build_dirs)}]: {build_dir}')
+    # pylint: enable=redefined-argument-from-local
 
     _LOG.debug('Patterns: %s', patterns)