pw_build: Python Mypy updates

- Pass all files to Mypy rather than the directory, in case tests
  happen to reside at different paths.
- Remove unnecessary aliases of packet_pb2 members.
- Move Python requirements that apply throughout the Python build from
  pw_presubmit to a pw_python_requirements target in pw_build.
- Update to Mypy 0.800 and mypy-protobuf 2.2.

Change-Id: I07ea07fb864ca4cd79fa5c0389e03146eca2b755
Reviewed-on: https://pigweed-review.googlesource.com/c/pigweed/pigweed/+/31600
Reviewed-by: Rob Mohr <mohrr@google.com>
diff --git a/pw_build/BUILD.gn b/pw_build/BUILD.gn
index d30bbc9..ab0f9f5 100644
--- a/pw_build/BUILD.gn
+++ b/pw_build/BUILD.gn
@@ -14,6 +14,7 @@
 
 import("//build_overrides/pigweed.gni")
 
+import("$dir_pw_build/python.gni")
 import("$dir_pw_docgen/docs.gni")
 
 # IMPORTANT: The compilation flags in this file must be kept in sync with
@@ -124,6 +125,14 @@
   depth = 1
 }
 
+# Requirements for the pw_python_package lint targets.
+pw_python_requirements("python_lint") {
+  requirements = [
+    "mypy==0.800",
+    "pylint==2.6.0",
+  ]
+}
+
 pw_doc_group("docs") {
   sources = [ "docs.rst" ]
 }
diff --git a/pw_build/python.gni b/pw_build/python.gni
index b94a526..031a7ba 100644
--- a/pw_build/python.gni
+++ b/pw_build/python.gni
@@ -244,7 +244,7 @@
   if (_should_lint || _test_sources != []) {
     # Packages that must be installed to use the package or run its tests.
     _test_install_deps = [ ":$_internal_target.install" ]
-    foreach(dep, _python_test_deps) {
+    foreach(dep, _python_test_deps + [ "$dir_pw_build:python_lint" ]) {
       _test_install_deps += [ "$dep.install" ]
     }
   }
@@ -273,11 +273,7 @@
         inputs = [ invoker.mypy_ini ]
       }
 
-      if (_is_package) {
-        args += [ rebase_path(_setup_dir) ]
-      } else {
-        args += rebase_path(_all_py_files)
-      }
+      args += rebase_path(_all_py_files)
 
       # Use this environment variable to force mypy to colorize output.
       # See https://github.com/python/mypy/issues/7771
diff --git a/pw_hdlc/BUILD.gn b/pw_hdlc/BUILD.gn
index c3f0dad..93d7344 100644
--- a/pw_hdlc/BUILD.gn
+++ b/pw_hdlc/BUILD.gn
@@ -14,6 +14,7 @@
 
 import("//build_overrides/pigweed.gni")
 
+import("$dir_pw_build/python.gni")
 import("$dir_pw_build/target_types.gni")
 import("$dir_pw_docgen/docs.gni")
 import("$dir_pw_unit_test/test.gni")
@@ -118,11 +119,14 @@
   sources = [ "encoder_test.cc" ]
 }
 
-action("generate_decoder_test") {
+pw_python_action("generate_decoder_test") {
   outputs = [ "$target_gen_dir/generated_decoder_test.cc" ]
   script = "py/decode_test.py"
   args = [ "--generate-cc-test" ] + rebase_path(outputs)
-  deps = [ "$dir_pw_build/py" ]
+  python_deps = [
+    "$dir_pw_build/py",
+    "py",
+  ]
 }
 
 pw_test("decoder_test") {
diff --git a/pw_presubmit/py/BUILD.gn b/pw_presubmit/py/BUILD.gn
index 6efb5eb..cfaa150 100644
--- a/pw_presubmit/py/BUILD.gn
+++ b/pw_presubmit/py/BUILD.gn
@@ -36,6 +36,7 @@
     "tools_test.py",
   ]
   python_deps = [
+    "$dir_pw_build:python_lint",
     "$dir_pw_cli/py",
     "$dir_pw_package/py",
   ]
diff --git a/pw_presubmit/py/setup.py b/pw_presubmit/py/setup.py
index 9832e9c..959a1d9 100644
--- a/pw_presubmit/py/setup.py
+++ b/pw_presubmit/py/setup.py
@@ -22,8 +22,6 @@
     author_email='pigweed-developers@googlegroups.com',
     description='Presubmit tools and a presubmit script for Pigweed',
     install_requires=[
-        'mypy==0.790',
-        'pylint==2.6.0',
         'yapf==0.30.0',
         'pw_cli',
         'pw_package',
diff --git a/pw_protobuf_compiler/BUILD.gn b/pw_protobuf_compiler/BUILD.gn
index f34438f..e974422 100644
--- a/pw_protobuf_compiler/BUILD.gn
+++ b/pw_protobuf_compiler/BUILD.gn
@@ -47,5 +47,5 @@
 # PyPI Requirements needed to install Python protobuf packages.
 pw_python_requirements("protobuf_requirements") {
   # mypy-protobuf 1.24 is required to support optional fields in proto3.
-  requirements = [ "mypy-protobuf>=1.24" ]
+  requirements = [ "mypy-protobuf>=2.2" ]
 }
diff --git a/pw_rpc/py/callback_client_test.py b/pw_rpc/py/callback_client_test.py
index 443b820..425fd0b 100755
--- a/pw_rpc/py/callback_client_test.py
+++ b/pw_rpc/py/callback_client_test.py
@@ -93,7 +93,7 @@
             payload = response.SerializeToString()
 
         self._next_packets.append(
-            (packet_pb2.RpcPacket(type=packets.PacketType.RESPONSE,
+            (packet_pb2.RpcPacket(type=packet_pb2.PacketType.RESPONSE,
                                   channel_id=channel_id,
                                   service_id=service_id,
                                   method_id=method_id,
@@ -107,7 +107,7 @@
                             status: Status = Status.OK,
                             process_status=Status.OK):
         self._next_packets.append(
-            (packet_pb2.RpcPacket(type=packets.PacketType.SERVER_STREAM_END,
+            (packet_pb2.RpcPacket(type=packet_pb2.PacketType.SERVER_STREAM_END,
                                   channel_id=channel_id,
                                   service_id=method.service.id,
                                   method_id=method.id,
@@ -215,7 +215,7 @@
             self._last_request = None
             self._service.SomeUnary.reinvoke(callback, magic_number=55)
             self.assertEqual(self._last_request.type,
-                             packets.PacketType.REQUEST)
+                             packet_pb2.PacketType.REQUEST)
 
     def test_invoke_server_streaming(self):
         method = self._service.SomeServerStreaming.method
@@ -277,7 +277,7 @@
         call.cancel()
 
         self.assertEqual(self._last_request.type,
-                         packets.PacketType.CANCEL_SERVER_STREAM)
+                         packet_pb2.PacketType.CANCEL_SERVER_STREAM)
 
         # Ensure the RPC can be called after being cancelled.
         self._enqueue_response(1, stub.method, response=resp)
diff --git a/pw_rpc/py/client_test.py b/pw_rpc/py/client_test.py
index bcf3d06..9a610f4 100755
--- a/pw_rpc/py/client_test.py
+++ b/pw_rpc/py/client_test.py
@@ -16,7 +16,7 @@
 
 import unittest
 
-from pw_rpc_protos.internal.packet_pb2 import RpcPacket
+from pw_rpc_protos.internal.packet_pb2 import PacketType, RpcPacket
 from pw_protobuf_compiler import python_protos
 from pw_status import Status
 
@@ -211,8 +211,7 @@
     def test_process_packet_not_for_client(self):
         self.assertIs(
             self._client.process_packet(
-                RpcPacket(
-                    type=packets.PacketType.REQUEST).SerializeToString()),
+                RpcPacket(type=PacketType.REQUEST).SerializeToString()),
             Status.INVALID_ARGUMENT)
 
     def test_process_packet_unrecognized_channel(self):
@@ -232,7 +231,7 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+            RpcPacket(type=PacketType.CLIENT_ERROR,
                       channel_id=1,
                       service_id=456,
                       method_id=789,
@@ -249,7 +248,7 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+            RpcPacket(type=PacketType.CLIENT_ERROR,
                       channel_id=1,
                       service_id=service.id,
                       method_id=789,
@@ -267,7 +266,7 @@
 
         self.assertEqual(
             self._last_packet_sent(),
-            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+            RpcPacket(type=PacketType.CLIENT_ERROR,
                       channel_id=1,
                       service_id=service.id,
                       method_id=method.id,
diff --git a/pw_rpc/py/packets_test.py b/pw_rpc/py/packets_test.py
index ea49f3b..b10b831 100755
--- a/pw_rpc/py/packets_test.py
+++ b/pw_rpc/py/packets_test.py
@@ -17,11 +17,11 @@
 import unittest
 
 from pw_status import Status
-from pw_rpc_protos.internal.packet_pb2 import RpcPacket
+from pw_rpc_protos.internal.packet_pb2 import PacketType, RpcPacket
 
 from pw_rpc import packets
 
-_TEST_REQUEST = RpcPacket(type=packets.PacketType.REQUEST,
+_TEST_REQUEST = RpcPacket(type=PacketType.REQUEST,
                           channel_id=1,
                           service_id=2,
                           method_id=3,
@@ -38,7 +38,7 @@
         self.assertEqual(_TEST_REQUEST, packet)
 
     def test_encode_response(self):
-        response = RpcPacket(type=packets.PacketType.RESPONSE,
+        response = RpcPacket(type=PacketType.RESPONSE,
                              channel_id=1,
                              service_id=2,
                              method_id=3,
@@ -58,7 +58,7 @@
 
         self.assertEqual(
             packet,
-            RpcPacket(type=packets.PacketType.CANCEL_SERVER_STREAM,
+            RpcPacket(type=PacketType.CANCEL_SERVER_STREAM,
                       channel_id=9,
                       service_id=8,
                       method_id=7))
@@ -71,7 +71,7 @@
 
         self.assertEqual(
             packet,
-            RpcPacket(type=packets.PacketType.CLIENT_ERROR,
+            RpcPacket(type=PacketType.CLIENT_ERROR,
                       channel_id=1,
                       service_id=2,
                       method_id=3,
@@ -86,7 +86,7 @@
 
         self.assertFalse(
             packets.for_server(
-                RpcPacket(type=packets.PacketType.RESPONSE,
+                RpcPacket(type=PacketType.RESPONSE,
                           channel_id=1,
                           service_id=2,
                           method_id=3,
diff --git a/pw_rpc/py/pw_rpc/client.py b/pw_rpc/py/pw_rpc/client.py
index 6c47ceb..2fd7ee1 100644
--- a/pw_rpc/py/pw_rpc/client.py
+++ b/pw_rpc/py/pw_rpc/client.py
@@ -19,11 +19,11 @@
 from typing import Collection, Dict, Iterable, Iterator, List, NamedTuple
 from typing import Optional
 
-from pw_rpc_protos.internal.packet_pb2 import RpcPacket
+from google.protobuf.message import DecodeError
+from pw_rpc_protos.internal.packet_pb2 import PacketType, RpcPacket
 from pw_status import Status
 
 from pw_rpc import descriptors, packets
-from pw_rpc.packets import PacketType
 from pw_rpc.descriptors import Channel, Service, Method
 
 _LOG = logging.getLogger(__name__)
@@ -207,7 +207,7 @@
     if packet.type == PacketType.RESPONSE:
         try:
             return packets.decode_payload(packet, rpc.method.response_type)
-        except packets.DecodeError as err:
+        except DecodeError as err:
             _LOG.warning('Failed to decode %s response for %s: %s',
                          rpc.method.response_type.DESCRIPTOR.full_name,
                          rpc.method.full_name, err)
@@ -340,7 +340,7 @@
         """
         try:
             packet = packets.decode(pw_rpc_raw_packet_data)
-        except packets.DecodeError as err:
+        except DecodeError as err:
             _LOG.warning('Failed to decode packet: %s', err)
             _LOG.debug('Raw packet: %r', pw_rpc_raw_packet_data)
             return Status.DATA_LOSS
diff --git a/pw_rpc/py/pw_rpc/packets.py b/pw_rpc/py/pw_rpc/packets.py
index 3ca6fbd..dd0917c 100644
--- a/pw_rpc/py/pw_rpc/packets.py
+++ b/pw_rpc/py/pw_rpc/packets.py
@@ -17,11 +17,6 @@
 from pw_rpc_protos.internal import packet_pb2
 from pw_status import Status
 
-DecodeError = message.DecodeError
-Message = message.Message
-
-PacketType = packet_pb2.PacketType
-
 
 def decode(data: bytes):
     packet = packet_pb2.RpcPacket()
diff --git a/pw_rpc/py/setup.py b/pw_rpc/py/setup.py
index 230b7ad..12a943e 100644
--- a/pw_rpc/py/setup.py
+++ b/pw_rpc/py/setup.py
@@ -33,6 +33,7 @@
     install_requires=[
         'protobuf',
         'pw_protobuf_compiler',
+        'pw_rpc_protos',
         'pw_status',
     ],
     tests_require=['pw_build'],