From 3877c7d188ebd0d807a66ce82fecc4285653f4c9 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 17 Feb 2025 15:49:20 +0000
Subject: [PATCH 01/14] mypy-full_packages unittests

---
 .github/workflows/python_actions.yml | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml
index a0093e871..7de181537 100644
--- a/.github/workflows/python_actions.yml
+++ b/.github/workflows/python_actions.yml
@@ -26,6 +26,5 @@ jobs:
       coverage-package: pacman
       flake8-packages: pacman unittests pacman_test_objects
       pylint-packages: pacman pacman_test_objects
-      mypy-full_packages: pacman pacman_test_objects
-      mypy-packages: unittests
+      mypy-full_packages: pacman pacman_test_objects unittests
     secrets: inherit

From 3100ccb25d1b1e275d3352396906f025db50ec01 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 17 Feb 2025 15:58:37 +0000
Subject: [PATCH 02/14] remove incorrect unreached test code

---
 .../splitter_slice_legacy_test.py                 | 15 ++++-----------
 1 file changed, 4 insertions(+), 11 deletions(-)

diff --git a/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py b/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
index ac30793f4..9cdaa85e7 100644
--- a/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
+++ b/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
@@ -13,7 +13,6 @@
 # limitations under the License.
 
 import unittest
-from testfixtures import LogCapture  # type: ignore[import]
 from pacman.config_setup import unittest_setup
 from pacman.exceptions import PacmanConfigurationException
 from pacman.model.partitioner_splitters import SplitterFixedLegacy
@@ -25,22 +24,16 @@ class TestSplitterFixedLegacy(unittest.TestCase):
     """ Tester for SplitterFixedLegacy
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_no_api(self):
+    def test_no_api(self) -> None:
         splitter = SplitterFixedLegacy()
         vertex = NonLegacyApplicationVertex()
         with self.assertRaises(PacmanConfigurationException):
             splitter.set_governed_app_vertex(vertex)
 
-    def test_with_api(self):
+    def test_with_api(self) -> None:
         splitter = SplitterFixedLegacy()
         vertex = SimpleTestVertex(12)
-        with LogCapture() as lc:
-            splitter.set_governed_app_vertex(vertex)
-            found = False
-            for record in lc.records:
-                if record.msg.fmt == splitter.NOT_API_WARNING:
-                    found = True
-            self.assertFalse(found)
+        splitter.set_governed_app_vertex(vertex)

From 4e21a93e93773a865cd1e2e546330848df03016f Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 17 Feb 2025 16:06:24 +0000
Subject: [PATCH 03/14] unittest typing

---
 mypyd.bash                                    |   2 +-
 unittests/data/test_data.py                   | 112 ++++++++++--------
 .../test_application_edge.py                  |  15 +--
 .../test_application_graph.py                 |  14 +--
 .../test_application_other.py                 |   6 +-
 .../test_application_vertex.py                |  52 ++++----
 .../graph_mapper_tests/test_graph_mapping.py  |   6 +-
 .../graph_mapper_tests/test_slice.py          |   8 +-
 .../machine_graph_tests/test_partitions.py    |  19 +--
 .../splitter_slice_legacy_test.py             |   4 +-
 .../test_placement_constraints.py             |   4 +-
 .../placement_tests/test_placement_object.py  |   8 +-
 .../placement_tests/test_placements_model.py  |  16 +--
 .../resources_tests/test_resources_model.py   |  32 ++---
 .../routing_info_tests/test_routing_info.py   |  29 ++---
 .../test_routing_tables_model.py              |  22 ++--
 .../test_one_app_one_machine.py               |   6 +-
 .../test_splitter_fixed_legacy.py             |   6 +-
 .../test_splitter_one_to_one_legacy.py        |   6 +-
 .../splitter_tests/test_splitter_reset.py     |   4 +-
 .../tag_tests/test_tag_infos_model.py         |  20 ++--
 unittests/model_tests/test_md_slice.py        |  10 +-
 unittests/model_tests/test_mdslice.py         |  14 +--
 unittests/model_tests/test_slice.py           |  22 ++--
 .../test_basic_partitioner.py                 |  12 +-
 .../test_application_placer.py                |  10 +-
 .../router_algorithms_tests/test_routers.py   |  42 +++----
 ...test_checked_unordered_pair_compression.py |   7 +-
 .../test_compressors.py                       |  18 +--
 .../test_ordered_covering_compression.py      |   9 +-
 .../test_pair_compression.py                  |  13 +-
 .../test_range_compressor.py                  |  21 ++--
 .../test_unordered_pair_compression.py        |  13 +-
 .../test_zoned_routing_allocator.py           |   8 +-
 .../test_basic.py                             |  22 ++--
 .../test_merged.py                            |  36 +++---
 .../test_tags_board_addresses.py              |  16 +--
 unittests/test_cfg_checker.py                 |   2 +-
 unittests/test_import_all.py                  |   2 +-
 unittests/test_version.py                     |   4 +-
 unittests/utilities_tests/test_constants.py   |   4 +-
 unittests/utilities_tests/test_json_utils.py  |   4 +-
 .../utilities_tests/test_routing_tree.py      |   4 +-
 43 files changed, 368 insertions(+), 316 deletions(-)

diff --git a/mypyd.bash b/mypyd.bash
index 7fb44b1d9..333bedae3 100755
--- a/mypyd.bash
+++ b/mypyd.bash
@@ -23,4 +23,4 @@ utils="../SpiNNUtils/spinn_utilities"
 machine="../SpiNNMachine/spinn_machine"
 man="../SpiNNMan/spinnman"
 
-mypy --python-version 3.8 --disallow-untyped-defs $utils $machine $man pacman pacman_test_objects
+mypy --python-version 3.8 --disallow-untyped-defs $utils $machine $man pacman pacman_test_objects unittests
diff --git a/unittests/data/test_data.py b/unittests/data/test_data.py
index 7097e121f..42dad2b3b 100644
--- a/unittests/data/test_data.py
+++ b/unittests/data/test_data.py
@@ -39,37 +39,38 @@ class SimpleTestVertex2(SimpleTestVertex):
 
 class TestSimulatorData(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_setup(self):
+    def test_setup(self) -> None:
         # What happens before setup depends on the previous test
         # Use manual_check to verify this without dependency
         PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_n_placements()
 
-    def test_mock(self):
+    def test_mock(self) -> None:
         PacmanDataWriter.mock()
         # check there is a value not what it is
         PacmanDataView.get_run_dir_path()
 
-    def test_graph_functions(self):
+    def test_graph_functions(self) -> None:
         writer = PacmanDataWriter.setup()
+        sdram = ConstantSDRAM(123)
         app1 = SimpleTestVertex(12, "app1")
-        m11 = app1.create_machine_vertex(Slice(0, 6), None)
+        m11 = app1.create_machine_vertex(Slice(0, 6), sdram)
         app1.remember_machine_vertex(m11)
-        m12 = app1.create_machine_vertex(Slice(7, 12), None)
+        m12 = app1.create_machine_vertex(Slice(7, 12), sdram)
         app1.remember_machine_vertex(m12)
         app2 = SimpleTestVertex2(23, "app21")
-        m21 = app2.create_machine_vertex(Slice(0, 23), None)
+        m21 = app2.create_machine_vertex(Slice(0, 23), sdram)
         app2.remember_machine_vertex(m21)
         app3 = SimpleTestVertex2(33, "app3")
-        m31 = app3.create_machine_vertex(Slice(0, 11), None)
+        m31 = app3.create_machine_vertex(Slice(0, 11), sdram)
         app3.remember_machine_vertex(m31)
-        m32 = app3.create_machine_vertex(Slice(11, 22), None)
+        m32 = app3.create_machine_vertex(Slice(11, 22), sdram)
         app3.remember_machine_vertex(m32)
-        m33 = app3.create_machine_vertex(Slice(22, 33), None)
+        m33 = app3.create_machine_vertex(Slice(22, 33), sdram)
         app3.remember_machine_vertex(m33)
         edge12 = ApplicationEdge(app1, app2)
         edge32 = ApplicationEdge(app3, app2)
@@ -98,7 +99,7 @@ def test_graph_functions(self):
         self.assertEqual(2, PacmanDataView.get_n_partitions())
         ps = PacmanDataView.get_outgoing_edge_partitions_starting_at_vertex(
             app1)
-        self.assertEqual(1, len(ps))
+        self.assertEqual(1, len(list(ps)))
         self.assertEqual([edge12, edge13, edge11, edge32],
                          PacmanDataView.get_edges())
         self.assertEqual(6, PacmanDataView.get_n_machine_vertices())
@@ -123,18 +124,20 @@ def test_graph_functions(self):
         with self.assertRaises(SimulatorShutdownException):
             PacmanDataView.add_edge(ApplicationEdge(app1, app2), "new")
 
-    def test_graph_safety_code(self):
+    def test_graph_safety_code(self) -> None:
         writer = PacmanDataWriter.setup()
         # there is always a graph so to hit safety code you need a hack
-        writer._PacmanDataWriter__pacman_data._graph = None
+        (writer.  # type: ignore[attr-defined]
+         _PacmanDataWriter__pacman_data)._graph = None
         with self.assertRaises(DataNotYetAvialable):
-            writer.add_vertex(None)
+            writer.add_vertex(SimpleTestVertex(1))
         with self.assertRaises(DataNotYetAvialable):
-            writer.add_edge(None, None)
+            writer.add_edge(ApplicationEdge(
+                SimpleTestVertex(1), SimpleTestVertex2(1)), "test")
         with self.assertRaises(DataNotYetAvialable):
             writer.iterate_vertices()
         with self.assertRaises(DataNotYetAvialable):
-            list(writer.get_vertices_by_type(None))
+            list(writer.get_vertices_by_type(SimpleTestVertex))
         with self.assertRaises(DataNotYetAvialable):
             writer.get_n_vertices()
         with self.assertRaises(DataNotYetAvialable):
@@ -142,7 +145,8 @@ def test_graph_safety_code(self):
         with self.assertRaises(DataNotYetAvialable):
             writer.get_n_partitions()
         with self.assertRaises(DataNotYetAvialable):
-            writer.get_outgoing_edge_partitions_starting_at_vertex(None)
+            writer.get_outgoing_edge_partitions_starting_at_vertex(
+                SimpleTestVertex(1))
         with self.assertRaises(DataNotYetAvialable):
             writer.get_edges()
         with self.assertRaises(DataNotYetAvialable):
@@ -150,47 +154,54 @@ def test_graph_safety_code(self):
         with self.assertRaises(DataNotYetAvialable):
             list(writer.iterate_machine_vertices())
 
-    def test_graph_never_changes(self):
+    def test_graph_never_changes(self) -> None:
         writer = PacmanDataWriter.setup()
         # graph is hidden so need a hack to get it.
-        graph1 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         writer.start_run()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph2 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
         writer.finish_run()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
         writer.soft_reset()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
         writer.hard_reset()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
         writer.start_run()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
         writer.finish_run()
-        graph2 = writer._PacmanDataWriter__pacman_data._graph
+        graph1 = (writer.  # type: ignore[attr-defined]
+                  _PacmanDataWriter__pacman_data._graph)
         self.assertEqual(id(graph1), id(graph2))
 
-    def test_placements_safety_code(self):
+    def test_placements_safety_code(self) -> None:
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             writer.iterate_placemements()
         with self.assertRaises(DataNotYetAvialable):
-            writer.iterate_placements_by_vertex_type(None)
+            writer.iterate_placements_by_vertex_type(SimpleTestVertex)
         with self.assertRaises(DataNotYetAvialable):
-            writer.iterate_placements_on_core((None, None))
+            writer.iterate_placements_on_core((1, 2))
         with self.assertRaises(DataNotYetAvialable):
-            writer.iterate_placements_by_xy_and_type((None, None), None)
+            writer.iterate_placements_by_xy_and_type((1, 1), SimpleTestVertex)
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_n_placements()
         with self.assertRaises(DataNotYetAvialable):
-            PacmanDataView.get_placement_of_vertex(None)
+            PacmanDataView.get_placement_of_vertex(SimpleMachineVertex(None))
         with self.assertRaises(DataNotYetAvialable):
-            PacmanDataView.get_placement_on_processor(None, None, None)
+            PacmanDataView.get_placement_on_processor(1, 2, 3)
 
-    def test_placements(self):
+    def test_placements(self) -> None:
         writer = PacmanDataWriter.setup()
         info = Placements([])
         p1 = Placement(SimpleMachineVertex(None), 1, 2, 3)
@@ -209,9 +220,9 @@ def test_placements(self):
             PacmanDataView.get_placement_of_vertex(SimpleMachineVertex(None))
 
         with self.assertRaises(TypeError):
-            writer.set_placements("Bacon")
+            writer.set_placements("Bacon")  # type: ignore[arg-type]
 
-    def test_routing_infos(self):
+    def test_routing_infos(self) -> None:
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_routing_infos()
@@ -219,9 +230,9 @@ def test_routing_infos(self):
         writer.set_routing_infos(info)
         self.assertEqual(info, PacmanDataView.get_routing_infos())
         with self.assertRaises(TypeError):
-            writer.set_routing_infos("Bacon")
+            writer.set_routing_infos("Bacon")  # type: ignore[arg-type]
 
-    def test_tags(self):
+    def test_tags(self) -> None:
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_tags()
@@ -229,9 +240,9 @@ def test_tags(self):
         writer.set_tags(tags)
         self.assertEqual(tags, PacmanDataView.get_tags())
         with self.assertRaises(TypeError):
-            writer.set_tags("Bacon")
+            writer.set_tags("Bacon")  # type: ignore[arg-type]
 
-    def test_router_tables(self):
+    def test_router_tables(self) -> None:
         table = MulticastRoutingTables()
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
@@ -241,9 +252,9 @@ def test_router_tables(self):
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_precompressed()
         with self.assertRaises(TypeError):
-            writer.set_uncompressed("Bacon")
+            writer.set_uncompressed("Bacon")  # type: ignore[arg-type]
 
-    def test_precompressed_router_tables(self):
+    def test_precompressed_router_tables(self) -> None:
         table = MulticastRoutingTables()
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
@@ -254,18 +265,18 @@ def test_precompressed_router_tables(self):
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_uncompressed()
         with self.assertRaises(TypeError):
-            writer.set_precompressed(None)
+            writer.set_precompressed(None)  # type: ignore[arg-type]
 
-    def test_plan_n_timesteps(self):
+    def test_plan_n_timesteps(self) -> None:
         writer = PacmanDataWriter.setup()
         writer.set_plan_n_timesteps(1234)
         self.assertEqual(1234, PacmanDataView.get_plan_n_timestep())
         with self.assertRaises(TypeError):
-            writer.set_plan_n_timesteps("Bacon")
+            writer.set_plan_n_timesteps("Bacon")  # type: ignore[arg-type]
         with self.assertRaises(PacmanConfigurationException):
             writer.set_plan_n_timesteps(-1)
 
-    def test_routing_table_by_partition(self):
+    def test_routing_table_by_partition(self) -> None:
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             PacmanDataView.get_routing_table_by_partition()
@@ -274,9 +285,10 @@ def test_routing_table_by_partition(self):
         self.assertEqual(
             table, PacmanDataView.get_routing_table_by_partition())
         with self.assertRaises(TypeError):
-            writer.set_routing_table_by_partition("Bacon")
+            writer.set_routing_table_by_partition(
+                "Bacon")  # type: ignore[arg-type]
 
-    def test_add_requires_mapping(self):
+    def test_add_requires_mapping(self) -> None:
         writer = PacmanDataWriter.setup()
         # before first run
         self.assertTrue(PacmanDataView.get_requires_mapping())
@@ -346,7 +358,7 @@ def test_add_requires_mapping(self):
         writer.hard_reset()
         self.assertTrue(PacmanDataView.get_requires_mapping())
 
-    def test_get_monitors(self):
+    def test_get_monitors(self) -> None:
         writer = PacmanDataWriter.setup()
         self.assertEqual(0, PacmanDataView.get_all_monitor_cores())
         self.assertEqual(ConstantSDRAM(0),
@@ -374,7 +386,7 @@ def test_get_monitors(self):
         self.assertEqual(VariableSDRAM(200 + 100 + 55, 10 + 15),
                          PacmanDataView.get_ethernet_monitor_sdram())
 
-    def test_required(self):
+    def test_required(self) -> None:
         writer = PacmanDataWriter.setup()
         with self.assertRaises(DataNotYetAvialable):
             self.assertIsNone(PacmanDataView.get_n_boards_required())
@@ -449,6 +461,6 @@ def test_required(self):
         with self.assertRaises(ValueError):
             writer.set_n_required(0, None)
         with self.assertRaises(TypeError):
-            writer.set_n_required(None, "five")
+            writer.set_n_required(None, "five")  # type: ignore[arg-type]
         with self.assertRaises(TypeError):
-            writer.set_n_required("2.3", None)
+            writer.set_n_required("2.3", None)  # type: ignore[arg-type]
diff --git a/unittests/model_tests/application_graph_tests/test_application_edge.py b/unittests/model_tests/application_graph_tests/test_application_edge.py
index 645d3dd14..575899e0e 100644
--- a/unittests/model_tests/application_graph_tests/test_application_edge.py
+++ b/unittests/model_tests/application_graph_tests/test_application_edge.py
@@ -17,6 +17,7 @@
 from pacman.exceptions import (
     PacmanAlreadyExistsException, PacmanConfigurationException,
     PacmanInvalidParameterException)
+from pacman.model.graphs import AbstractEdge
 from pacman.model.graphs.application import ApplicationEdgePartition
 from pacman_test_objects import SimpleTestEdge, SimpleTestVertex
 
@@ -26,10 +27,10 @@ class TestApplicationEdgeModel(unittest.TestCase):
     tests which test the application graph object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_new_edge(self):
+    def test_create_new_edge(self) -> None:
         """
         test that you can create a edge between two vertices
         """
@@ -39,7 +40,7 @@ def test_create_new_edge(self):
         self.assertEqual(edge1.pre_vertex, vert1)
         self.assertEqual(edge1.post_vertex, vert2)
 
-    def test_create_new_edge_without_label(self):
+    def test_create_new_edge_without_label(self) -> None:
         """
         test initisation of a edge without a label
         """
@@ -50,7 +51,7 @@ def test_create_new_edge_without_label(self):
         self.assertEqual(edge1.post_vertex, vert2)
         self.assertEqual(edge1.label, None)
 
-    def test_partition(self):
+    def test_partition(self) -> None:
         vert1 = SimpleTestVertex(10, "Vertex 1", 256)
         partition = ApplicationEdgePartition("spikes", vert1)
         vert2 = SimpleTestVertex(5, "Vertex 2", 256)
@@ -59,12 +60,12 @@ def test_partition(self):
         with self.assertRaises(PacmanAlreadyExistsException):
             partition.add_edge(edge1)
         with self.assertRaises(PacmanInvalidParameterException):
-            partition.add_edge("edge")
+            partition.add_edge("edge")  # type: ignore[arg-type]
         edge2 = SimpleTestEdge(vert1, vert2)
-        self.assertNotIn(edge2, partition)
+        assert edge2 not in partition
         partition.add_edge(edge2)
         self.assertEqual(2, partition.n_edges)
-        self.assertIn(edge2, partition)
+        #self.assertIn(edge2, partition)
         self.assertIn("ApplicationEdgePartition", str(partition))
         self.assertIn("spikes", repr(partition))
         vert3 = SimpleTestVertex(5, "Vertex 3", 256)
diff --git a/unittests/model_tests/application_graph_tests/test_application_graph.py b/unittests/model_tests/application_graph_tests/test_application_graph.py
index 268c1b80f..80e666ee9 100644
--- a/unittests/model_tests/application_graph_tests/test_application_graph.py
+++ b/unittests/model_tests/application_graph_tests/test_application_graph.py
@@ -25,13 +25,13 @@ class TestApplicationGraphModel(unittest.TestCase):
     tests which test the application graph object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_new_empty_graph(self):
+    def test_create_new_empty_graph(self) -> None:
         ApplicationGraph()
 
-    def test_create_new_graph(self):
+    def test_create_new_graph(self) -> None:
         vert1 = SimpleTestVertex(10, "New AbstractConstrainedVertex 1", 256)
         vert2 = SimpleTestVertex(5, "New AbstractConstrainedVertex 2", 256)
         vert3 = SimpleTestVertex(3, "New AbstractConstrainedVertex 3", 256)
@@ -49,10 +49,10 @@ def test_create_new_graph(self):
         assert frozenset(edges) == frozenset(graph.edges)
         graph.reset()
 
-    def test_add_vertex(self):
+    def test_add_vertex(self) -> None:
         graph = ApplicationGraph()
         with self.assertRaises(PacmanInvalidParameterException):
-            graph.add_vertex("vertex")
+            graph.add_vertex("vertex")  # type: ignore[arg-type]
         vert1 = SimpleTestVertex(10, "Test", 256)
         graph.add_vertex(vert1)
         with self.assertRaises(PacmanAlreadyExistsException):
@@ -64,10 +64,10 @@ def test_add_vertex(self):
         self.assertNotEqual(vert1.label, vert2.label)
         self.assertEqual(vert1, graph.vertex_by_label("Test"))
 
-    def test_add_edge(self):
+    def test_add_edge(self) -> None:
         graph = ApplicationGraph()
         with self.assertRaises(PacmanInvalidParameterException):
-            graph.add_edge("edge", "spikes")
+            graph.add_edge("edge", "spikes")  # type: ignore[arg-type]
         vert1 = SimpleTestVertex(10, "Vertex 1", 256)
         vert2 = SimpleTestVertex(5, "Vertex 2", 256)
         edge1 = ApplicationEdge(vert1, vert2, label="First edge")
diff --git a/unittests/model_tests/application_graph_tests/test_application_other.py b/unittests/model_tests/application_graph_tests/test_application_other.py
index 1e2e8a41c..71d38543e 100644
--- a/unittests/model_tests/application_graph_tests/test_application_other.py
+++ b/unittests/model_tests/application_graph_tests/test_application_other.py
@@ -23,15 +23,15 @@ class TestApplicationOther(unittest.TestCase):
     tests which test the application graph object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_spinnaker_link(self):
+    def test_spinnaker_link(self) -> None:
         slv = ApplicationSpiNNakerLinkVertex(100, 2, "127.4.5.6")
         self.assertEqual(2, slv.spinnaker_link_id)
         self.assertEqual("127.4.5.6", slv.board_address)
 
-    def test_fpga_no_connection(self):
+    def test_fpga_no_connection(self) -> None:
         fpga = ApplicationFPGAVertex(100)
         self.assertEqual(0, len(list(fpga.incoming_fpga_connections)))
         self.assertIsNone(fpga.outgoing_fpga_connection)
diff --git a/unittests/model_tests/application_graph_tests/test_application_vertex.py b/unittests/model_tests/application_graph_tests/test_application_vertex.py
index a6e97de58..470408813 100644
--- a/unittests/model_tests/application_graph_tests/test_application_vertex.py
+++ b/unittests/model_tests/application_graph_tests/test_application_vertex.py
@@ -12,8 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from typing import Tuple
+
 import numpy
 import unittest
+
 from pacman.config_setup import unittest_setup
 from pacman.exceptions import (
     PacmanConfigurationException, PacmanInvalidParameterException)
@@ -22,29 +25,33 @@
 from pacman.model.graphs.application import ApplicationVertex
 from pacman.model.partitioner_splitters import SplitterFixedLegacy
 from pacman_test_objects import SimpleTestVertex
+from spinn_utilities.overrides import overrides
 
 
 class MockSplitter(SplitterFixedLegacy):
 
     reset_seen = False
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         self.reset_seen = True
 
 
 class SimpleMDVertex(ApplicationVertex):
 
-    def __init__(self, max_atoms_per_core, atoms_shape):
+    def __init__(self, max_atoms_per_core:Tuple[int, ...],
+                 atoms_shape: Tuple[int, ...]):
         super(SimpleMDVertex, self).__init__(
             max_atoms_per_core=max_atoms_per_core)
         self.__atoms_shape = atoms_shape
 
     @property
-    def n_atoms(self):
+    @overrides(ApplicationVertex.round_n_atoms)
+    def n_atoms(self) -> int:
         return numpy.prod(self.__atoms_shape)
 
     @property
-    def atoms_shape(self):
+    @overrides(ApplicationVertex.atoms_shape)
+    def atoms_shape(self) -> Tuple[int, ...]:
         return self.__atoms_shape
 
 
@@ -53,10 +60,10 @@ class TestApplicationGraphModel(unittest.TestCase):
     tests which test the application graph object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_new_vertex(self):
+    def test_create_new_vertex(self) -> None:
         """
         test initialisation of a vertex
         """
@@ -64,16 +71,18 @@ def test_create_new_vertex(self):
         self.assertEqual(vert.n_atoms, 10)
         self.assertEqual(vert.label, "New AbstractConstrainedVertex")
 
-    def test_create_new_vertex_without_label(self):
+    def test_create_new_vertex_without_label(self) -> None:
         """
         test initialisation of a vertex without a label
         """
         vert = SimpleTestVertex(10, "Population", 256)
         self.assertEqual(vert.n_atoms, 10)
-        pieces = vert.label.split(" ")
-        self.assertIn(pieces[0], "Population n")
+        label = vert.label
+        assert label is not None
+        pieces = label.split(" ")
+        assert pieces[0] in "Population n"
 
-    def test_create_new_vertex_add_fixed(self):
+    def test_create_new_vertex_add_fixed(self) -> None:
         """
         test that creating a vertex and then adding fixed_locations
         """
@@ -85,7 +94,7 @@ def test_create_new_vertex_add_fixed(self):
             vert.set_fixed_location(0, 0)
         vert.set_fixed_location(0, 0, 1)
 
-    def test_new_create_vertex_from_vertex_no_fixed(self):
+    def test_new_create_vertex_from_vertex_no_fixed(self) -> None:
         """
         test the creating of a vertex by the
         create vertex method will actually create a vertex of the
@@ -97,7 +106,7 @@ def test_new_create_vertex_from_vertex_no_fixed(self):
             vert.get_sdram_used_by_atoms(Slice(0, 9)))
         self.assertIsInstance(vertex, SimpleMachineVertex)
 
-    def test_new_create_vertex_from_vertex_check_resources(self):
+    def test_new_create_vertex_from_vertex_check_resources(self) -> None:
         """
         check that the creation of a vertex means that the resources
         calculated by the vertex is the same as what the
@@ -109,18 +118,19 @@ def test_new_create_vertex_from_vertex_check_resources(self):
         subv_from_vert = vert.create_machine_vertex(Slice(0, 9), sdram, "")
         self.assertEqual(subv_from_vert.sdram_required, sdram)
 
-    def test_round_n_atoms(self):
-        # .1 is not exact in floating point
+    def test_round_n_atoms(self) -> None:
+        # .1 is not exact an floating point
         near = .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1 + .1
         self.assertNotEqual(1, near)
-        vert = SimpleTestVertex(near)
+        vert = SimpleTestVertex(near)   # type: ignore[arg-type]
         self.assertEqual(1, vert.n_atoms)
         with self.assertRaises(PacmanInvalidParameterException):
-            SimpleTestVertex(1.5)
-        vert = SimpleTestVertex(numpy.int64(23))
+            SimpleTestVertex(1.5)   # type: ignore[arg-type]
+        vert = SimpleTestVertex(numpy.int64(23))   # type: ignore[arg-type]
+        self.assertTrue(isinstance(numpy.int64(23), int))
         self.assertTrue(isinstance(vert.n_atoms, int))
 
-    def test_set_splitter(self):
+    def test_set_splitter(self) -> None:
         split1 = MockSplitter()
         vert = SimpleTestVertex(5, splitter=split1)
         self.assertEqual(split1, vert.splitter)
@@ -133,7 +143,7 @@ def test_set_splitter(self):
         vert.reset()
         self.assertTrue(split1.reset_seen)
 
-    def test_set_label(self):
+    def test_set_label(self) -> None:
         vert = SimpleTestVertex(5)
         vert.set_label("test 1")
         self.assertEqual("test 1", vert.label)
@@ -143,7 +153,7 @@ def test_set_label(self):
             vert.set_label("test 2")
         self.assertTrue(vert.has_been_added_to_graph())
 
-    def test_get_key_ordered_indices(self):
+    def test_get_key_ordered_indices(self) -> None:
         vtx = SimpleMDVertex((3, 3), (6, 6))
         # From the interdimensional compatibility documentation diagram, we can
         # check we get what we expect
@@ -162,7 +172,7 @@ def test_get_key_ordered_indices(self):
         test_array[row_indices] += 1
         assert all(numpy.equal(test_array, 1))
 
-    def test_get_raster_ordered_indices(self):
+    def test_get_raster_ordered_indices(self) -> None:
         # Go forward to row indices then back to atoms
         vtx = SimpleMDVertex((3, 4, 5), (9, 16, 25))
         all_atoms = numpy.arange(9 * 16 * 25)
diff --git a/unittests/model_tests/graph_mapper_tests/test_graph_mapping.py b/unittests/model_tests/graph_mapper_tests/test_graph_mapping.py
index 9be42761e..b71298ed2 100644
--- a/unittests/model_tests/graph_mapper_tests/test_graph_mapping.py
+++ b/unittests/model_tests/graph_mapper_tests/test_graph_mapping.py
@@ -28,10 +28,10 @@ class TestGraphMapping(unittest.TestCase):
     graph mapper tests
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_get_vertices_from_vertex(self):
+    def test_get_vertices_from_vertex(self) -> None:
         """
         test getting the vertex from a graph mapper via the vertex
         """
@@ -53,7 +53,7 @@ def test_get_vertices_from_vertex(self):
         for v in vertices:
             self.assertNotIn(v, returned_vertices)
 
-    def test_get_vertex_from_vertex(self):
+    def test_get_vertex_from_vertex(self) -> None:
         """
         test that the graph mapper can retrieve a vertex from a given vertex
         """
diff --git a/unittests/model_tests/graph_mapper_tests/test_slice.py b/unittests/model_tests/graph_mapper_tests/test_slice.py
index daf794802..db609ec1d 100644
--- a/unittests/model_tests/graph_mapper_tests/test_slice.py
+++ b/unittests/model_tests/graph_mapper_tests/test_slice.py
@@ -26,22 +26,22 @@ class TestSliceFunctions(unittest.TestCase):
     slice function tests
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_slice_valid(self):
+    def test_create_slice_valid(self) -> None:
         """
         test creating a empty slice
         """
         Slice(0, 1)
 
-    def test_slice_invalid_neg(self):
+    def test_slice_invalid_neg(self) -> None:
         """
         test that a invalid slice of negative value generates an error
         """
         self.assertRaises(PacmanValueError, Slice, -2, 0)
 
-    def test_slice_invalid_lo_higher_than_hi(self):
+    def test_slice_invalid_lo_higher_than_hi(self) -> None:
         """
         test that a invalid slice generates an error
         """
diff --git a/unittests/model_tests/machine_graph_tests/test_partitions.py b/unittests/model_tests/machine_graph_tests/test_partitions.py
index 3daa89b51..63b09ac54 100644
--- a/unittests/model_tests/machine_graph_tests/test_partitions.py
+++ b/unittests/model_tests/machine_graph_tests/test_partitions.py
@@ -23,6 +23,7 @@
 from pacman.model.graphs.machine import (
      ConstantSDRAMMachinePartition,
      DestinationSegmentedSDRAMMachinePartition,
+     MachineEdge,
      SDRAMMachineEdge, SimpleMachineVertex,
      SourceSegmentedSDRAMMachinePartition)
 from pacman.model.resources import ConstantSDRAM
@@ -41,14 +42,15 @@ class TestPartition(unittest.TestCase):
     tests which test the application graph object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_constant(self):
+    def test_constant(self) -> None:
         """
         test ConstantSDRAMMachinePartition
         """
         v1 = MockSupportsSDRAMEdges(ConstantSDRAM(24))
+        part: ConstantSDRAMMachinePartition
         part = ConstantSDRAMMachinePartition("foo", v1)
         with self.assertRaises(PartitionMissingEdgesException):
             part.total_sdram_requirements()
@@ -79,7 +81,7 @@ def test_constant(self):
             part.add_edge(e4)
         self.assertEqual(2, len(part.edges))
 
-    def test_destination(self):
+    def test_destination(self) -> None:
         """
         test DestinationSegmentedSDRAMMachinePartition
         """
@@ -120,7 +122,7 @@ def test_destination(self):
         with self.assertRaises(PacmanValueError):
             part.get_sdram_base_address_for(v4)
 
-    def test_sdram_machine_edge(self):
+    def test_sdram_machine_edge(self) -> None:
         """
         test SDRAMMachineEdge
         """
@@ -132,7 +134,7 @@ def test_sdram_machine_edge(self):
         with self.assertRaises(PacmanConfigurationException):
             SDRAMMachineEdge(v2, v1, "bar")
 
-    def test_source(self):
+    def test_source(self) -> None:
         """
         test DestinationSegmentedSDRAMMachinePartition
         """
@@ -177,12 +179,13 @@ def test_source(self):
         self.assertEqual(100, part.get_sdram_base_address_for(v3))
         self.assertEqual(40 + 28, part.get_sdram_size_of_region_for(v3))
 
-    def test_abstract_multiple_partition(self):
+    # type: ignore[arg-type]
+    def test_abstract_multiple_partition(self) -> None:
         v1 = MockSupportsSDRAMEdges(ConstantSDRAM(12))
         v2 = MockSupportsSDRAMEdges(ConstantSDRAM(12))
         v3 = MockSupportsSDRAMEdges(ConstantSDRAM(12))
         with self.assertRaises(PacmanConfigurationException):
-            AbstractMultiplePartition([v1, v1], "foo", None)
-        part = AbstractMultiplePartition([v1, v2], "foo", None)
+            AbstractMultiplePartition([v1, v1], "foo", (MachineEdge))
+        part = AbstractMultiplePartition([v1, v2], "foo", (MachineEdge))
         with self.assertRaises(Exception):
             part.add_edge(SDRAMMachineEdge(v3, v1, "foo"))
diff --git a/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py b/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
index 9cdaa85e7..6783c2bd3 100644
--- a/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
+++ b/unittests/model_tests/partitioner_splitters_tests/splitter_slice_legacy_test.py
@@ -28,12 +28,12 @@ def setUp(self) -> None:
         unittest_setup()
 
     def test_no_api(self) -> None:
-        splitter = SplitterFixedLegacy()
+        splitter: SplitterFixedLegacy = SplitterFixedLegacy()
         vertex = NonLegacyApplicationVertex()
         with self.assertRaises(PacmanConfigurationException):
             splitter.set_governed_app_vertex(vertex)
 
     def test_with_api(self) -> None:
-        splitter = SplitterFixedLegacy()
+        splitter: SplitterFixedLegacy = SplitterFixedLegacy()
         vertex = SimpleTestVertex(12)
         splitter.set_governed_app_vertex(vertex)
diff --git a/unittests/model_tests/placement_tests/test_placement_constraints.py b/unittests/model_tests/placement_tests/test_placement_constraints.py
index 1569c8358..980c457a2 100644
--- a/unittests/model_tests/placement_tests/test_placement_constraints.py
+++ b/unittests/model_tests/placement_tests/test_placement_constraints.py
@@ -21,10 +21,10 @@ class TestPlacementConstraints(unittest.TestCase):
     """ Tester for ChipAndCore
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_chip_and_core_constraint(self):
+    def test_chip_and_core_constraint(self) -> None:
         c1 = ChipAndCore(1, 2)
         self.assertEqual(c1.x, 1)
         self.assertEqual(c1.y, 2)
diff --git a/unittests/model_tests/placement_tests/test_placement_object.py b/unittests/model_tests/placement_tests/test_placement_object.py
index a8fd3933a..32e24881f 100644
--- a/unittests/model_tests/placement_tests/test_placement_object.py
+++ b/unittests/model_tests/placement_tests/test_placement_object.py
@@ -40,10 +40,10 @@ class TestPlacement(unittest.TestCase):
     tester for placement object in pacman.model.placements.placement
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_new_placement(self):
+    def test_create_new_placement(self) -> None:
         """
         test that creating a new placement puts stuff in the right place
         """
@@ -60,7 +60,7 @@ def test_create_new_placement(self):
         self.assertEqual(hash(pl), hash(pl2))
         self.assertFalse(pl != pl2)
 
-    def test_create_new_placements_duplicate_vertex(self):
+    def test_create_new_placements_duplicate_vertex(self) -> None:
         """
         check that you cant put a vertex in multiple placements
         """
@@ -71,7 +71,7 @@ def test_create_new_placements_duplicate_vertex(self):
         with self.assertRaises(PacmanAlreadyPlacedError):
             Placements(pl)
 
-    def test_iterate_by_type(self):
+    def test_iterate_by_type(self) -> None:
         v1a = ExtendedVertex1(None)
         p1a = Placement(v1a, 0, 1, 1)
         v1b = ExtendedVertex1(None)
diff --git a/unittests/model_tests/placement_tests/test_placements_model.py b/unittests/model_tests/placement_tests/test_placements_model.py
index 8f3138e90..bd258d004 100644
--- a/unittests/model_tests/placement_tests/test_placements_model.py
+++ b/unittests/model_tests/placement_tests/test_placements_model.py
@@ -29,10 +29,10 @@ class TestPlacements(unittest.TestCase):
     tester for placements object in pacman.model.placements.placements
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_create_new_placements(self):
+    def test_create_new_placements(self) -> None:
         """
         test creating a placements object
         """
@@ -40,7 +40,7 @@ def test_create_new_placements(self):
         pl = Placement(subv, 0, 0, 1)
         Placements([pl])
 
-    def test_create_new_empty_placements(self):
+    def test_create_new_empty_placements(self) -> None:
         """
         checks that creating an empty placements object is valid
         """
@@ -48,7 +48,7 @@ def test_create_new_empty_placements(self):
         self.assertEqual(pls._placements, dict())
         self.assertEqual(pls._machine_vertices, dict())
 
-    def test_get_placement_of_vertex(self):
+    def test_get_placement_of_vertex(self) -> None:
         """
         checks the placements get placement method
         """
@@ -64,7 +64,7 @@ def test_get_placement_of_vertex(self):
         for i in range(4):
             self.assertEqual(pls.get_placement_of_vertex(subv[i]), pl[i])
 
-    def test_get_vertex_on_processor(self):
+    def test_get_vertex_on_processor(self) -> None:
         """
         checks that from a placements object, you can get to the correct
         vertex using the get_vertex_on_processor() method
@@ -84,7 +84,7 @@ def test_get_vertex_on_processor(self):
 
         self.assertEqual(pls.get_placement_of_vertex(subv[0]), pl[0])
 
-    def test_get_placements(self):
+    def test_get_placements(self) -> None:
         """
         tests the placements iterator functionality.
         """
@@ -100,7 +100,7 @@ def test_get_placements(self):
         for i in range(4):
             self.assertIn(pl[i], pls)
 
-    def test_safety_code(self):
+    def test_safety_code(self) -> None:
         subv = SimpleMachineVertex(None, "1")
         pl = Placement(subv, 0, 0, 1)
         pls = Placements([pl])
@@ -115,7 +115,7 @@ def test_safety_code(self):
         with self.assertRaises(PacmanNotPlacedError):
             pls.get_placement_of_vertex(subv2)
 
-    def test_infos_code(self):
+    def test_infos_code(self) -> None:
         subv = SimpleMachineVertex(None, "1")
         pl = Placement(subv, 0, 0, 1)
         pls = Placements([pl])
diff --git a/unittests/model_tests/resources_tests/test_resources_model.py b/unittests/model_tests/resources_tests/test_resources_model.py
index 196436c0c..e4fdd7974 100644
--- a/unittests/model_tests/resources_tests/test_resources_model.py
+++ b/unittests/model_tests/resources_tests/test_resources_model.py
@@ -35,10 +35,10 @@ class TestResourceModels(unittest.TestCase):
     unit tests on the resources object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_sdram(self):
+    def test_sdram(self) -> None:
         """
         test that adding a SDRAM resource to a resource container works
         correctly
@@ -93,13 +93,13 @@ def test_sdram(self):
             multi3.report(1000, target=target)
         multi3.report(1000, preamble="core (0,0,1):")
 
-    def test_add(self):
+    def test_add(self) -> None:
         multi1 = MultiRegionSDRAM()
         multi1.add_cost(1, 100, 4)
         multi1.add_cost(1, 50)
         self.assertEqual(multi1.regions[1], VariableSDRAM(150, 4))
 
-    def test_nest(self):
+    def test_nest(self) -> None:
         multi1 = MultiRegionSDRAM()
         multi1.add_cost(1, 100, 4)
         multi2 = MultiRegionSDRAM()
@@ -107,7 +107,7 @@ def test_nest(self):
         multi1.nest(1, multi2)
         self.assertEqual(multi1.regions[1], VariableSDRAM(150, 4))
 
-    def test_nest2(self):
+    def test_nest2(self) -> None:
         multi1 = MultiRegionSDRAM()
         multi1.add_cost(1, 100, 4)
         multi2 = MultiRegionSDRAM()
@@ -118,17 +118,17 @@ def test_nest2(self):
         self.assertEqual(multi3.regions[12], VariableSDRAM(150, 4))
         multi3.report(1000)
 
-    def test_tags_resources(self):
-        IPtagResource("1", 2, 3)  # Minimal args
-        iptr = IPtagResource("1.2.3.4", 2, 3, 4, 5)
+    def test_tags_resources(self) -> None:
+        IPtagResource("1", 2, True)  # Minimal args
+        iptr = IPtagResource("1.2.3.4", 2, False, 4, "bacon")
         self.assertEqual(iptr.ip_address, "1.2.3.4")
         self.assertEqual(iptr.port, 2)
-        self.assertEqual(iptr.strip_sdp, 3)
+        self.assertEqual(iptr.strip_sdp, False)
         self.assertEqual(iptr.tag, 4)
-        self.assertEqual(iptr.traffic_identifier, 5)
+        self.assertEqual(iptr.traffic_identifier, "bacon")
         self.assertEqual(str(iptr),
                          "IPTagResource(ip_address=1.2.3.4, port=2, "
-                         "strip_sdp=3, tag=4, traffic_identifier=5)")
+                         "strip_sdp=False, tag=4, traffic_identifier=bacon)")
 
         ReverseIPtagResource()  # Minimal args
         riptr = ReverseIPtagResource(1, 2, 3)
@@ -142,14 +142,14 @@ def test_tags_resources(self):
         self.assertEqual(riptr, riptr2)
         self.assertEqual(hash(riptr), hash(riptr2))
 
-    def test_total(self):
+    def test_total(self) -> None:
         var0 = VariableSDRAM(28, 0)
         self.assertEqual(28, var0.get_total_sdram(None))
         var4 = VariableSDRAM(28, 4)
         with self.assertRaises(PacmanConfigurationException):
             var4.get_total_sdram(None)
 
-    def test_shared(self):
+    def test_shared(self) -> None:
         var1 = VariableSDRAM(20, 1)
         sh1 = SharedSDRAM({"foo": var1})
         sh1.report(10)
@@ -167,7 +167,7 @@ def test_shared(self):
         self.assertEqual(combo4.get_total_sdram(5), 37)
         self.assertEqual(combo3, combo4)
 
-    def test_sdram_multi(self):
+    def test_sdram_multi(self) -> None:
         multi1 = MultiRegionSDRAM()
         multi1.add_cost(1, 100, 4)
         sh1 = SharedSDRAM({"foo": multi1})
@@ -182,7 +182,7 @@ def test_sdram_multi(self):
         combo = sh1 + sh2
         self.assertEqual(combo.get_total_sdram(10), 100 + 4 * 10 + 20 + 10)
 
-    def test_nested_shared(self):
+    def test_nested_shared(self) -> None:
         # nested sdram do not make sense but do work
         # all but the outer sdram acts like a non shared sdram
         c1 = ConstantSDRAM(45)
@@ -190,7 +190,7 @@ def test_nested_shared(self):
         sh2 = SharedSDRAM({"bar": sh1})
         self.assertEqual(sh2.get_total_sdram(None), 45)
 
-    def test_reused_key(self):
+    def test_reused_key(self) -> None:
         var1 = VariableSDRAM(20, 1)
         sh1 = SharedSDRAM({"foo": var1})
         var2 = VariableSDRAM(20, 1)
diff --git a/unittests/model_tests/routing_info_tests/test_routing_info.py b/unittests/model_tests/routing_info_tests/test_routing_info.py
index 9fffc231d..71ed24f11 100644
--- a/unittests/model_tests/routing_info_tests/test_routing_info.py
+++ b/unittests/model_tests/routing_info_tests/test_routing_info.py
@@ -25,12 +25,12 @@
 
 class TestRoutingInfo(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
     # TODO: Replace (currently temporarily broken to make sure we don't
     # call it)
-    # def test_routing_info_deprecated(self):
+    # def test_routing_info_deprecated(self) -> None:
     #     pre_vertex = SimpleMachineVertex(ConstantSDRAM(0))
     #     key = 12345
     #     info = MachineVertexRoutingInfo(
@@ -75,13 +75,14 @@ def setUp(self):
     #     assert routing_info.get_routing_info_from_pre_vertex(
     #         pre_vertex, "Test2").get_keys().tolist() == [key]
 
-    def test_routing_info(self):
+    def test_routing_info(self) -> None:
         pre_vertex = SimpleMachineVertex(ConstantSDRAM(0))
         key = 12345
         info = MachineVertexRoutingInfo(
             BaseKeyAndMask(key, FULL_MASK), "Test", pre_vertex, 0)
         routing_info = RoutingInfo()
         routing_info.add_routing_info(info)
+        orphan = SimpleMachineVertex(ConstantSDRAM(0))
 
         with self.assertRaises(PacmanAlreadyExistsException):
             routing_info.add_routing_info(info)
@@ -90,31 +91,31 @@ def test_routing_info(self):
             pre_vertex, "Test") == info
         with self.assertRaises(KeyError):
             routing_info.get_info_from(
-                None, "Test")
-        with self.assertRaises(KeyError):
-            routing_info.get_info_from(
-                pre_vertex, "None")
+                None, "Test")  # type: ignore[arg-type]
+        #with self.assertRaises(KeyError):
+        #    routing_info.get_info_from(
+        #        pre_vertex, None)  # type: ignore[arg-type]
 
         assert routing_info.get_key_from(
             pre_vertex, "Test") == key
         with self.assertRaises(KeyError):
             routing_info.get_key_from(
-                None, "Test")
+                None, "Test")  # type: ignore[arg-type]
         with self.assertRaises(KeyError):
             routing_info.get_key_from(
-                pre_vertex, "None")
+                pre_vertex, "None")  # type: ignore[arg-type]
 
         assert list(routing_info.get_partitions_from(
             pre_vertex)) == ["Test"]
         assert list(routing_info.get_partitions_from(
-            None)) == []
+            orphan)) == []
 
         # This should work as can be either partition
         routing_info.check_info_from(
             pre_vertex, {"Test", "Test2"})
 
-        # Works because None has no partitions!
-        routing_info.check_info_from(None, {"Test"})
+        # Works because orphan has no partitions!
+        routing_info.check_info_from(orphan, {"Test"})
 
         # This should not work
         with self.assertRaises(KeyError):
@@ -123,7 +124,7 @@ def test_routing_info(self):
         assert routing_info.has_info_from(
             pre_vertex, "Test")
         assert not routing_info.has_info_from(
-            None, "Test")
+            None, "Test")  # type: ignore[arg-type]
         assert not routing_info.has_info_from(
             pre_vertex, "None")
 
@@ -154,7 +155,7 @@ def test_routing_info(self):
 
         self.assertEqual(len(routing_info), len(list(routing_info)))
 
-    def test_base_key_and_mask(self):
+    def test_base_key_and_mask(self) -> None:
         with self.assertRaises(PacmanConfigurationException):
             BaseKeyAndMask(0xF0, 0x40)
         bkm1 = BaseKeyAndMask(0x40, 0xF0)
diff --git a/unittests/model_tests/routing_table_tests/test_routing_tables_model.py b/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
index e113b5c11..83dba0b60 100644
--- a/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
+++ b/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
@@ -32,10 +32,10 @@ class TestRoutingTable(unittest.TestCase):
     tests for the routing table object
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_new_multicast_routing_table_entry(self):
+    def test_new_multicast_routing_table_entry(self) -> None:
         """
         test that creating a multicast routing entry works
         """
@@ -47,7 +47,7 @@ def test_new_multicast_routing_table_entry(self):
         MulticastRoutingEntry(key_combo, mask, RoutingEntry(
             processor_ids=proc_ids, link_ids=link_ids))
 
-    def test_new_multicast_routing_table(self):
+    def test_new_multicast_routing_table(self) -> None:
         """
         test that creating a multicast routing entry and adding it to the table
         works
@@ -73,13 +73,13 @@ def test_new_multicast_routing_table(self):
         for entry in mre:
             self.assertIn(entry, multicast_entries)
 
-    def test_new_multicast_routing_table_empty(self):
+    def test_new_multicast_routing_table_empty(self) -> None:
         """
         tests creating a basic multicast routing table
         """
         UnCompressedMulticastRoutingTable(0, 0)
 
-    def test_new_multicast_routing_table_duplicate_entry(self):
+    def test_new_multicast_routing_table_duplicate_entry(self) -> None:
         """
         test that adding multiple identical entries into a multicast table
         causes an error
@@ -104,7 +104,7 @@ def test_new_multicast_routing_table_duplicate_entry(self):
                 key_combo, mask,
                 RoutingEntry(processor_ids=[], link_ids=link_ids)))
 
-    def test_new_multicast_routing_table_duplicate_key_combo(self):
+    def test_new_multicast_routing_table_duplicate_key_combo(self) -> None:
 
         key_combo = 0xff35
         mask = 0xffff
@@ -122,7 +122,7 @@ def test_new_multicast_routing_table_duplicate_key_combo(self):
         # We can add entries that are exactly the same
         UnCompressedMulticastRoutingTable(0, 0, multicast_entries)
 
-    def test_new_multicast_routing_tables(self):
+    def test_new_multicast_routing_tables(self) -> None:
         key_combo = 0xff35
         mask = 0xffff
         proc_ids = list()
@@ -162,10 +162,10 @@ def test_new_multicast_routing_tables(self):
         self.assertEqual(new_tables.get_routing_table_for_chip(1, 0), t2)
         self.assertEqual(new_tables.get_routing_table_for_chip(2, 0), None)
 
-    def test_new_multicast_routing_tables_empty(self):
+    def test_new_multicast_routing_tables_empty(self) -> None:
         MulticastRoutingTables()
 
-    def test_add_routing_table_for_duplicate_chip(self):
+    def test_add_routing_table_for_duplicate_chip(self) -> None:
         key_combo = 0xff35
         mask = 0xffff
         proc_ids = list()
@@ -189,7 +189,7 @@ def test_add_routing_table_for_duplicate_chip(self):
         with self.assertRaises(PacmanAlreadyExistsException):
             MulticastRoutingTables(mrt)
 
-    def test_multicast_routing_table_by_partition(self):
+    def test_multicast_routing_table_by_partition(self) -> None:
         mrt = MulticastRoutingTableByPartition()
         partition_id = "foo"
         source_vertex = SimpleMachineVertex(sdram=None)
@@ -209,7 +209,7 @@ def test_multicast_routing_table_by_partition(self):
         assert mre == mrt.get_entry_on_coords_for_edge(
             source_vertex, partition_id, 0, 0)
 
-    def test_multicast_routing_table_by_partition_entry(self):
+    def test_multicast_routing_table_by_partition_entry(self) -> None:
         with self.assertRaises(SpinnMachineInvalidParameterException):
             RoutingEntry(link_ids=range(6), processor_ids=range(18),
                          incoming_processor=4, incoming_link=3)
diff --git a/unittests/model_tests/splitter_tests/test_one_app_one_machine.py b/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
index 32af06af6..048de7e30 100644
--- a/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
+++ b/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
@@ -31,10 +31,10 @@
 
 class TestSplitterOneAppOneMachine(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_legacy(self):
+    def test_legacy(self) -> None:
         set_config("Machine", "versions", VersionStrings.ANY.text)
         splitter = SplitterOneAppOneMachine()
         v1 = NonLegacyApplicationVertex("v1")
@@ -61,6 +61,6 @@ def test_legacy(self):
         self.assertEqual(6, v2.n_atoms)
         v2.reset()
 
-    def test_default_name(self):
+    def test_default_name(self) -> None:
         splitter = SplitterOneAppOneMachine()
         self.assertIn("SplitterOneAppOneMachine", str(splitter))
diff --git a/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py b/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
index 83bad6205..de1b5c412 100644
--- a/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
+++ b/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
@@ -26,10 +26,10 @@
 
 class TestSplitterFixedLegacy(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_api(self):
+    def test_api(self) -> None:
         set_config("Machine", "versions", VersionStrings.ANY.text)
         splitter = SplitterFixedLegacy()
         self.assertIsNotNone(str(splitter))
@@ -53,7 +53,7 @@ def test_api(self):
         self.assertEqual([], splitter.get_internal_multicast_partitions())
         self.assertEqual([], splitter.get_internal_sdram_partitions())
 
-    def test_not_api(self):
+    def test_not_api(self) -> None:
         splitter = SplitterFixedLegacy()
         v1 = NonLegacyApplicationVertex("v1")
         with self.assertRaises(PacmanConfigurationException):
diff --git a/unittests/model_tests/splitter_tests/test_splitter_one_to_one_legacy.py b/unittests/model_tests/splitter_tests/test_splitter_one_to_one_legacy.py
index 315be6820..963838e0b 100644
--- a/unittests/model_tests/splitter_tests/test_splitter_one_to_one_legacy.py
+++ b/unittests/model_tests/splitter_tests/test_splitter_one_to_one_legacy.py
@@ -27,10 +27,10 @@
 
 class TestSplitterFixedLegacy(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_api(self):
+    def test_api(self) -> None:
         set_config("Machine", "versions", VersionStrings.ANY.text)
         splitter = SplitterOneToOneLegacy()
         self.assertIsNotNone(str(splitter))
@@ -52,7 +52,7 @@ def test_api(self):
         self.assertEqual(splitter.machine_vertices_for_recording("foo"), mvs)
         splitter.reset_called()
 
-    def test_not_api(self):
+    def test_not_api(self) -> None:
         splitter = SplitterOneToOneLegacy()
         v1 = NonLegacyApplicationVertex("v1")
         with self.assertRaises(PacmanConfigurationException):
diff --git a/unittests/model_tests/splitter_tests/test_splitter_reset.py b/unittests/model_tests/splitter_tests/test_splitter_reset.py
index 682c420bf..b3280aa89 100644
--- a/unittests/model_tests/splitter_tests/test_splitter_reset.py
+++ b/unittests/model_tests/splitter_tests/test_splitter_reset.py
@@ -22,10 +22,10 @@
 
 class TestSplitterReset(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_reset(self):
+    def test_reset(self) -> None:
         # With slitter
         v1 = SimpleTestVertex(1, "v1")
         PacmanDataView.add_vertex(v1)
diff --git a/unittests/model_tests/tag_tests/test_tag_infos_model.py b/unittests/model_tests/tag_tests/test_tag_infos_model.py
index a9769ae5f..1aee3fa29 100644
--- a/unittests/model_tests/tag_tests/test_tag_infos_model.py
+++ b/unittests/model_tests/tag_tests/test_tag_infos_model.py
@@ -28,16 +28,16 @@ class TestTagsModel(unittest.TestCase):
     test that the tags object works as expected
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_new_tag_info(self):
+    def test_new_tag_info(self) -> None:
         """
         test that creating a empty tag object works
         """
         Tags()
 
-    def test_adding_a_iptag_to_tag_info(self):
+    def test_adding_a_iptag_to_tag_info(self) -> None:
         """
         check that adding a tag after initialisation works
         """
@@ -46,7 +46,7 @@ def test_adding_a_iptag_to_tag_info(self):
         machine_vertex = SimpleMachineVertex(None, "")
         tag_info.add_ip_tag(iptag, machine_vertex)
 
-    def test_adding_a_reverse_iptag(self):
+    def test_adding_a_reverse_iptag(self) -> None:
         """
         check that adding a reverse iptag works correctly
         """
@@ -55,7 +55,7 @@ def test_adding_a_reverse_iptag(self):
         machine_vertex = SimpleMachineVertex(None, "")
         tag_info.add_reverse_ip_tag(reverse_iptag, machine_vertex)
 
-    def test_add_iptag_then_locate_tag(self):
+    def test_add_iptag_then_locate_tag(self) -> None:
         """
         check that locating a iptag via get_ip_tags_for_vertex function
         """
@@ -67,7 +67,7 @@ def test_add_iptag_then_locate_tag(self):
         gotton_tag = tag_info.get_ip_tags_for_vertex(machine_vertex)
         self.assertEqual(gotton_tag[0], iptag)
 
-    def test_add_iptag_then_fail_to_locate(self):
+    def test_add_iptag_then_fail_to_locate(self) -> None:
         """
         test that asking for a invalid iptag returns a None value
         """
@@ -80,7 +80,7 @@ def test_add_iptag_then_fail_to_locate(self):
         gotton_tag = tag_info.get_ip_tags_for_vertex(machine_vertex_2)
         self.assertEqual(gotton_tag, None)
 
-    def test_add_reverse_iptag_then_locate_tag(self):
+    def test_add_reverse_iptag_then_locate_tag(self) -> None:
         """
         check that asking for a reverse iptag for a specific machine vertex
         works
@@ -93,7 +93,7 @@ def test_add_reverse_iptag_then_locate_tag(self):
             machine_vertex)
         self.assertEqual(gotton_tag[0], reverse_iptag)
 
-    def test_add_reverse_iptag_then_not_locate_tag(self):
+    def test_add_reverse_iptag_then_not_locate_tag(self) -> None:
         """
         check that asking for a reverse iptag with a incorrect machine vertex
         will cause a none returned
@@ -107,7 +107,7 @@ def test_add_reverse_iptag_then_not_locate_tag(self):
             machine_vertex)
         self.assertEqual(gotton_tag, None)
 
-    def test_add_conflicting_ip_tag(self):
+    def test_add_conflicting_ip_tag(self) -> None:
         tags = Tags()
         tag1 = IPTag("", 0, 0, 1, "122.2.2.2", 1, False)
         tag2 = IPTag("", 0, 7, 1, "122.2.2.3", 1, False)
@@ -127,7 +127,7 @@ def test_add_conflicting_ip_tag(self):
         self.assertIn("Only add IP tags with this method.",
                       str(e.exception))
 
-    def test_add_conflicting_reverse_ip_tag(self):
+    def test_add_conflicting_reverse_ip_tag(self) -> None:
         tags = Tags()
         tag1 = ReverseIPTag("", 1, 23, 0, 0, 1, 1)
         tag2 = ReverseIPTag("", 1, 23, 0, 0, 1, 1)
diff --git a/unittests/model_tests/test_md_slice.py b/unittests/model_tests/test_md_slice.py
index 1233e9c13..1b110dbcc 100644
--- a/unittests/model_tests/test_md_slice.py
+++ b/unittests/model_tests/test_md_slice.py
@@ -20,28 +20,28 @@
 class TestMD_Slice(unittest.TestCase):
     """Tests that Slices expose the correct options and are immutable."""
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_2d(self):
+    def test_2d(self) -> None:
         s = MDSlice(0, 8, (3, 3), (0, 0), (6, 6))
         self.assertEqual("0(6, 6)(0:3)(0:3)", str(s))
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_2a(self):
+    def test_2a(self) -> None:
         s = MDSlice(36, 44, (3, 3), (0, 6), (5, 11))
         self.assertEqual("36(5, 11)(0:3)(6:9)", str(s))
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_2b(self):
+    def test_2b(self) -> None:
         s = MDSlice(9, 17, (3, 3), (3, 0), (7, 8))
         self.assertEqual("9(7, 8)(3:6)(0:3)", str(s))
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_3b(self):
+    def test_3b(self) -> None:
         s = MDSlice(432, 455, (2, 3, 4), (6, 9, 16), (11, 15, 23))
         self.assertEqual("432(11, 15, 23)(6:8)(9:12)(16:20)", str(s))
         s2 = MDSlice.from_string(str(s))
diff --git a/unittests/model_tests/test_mdslice.py b/unittests/model_tests/test_mdslice.py
index c606dfc32..cadc0400e 100644
--- a/unittests/model_tests/test_mdslice.py
+++ b/unittests/model_tests/test_mdslice.py
@@ -21,10 +21,10 @@
 class TestSlice(unittest.TestCase):
     """Tests that Slices expose the correct options and are immutable."""
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_2d(self):
+    def test_2d(self) -> None:
         s = MDSlice(0, 8, (3, 3), (0, 0), (6, 6))
         self.assertEqual(9, s.n_atoms)  # 10 - 0 + 1
         self.assertEqual(0, s.lo_atom)  # As specified
@@ -37,7 +37,7 @@ def test_2d(self):
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_2a(self):
+    def test_2a(self) -> None:
         s = MDSlice(36, 44, (3, 3), (0, 6), (6, 12))
         self.assertEqual(9, s.n_atoms)  # 10 - 0 + 1
         self.assertEqual(36, s.lo_atom)  # As specified
@@ -48,7 +48,7 @@ def test_2a(self):
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_2b(self):
+    def test_2b(self) -> None:
         s = MDSlice(9, 17, (3, 3), (3, 0), (6, 12))
         self.assertEqual(9, s.n_atoms)  # 10 - 0 + 1
         self.assertEqual(9, s.lo_atom)  # As specified
@@ -61,7 +61,7 @@ def test_2b(self):
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_3b(self):
+    def test_3b(self) -> None:
         s = MDSlice(432, 455, (2, 3, 4), (6, 9, 16), (9, 15, 20))
         self.assertEqual(24, s.n_atoms)  # 10 - 0 + 1
         self.assertEqual(432, s.lo_atom)  # As specified
@@ -78,14 +78,14 @@ def test_3b(self):
         s2 = MDSlice.from_string(str(s))
         self.assertEqual(s, s2)
 
-    def test_get_relative_indices(self):
+    def test_get_relative_indices(self) -> None:
         s = MDSlice(22, 89, (2, 3, 2), (4, 3, 0), (6, 9, 4))
         # Going over the raster IDs should result in a line over the core
         self.assertListEqual(list(range(2 * 3 * 2)),
                              list((s.get_relative_indices(
                                  s.get_raster_ids()))))
 
-    def test_get_raster_indices(self):
+    def test_get_raster_indices(self) -> None:
         s = MDSlice(22, 89, (2, 3, 2), (4, 3, 0), (6, 9, 4))
         # Going from a line over the core should come back to the raster
         # indices
diff --git a/unittests/model_tests/test_slice.py b/unittests/model_tests/test_slice.py
index 213d15fb1..edab555cb 100644
--- a/unittests/model_tests/test_slice.py
+++ b/unittests/model_tests/test_slice.py
@@ -20,10 +20,10 @@
 class TestSlice(unittest.TestCase):
     """Tests that Slices expose the correct options and are immutable."""
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_basic(self):
+    def test_basic(self) -> None:
         s = Slice(0, 10)
         self.assertEqual(11, s.n_atoms)  # 10 - 0 + 1
         self.assertEqual(0, s.lo_atom)  # As specified
@@ -40,30 +40,30 @@ def test_basic(self):
         target = list(range(0, 20))[s.as_slice]
         self.assertListEqual(target, list(s.get_raster_ids()))
 
-    def test_check_lo_atom_sanity(self):
+    def test_check_lo_atom_sanity(self) -> None:
         # Check for value sanity
         with self.assertRaises(ValueError):
             # Check for negative atom
             Slice(-1, 10)
 
-    def test_check_lo_atom_int(self):
+    def test_check_lo_atom_int(self) -> None:
         # Check for value sanity
         with self.assertRaises(Exception):
             # Check for int atom
             Slice("1", 10)
 
-    def test_check_hi_atom_sanity(self):
+    def test_check_hi_atom_sanity(self) -> None:
         with self.assertRaises(ValueError):
             # Check for slice which goes backwards
             Slice(5, 4)
 
-    def test_check_hi_atom_int(self):
+    def test_check_hi_atom_int(self) -> None:
         # Check for value sanity
         with self.assertRaises(Exception):
             # Check for int atom
             Slice(1, "10")
 
-    def test_equal_hi_lo_atoms(self):
+    def test_equal_hi_lo_atoms(self) -> None:
         # This should be fine...
         s = Slice(4, 4)
         self.assertEqual(1, s.n_atoms)  # 10 - 0 + 1
@@ -79,22 +79,22 @@ def test_equal_hi_lo_atoms(self):
         self.assertEqual((4, ), s.start)
         self.assertEqual(s, s2)
 
-    def test_immutability_lo_atom(self):
+    def test_immutability_lo_atom(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
             s.lo_atom = 3
 
-    def test_immutability_hi_atom(self):
+    def test_immutability_hi_atom(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
             s.hi_atom = 3
 
-    def test_immutability_n_atoms(self):
+    def test_immutability_n_atoms(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
             s.n_atoms = 3
 
-    def test_immutability_as_slice(self):
+    def test_immutability_as_slice(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
             s.as_slice = slice(2, 10)
diff --git a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
index fb3f51e04..e21358624 100644
--- a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
+++ b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
@@ -40,14 +40,14 @@ class TestBasicPartitioner(unittest.TestCase):
 
     TheTestAddress = "192.162.240.253"
 
-    def setUp(self):
+    def setUp(self) -> None:
         """
         setup for all basic partitioner tests
         """
         unittest_setup()
         set_config("Machine", "versions", VersionStrings.ANY.text)
 
-    def test_partition_with_no_fixed(self):
+    def test_partition_with_no_fixed(self) -> None:
         """
         test a partitioning with a graph with no fixed_location
         """
@@ -66,7 +66,7 @@ def test_partition_with_no_fixed(self):
             for m_vert in vert.machine_vertices:
                 self.assertEqual(vert.n_atoms, m_vert.vertex_slice.n_atoms)
 
-    def test_partition_on_large_vertex_than_has_to_be_split(self):
+    def test_partition_on_large_vertex_than_has_to_be_split(self) -> None:
         """
         test that partitioning 1 large vertex can make it into 2 small ones
         """
@@ -77,7 +77,7 @@ def test_partition_on_large_vertex_than_has_to_be_split(self):
         splitter_partitioner()
         self.assertEqual(PacmanDataView.get_n_machine_vertices(), 2)
 
-    def test_partition_on_target_size_vertex_than_has_to_be_split(self):
+    def test_partition_on_target_size_vertex_than_has_to_be_split(self) -> None:
         """
         test that fixed partitioning causes correct number of vertices
         """
@@ -88,14 +88,14 @@ def test_partition_on_target_size_vertex_than_has_to_be_split(self):
         splitter_partitioner()
         self.assertEqual(PacmanDataView.get_n_machine_vertices(), 100)
 
-    def test_partition_with_empty_graph(self):
+    def test_partition_with_empty_graph(self) -> None:
         """
         test that the partitioner can work with an empty graph
         """
         splitter_partitioner()
         self.assertEqual(PacmanDataView.get_n_machine_vertices(), 0)
 
-    def test_partition_with_fixed_atom(self):
+    def test_partition_with_fixed_atom(self) -> None:
         """
         test a partitioning with a graph with fixed atom constraint which\
         should fit but is close to the limit
diff --git a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
index fc57f7d40..31d2109e4 100644
--- a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
+++ b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
@@ -51,10 +51,10 @@ def create_machine_vertices(self, chip_counter):
             self.__same_chip_groups.append(
                 (m_vertices, ConstantSDRAM(self.__sdram)))
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -66,10 +66,10 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
-    def get_same_chip_groups(self):
+    def get_same_chip_groups(self) -> None:
         return self.__same_chip_groups
 
 
@@ -79,7 +79,7 @@ def __init__(self, n_atoms, label):
         self.__n_atoms = n_atoms
 
     @property
-    def n_atoms(self):
+    def n_atoms(self) -> None:
         return self.__n_atoms
 
 
diff --git a/unittests/operations_tests/router_algorithms_tests/test_routers.py b/unittests/operations_tests/router_algorithms_tests/test_routers.py
index 208be920f..9c03c3f14 100644
--- a/unittests/operations_tests/router_algorithms_tests/test_routers.py
+++ b/unittests/operations_tests/router_algorithms_tests/test_routers.py
@@ -67,10 +67,10 @@ def create_machine_vertices(self, chip_counter):
         for m_vertex in m_vertices:
             self.governed_app_vertex.remember_machine_vertex(m_vertex)
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -82,7 +82,7 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
 
@@ -132,10 +132,10 @@ def create_machine_vertices(self, chip_counter):
                             in_part.add_edge(MachineEdge(this_in, last_in))
                 last_incoming = incoming
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -164,13 +164,13 @@ def get_source_specific_in_coming_vertices(
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def get_internal_multicast_partitions(self):
+    def get_internal_multicast_partitions(self) -> None:
         return self.__internal_multicast_partitions
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
-    def get_same_chip_groups(self):
+    def get_same_chip_groups(self) -> None:
         return self.__same_chip_groups
 
 
@@ -189,10 +189,10 @@ def create_machine_vertices(self, chip_counter):
         for m_vertex in m_vertices:
             self.governed_app_vertex.remember_machine_vertex(m_vertex)
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -204,7 +204,7 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
     def get_source_specific_in_coming_vertices(
@@ -218,7 +218,7 @@ def get_source_specific_in_coming_vertices(
 
 class MockNearestEthernetSplitter(AbstractSplitterCommon):
 
-    def __init__(self):
+    def __init__(self) -> None:
         super().__init__()
         self.__placements = Placements()
         self.__m_vertex_by_ethernet = dict()
@@ -234,10 +234,10 @@ def create_machine_vertices(self, chip_counter):
                 Placement(m_vertex, chip.x, chip.y, 1))
             self.__m_vertex_by_ethernet[chip.x, chip.y] = m_vertex
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -249,7 +249,7 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
     def get_source_specific_in_coming_vertices(
@@ -264,7 +264,7 @@ def get_source_specific_in_coming_vertices(
         return [(target_m_vertex, [source_vertex])]
 
     @property
-    def placements(self):
+    def placements(self) -> None:
         return self.__placements
 
 
@@ -300,10 +300,10 @@ def create_machine_vertices(self, chip_counter):
             for end_v in self.__incoming_machine_vertices:
                 part.add_edge(MachineEdge(start_v, end_v))
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return None
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return None
 
     def get_out_going_vertices(self, partition_id):
@@ -315,10 +315,10 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return []
 
-    def get_internal_multicast_partitions(self):
+    def get_internal_multicast_partitions(self) -> None:
         return self.__internal_multicast_partitions
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
 
@@ -328,7 +328,7 @@ def __init__(self, n_atoms, label):
         self.__n_atoms = n_atoms
 
     @property
-    def n_atoms(self):
+    def n_atoms(self) -> None:
         return self.__n_atoms
 
 
diff --git a/unittests/operations_tests/router_compressor_tests/test_checked_unordered_pair_compression.py b/unittests/operations_tests/router_compressor_tests/test_checked_unordered_pair_compression.py
index 30f4fb944..7f68f6876 100644
--- a/unittests/operations_tests/router_compressor_tests/test_checked_unordered_pair_compression.py
+++ b/unittests/operations_tests/router_compressor_tests/test_checked_unordered_pair_compression.py
@@ -29,14 +29,15 @@
 
 class TestUnorderedPairCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # This tests needs exactly version 5 as on Spin2 it would fit
-        set_config("Machine", "version", FIVE)
+        set_config("Machine", "version", str(FIVE))
 
-    def test_onordered_pair_big(self):
+    def test_onordered_pair_big(self) -> None:
 
         class_file = sys.modules[self.__module__].__file__
+        assert class_file is not None
         path = os.path.dirname(os.path.abspath(class_file))
         j_router = os.path.join(path, "many_to_one.json.gz")
         original_tables = from_json(j_router)
diff --git a/unittests/operations_tests/router_compressor_tests/test_compressors.py b/unittests/operations_tests/router_compressor_tests/test_compressors.py
index 39d4ff8d9..98987a482 100644
--- a/unittests/operations_tests/router_compressor_tests/test_compressors.py
+++ b/unittests/operations_tests/router_compressor_tests/test_compressors.py
@@ -32,7 +32,7 @@
 
 class TestCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         original_tables = MulticastRoutingTables()
         original_table = UnCompressedMulticastRoutingTable(x=0, y=0)
         original_table.add_multicast_routing_entry(
@@ -62,41 +62,43 @@ def setUp(self):
         original_tables.add_routing_table(original_table)
         unittest_setup()
         set_config(
-            "Mapping", "router_table_compress_as_far_as_possible", True)
+            "Mapping", "router_table_compress_as_far_as_possible", "True")
         set_config("Machine", "versions", VersionStrings.ANY.text)
         writer = PacmanDataWriter.mock()
         writer.set_uncompressed(original_tables)
         writer.set_precompressed(original_tables)
 
-    def check_compression(self, compressed_tables):
+    def check_compression(
+            self, compressed_tables: MulticastRoutingTables) -> None:
         for original in PacmanDataView.get_precompressed():
             compressed = compressed_tables.get_routing_table_for_chip(
                 original.x, original.y)
+            assert compressed is not None
             assert compressed.number_of_entries < original.number_of_entries
             compare_tables(original, original)
 
-    def test_pair_compressor(self):
+    def test_pair_compressor(self) -> None:
         compressed_tables = pair_compressor()
         self.check_compression(compressed_tables)
 
-    def test_range_compressor_skipped(self):
+    def test_range_compressor_skipped(self) -> None:
         compressed_tables = range_compressor()
         for original in PacmanDataView.get_uncompressed():
             compressed = compressed_tables.get_routing_table_for_chip(
                 original.x, original.y)
             self.assertEqual(original, compressed)
 
-    def test_checked_unordered_pair_compressor(self):
+    def test_checked_unordered_pair_compressor(self) -> None:
         compressed_tables = pair_compressor(
             ordered=False, accept_overflow=False)
         self.check_compression(compressed_tables)
 
-    def test_unordered_pair_compressor(self):
+    def test_unordered_pair_compressor(self) -> None:
         compressed_tables = pair_compressor(
             ordered=False, accept_overflow=True)
         self.check_compression(compressed_tables)
 
-    def test_ordered_covering_compressor(self):
+    def test_ordered_covering_compressor(self) -> None:
         compressed_tables = ordered_covering_compressor()
         self.check_compression(compressed_tables)
 
diff --git a/unittests/operations_tests/router_compressor_tests/test_ordered_covering_compression.py b/unittests/operations_tests/router_compressor_tests/test_ordered_covering_compression.py
index 096d7b55e..a6c4b25f6 100644
--- a/unittests/operations_tests/router_compressor_tests/test_ordered_covering_compression.py
+++ b/unittests/operations_tests/router_compressor_tests/test_ordered_covering_compression.py
@@ -30,14 +30,16 @@
 
 class TestOrderedCoveringCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # tests against version 5 as Spin2 would not need compression
-        set_config("Machine", "version", FIVE)
+        set_config("Machine", "version", str(FIVE))
 
-    def test_oc_big(self):
+    def test_oc_big(self) -> None:
         class_file = sys.modules[self.__module__].__file__
+        assert class_file is not None
         path = os.path.dirname(os.path.abspath(class_file))
+        assert path is not None
         j_router = os.path.join(path,
                                 "many_to_one.json.gz")
         original_tables = from_json(j_router)
@@ -51,4 +53,5 @@ def test_oc_big(self):
         for original in original_tables:
             compressed = compressed_tables.get_routing_table_for_chip(
                 original.x, original.y)
+            assert compressed is not None
             compare_tables(original, compressed)
diff --git a/unittests/operations_tests/router_compressor_tests/test_pair_compression.py b/unittests/operations_tests/router_compressor_tests/test_pair_compression.py
index 8dcb8562d..9e2f80334 100644
--- a/unittests/operations_tests/router_compressor_tests/test_pair_compression.py
+++ b/unittests/operations_tests/router_compressor_tests/test_pair_compression.py
@@ -29,14 +29,16 @@
 
 class TestPairCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # tests against version 5 as Spin2 would not need compression
-        set_config("Machine", "version", FIVE)
+        set_config("Machine", "version", str(FIVE))
 
-    def do_pair_big(self, c_sort):
+    def do_pair_big(self, c_sort: bool) -> None:
         class_file = sys.modules[self.__module__].__file__
+        assert class_file is not None
         path = os.path.dirname(os.path.abspath(class_file))
+        assert path is not None
         j_router = os.path.join(path, "many_to_one.json.gz")
         original_tables = from_json(j_router)
         writer = PacmanDataWriter.mock()
@@ -49,10 +51,11 @@ def do_pair_big(self, c_sort):
         for original in original_tables:
             compressed = compressed_tables.get_routing_table_for_chip(
                 original.x, original.y)
+            assert compressed is not None
             compare_tables(original, compressed)
 
-    def test_pair_big_c_sort(self):
+    def test_pair_big_c_sort(self) -> None:
         self.do_pair_big(True)
 
-    def test_pair_big_python_sort(self):
+    def test_pair_big_python_sort(self) -> None:
         self.do_pair_big(False)
diff --git a/unittests/operations_tests/router_compressor_tests/test_range_compressor.py b/unittests/operations_tests/router_compressor_tests/test_range_compressor.py
index 99a224a06..b051efd7b 100644
--- a/unittests/operations_tests/router_compressor_tests/test_range_compressor.py
+++ b/unittests/operations_tests/router_compressor_tests/test_range_compressor.py
@@ -30,30 +30,37 @@
 
 class TestRangeCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # tests against version 5 as Spin2 would not need compression
-        set_config("Machine", "version", FIVE)
+        set_config("Machine", "version", str(FIVE))
         set_config(
-            "Mapping", "router_table_compress_as_far_as_possible", True)
+            "Mapping", "router_table_compress_as_far_as_possible", str(True))
 
-    def test_big(self):
-        path = os.path.dirname(sys.modules[self.__module__].__file__)
+    def test_big(self) -> None:
+        file_path = sys.modules[self.__module__].__file__
+        assert file_path is not None
+        path = os.path.dirname(file_path)
+        assert path is not None
         table_path = os.path.join(path, "table1.csv.gz")
         table = from_csv(table_path)
         compressor = RangeCompressor()
         compressed = compressor.compress_table(table)
         compare_tables(table, compressed)
 
-    def test_tables(self):
+    def test_tables(self) -> None:
         tables = MulticastRoutingTables()
-        path = os.path.dirname(sys.modules[self.__module__].__file__)
+        file_path = sys.modules[self.__module__].__file__
+        assert file_path is not None
+        path = os.path.dirname(file_path)
+        assert path is not None
         table_path = os.path.join(path, "table2.csv.gz")
         table = from_csv(table_path)
         tables.add_routing_table(table)
         PacmanDataWriter.mock().set_uncompressed(tables)
         compressed = range_compressor()
         c_table = compressed.get_routing_table_for_chip(0, 0)
+        assert c_table is not None
         compare_tables(table, c_table)
 
 
diff --git a/unittests/operations_tests/router_compressor_tests/test_unordered_pair_compression.py b/unittests/operations_tests/router_compressor_tests/test_unordered_pair_compression.py
index 5c8f28e13..a91806fdf 100644
--- a/unittests/operations_tests/router_compressor_tests/test_unordered_pair_compression.py
+++ b/unittests/operations_tests/router_compressor_tests/test_unordered_pair_compression.py
@@ -30,14 +30,16 @@
 
 class TestUnorderedPairCompressor(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # tests against version 5 as Spin2 would not need compression
-        set_config("Machine", "version", FIVE)
+        set_config("Machine", "version", str(FIVE))
 
-    def test_onordered_pair_big(self):
-        class_file = sys.modules[self.__module__].__file__
-        path = os.path.dirname(os.path.abspath(class_file))
+    def test_onordered_pair_big(self) -> None:
+        file_path = sys.modules[self.__module__].__file__
+        assert file_path is not None
+        path = os.path.dirname(file_path)
+        assert path is not None
         j_router = os.path.join(path, "many_to_one.json.gz")
         original_tables = from_json(j_router)
         writer = PacmanDataWriter.mock()
@@ -51,4 +53,5 @@ def test_onordered_pair_big(self):
         for original in original_tables:
             compressed = compressed_tables.get_routing_table_for_chip(
                 original.x, original.y)
+            assert compressed is not None
             compare_tables(original, compressed)
diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index 4ed07886c..d367ef0a8 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -37,13 +37,13 @@ def get_in_coming_vertices(self, partition_id):
     def machine_vertices_for_recording(self, variable_to_record):
         return list(self.governed_app_vertex.machine_vertices)
 
-    def get_out_going_slices(self):
+    def get_out_going_slices(self) -> None:
         return [m.slice for m in self.governed_app_vertex.machine_vertices]
 
-    def get_in_coming_slices(self):
+    def get_in_coming_slices(self) -> None:
         return [m.slice for m in self.governed_app_vertex.machine_vertices]
 
-    def reset_called(self):
+    def reset_called(self) -> None:
         pass
 
 
@@ -94,7 +94,7 @@ def get_n_keys_for_partition(self, partition_id):
         return self.__n_keys_required[partition_id]
 
     @property
-    def sdram_required(self):
+    def sdram_required(self) -> None:
         # Not needed for test
         return None
 
diff --git a/unittests/operations_tests/routing_table_generator_tests/test_basic.py b/unittests/operations_tests/routing_table_generator_tests/test_basic.py
index 0cb0fb122..95f6efa68 100644
--- a/unittests/operations_tests/routing_table_generator_tests/test_basic.py
+++ b/unittests/operations_tests/routing_table_generator_tests/test_basic.py
@@ -41,7 +41,8 @@
 class FixedKeyAppVertex(AbstractOneAppOneMachineVertex):
 
     def __init__(
-            self, fixed_key_and_mask, label: Optional[str] = None,
+            self, fixed_key_and_mask: Optional[BaseKeyAndMask],
+            label: Optional[str] = None,
             n_atoms: int = 1):
         AbstractOneAppOneMachineVertex.__init__(
             self, SimpleMachineVertex(ConstantSDRAM(1000)), label,
@@ -57,13 +58,13 @@ def get_fixed_key_and_mask(
 
 class TestBasic(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # TODO check after
         #  https://github.com/SpiNNakerManchester/PACMAN/pull/555
-        set_config("Machine", "version", 5)
+        set_config("Machine", "version", "5")
 
-    def create_graphs3(self, writer):
+    def create_graphs3(self, writer: PacmanDataWriter) -> None:
         v1 = SimpleTestVertex(
             300, "app1", max_atoms_per_core=10, splitter=SplitterFixedLegacy())
         v2 = SimpleTestVertex(
@@ -82,7 +83,8 @@ def create_graphs3(self, writer):
         writer.add_edge(ApplicationEdge(v2, v4), "foo")
         writer.add_edge(ApplicationEdge(v1, v1), "foo")
 
-    def make_infos(self, writer, system_placements=None):
+    def make_infos(self, writer: PacmanDataWriter,
+                   system_placements: Optional[Placements] = None) -> None:
         if system_placements is None:
             system_placements = Placements()
         splitter_partitioner()
@@ -91,14 +93,14 @@ def make_infos(self, writer, system_placements=None):
         allocator = ZonedRoutingInfoAllocator()
         writer.set_routing_infos(allocator.allocate([]))
 
-    def test_empty(self):
+    def test_empty(self) -> None:
         writer = PacmanDataWriter.mock()
         self.make_infos(writer)
         data = basic_routing_table_generator()
         self.assertEqual(0, data.get_max_number_of_entries())
         self.assertEqual(0, len(list(data.routing_tables)))
 
-    def test_graph3_with_system(self):
+    def test_graph3_with_system(self) -> None:
         writer = PacmanDataWriter.mock()
         self.create_graphs3(writer)
         system_plaements = Placements()
@@ -110,7 +112,7 @@ def test_graph3_with_system(self):
         self.assertEqual(108, data.get_total_number_of_entries())
         self.assertEqual(5, len(list(data.routing_tables)))
 
-    def test_overlapping(self):
+    def test_overlapping(self) -> None:
         # Two vertices in the same router can't send with the same key
         writer = PacmanDataWriter.mock()
         v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
@@ -128,7 +130,7 @@ def test_overlapping(self):
         with self.assertRaises(KeyError):
             basic_routing_table_generator()
 
-    def test_overlapping_different_chips(self):
+    def test_overlapping_different_chips(self) -> None:
         # Two vertices in the same router can't send with the same key
         writer = PacmanDataWriter.mock()
         v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
@@ -146,7 +148,7 @@ def test_overlapping_different_chips(self):
         with self.assertRaises(KeyError):
             basic_routing_table_generator()
 
-    def test_non_overlapping_different_chips(self):
+    def test_non_overlapping_different_chips(self) -> None:
         # Two vertices with non-overlapping routes can use the same key
         writer = PacmanDataWriter.mock()
         v_target_1 = FixedKeyAppVertex(None)
diff --git a/unittests/operations_tests/routing_table_generator_tests/test_merged.py b/unittests/operations_tests/routing_table_generator_tests/test_merged.py
index bcbbc72e9..319c047b5 100644
--- a/unittests/operations_tests/routing_table_generator_tests/test_merged.py
+++ b/unittests/operations_tests/routing_table_generator_tests/test_merged.py
@@ -12,8 +12,11 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from typing import Optional
 import unittest
+
 from spinn_utilities.config_holder import set_config
+
 from pacman.config_setup import unittest_setup
 from pacman.data.pacman_data_writer import PacmanDataWriter
 from pacman.exceptions import PacmanRoutingException
@@ -38,13 +41,13 @@
 
 class TestMerged(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         # TODO check after
         #  https://github.com/SpiNNakerManchester/PACMAN/pull/555
-        set_config("Machine", "version", 5)
+        set_config("Machine", "version", "5")
 
-    def create_graphs1(self, writer):
+    def create_graphs1(self, writer: PacmanDataWriter) -> None:
         v1 = SimpleTestVertex(
             10, "app1", max_atoms_per_core=10, splitter=SplitterFixedLegacy())
         v2 = SimpleTestVertex(
@@ -53,7 +56,7 @@ def create_graphs1(self, writer):
         writer.add_vertex(v2)
         writer.add_edge(ApplicationEdge(v1, v2), "foo")
 
-    def create_graphs2(self, writer):
+    def create_graphs2(self, writer: PacmanDataWriter) -> None:
         v1 = SimpleTestVertex(
             10, "app1", max_atoms_per_core=10, splitter=SplitterFixedLegacy())
         v2 = SimpleTestVertex(
@@ -70,7 +73,7 @@ def create_graphs2(self, writer):
         writer.add_edge(ApplicationEdge(v2, v3), "foo")
         writer.add_edge(ApplicationEdge(v3, v4), "foo")
 
-    def create_graphs3(self, writer):
+    def create_graphs3(self, writer: PacmanDataWriter) -> None:
         v1 = SimpleTestVertex(
             300, "app1", max_atoms_per_core=10, splitter=SplitterFixedLegacy())
         v2 = SimpleTestVertex(
@@ -89,7 +92,8 @@ def create_graphs3(self, writer):
         writer.add_edge(ApplicationEdge(v2, v4), "foo")
         writer.add_edge(ApplicationEdge(v1, v1), "foo")
 
-    def make_infos(self, writer, system_placements=None):
+    def make_infos(self, writer: PacmanDataWriter,
+                   system_placements: Optional[Placements] = None) -> None:
         if system_placements is None:
             system_placements = Placements()
         splitter_partitioner()
@@ -98,14 +102,14 @@ def make_infos(self, writer, system_placements=None):
         allocator = ZonedRoutingInfoAllocator()
         writer.set_routing_infos(allocator.allocate([]))
 
-    def test_empty(self):
+    def test_empty(self) -> None:
         writer = PacmanDataWriter.mock()
         self.make_infos(writer)
         data = merged_routing_table_generator()
         self.assertEqual(0, data.get_max_number_of_entries())
         self.assertEqual(0, len(list(data.routing_tables)))
 
-    def test_graph1(self):
+    def test_graph1(self) -> None:
         writer = PacmanDataWriter.mock()
         self.create_graphs1(writer)
         self.make_infos(writer)
@@ -113,7 +117,7 @@ def test_graph1(self):
         self.assertEqual(1, data.get_max_number_of_entries())
         self.assertEqual(1, len(list(data.routing_tables)))
 
-    def test_graph2(self):
+    def test_graph2(self) -> None:
         writer = PacmanDataWriter.mock()
         self.create_graphs3(writer)
         self.make_infos(writer)
@@ -121,7 +125,7 @@ def test_graph2(self):
         self.assertEqual(6, data.get_max_number_of_entries())
         self.assertEqual(5, len(list(data.routing_tables)))
 
-    def test_graph3_with_system(self):
+    def test_graph3_with_system(self) -> None:
         writer = PacmanDataWriter.mock()
         self.create_graphs3(writer)
         system_plaements = Placements()
@@ -132,7 +136,7 @@ def test_graph3_with_system(self):
         self.assertEqual(6, data.get_max_number_of_entries())
         self.assertEqual(5, len(list(data.routing_tables)))
 
-    def test_bad_infos(self):
+    def test_bad_infos(self) -> None:
         writer = PacmanDataWriter.mock()
         self.create_graphs1(writer)
         self.make_infos(writer)
@@ -144,8 +148,8 @@ def test_bad_infos(self):
         except KeyError as ex:
             self.assertIn("foo", str(ex))
 
-    def test_iterator_with_next(self):
-        empty = _IteratorWithNext([])
+    def test_iterator_with_next(self) -> None:
+        empty: _IteratorWithNext = _IteratorWithNext([])
         self.assertFalse(empty.has_next)
         with self.assertRaises(StopIteration):
             empty.pop()
@@ -156,7 +160,7 @@ def test_iterator_with_next(self):
             check.append(ten.pop())
         self.assertEqual(10, len(check))
 
-    def test_overlapping(self):
+    def test_overlapping(self) -> None:
         # Two vertices in the same router can't send with the same key
         writer = PacmanDataWriter.mock()
         v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
@@ -174,7 +178,7 @@ def test_overlapping(self):
         with self.assertRaises(KeyError):
             merged_routing_table_generator()
 
-    def test_overlapping_different_chips(self):
+    def test_overlapping_different_chips(self) -> None:
         # Two vertices in the same router can't send with the same key
         writer = PacmanDataWriter.mock()
         v_target = SimpleTestVertex(1, splitter=SplitterFixedLegacy())
@@ -192,7 +196,7 @@ def test_overlapping_different_chips(self):
         with self.assertRaises(KeyError):
             merged_routing_table_generator()
 
-    def test_non_overlapping_different_chips(self):
+    def test_non_overlapping_different_chips(self) -> None:
         # Two vertices with non-overlapping routes can use the same key
         writer = PacmanDataWriter.mock()
         v_target_1 = FixedKeyAppVertex(None)
diff --git a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
index 3215a9355..81ca4cd1c 100644
--- a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
+++ b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
@@ -31,11 +31,11 @@
 class TestTagsBoardAddresses(unittest.TestCase):
     """ Tests for ip tags on different boards
     """
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
         set_config("Machine", "versions", VersionStrings.BIG.text)
 
-    def test_ip_tags(self):
+    def test_ip_tags(self) -> None:
         writer = PacmanDataWriter.mock()
         machine = virtual_machine_by_boards(3)
         writer.set_machine(machine)
@@ -119,7 +119,7 @@ def do_too_many_ip_tags_for_1_board(self, machine):
             len(tags_by_board[eth_chip.ip_address]), len(eth_chip.tag_ids),
             "Wrong number of tags assigned to first Ethernet")
 
-    def test_fixed_tag(self):
+    def test_fixed_tag(self) -> None:
         writer = PacmanDataWriter.mock()
         machine = writer.get_machine()
         chip00 = machine.get_chip_at(0, 0)
@@ -158,21 +158,21 @@ def do_fixed_repeat_tag(self, machine):
         tags = basic_tag_allocator()
         self.assertEqual(6, len(list(tags.ip_tags_vertices)))
 
-    def test_too_many_ip_tags_for_1_board(self):
+    def test_too_many_ip_tags_for_1_board(self) -> None:
         machine = PacmanDataView.get_machine()
         with self.assertRaises(PacmanNotFoundError):
             self.do_too_many_ip_tags_for_1_board(machine)
 
-    def test_spread_ip_tags(self):
+    def test_spread_ip_tags(self) -> None:
         machine = virtual_machine_by_boards(3)
         self.do_too_many_ip_tags_for_1_board(machine)
 
-    def test_fixed_repeat_tag_1_board(self):
+    def test_fixed_repeat_tag_1_board(self) -> None:
         machine = PacmanDataView.get_machine()
         with self.assertRaises(PacmanNotFoundError):
             self.do_fixed_repeat_tag(machine)
 
-    def test_fixed_repeat_tag_3_boards(self):
+    def test_fixed_repeat_tag_3_boards(self) -> None:
         machine = virtual_machine_by_boards(3)
         self.do_fixed_repeat_tag(machine)
 
@@ -191,6 +191,6 @@ def do_reverse(self, machine):
         tags = basic_tag_allocator()
         self.assertEqual(1, len(list(tags.reverse_ip_tags)))
 
-    def test_do_reverse_3_boards(self):
+    def test_do_reverse_3_boards(self) -> None:
         machine = virtual_machine_by_boards(3)
         self.do_reverse(machine)
diff --git a/unittests/test_cfg_checker.py b/unittests/test_cfg_checker.py
index cd215e295..b0a7d02e5 100644
--- a/unittests/test_cfg_checker.py
+++ b/unittests/test_cfg_checker.py
@@ -26,7 +26,7 @@ class TestCfgChecker(unittest.TestCase):
     def setUpClass(cls):
         unittest_setup()
 
-    def test_cfg_check(self):
+    def test_cfg_check(self) -> None:
         unittests = os.path.dirname(__file__)
         pacman_dir = pacman.__path__[0]
         uinit_test_objects = pacman_test_objects.__path__[0]
diff --git a/unittests/test_import_all.py b/unittests/test_import_all.py
index 295c38442..28458f491 100644
--- a/unittests/test_import_all.py
+++ b/unittests/test_import_all.py
@@ -21,7 +21,7 @@ class ImportAllModule(unittest.TestCase):
 
     # no unittest_setup to check all imports work without it
 
-    def test_import_all(self):
+    def test_import_all(self) -> None:
         if os.environ.get('CONTINUOUS_INTEGRATION', 'false').lower() == 'true':
             package_loader.load_module("pacman", remove_pyc_files=False)
         else:
diff --git a/unittests/test_version.py b/unittests/test_version.py
index 924e1a3e0..a5a6795ee 100644
--- a/unittests/test_version.py
+++ b/unittests/test_version.py
@@ -23,10 +23,10 @@ class Test(unittest.TestCase):
     """ Tests for the SCAMP version comparison
     """
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_compare_versions(self):
+    def test_compare_versions(self) -> None:
         spinn_utilities_parts = spinn_utilities.__version__.split('.')
         spinn_machine_parts = spinn_machine.__version__.split('.')
         pacman_parts = pacman.__version__.split('.')
diff --git a/unittests/utilities_tests/test_constants.py b/unittests/utilities_tests/test_constants.py
index 8fc0f3810..f4ed28d26 100644
--- a/unittests/utilities_tests/test_constants.py
+++ b/unittests/utilities_tests/test_constants.py
@@ -19,10 +19,10 @@
 
 class TestConstants(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_edges_enum(self):
+    def test_edges_enum(self) -> None:
         self.assertEqual(constants.EDGES.EAST.value, 0)
         self.assertEqual(constants.EDGES.NORTH_EAST.value, 1)
         self.assertEqual(constants.EDGES.NORTH.value, 2)
diff --git a/unittests/utilities_tests/test_json_utils.py b/unittests/utilities_tests/test_json_utils.py
index 0711555f4..23c89232b 100644
--- a/unittests/utilities_tests/test_json_utils.py
+++ b/unittests/utilities_tests/test_json_utils.py
@@ -27,7 +27,7 @@ class TestJsonUtils(unittest.TestCase):
     # Basic graph comparators
     # ------------------------------------------------------------------
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
     def _compare_constraint(self, c1, c2, seen=None):
@@ -70,7 +70,7 @@ def placement_there_and_back(self, there):
     # Test cases
     # ------------------------------------------------------------------
 
-    def test_placement(self):
+    def test_placement(self) -> None:
         s1 = SimpleMachineVertex(
             sdram=ConstantSDRAM(0),
             iptags=[IPtagResource("127.0.0.1", port=None, strip_sdp=True)],
diff --git a/unittests/utilities_tests/test_routing_tree.py b/unittests/utilities_tests/test_routing_tree.py
index 47aa5a396..437c5e488 100644
--- a/unittests/utilities_tests/test_routing_tree.py
+++ b/unittests/utilities_tests/test_routing_tree.py
@@ -19,10 +19,10 @@
 
 class TestRoutingTre(unittest.TestCase):
 
-    def setUp(self):
+    def setUp(self) -> None:
         unittest_setup()
 
-    def test_call(self):
+    def test_call(self) -> None:
         # Note Vertices as string is incorrect but easier to do for test
 
         rt1 = RoutingTree((3, 4))

From 30d52e61d7c88067392abe6f4c2deff8cec0c6dc Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Thu, 20 Feb 2025 12:31:21 +0000
Subject: [PATCH 04/14] unittest typing

---
 pacman/model/graphs/application/application_vertex.py  | 10 ++++++----
 pacman_test_objects/simple_test_vertex.py              |  4 +---
 .../application_graph_tests/test_application_vertex.py |  3 +--
 .../routing_info_tests/test_routing_info.py            |  6 +++---
 .../routing_table_tests/test_routing_tables_model.py   |  9 +++++----
 .../splitter_tests/test_one_app_one_machine.py         |  4 ++--
 .../splitter_tests/test_splitter_fixed_legacy.py       |  4 ++--
 .../model_tests/splitter_tests/test_splitter_reset.py  |  2 +-
 8 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/pacman/model/graphs/application/application_vertex.py b/pacman/model/graphs/application/application_vertex.py
index a2645664b..c13a304a2 100644
--- a/pacman/model/graphs/application/application_vertex.py
+++ b/pacman/model/graphs/application/application_vertex.py
@@ -33,11 +33,12 @@
     from .application_edge import ApplicationEdge
     from .application_edge_partition import ApplicationEdgePartition
 #: :meta private:
+APPV = TypeVar("APPV", bound='ApplicationVertex')
 MV = TypeVar("MV", bound='MachineVertex')
 logger = FormatAdapter(logging.getLogger(__file__))
 
 
-class ApplicationVertex(AbstractVertex, Generic[MV], metaclass=AbstractBase):
+class ApplicationVertex(AbstractVertex, Generic[APPV], metaclass=AbstractBase):
     """
     A vertex that can be broken down into a number of smaller vertices
     based on the resources that the vertex requires.
@@ -62,7 +63,7 @@ class ApplicationVertex(AbstractVertex, Generic[MV], metaclass=AbstractBase):
     def __init__(
             self, label: Optional[str] = None,
             max_atoms_per_core: Optional[Union[int, Tuple[int, ...]]] = None,
-            splitter: Optional[AbstractSplitterCommon[Self]] = None):
+            splitter: Optional[AbstractSplitterCommon[ApplicationVertex]] = None):
         """
         :param str label: The optional name of the vertex.
         :param max_atoms_per_core: The max number of atoms that can be
@@ -105,7 +106,7 @@ def has_splitter(self) -> bool:
         return self._splitter is not None
 
     @property
-    def splitter(self) -> AbstractSplitterCommon[Self]:
+    def splitter(self) -> AbstractSplitterCommon[APPV]:
         """
         :rtype: ~pacman.model.partitioner_splitters.AbstractSplitterCommon
         """
@@ -117,7 +118,8 @@ def splitter(self) -> AbstractSplitterCommon[Self]:
         return s
 
     @splitter.setter
-    def splitter(self, new_value: AbstractSplitterCommon[Self]) -> None:
+    def splitter(self,
+                 new_value: AbstractSplitterCommon[APPV]) -> None:
         """
         Sets the splitter object. Does not allow repeated settings.
 
diff --git a/pacman_test_objects/simple_test_vertex.py b/pacman_test_objects/simple_test_vertex.py
index 70d161c99..35c4e5aa1 100644
--- a/pacman_test_objects/simple_test_vertex.py
+++ b/pacman_test_objects/simple_test_vertex.py
@@ -16,8 +16,6 @@
 """
 from typing import Optional
 
-from typing_extensions import Self
-
 from spinn_utilities.overrides import overrides
 
 from pacman.model.partitioner_interfaces.legacy_partitioner_api import (
@@ -38,7 +36,7 @@ class SimpleTestVertex(ApplicationVertex, LegacyPartitionerAPI):
     def __init__(self, n_atoms: int, label: str = "testVertex",
                  max_atoms_per_core: int = 256,
                  fixed_sdram_value: Optional[int] = None,
-                 splitter: Optional[AbstractSplitterCommon[Self]] = None):
+                 splitter: Optional[AbstractSplitterCommon[ApplicationVertex]] = None):
         super().__init__(
             label=label, max_atoms_per_core=max_atoms_per_core,
             splitter=splitter)
diff --git a/unittests/model_tests/application_graph_tests/test_application_vertex.py b/unittests/model_tests/application_graph_tests/test_application_vertex.py
index 470408813..92a05604f 100644
--- a/unittests/model_tests/application_graph_tests/test_application_vertex.py
+++ b/unittests/model_tests/application_graph_tests/test_application_vertex.py
@@ -45,7 +45,7 @@ def __init__(self, max_atoms_per_core:Tuple[int, ...],
         self.__atoms_shape = atoms_shape
 
     @property
-    @overrides(ApplicationVertex.round_n_atoms)
+    @overrides(ApplicationVertex.n_atoms)
     def n_atoms(self) -> int:
         return numpy.prod(self.__atoms_shape)
 
@@ -127,7 +127,6 @@ def test_round_n_atoms(self) -> None:
         with self.assertRaises(PacmanInvalidParameterException):
             SimpleTestVertex(1.5)   # type: ignore[arg-type]
         vert = SimpleTestVertex(numpy.int64(23))   # type: ignore[arg-type]
-        self.assertTrue(isinstance(numpy.int64(23), int))
         self.assertTrue(isinstance(vert.n_atoms, int))
 
     def test_set_splitter(self) -> None:
diff --git a/unittests/model_tests/routing_info_tests/test_routing_info.py b/unittests/model_tests/routing_info_tests/test_routing_info.py
index 1fdfd7d93..58eeebe45 100644
--- a/unittests/model_tests/routing_info_tests/test_routing_info.py
+++ b/unittests/model_tests/routing_info_tests/test_routing_info.py
@@ -92,9 +92,9 @@ def test_routing_info(self) -> None:
         with self.assertRaises(KeyError):
             routing_info.get_info_from(
                 None, "Test")  # type: ignore[arg-type]
-        #with self.assertRaises(KeyError):
-        #    routing_info.get_info_from(
-        #        pre_vertex, None)  # type: ignore[arg-type]
+        with self.assertRaises(KeyError):
+            routing_info.get_info_from(
+                pre_vertex, None)  # type: ignore[arg-type]
 
         assert routing_info.get_key_from(
             pre_vertex, "Test") == key
diff --git a/unittests/model_tests/routing_table_tests/test_routing_tables_model.py b/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
index 83dba0b60..de7fef198 100644
--- a/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
+++ b/unittests/model_tests/routing_table_tests/test_routing_tables_model.py
@@ -200,10 +200,11 @@ def test_multicast_routing_table_by_partition(self) -> None:
         entry = RoutingEntry(link_ids=range(4, 6), processor_ids=range(8, 12))
         mrt.add_path_entry(entry, 0, 0, source_vertex, partition_id)
         assert list(mrt.get_routers()) == [(0, 0)]
-        assert len(mrt.get_entries_for_router(0, 0)) == 1
-        assert next(iter(mrt.get_entries_for_router(0, 0))) == (
-            source_vertex, partition_id)
-        mre = mrt.get_entries_for_router(0, 0)[source_vertex, partition_id]
+        entries = mrt.get_entries_for_router(0, 0)
+        assert entries is not None
+        assert len(entries) == 1
+        assert next(iter(entries)) == (source_vertex, partition_id)
+        mre = entries[source_vertex, partition_id]
         assert str(mre) == (
             "{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}:{0, 1, 2, 3, 4, 5}")
         assert mre == mrt.get_entry_on_coords_for_edge(
diff --git a/unittests/model_tests/splitter_tests/test_one_app_one_machine.py b/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
index 048de7e30..edd5b19f8 100644
--- a/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
+++ b/unittests/model_tests/splitter_tests/test_one_app_one_machine.py
@@ -36,7 +36,7 @@ def setUp(self) -> None:
 
     def test_legacy(self) -> None:
         set_config("Machine", "versions", VersionStrings.ANY.text)
-        splitter = SplitterOneAppOneMachine()
+        splitter: SplitterOneAppOneMachine = SplitterOneAppOneMachine()
         v1 = NonLegacyApplicationVertex("v1")
         a = str(splitter)
         self.assertIsNotNone(a)
@@ -62,5 +62,5 @@ def test_legacy(self) -> None:
         v2.reset()
 
     def test_default_name(self) -> None:
-        splitter = SplitterOneAppOneMachine()
+        splitter: SplitterOneAppOneMachine = SplitterOneAppOneMachine()
         self.assertIn("SplitterOneAppOneMachine", str(splitter))
diff --git a/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py b/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
index de1b5c412..58fc259a3 100644
--- a/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
+++ b/unittests/model_tests/splitter_tests/test_splitter_fixed_legacy.py
@@ -31,7 +31,7 @@ def setUp(self) -> None:
 
     def test_api(self) -> None:
         set_config("Machine", "versions", VersionStrings.ANY.text)
-        splitter = SplitterFixedLegacy()
+        splitter: SplitterFixedLegacy = SplitterFixedLegacy()
         self.assertIsNotNone(str(splitter))
         self.assertIsNotNone(repr(splitter))
         v1 = SimpleTestVertex(1, "v1")
@@ -54,7 +54,7 @@ def test_api(self) -> None:
         self.assertEqual([], splitter.get_internal_sdram_partitions())
 
     def test_not_api(self) -> None:
-        splitter = SplitterFixedLegacy()
+        splitter: SplitterFixedLegacy = SplitterFixedLegacy()
         v1 = NonLegacyApplicationVertex("v1")
         with self.assertRaises(PacmanConfigurationException):
             splitter.set_governed_app_vertex(v1)
diff --git a/unittests/model_tests/splitter_tests/test_splitter_reset.py b/unittests/model_tests/splitter_tests/test_splitter_reset.py
index b3280aa89..e4ba9ae63 100644
--- a/unittests/model_tests/splitter_tests/test_splitter_reset.py
+++ b/unittests/model_tests/splitter_tests/test_splitter_reset.py
@@ -29,7 +29,7 @@ def test_reset(self) -> None:
         # With slitter
         v1 = SimpleTestVertex(1, "v1")
         PacmanDataView.add_vertex(v1)
-        splitter = SplitterFixedLegacy()
+        splitter: SplitterFixedLegacy = SplitterFixedLegacy()
         v1.splitter = splitter
         # no splitter
         v2 = SimpleTestVertex(1, "v2")

From 0c212db5dc758f6232017a41dd9ae28d2098fa01 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Thu, 20 Feb 2025 13:21:25 +0000
Subject: [PATCH 05/14] remove the Self from the AbstractSplitterCommon type

---
 .../model/graphs/application/application_vertex.py   | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/pacman/model/graphs/application/application_vertex.py b/pacman/model/graphs/application/application_vertex.py
index c13a304a2..2ceef3923 100644
--- a/pacman/model/graphs/application/application_vertex.py
+++ b/pacman/model/graphs/application/application_vertex.py
@@ -33,12 +33,11 @@
     from .application_edge import ApplicationEdge
     from .application_edge_partition import ApplicationEdgePartition
 #: :meta private:
-APPV = TypeVar("APPV", bound='ApplicationVertex')
 MV = TypeVar("MV", bound='MachineVertex')
 logger = FormatAdapter(logging.getLogger(__file__))
 
 
-class ApplicationVertex(AbstractVertex, Generic[APPV], metaclass=AbstractBase):
+class ApplicationVertex(AbstractVertex, Generic[MV], metaclass=AbstractBase):
     """
     A vertex that can be broken down into a number of smaller vertices
     based on the resources that the vertex requires.
@@ -63,7 +62,7 @@ class ApplicationVertex(AbstractVertex, Generic[APPV], metaclass=AbstractBase):
     def __init__(
             self, label: Optional[str] = None,
             max_atoms_per_core: Optional[Union[int, Tuple[int, ...]]] = None,
-            splitter: Optional[AbstractSplitterCommon[ApplicationVertex]] = None):
+            splitter: Optional[AbstractSplitterCommon] = None):
         """
         :param str label: The optional name of the vertex.
         :param max_atoms_per_core: The max number of atoms that can be
@@ -78,7 +77,7 @@ def __init__(
             ~pacman.model.partitioner_splitters.AbstractSplitterCommon
         """
         # Need to set to None temporarily as add_constraint checks splitter
-        self._splitter: Optional[AbstractSplitterCommon[Self]] = None
+        self._splitter: Optional[AbstractSplitterCommon] = None
         super().__init__(label)
         self._machine_vertices: OrderedSet[MV] = OrderedSet()
         if splitter:
@@ -106,7 +105,7 @@ def has_splitter(self) -> bool:
         return self._splitter is not None
 
     @property
-    def splitter(self) -> AbstractSplitterCommon[APPV]:
+    def splitter(self) -> AbstractSplitterCommon:
         """
         :rtype: ~pacman.model.partitioner_splitters.AbstractSplitterCommon
         """
@@ -118,8 +117,7 @@ def splitter(self) -> AbstractSplitterCommon[APPV]:
         return s
 
     @splitter.setter
-    def splitter(self,
-                 new_value: AbstractSplitterCommon[APPV]) -> None:
+    def splitter(self, new_value: AbstractSplitterCommon) -> None:
         """
         Sets the splitter object. Does not allow repeated settings.
 

From 9d321fc38a38cf29c4cbd636558898b5715c6b36 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Thu, 20 Feb 2025 14:02:37 +0000
Subject: [PATCH 06/14] get_reverse_ip_tags_for_vertex returns a List

---
 pacman/model/tags/tags.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pacman/model/tags/tags.py b/pacman/model/tags/tags.py
index 012da646e..1cb5b79d1 100644
--- a/pacman/model/tags/tags.py
+++ b/pacman/model/tags/tags.py
@@ -181,7 +181,7 @@ def get_ip_tags_for_vertex(self, vertex: MachineVertex) -> Optional[
         return self._ip_tags_by_vertex.get(vertex)
 
     def get_reverse_ip_tags_for_vertex(
-            self, vertex: MachineVertex) -> Optional[Iterable[ReverseIPTag]]:
+            self, vertex: MachineVertex) -> Optional[List[ReverseIPTag]]:
         """
         Get the Reverse IP Tags assigned to a given machine vertex.
 

From a20c5c7189a6d2a29b540c2314f37844e52fae4b Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Fri, 21 Feb 2025 07:46:11 +0000
Subject: [PATCH 07/14] unittest typing and minor fixes

---
 .../tag_tests/test_tag_infos_model.py         |   7 +-
 unittests/model_tests/test_slice.py           |  14 +-
 .../test_application_placer.py                |  44 +++--
 .../router_algorithms_tests/test_routers.py   | 177 +++++++++++++-----
 .../test_zoned_routing_allocator.py           |  58 ++++--
 .../test_tags_board_addresses.py              |   5 +-
 unittests/utilities_tests/test_json_utils.py  |   2 +-
 .../utilities_tests/test_routing_tree.py      |  27 +--
 8 files changed, 228 insertions(+), 106 deletions(-)

diff --git a/unittests/model_tests/tag_tests/test_tag_infos_model.py b/unittests/model_tests/tag_tests/test_tag_infos_model.py
index 1aee3fa29..e52ded436 100644
--- a/unittests/model_tests/tag_tests/test_tag_infos_model.py
+++ b/unittests/model_tests/tag_tests/test_tag_infos_model.py
@@ -65,6 +65,7 @@ def test_add_iptag_then_locate_tag(self) -> None:
         tag_info.add_ip_tag(iptag, machine_vertex)
 
         gotton_tag = tag_info.get_ip_tags_for_vertex(machine_vertex)
+        assert gotton_tag is not None
         self.assertEqual(gotton_tag[0], iptag)
 
     def test_add_iptag_then_fail_to_locate(self) -> None:
@@ -91,6 +92,7 @@ def test_add_reverse_iptag_then_locate_tag(self) -> None:
         tag_info.add_reverse_ip_tag(reverse_iptag, machine_vertex)
         gotton_tag = tag_info.get_reverse_ip_tags_for_vertex(
             machine_vertex)
+        assert gotton_tag is not None
         self.assertEqual(gotton_tag[0], reverse_iptag)
 
     def test_add_reverse_iptag_then_not_locate_tag(self) -> None:
@@ -123,7 +125,7 @@ def test_add_conflicting_ip_tag(self) -> None:
         self.assertIn("The tag has already been assigned on the given board",
                       str(e.exception))
         with self.assertRaises(PacmanInvalidParameterException) as e:
-            tags.add_ip_tag(tag3, machine_vertex)
+            tags.add_ip_tag(tag3, machine_vertex)  # type: ignore[arg-type]
         self.assertIn("Only add IP tags with this method.",
                       str(e.exception))
 
@@ -143,7 +145,8 @@ def test_add_conflicting_reverse_ip_tag(self) -> None:
         self.assertIn("The tag has already been assigned to a reverse IP tag"
                       " on the given board", str(e.exception))
         with self.assertRaises(PacmanInvalidParameterException) as e:
-            tags.add_reverse_ip_tag(tag3, machine_vertex)
+            tags.add_reverse_ip_tag(
+                tag3, machine_vertex)  # type: ignore[arg-type]
         self.assertIn("Only add reverse IP tags with this method.",
                       str(e.exception))
 
diff --git a/unittests/model_tests/test_slice.py b/unittests/model_tests/test_slice.py
index edab555cb..152d55348 100644
--- a/unittests/model_tests/test_slice.py
+++ b/unittests/model_tests/test_slice.py
@@ -50,18 +50,18 @@ def test_check_lo_atom_int(self) -> None:
         # Check for value sanity
         with self.assertRaises(Exception):
             # Check for int atom
-            Slice("1", 10)
+            Slice("1", 10)  # type: ignore[arg-type]
 
     def test_check_hi_atom_sanity(self) -> None:
         with self.assertRaises(ValueError):
             # Check for slice which goes backwards
-            Slice(5, 4)
+            Slice(5, 4)    # type: ignore[arg-type]
 
     def test_check_hi_atom_int(self) -> None:
         # Check for value sanity
         with self.assertRaises(Exception):
             # Check for int atom
-            Slice(1, "10")
+            Slice(1, "10")   # type: ignore[arg-type]
 
     def test_equal_hi_lo_atoms(self) -> None:
         # This should be fine...
@@ -82,19 +82,19 @@ def test_equal_hi_lo_atoms(self) -> None:
     def test_immutability_lo_atom(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
-            s.lo_atom = 3
+            s.lo_atom = 3   # type: ignore[misc]
 
     def test_immutability_hi_atom(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
-            s.hi_atom = 3
+            s.hi_atom = 3   # type: ignore[misc]
 
     def test_immutability_n_atoms(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
-            s.n_atoms = 3
+            s.n_atoms = 3   # type: ignore[misc]
 
     def test_immutability_as_slice(self) -> None:
         s = Slice(0, 10)
         with self.assertRaises(AttributeError):
-            s.as_slice = slice(2, 10)
+            s.as_slice = slice(2, 10)    # type: ignore[misc]
diff --git a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
index 31d2109e4..cc8abd178 100644
--- a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
+++ b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
@@ -11,17 +11,24 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+from typing import Iterable, Sequence, Tuple
+
 from spinn_utilities.config_holder import set_config
+from spinn_utilities.overrides import overrides
+
 from spinn_machine.virtual_machine import virtual_machine_by_cores
 from spinn_machine.version.version_strings import VersionStrings
+
 from pacman.data.pacman_data_writer import PacmanDataWriter
 from pacman.exceptions import (PacmanPlaceException, PacmanTooBigToPlace)
 from pacman.model.partitioner_splitters import (
     SplitterFixedLegacy, AbstractSplitterCommon)
 from pacman.operations.placer_algorithms.application_placer import (
     place_application_graph, ApplicationPlacer)
-from pacman.model.graphs.machine import SimpleMachineVertex
-from pacman.model.resources import ConstantSDRAM
+from pacman.model.graphs.common import Slice
+from pacman.model.graphs.machine import MachineVertex, SimpleMachineVertex
+from pacman.model.resources import ConstantSDRAM, AbstractSDRAM
 from pacman.model.graphs.application import ApplicationVertex
 from pacman.config_setup import unittest_setup
 from pacman.model.placements.placements import Placements
@@ -38,7 +45,8 @@ def __init__(self, n_groups, n_machine_vertices, sdram=0):
         self.__same_chip_groups = list()
         self.__sdram = sdram
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         for _ in range(self.__n_groups):
             m_vertices = [
                 SimpleMachineVertex(
@@ -51,25 +59,36 @@ def create_machine_vertices(self, chip_counter):
             self.__same_chip_groups.append(
                 (m_vertices, ConstantSDRAM(self.__sdram)))
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
-    def get_same_chip_groups(self) -> None:
+    @overrides(AbstractSplitterCommon.get_same_chip_groups)
+    def get_same_chip_groups(self) -> Sequence[
+            Tuple[Sequence[MachineVertex], AbstractSDRAM]]:
         return self.__same_chip_groups
 
 
@@ -79,7 +98,8 @@ def __init__(self, n_atoms, label):
         self.__n_atoms = n_atoms
 
     @property
-    def n_atoms(self) -> None:
+    @overrides(ApplicationVertex.n_atoms)
+    def n_atoms(self) -> int:
         return self.__n_atoms
 
 
diff --git a/unittests/operations_tests/router_algorithms_tests/test_routers.py b/unittests/operations_tests/router_algorithms_tests/test_routers.py
index 9c03c3f14..53e909559 100644
--- a/unittests/operations_tests/router_algorithms_tests/test_routers.py
+++ b/unittests/operations_tests/router_algorithms_tests/test_routers.py
@@ -11,19 +11,28 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
+
+from typing import Dict, Iterable, Sequence, Tuple
+from spinn_utilities.overrides import overrides
+
 from spinn_utilities.timer import Timer
 from spinn_utilities.config_holder import set_config
+
 from spinn_machine.version import FIVE
 from spinn_machine.version.version_strings import VersionStrings
 from spinn_machine.virtual_machine import (
     virtual_machine_by_boards, virtual_machine_by_cores)
+
 from pacman.data import PacmanDataView
 from pacman.data.pacman_data_writer import PacmanDataWriter
 from pacman.exceptions import PacmanRoutingException
+from pacman.model.graphs import AbstractVertex
 from pacman.model.graphs.application import (
     ApplicationVertex, ApplicationEdge,
     ApplicationSpiNNakerLinkVertex, ApplicationFPGAVertex, FPGAConnection)
-from pacman.model.graphs.machine import MulticastEdgePartition, MachineEdge
+from pacman.model.graphs.common import Slice
+from pacman.model.graphs.machine import (
+    MachineEdge, MachineVertex, MulticastEdgePartition)
 from pacman.model.partitioner_splitters import (
     SplitterExternalDevice, AbstractSplitterCommon)
 from pacman.utilities.utility_objs import ChipCounter
@@ -37,7 +46,7 @@
 from pacman.config_setup import unittest_setup
 from pacman.model.graphs.machine import SimpleMachineVertex
 from pacman.model.placements import Placements, Placement
-from pacman.model.resources import ConstantSDRAM
+from pacman.model.resources import AbstractSDRAM, ConstantSDRAM
 from pacman.model.graphs.machine import (
     MachineFPGAVertex, MachineSpiNNakerLinkVertex)
 
@@ -58,7 +67,8 @@ def __init__(self, n_machine_vertices):
         super().__init__()
         self.__n_machine_vertices = n_machine_vertices
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         m_vertices = [
             SimpleMachineVertex(
                 ConstantSDRAM(0), app_vertex=self.governed_app_vertex,
@@ -67,21 +77,30 @@ def create_machine_vertices(self, chip_counter):
         for m_vertex in m_vertices:
             self.governed_app_vertex.remember_machine_vertex(m_vertex)
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
@@ -102,7 +121,8 @@ def __init__(self, n_incoming_machine_vertices,
         self.__outgoing_machine_vertices = list()
         self.__internal_multicast_partitions = list()
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         last_incoming = None
         for i in range(self.__n_groups):
             incoming = [
@@ -132,20 +152,29 @@ def create_machine_vertices(self, chip_counter):
                             in_part.add_edge(MachineEdge(this_in, last_in))
                 last_incoming = incoming
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.__outgoing_machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return [v for lst in self.__incoming_machine_vertices for v in lst]
 
+    @overrides(AbstractSplitterCommon.get_source_specific_in_coming_vertices)
     def get_source_specific_in_coming_vertices(
-            self, source_vertex, partition_id):
+            self, source_vertex: ApplicationVertex,
+            partition_id: str) -> Sequence[Tuple[
+                MachineVertex, Sequence[AbstractVertex]]]:
         sources = source_vertex.splitter.get_out_going_vertices(partition_id)
         n_sources = len(sources)
         sources_per_incoming = int(math.ceil(
@@ -161,16 +190,23 @@ def get_source_specific_in_coming_vertices(
                 result.append((i_vertex, source_range))
         return result
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
-    def get_internal_multicast_partitions(self) -> None:
+    @overrides(AbstractSplitterCommon.get_internal_multicast_partitions)
+    def get_internal_multicast_partitions(
+            self) -> Sequence[MulticastEdgePartition]:
         return self.__internal_multicast_partitions
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
-    def get_same_chip_groups(self) -> None:
+    @overrides(AbstractSplitterCommon.get_same_chip_groups)
+    def get_same_chip_groups(self) -> Sequence[
+            Tuple[Sequence[MachineVertex], AbstractSDRAM]]:
         return self.__same_chip_groups
 
 
@@ -180,7 +216,8 @@ def __init__(self, n_machine_vertices):
         super().__init__()
         self.__n_machine_vertices = n_machine_vertices
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         m_vertices = [
             SimpleMachineVertex(
                 ConstantSDRAM(0), app_vertex=self.governed_app_vertex,
@@ -189,26 +226,38 @@ def create_machine_vertices(self, chip_counter):
         for m_vertex in m_vertices:
             self.governed_app_vertex.remember_machine_vertex(m_vertex)
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
+    @overrides(AbstractSplitterCommon.get_source_specific_in_coming_vertices)
     def get_source_specific_in_coming_vertices(
-            self, source_vertex, partition_id):
+            self, source_vertex: ApplicationVertex,
+            partition_id: str) -> Sequence[Tuple[
+                MachineVertex, Sequence[AbstractVertex]]]:
         return [
             (target, [source])
             for source, target in zip(
@@ -221,9 +270,11 @@ class MockNearestEthernetSplitter(AbstractSplitterCommon):
     def __init__(self) -> None:
         super().__init__()
         self.__placements = Placements()
+        self.__m_vertex_by_ethernet: Dict[Tuple[int, int], MachineVertex]
         self.__m_vertex_by_ethernet = dict()
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         machine = PacmanDataView.get_machine()
         for chip in machine.ethernet_connected_chips:
             m_vertex = SimpleMachineVertex(
@@ -234,26 +285,38 @@ def create_machine_vertices(self, chip_counter):
                 Placement(m_vertex, chip.x, chip.y, 1))
             self.__m_vertex_by_ethernet[chip.x, chip.y] = m_vertex
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
+    @overrides(AbstractSplitterCommon.get_source_specific_in_coming_vertices)
     def get_source_specific_in_coming_vertices(
-            self, source_vertex, partition_id):
+            self, source_vertex: ApplicationVertex,
+            partition_id: str) -> Sequence[Tuple[
+                MachineVertex, Sequence[AbstractVertex]]]:
 
         m_vertex = next(iter(source_vertex.splitter.get_out_going_vertices(
             partition_id)))
@@ -264,7 +327,7 @@ def get_source_specific_in_coming_vertices(
         return [(target_m_vertex, [source_vertex])]
 
     @property
-    def placements(self) -> None:
+    def placements(self) -> Placements:
         return self.__placements
 
 
@@ -277,7 +340,8 @@ def __init__(self, n_incoming, n_outgoing):
         self.__outgoing_machine_vertices = list()
         self.__internal_multicast_partitions = list()
 
-    def create_machine_vertices(self, chip_counter):
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
         self.__incoming_machine_vertices = [
             SimpleMachineVertex(
                 ConstantSDRAM(0), app_vertex=self.governed_app_vertex,
@@ -300,24 +364,35 @@ def create_machine_vertices(self, chip_counter):
             for end_v in self.__incoming_machine_vertices:
                 part.add_edge(MachineEdge(start_v, end_v))
 
-    def get_out_going_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_in_coming_slices(self) -> None:
-        return None
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
+        raise NotImplementedError
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.__outgoing_machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
-        return self.__incoming_machine_vertices
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
+       return self.__incoming_machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return []
 
-    def get_internal_multicast_partitions(self) -> None:
+    @overrides(AbstractSplitterCommon.get_internal_multicast_partitions)
+    def get_internal_multicast_partitions(
+            self) -> Sequence[MulticastEdgePartition]:
         return self.__internal_multicast_partitions
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
@@ -328,7 +403,7 @@ def __init__(self, n_atoms, label):
         self.__n_atoms = n_atoms
 
     @property
-    def n_atoms(self) -> None:
+    def n_atoms(self) -> int:
         return self.__n_atoms
 
 
diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index d367ef0a8..fcd25b4e5 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -11,38 +11,52 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-from typing import Optional
+from typing import Dict, Optional, Sequence, Tuple
+
 from spinn_utilities.overrides import overrides
+
 from pacman.config_setup import unittest_setup
 from pacman.data import PacmanDataView
 from pacman.operations.routing_info_allocator_algorithms.\
     zoned_routing_info_allocator import (flexible_allocate, global_allocate)
 from pacman.model.graphs.application import ApplicationEdge, ApplicationVertex
+from pacman.model.graphs.common import Slice
+from pacman.model.resources import AbstractSDRAM
 from pacman.model.routing_info.base_key_and_mask import BaseKeyAndMask
 from pacman.model.graphs.machine.machine_vertex import MachineVertex
 from pacman.model.partitioner_splitters import AbstractSplitterCommon
+from pacman.model.routing_info import RoutingInfo, MachineVertexRoutingInfo
+from pacman.utilities.utility_objs.chip_counter import ChipCounter
 
 
 class MockSplitter(AbstractSplitterCommon):
 
-    def create_machine_vertices(self, chip_counter):
-        return 1
+    @overrides(AbstractSplitterCommon.create_machine_vertices)
+    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
+        pass
 
-    def get_out_going_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_out_going_vertices)
+    def get_out_going_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def get_in_coming_vertices(self, partition_id):
+    @overrides(AbstractSplitterCommon.get_in_coming_vertices)
+    def get_in_coming_vertices(
+            self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
     def machine_vertices_for_recording(self, variable_to_record):
         return list(self.governed_app_vertex.machine_vertices)
 
-    def get_out_going_slices(self) -> None:
+    @overrides(AbstractSplitterCommon.get_out_going_slices)
+    def get_out_going_slices(self) -> Sequence[Slice]:
         return [m.slice for m in self.governed_app_vertex.machine_vertices]
 
-    def get_in_coming_slices(self) -> None:
+    @overrides(AbstractSplitterCommon.get_in_coming_slices)
+    def get_in_coming_slices(self) -> Sequence[Slice]:
         return [m.slice for m in self.governed_app_vertex.machine_vertices]
 
+    @overrides(AbstractSplitterCommon.reset_called)
     def reset_called(self) -> None:
         pass
 
@@ -90,24 +104,27 @@ def __init__(
             label=label, app_vertex=app_vertex, vertex_slice=vertex_slice)
         self.__n_keys_required = n_keys_required
 
-    def get_n_keys_for_partition(self, partition_id):
+    @overrides(MachineVertex.get_n_keys_for_partition)
+    def get_n_keys_for_partition(self, partition_id: str) -> int:
         return self.__n_keys_required[partition_id]
 
     @property
-    def sdram_required(self) -> None:
+    @overrides(MachineVertex.sdram_required)
+    def sdram_required(self) -> AbstractSDRAM:
         # Not needed for test
-        return None
+        raise NotImplementedError()
 
 
-def create_graphs1(with_fixed):
+def create_graphs1(with_fixed: bool) -> None:
     # An output vertex to aim things at (to make keys required)
     out_app_vertex = MockAppVertex(splitter=MockSplitter())
     PacmanDataView.add_vertex(out_app_vertex)
     # Create 5 application vertices (3 bits)
     app_vertices = list()
     for app_index in range(5):
-        fixed_keys_by_partition = None
-        fixed_machine_keys_by_partition = None
+        fixed_keys_by_partition: Optional[Dict[str, BaseKeyAndMask]] = None
+        fixed_machine_keys_by_partition: \
+                Optional[Dict[Tuple[MachineVertex, str], BaseKeyAndMask]] = None
         if with_fixed:
             fixed_keys_by_partition = dict()
             fixed_machine_keys_by_partition = dict()
@@ -134,7 +151,7 @@ def create_graphs1(with_fixed):
                 app_vertex=app_vertex,
                 n_keys_required={f"Part{i}": (mac_index * 2) + 1
                                  for i in range((app_index * 10) + 1)})
-            if with_fixed:
+            if fixed_machine_keys_by_partition is not None:  # with_fixed:
                 if app_index == 2:
                     fixed_machine_keys_by_partition[
                         mac_vertex, "Part7"] = BaseKeyAndMask(
@@ -166,7 +183,7 @@ def create_graphs1(with_fixed):
                 ApplicationEdge(app_vertex, out_app_vertex), f"Part{i}")
 
 
-def create_graphs_only_fixed(overlap: bool):
+def create_graphs_only_fixed(overlap: bool) -> None:
     # An output vertex to aim things at (to make keys required)
     out_app_vertex = MockAppVertex(splitter=MockSplitter())
     PacmanDataView.add_vertex(out_app_vertex)
@@ -202,7 +219,7 @@ def create_graphs_only_fixed(overlap: bool):
         ApplicationEdge(app_vertex, out_app_vertex), "Part1")
 
 
-def create_graphs_no_edge():
+def create_graphs_no_edge() -> None:
     out_app_vertex = MockAppVertex(splitter=MockSplitter())
     PacmanDataView.add_vertex(out_app_vertex)
     app_vertex = MockAppVertex(splitter=MockSplitter())
@@ -216,20 +233,23 @@ def create_graphs_no_edge():
     app_vertex.remember_machine_vertex(mac_vertex)
 
 
-def check_masks_all_the_same(routing_info, mask):
+def check_masks_all_the_same(routing_info: RoutingInfo, mask: int) -> None:
     # Check the mask is the same for all, and allows for the space required
     # for the maximum number of keys in total
     seen_keys = set()
     for r_info in routing_info:
         if isinstance(r_info.vertex, MachineVertex):
+            assert isinstance(r_info, MachineVertexRoutingInfo)
             assert (r_info.mask == mask or
                     r_info.machine_vertex.label == "RETINA")
             assert r_info.key not in seen_keys
             seen_keys.add(r_info.key)
 
 
-def check_fixed(m_vertex, part_id, key):
-    key_and_mask = m_vertex.app_vertex.get_machine_fixed_key_and_mask(
+def check_fixed(m_vertex: MachineVertex, part_id: str, key: int) -> bool:
+    app_vertex = m_vertex.app_vertex
+    assert app_vertex is not None
+    key_and_mask = app_vertex.get_machine_fixed_key_and_mask(
         m_vertex, part_id)
     if key_and_mask is None:
         return False
diff --git a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
index 81ca4cd1c..70d7d147d 100644
--- a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
+++ b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
@@ -44,7 +44,7 @@ def test_ip_tags(self) -> None:
             SimpleMachineVertex(
                 sdram=ConstantSDRAM(0),
                 iptags=[IPtagResource(
-                    "127.0.0.1", port=None, strip_sdp=True)],
+                    "127.0.0.1", port=123, strip_sdp=True)],
                 label="Vertex {}".format(i))
             for i in range(len(eth_chips))]
         print("Created {} vertices".format(len(vertices)))
@@ -57,6 +57,7 @@ def test_ip_tags(self) -> None:
 
         for vertex, chip in zip(vertices, eth_chips):
             iptags = tags.get_ip_tags_for_vertex(vertex)
+            assert iptags is not None
             self.assertEqual(
                 len(iptags), 1, "Incorrect number of tags assigned")
             self.assertEqual(
@@ -122,7 +123,7 @@ def do_too_many_ip_tags_for_1_board(self, machine):
     def test_fixed_tag(self) -> None:
         writer = PacmanDataWriter.mock()
         machine = writer.get_machine()
-        chip00 = machine.get_chip_at(0, 0)
+        chip00 = machine[0, 0]
         procs = chip00.placable_processors_ids
         placements = Placements()
         for i in range(5):
diff --git a/unittests/utilities_tests/test_json_utils.py b/unittests/utilities_tests/test_json_utils.py
index 23c89232b..abcdc165b 100644
--- a/unittests/utilities_tests/test_json_utils.py
+++ b/unittests/utilities_tests/test_json_utils.py
@@ -73,7 +73,7 @@ def placement_there_and_back(self, there):
     def test_placement(self) -> None:
         s1 = SimpleMachineVertex(
             sdram=ConstantSDRAM(0),
-            iptags=[IPtagResource("127.0.0.1", port=None, strip_sdp=True)],
+            iptags=[IPtagResource("127.0.0.1", port=456, strip_sdp=True)],
             reverse_iptags=[ReverseIPtagResource(port=25, sdp_port=2, tag=5)],
             label="PVertex")
         p1 = Placement(s1, 1, 2, 3)
diff --git a/unittests/utilities_tests/test_routing_tree.py b/unittests/utilities_tests/test_routing_tree.py
index 437c5e488..78848157c 100644
--- a/unittests/utilities_tests/test_routing_tree.py
+++ b/unittests/utilities_tests/test_routing_tree.py
@@ -14,6 +14,7 @@
 
 import unittest
 from pacman.config_setup import unittest_setup
+from pacman.model.graphs.machine import SimpleMachineVertex
 from pacman.utilities.algorithm_utilities.routing_tree import RoutingTree
 
 
@@ -23,35 +24,37 @@ def setUp(self) -> None:
         unittest_setup()
 
     def test_call(self) -> None:
-        # Note Vertices as string is incorrect but easier to do for test
-
+        m_vertex_a = SimpleMachineVertex(None, "m_vertex_a")
+        m_vertex_b = SimpleMachineVertex(None, "m_vertex_b")
+        m_vertex_1 = SimpleMachineVertex(None, "m_vertex_1")
+        m_vertex_2 = SimpleMachineVertex(None, "m_vertex_2")
         rt1 = RoutingTree((3, 4))
         self.assertIsNone(rt1.label)
         self.assertEqual(rt1.chip, (3, 4))
         self.assertTrue(rt1.is_leaf)
         self.assertIsNotNone(repr(rt1))
-        rt1.append_child((1, "m_vertexA"))
-        rt1.append_child((2, "m_vertexB"))
+        rt1.append_child((1, m_vertex_a))
+        rt1.append_child((2, m_vertex_b))
         self.assertFalse(rt1.is_leaf)
-        self.assertListEqual([(1, "m_vertexA"), (2, "m_vertexB")],
+        self.assertListEqual([(1, m_vertex_a), (2, m_vertex_b)],
                              list(rt1.children))
-        self.assertListEqual([rt1, "m_vertexA", "m_vertexB"],
+        self.assertListEqual([rt1, m_vertex_a, m_vertex_b],
                              list(iter(rt1)))
         self.assertEqual(len(rt1), len(list(rt1)))
 
         rt2 = RoutingTree((4, 5), "foo")
         self.assertEqual("foo", rt2.label)
-        rt2.append_child((2, "m_vertex1"))
+        rt2.append_child((2, m_vertex_1))
         self.assertFalse(rt2.is_leaf)
-        rt2.append_child((1, "m_vertex2"))
+        rt2.append_child((1, m_vertex_2))
         rt2.append_child((3, rt1))
 
-        self.assertListEqual([(2, "m_vertex1"), (1, "m_vertex2"), (3, rt1)],
+        self.assertListEqual([(2, m_vertex_1), (1, m_vertex_2), (3, rt1)],
                              list(rt2.children))
         self.assertIsNotNone(str(rt2))
-        rt2.remove_child((1, "m_vertex2"))
-        self.assertListEqual([(2, "m_vertex1"), (3, rt1)], list(rt2.children))
-        self.assertListEqual([rt2, "m_vertex1", rt1, "m_vertexA", "m_vertexB"],
+        rt2.remove_child((1, m_vertex_2))
+        self.assertListEqual([(2, m_vertex_1), (3, rt1)], list(rt2.children))
+        self.assertListEqual([rt2, m_vertex_1, rt1, m_vertex_a, m_vertex_b],
                              list(iter(rt2)))
         self.assertListEqual(
             [(None, (4, 5), {2, 3}), (3, (3, 4), {1, 2})],

From ac26985f63c55426c62e28c536fd65e1ecedaec9 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Fri, 21 Feb 2025 07:56:16 +0000
Subject: [PATCH 08/14] flake8

---
 pacman/model/graphs/application/application_vertex.py          | 1 -
 pacman_test_objects/simple_test_vertex.py                      | 2 +-
 .../application_graph_tests/test_application_edge.py           | 3 +--
 .../application_graph_tests/test_application_vertex.py         | 2 +-
 .../partition_algorithms_tests/test_basic_partitioner.py       | 3 ++-
 .../operations_tests/router_algorithms_tests/test_routers.py   | 2 +-
 .../test_zoned_routing_allocator.py                            | 2 +-
 7 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/pacman/model/graphs/application/application_vertex.py b/pacman/model/graphs/application/application_vertex.py
index 2ceef3923..00165022a 100644
--- a/pacman/model/graphs/application/application_vertex.py
+++ b/pacman/model/graphs/application/application_vertex.py
@@ -17,7 +17,6 @@
     Collection, Generic, Optional, Tuple, TypeVar, Union, cast, TYPE_CHECKING)
 
 import numpy
-from typing_extensions import Self
 
 from spinn_utilities.abstract_base import AbstractBase, abstractmethod
 from spinn_utilities.ordered_set import OrderedSet
diff --git a/pacman_test_objects/simple_test_vertex.py b/pacman_test_objects/simple_test_vertex.py
index 35c4e5aa1..8a4c36007 100644
--- a/pacman_test_objects/simple_test_vertex.py
+++ b/pacman_test_objects/simple_test_vertex.py
@@ -36,7 +36,7 @@ class SimpleTestVertex(ApplicationVertex, LegacyPartitionerAPI):
     def __init__(self, n_atoms: int, label: str = "testVertex",
                  max_atoms_per_core: int = 256,
                  fixed_sdram_value: Optional[int] = None,
-                 splitter: Optional[AbstractSplitterCommon[ApplicationVertex]] = None):
+                 splitter: Optional[AbstractSplitterCommon] = None):
         super().__init__(
             label=label, max_atoms_per_core=max_atoms_per_core,
             splitter=splitter)
diff --git a/unittests/model_tests/application_graph_tests/test_application_edge.py b/unittests/model_tests/application_graph_tests/test_application_edge.py
index 575899e0e..3b016a9f4 100644
--- a/unittests/model_tests/application_graph_tests/test_application_edge.py
+++ b/unittests/model_tests/application_graph_tests/test_application_edge.py
@@ -17,7 +17,6 @@
 from pacman.exceptions import (
     PacmanAlreadyExistsException, PacmanConfigurationException,
     PacmanInvalidParameterException)
-from pacman.model.graphs import AbstractEdge
 from pacman.model.graphs.application import ApplicationEdgePartition
 from pacman_test_objects import SimpleTestEdge, SimpleTestVertex
 
@@ -65,7 +64,7 @@ def test_partition(self) -> None:
         assert edge2 not in partition
         partition.add_edge(edge2)
         self.assertEqual(2, partition.n_edges)
-        #self.assertIn(edge2, partition)
+        self.assertIn(edge2, partition)
         self.assertIn("ApplicationEdgePartition", str(partition))
         self.assertIn("spikes", repr(partition))
         vert3 = SimpleTestVertex(5, "Vertex 3", 256)
diff --git a/unittests/model_tests/application_graph_tests/test_application_vertex.py b/unittests/model_tests/application_graph_tests/test_application_vertex.py
index 92a05604f..95e10d259 100644
--- a/unittests/model_tests/application_graph_tests/test_application_vertex.py
+++ b/unittests/model_tests/application_graph_tests/test_application_vertex.py
@@ -38,7 +38,7 @@ def reset_called(self) -> None:
 
 class SimpleMDVertex(ApplicationVertex):
 
-    def __init__(self, max_atoms_per_core:Tuple[int, ...],
+    def __init__(self, max_atoms_per_core: Tuple[int, ...],
                  atoms_shape: Tuple[int, ...]):
         super(SimpleMDVertex, self).__init__(
             max_atoms_per_core=max_atoms_per_core)
diff --git a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
index e21358624..c1b7f8c44 100644
--- a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
+++ b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
@@ -77,7 +77,8 @@ def test_partition_on_large_vertex_than_has_to_be_split(self) -> None:
         splitter_partitioner()
         self.assertEqual(PacmanDataView.get_n_machine_vertices(), 2)
 
-    def test_partition_on_target_size_vertex_than_has_to_be_split(self) -> None:
+    def test_partition_on_target_size_vertex_than_has_to_be_split(
+            self) -> None:
         """
         test that fixed partitioning causes correct number of vertices
         """
diff --git a/unittests/operations_tests/router_algorithms_tests/test_routers.py b/unittests/operations_tests/router_algorithms_tests/test_routers.py
index 53e909559..aacfa00c2 100644
--- a/unittests/operations_tests/router_algorithms_tests/test_routers.py
+++ b/unittests/operations_tests/router_algorithms_tests/test_routers.py
@@ -380,7 +380,7 @@ def get_out_going_vertices(
     @overrides(AbstractSplitterCommon.get_in_coming_vertices)
     def get_in_coming_vertices(
             self, partition_id: str) -> Sequence[MachineVertex]:
-       return self.__incoming_machine_vertices
+        return self.__incoming_machine_vertices
 
     @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
     def machine_vertices_for_recording(
diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index fcd25b4e5..374bace8d 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -124,7 +124,7 @@ def create_graphs1(with_fixed: bool) -> None:
     for app_index in range(5):
         fixed_keys_by_partition: Optional[Dict[str, BaseKeyAndMask]] = None
         fixed_machine_keys_by_partition: \
-                Optional[Dict[Tuple[MachineVertex, str], BaseKeyAndMask]] = None
+            Optional[Dict[Tuple[MachineVertex, str], BaseKeyAndMask]] = None
         if with_fixed:
             fixed_keys_by_partition = dict()
             fixed_machine_keys_by_partition = dict()

From 8224167582623d2ea5694c88272605e3d90340cd Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Fri, 21 Feb 2025 08:17:00 +0000
Subject: [PATCH 09/14] fixes for typing

---
 .../application_graph_tests/test_application_edge.py            | 2 +-
 .../application_graph_tests/test_application_vertex.py          | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/unittests/model_tests/application_graph_tests/test_application_edge.py b/unittests/model_tests/application_graph_tests/test_application_edge.py
index 3b016a9f4..3b1d918c5 100644
--- a/unittests/model_tests/application_graph_tests/test_application_edge.py
+++ b/unittests/model_tests/application_graph_tests/test_application_edge.py
@@ -64,7 +64,7 @@ def test_partition(self) -> None:
         assert edge2 not in partition
         partition.add_edge(edge2)
         self.assertEqual(2, partition.n_edges)
-        self.assertIn(edge2, partition)
+        assert edge2 in partition
         self.assertIn("ApplicationEdgePartition", str(partition))
         self.assertIn("spikes", repr(partition))
         vert3 = SimpleTestVertex(5, "Vertex 3", 256)
diff --git a/unittests/model_tests/application_graph_tests/test_application_vertex.py b/unittests/model_tests/application_graph_tests/test_application_vertex.py
index 95e10d259..408d7f9f4 100644
--- a/unittests/model_tests/application_graph_tests/test_application_vertex.py
+++ b/unittests/model_tests/application_graph_tests/test_application_vertex.py
@@ -47,7 +47,7 @@ def __init__(self, max_atoms_per_core: Tuple[int, ...],
     @property
     @overrides(ApplicationVertex.n_atoms)
     def n_atoms(self) -> int:
-        return numpy.prod(self.__atoms_shape)
+        return int(numpy.prod(self.__atoms_shape))
 
     @property
     @overrides(ApplicationVertex.atoms_shape)

From f36f7bde196c39ecae5bc0f3b75348a6163e7fcc Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Fri, 21 Feb 2025 17:27:26 +0000
Subject: [PATCH 10/14] unittest typing

---
 .../test_basic_partitioner.py                 |   4 -
 .../test_application_placer.py                |  43 +++--
 .../router_algorithms_tests/test_routers.py   | 173 ++++++++++--------
 .../test_zoned_routing_allocator.py           |  45 +++--
 4 files changed, 151 insertions(+), 114 deletions(-)

diff --git a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
index c1b7f8c44..1ad54e045 100644
--- a/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
+++ b/unittests/operations_tests/partition_algorithms_tests/test_basic_partitioner.py
@@ -28,10 +28,6 @@
 from pacman_test_objects import SimpleTestVertex
 
 
-def _n_machine_vertices(graph):
-    return sum([len(v.machine_vertices) for v in graph.vertices])
-
-
 class TestBasicPartitioner(unittest.TestCase):
     """
     test for basic partitioning algorithm
diff --git a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
index cc8abd178..66bf5d187 100644
--- a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
+++ b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
@@ -12,7 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Iterable, Sequence, Tuple
+from typing import Iterable, List, Optional, Sequence, Tuple
 
 from spinn_utilities.config_holder import set_config
 from spinn_utilities.overrides import overrides
@@ -38,15 +38,17 @@
 
 class MockSplitter(AbstractSplitterCommon):
 
-    def __init__(self, n_groups, n_machine_vertices, sdram=0):
+    def __init__(self, n_groups: int, n_machine_vertices: int, sdram: int = 0):
         super().__init__()
         self.__n_groups = n_groups
         self.__n_machine_vertices = n_machine_vertices
-        self.__same_chip_groups = list()
+        self.__same_chip_groups: List[Tuple[Sequence[MachineVertex],
+                AbstractSDRAM]] = list()
         self.__sdram = sdram
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
-    def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
+    def create_machine_vertices(
+            self, chip_counter: Optional[ChipCounter]) -> None:
         for _ in range(self.__n_groups):
             m_vertices = [
                 SimpleMachineVertex(
@@ -93,7 +95,7 @@ def get_same_chip_groups(self) -> Sequence[
 
 
 class MockAppVertex(ApplicationVertex):
-    def __init__(self, n_atoms, label):
+    def __init__(self, n_atoms: int, label: str):
         super().__init__(label)
         self.__n_atoms = n_atoms
 
@@ -104,7 +106,8 @@ def n_atoms(self) -> int:
 
 
 def _make_vertices(
-        writer, n_atoms, n_groups, n_machine_vertices, label, sdram=0):
+        writer: PacmanDataWriter, n_atoms: int, n_groups: int,
+        n_machine_vertices: int, label: str, sdram: int=0) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockSplitter(n_groups, n_machine_vertices, sdram)
     writer.add_vertex(vertex)
@@ -112,7 +115,7 @@ def _make_vertices(
     return vertex
 
 
-def test_application_placer():
+def test_application_placer() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -126,11 +129,11 @@ def test_application_placer():
         _make_vertices(writer, 1000, 14, 5, f"app_vertex_{i}")
     # Fudge factor needed as not filling chips well
     writer.set_machine(virtual_machine_by_cores(
-        n_cores=writer.get_n_machine_vertices() * 1.2))
+        n_cores=int(writer.get_n_machine_vertices() * 1.2)))
     place_application_graph(Placements())
 
 
-def test_application_placer_large_groups():
+def test_application_placer_large_groups() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -151,7 +154,7 @@ def test_application_placer_large_groups():
     place_application_graph(Placements())
 
 
-def test_application_placer_too_few_boards():
+def test_application_placer_too_few_boards() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -167,7 +170,7 @@ def test_application_placer_too_few_boards():
         _make_vertices(writer, 1000, 14, n_machine_vertices, f"app_vertex_{i}")
     # intentionally too small
     writer.set_machine(virtual_machine_by_cores(
-        n_cores=writer.get_n_machine_vertices() / 2))
+        n_cores=writer.get_n_machine_vertices() // 2))
     try:
         place_application_graph(Placements())
         raise AssertionError("Error not raise")
@@ -175,7 +178,7 @@ def test_application_placer_too_few_boards():
         assert ("No more chips to start" in str(ex))
 
 
-def test_application_placer_restart_needed():
+def test_application_placer_restart_needed() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -193,7 +196,7 @@ def test_application_placer_restart_needed():
     place_application_graph(Placements())
 
 
-def test_application_placer_late_fixed():
+def test_application_placer_late_fixed() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -211,7 +214,7 @@ def test_application_placer_late_fixed():
     place_application_graph(Placements())
 
 
-def test_application_placer_fill_chips():
+def test_application_placer_fill_chips() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     writer = PacmanDataWriter.mock()
@@ -232,7 +235,7 @@ def test_application_placer_fill_chips():
     place_application_graph(Placements())
 
 
-def test_sdram_bigger_than_chip():
+def test_sdram_bigger_than_chip() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
@@ -246,7 +249,7 @@ def test_sdram_bigger_than_chip():
         assert ("a Chip only has" in str(ex))
 
 
-def test_sdram_bigger_monitors():
+def test_sdram_bigger_monitors() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
@@ -263,7 +266,7 @@ def test_sdram_bigger_monitors():
         assert ("after monitors only" in str(ex))
 
 
-def test_more_cores_than_chip():
+def test_more_cores_than_chip() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
@@ -276,7 +279,7 @@ def test_more_cores_than_chip():
         assert ("number of cores on a chip" in str(ex))
 
 
-def test_more_cores_than_user():
+def test_more_cores_than_user() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
@@ -289,7 +292,7 @@ def test_more_cores_than_user():
         assert ("the user cores" in str(ex))
 
 
-def test_more_cores_with_monitor():
+def test_more_cores_with_monitor() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
@@ -305,7 +308,7 @@ def test_more_cores_with_monitor():
         assert ("reserved for monitors" in str(ex))
 
 
-def test_could_fit():
+def test_could_fit() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
     writer = PacmanDataWriter.mock()
diff --git a/unittests/operations_tests/router_algorithms_tests/test_routers.py b/unittests/operations_tests/router_algorithms_tests/test_routers.py
index aacfa00c2..932266226 100644
--- a/unittests/operations_tests/router_algorithms_tests/test_routers.py
+++ b/unittests/operations_tests/router_algorithms_tests/test_routers.py
@@ -12,12 +12,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Dict, Iterable, Sequence, Tuple
-from spinn_utilities.overrides import overrides
+from collections import defaultdict
+import math
+from typing import (
+    Any, Callable, cast, Dict, Iterable, Optional, List, Sequence, Set, Tuple)
+from typing_extensions import TypeAlias
+
+import pytest
 
-from spinn_utilities.timer import Timer
 from spinn_utilities.config_holder import set_config
+from spinn_utilities.overrides import overrides
+from spinn_utilities.timer import Timer
+from spinn_utilities.typing.coords import XY
 
+from spinn_machine import Machine, RoutingEntry
+from spinn_machine.link_data_objects import AbstractLinkData
 from spinn_machine.version import FIVE
 from spinn_machine.version.version_strings import VersionStrings
 from spinn_machine.virtual_machine import (
@@ -35,6 +44,8 @@
     MachineEdge, MachineVertex, MulticastEdgePartition)
 from pacman.model.partitioner_splitters import (
     SplitterExternalDevice, AbstractSplitterCommon)
+from pacman.model.routing_table_by_partition import (
+    MulticastRoutingTableByPartition)
 from pacman.utilities.utility_objs import ChipCounter
 from pacman.operations.placer_algorithms.application_placer import (
     place_application_graph)
@@ -50,20 +61,19 @@
 from pacman.model.graphs.machine import (
     MachineFPGAVertex, MachineSpiNNakerLinkVertex)
 
-from collections import defaultdict
-import math
-import pytest
+TA_ALG: TypeAlias = Callable[[], MulticastRoutingTableByPartition]
+TA_PARAMS: TypeAlias = Tuple[TA_ALG, int, int]
 
 
 @pytest.fixture(params=[
     (route_application_graph, 10, 50)])
-def params(request):
+def params(request: Any) -> TA_PARAMS:
     return request.param
 
 
 class MockSplitter(AbstractSplitterCommon):
 
-    def __init__(self, n_machine_vertices):
+    def __init__(self, n_machine_vertices: int):
         super().__init__()
         self.__n_machine_vertices = n_machine_vertices
 
@@ -107,19 +117,20 @@ def reset_called(self) -> None:
 
 class MockMultiInputSplitter(AbstractSplitterCommon):
 
-    def __init__(self, n_incoming_machine_vertices,
-                 n_outgoing_machine_vertices, n_groups,
-                 internal_multicast=False):
+    def __init__(self, n_incoming_machine_vertices: int,
+                 n_outgoing_machine_vertices: int, n_groups: int,
+                 internal_multicast: bool = False):
         super().__init__()
         self.__n_incoming_machine_vertices = n_incoming_machine_vertices
         self.__n_outgoing_machine_vertices = n_outgoing_machine_vertices
         self.__n_groups = n_groups
         self.__internal_multicast = internal_multicast
-        self.__same_chip_groups = list()
-        self.__incoming_machine_vertices = [
+        self.__same_chip_groups: List[Tuple[
+            Sequence[MachineVertex], AbstractSDRAM]] = list()
+        self.__incoming_machine_vertices: List[List[MachineVertex]] = [
             list() for _ in range(n_incoming_machine_vertices)]
-        self.__outgoing_machine_vertices = list()
-        self.__internal_multicast_partitions = list()
+        self.__outgoing_machine_vertices: List[MachineVertex] = list()
+        self.__internal_multicast_partitions: List[MulticastEdgePartition] = list()
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
     def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
@@ -212,7 +223,7 @@ def get_same_chip_groups(self) -> Sequence[
 
 class MockOneToOneSplitter(AbstractSplitterCommon):
 
-    def __init__(self, n_machine_vertices):
+    def __init__(self, n_machine_vertices: int):
         super().__init__()
         self.__n_machine_vertices = n_machine_vertices
 
@@ -332,13 +343,13 @@ def placements(self) -> Placements:
 
 
 class MockInputOutputSplitter(AbstractSplitterCommon):
-    def __init__(self, n_incoming, n_outgoing):
+    def __init__(self, n_incoming: int, n_outgoing: int):
         super().__init__()
-        self.__n_incoming = n_incoming
-        self.__n_outgoing = n_outgoing
-        self.__incoming_machine_vertices = list()
-        self.__outgoing_machine_vertices = list()
-        self.__internal_multicast_partitions = list()
+        self.__n_incoming: int = n_incoming
+        self.__n_outgoing: int = n_outgoing
+        self.__incoming_machine_vertices: List[MachineVertex] = list()
+        self.__outgoing_machine_vertices: List[MachineVertex] = list()
+        self.__internal_multicast_partitions: List[MulticastEdgePartition] = list()
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
     def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
@@ -398,7 +409,7 @@ def reset_called(self) -> None:
 
 
 class MockAppVertex(ApplicationVertex):
-    def __init__(self, n_atoms, label):
+    def __init__(self, n_atoms: int, label: str):
         super(MockAppVertex, self).__init__(label)
         self.__n_atoms = n_atoms
 
@@ -407,53 +418,64 @@ def n_atoms(self) -> int:
         return self.__n_atoms
 
 
-def _make_vertices(writer, n_atoms, n_machine_vertices, label):
+def _make_vertices(writer: PacmanDataWriter, n_atoms: int,
+                   n_machine_vertices: int, label: str) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockSplitter(n_machine_vertices)
     writer.add_vertex(vertex)
-    vertex.splitter.create_machine_vertices(None)
+    vertex.splitter.create_machine_vertices(ChipCounter())
     return vertex
 
 
-def _make_one_to_one_vertices(writer, n_atoms, n_machine_vertices, label):
+def _make_one_to_one_vertices(
+        writer: PacmanDataWriter, n_atoms: int, n_machine_vertices: int,
+        label: str) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockOneToOneSplitter(n_machine_vertices)
     writer.add_vertex(vertex)
-    vertex.splitter.create_machine_vertices(None)
+    vertex.splitter.create_machine_vertices(ChipCounter())
     return vertex
 
 
-def _make_ethernet_vertices(writer, n_atoms, label):
+def _make_ethernet_vertices(
+        writer: PacmanDataWriter, n_atoms: int, label: str) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockNearestEthernetSplitter()
     writer.add_vertex(vertex)
-    vertex.splitter.create_machine_vertices(None)
+    vertex.splitter.create_machine_vertices(ChipCounter())
     return vertex
 
 
 def _make_vertices_split(
-        writer, n_atoms, n_incoming, n_outgoing, n_groups, label,
-        internal_multicast=False):
+        writer: PacmanDataWriter, n_atoms: int, n_incoming: int,
+        n_outgoing: int, n_groups: int, label: str,
+        internal_multicast: bool = False) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockMultiInputSplitter(
         n_incoming, n_outgoing, n_groups, internal_multicast)
     writer.add_vertex(vertex)
-    vertex.splitter.create_machine_vertices(None)
+    vertex.splitter.create_machine_vertices(ChipCounter())
     return vertex
 
 
 def _make_input_output_vertices(
-        writer, n_atoms, n_incoming, n_outgoing, label):
+        writer: PacmanDataWriter, n_atoms: int, n_incoming: int,
+        n_outgoing: int, label: str) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockInputOutputSplitter(n_incoming, n_outgoing)
     writer.add_vertex(vertex)
-    vertex.splitter.create_machine_vertices(None)
+    vertex.splitter.create_machine_vertices(ChipCounter())
     return vertex
 
 
-def _get_entry(routing_tables, x, y, source_vertex, partition_id, allow_none):
+def _get_entry(
+        routing_tables: MulticastRoutingTableByPartition, x: int, y: int,
+        source_vertex: MachineVertex, partition_id: str,
+        allow_none: bool) -> Optional[RoutingEntry]:
+    app_vertex = source_vertex.app_vertex
+    assert app_vertex is not None
     app_entry = routing_tables.get_entry_on_coords_for_edge(
-        source_vertex.app_vertex, partition_id, x, y)
+        app_vertex, partition_id, x, y)
     entry = routing_tables.get_entry_on_coords_for_edge(
         source_vertex, partition_id, x, y)
 
@@ -472,9 +494,12 @@ def _get_entry(routing_tables, x, y, source_vertex, partition_id, allow_none):
 
 
 def _find_targets(
-        routing_tables, expected_virtual, source_vertex, partition_id):
-    found_targets = set()
-    to_follow = list()
+        routing_tables: MulticastRoutingTableByPartition,
+        expected_virtual: Set[Tuple[int, int, int]],
+        source_vertex: MachineVertex, partition_id: str) -> Set[
+            Tuple[XY, Optional[int], Optional[int]]]:
+    found_targets: Set[Tuple[XY, Optional[int], Optional[int]]] = set()
+    to_follow: List[Tuple[int, int, Optional[RoutingEntry]]] = list()
     x, y = vertex_xy(source_vertex)
     first_entry = _get_entry(
         routing_tables, x, y, source_vertex, partition_id, True)
@@ -485,6 +510,7 @@ def _find_targets(
     machine = PacmanDataView.get_machine()
     while to_follow:
         x, y, next_to_follow = to_follow.pop()
+        assert next_to_follow is not None
         if not machine.is_chip_at(x, y):
             raise PacmanRoutingException(
                 f"Route goes through {x}, {y} but that doesn't exist!")
@@ -512,8 +538,9 @@ def _find_targets(
     return found_targets
 
 
-def _add_virtual(expected_virtual, vertex):
-    link_data = None
+def _add_virtual(expected_virtual: Set[Tuple[int, int, int]],
+                 vertex: MachineVertex) -> None:
+    link_data: Optional[AbstractLinkData] = None
     if isinstance(vertex, MachineFPGAVertex):
         link_data = PacmanDataView.get_machine().get_fpga_link_with_id(
             vertex.fpga_id, vertex.fpga_link_id, vertex.board_address)
@@ -526,12 +553,12 @@ def _add_virtual(expected_virtual, vertex):
             link_data.connected_link))
 
 
-def _check_edges(routing_tables):
+def _check_edges(routing_tables: MulticastRoutingTableByPartition) -> None:
     for part in get_app_partitions():
 
         # Find the required targets
         required_targets = defaultdict(set)
-        expected_virtual = set()
+        expected_virtual: Set[Tuple[int, int, int]] = set()
         for edge in part.edges:
             post = edge.post_vertex
             targets = post.splitter.get_source_specific_in_coming_vertices(
@@ -564,7 +591,7 @@ def _check_edges(routing_tables):
             assert not actual_targets.difference(required_targets[m_vertex])
 
 
-def _route_and_time(algorithm):
+def _route_and_time(algorithm: TA_ALG) -> MulticastRoutingTableByPartition:
     timer = Timer()
     with timer:
         result = algorithm()
@@ -572,7 +599,7 @@ def _route_and_time(algorithm):
     return result
 
 
-def test_simple(params):
+def test_simple(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -586,12 +613,10 @@ def test_simple(params):
     _check_edges(routing_tables)
 
 
-def test_self(params):
+def test_self(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, n_m_vertices = params
     unittest_setup()
-    # TODO check after
-    #  https://github.com/SpiNNakerManchester/PACMAN/pull/555
-    set_config("Machine", "version", 5)
+    set_config("Machine", "version", "5")
     writer = PacmanDataWriter.mock()
     source_vertex = _make_vertices(writer, 1000, n_m_vertices, "self")
     writer.add_edge(ApplicationEdge(source_vertex, source_vertex), "Test")
@@ -601,7 +626,7 @@ def test_self(params):
     _check_edges(routing_tables)
 
 
-def test_simple_self(params):
+def test_simple_self(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -617,7 +642,7 @@ def test_simple_self(params):
     _check_edges(routing_tables)
 
 
-def test_multi(params):
+def test_multi(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -634,7 +659,7 @@ def test_multi(params):
     _check_edges(routing_tables)
 
 
-def test_multi_self(params):
+def test_multi_self(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -650,7 +675,7 @@ def test_multi_self(params):
     _check_edges(routing_tables)
 
 
-def test_multi_split(params):
+def test_multi_split(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -670,7 +695,7 @@ def test_multi_split(params):
     _check_edges(routing_tables)
 
 
-def test_multi_self_split(params):
+def test_multi_self_split(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -689,7 +714,7 @@ def test_multi_self_split(params):
     _check_edges(routing_tables)
 
 
-def test_multi_down_chips_and_links(params):
+def test_multi_down_chips_and_links(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -704,7 +729,7 @@ def test_multi_down_chips_and_links(params):
     routing_tables = _route_and_time(algorithm)
 
     # Pick a few of the chips and links used and take them out
-    chosen_entries = list()
+    chosen_entries: List[Tuple[int, int, RoutingEntry]] = list()
     count = 2
     for x, y in routing_tables.get_routers():
         if len(chosen_entries) >= 10:
@@ -714,6 +739,7 @@ def test_multi_down_chips_and_links(params):
             count -= 1
         else:
             entries = routing_tables.get_entries_for_router(x, y)
+            assert entries is not None
             count = 11 - len(chosen_entries)
             for entry in entries.values():
                 if count != 0:
@@ -745,7 +771,7 @@ def test_multi_down_chips_and_links(params):
     _check_edges(routing_tables)
 
 
-def test_internal_only(params):
+def test_internal_only(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, _n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.ANY.text)
@@ -761,7 +787,7 @@ def test_internal_only(params):
     _check_edges(routing_tables)
 
 
-def test_internal_and_split(params):
+def test_internal_and_split(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -782,11 +808,11 @@ def test_internal_and_split(params):
     _check_edges(routing_tables)
 
 
-def test_spinnaker_link(params):
+def test_spinnaker_link(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     # TODO SPIN2 spinnaker links
-    set_config("Machine", "version", FIVE)
+    set_config("Machine", "version", str(FIVE))
     writer = PacmanDataWriter.mock()
     in_device = ApplicationSpiNNakerLinkVertex(100, 0)
     in_device.splitter = SplitterExternalDevice()
@@ -807,11 +833,11 @@ def test_spinnaker_link(params):
     _check_edges(routing_tables)
 
 
-def test_fpga_link(params):
+def test_fpga_link(params: TA_PARAMS) -> None:
     algorithm, n_vertices, n_m_vertices = params
     unittest_setup()
     # TODO spin2 fpga
-    set_config("Machine", "version", 5)
+    set_config("Machine", "version", "5")
     writer = PacmanDataWriter.mock()
     in_device = ApplicationFPGAVertex(
         100, [FPGAConnection(0, 0, None, None)], None)
@@ -835,11 +861,11 @@ def test_fpga_link(params):
     _check_edges(routing_tables)
 
 
-def test_fpga_link_overlap(params):
+def test_fpga_link_overlap(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, _n_m_vertices = params
     unittest_setup()
     # TODO Spin2 links
-    set_config("Machine", "version", 5)
+    set_config("Machine", "version", "5")
     writer = PacmanDataWriter.mock()
     set_config("Machine", "down_chips", "6,1")
     in_device = ApplicationFPGAVertex(
@@ -859,7 +885,7 @@ def test_fpga_link_overlap(params):
     _check_edges(routing_tables)
 
 
-def test_odd_case(params):
+def test_odd_case(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, _n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -894,7 +920,7 @@ def test_odd_case(params):
     _check_edges(routing_tables)
 
 
-def test_with_ethernet_system_placements(params):
+def test_with_ethernet_system_placements(params: TA_PARAMS) -> None:
     # This is a test of LPG-style functionality, where an application vertex
     # is placed on multiple ethernet chips, but the source is only connected
     # to one of them
@@ -906,7 +932,8 @@ def test_with_ethernet_system_placements(params):
     source_vertex = _make_vertices(writer, 200, 3, "app_vertex")
     target_vertex = _make_ethernet_vertices(writer, 1, "eth_vertex")
     writer.add_edge(ApplicationEdge(source_vertex, target_vertex), "Test")
-    placements = target_vertex.splitter.placements
+    splitter = cast(MockNearestEthernetSplitter, target_vertex.splitter)
+    placements = splitter.placements
     chips_to_use = [(7, 8), (7, 7), (8, 7)]
     for m_vertex, chip in zip(source_vertex.machine_vertices, chips_to_use):
         placements.add_placement(Placement(m_vertex, chip[0], chip[1], 2))
@@ -915,7 +942,8 @@ def test_with_ethernet_system_placements(params):
     _check_edges(routing_tables)
 
 
-def _check_path(source, nodes_fixed, machine, target):
+def _check_path(source: XY, nodes_fixed: List[Tuple[int, XY]],
+                machine: Machine, target: XY) -> None:
     c_x, c_y = source
     seen = set()
     for direction, (n_x, n_y) in nodes_fixed:
@@ -941,7 +969,7 @@ def _check_path(source, nodes_fixed, machine, target):
             f"Route doesn't end at (5, 5): {nodes_fixed}")
 
 
-def test_route_around():
+def test_route_around() -> None:
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
     # Take out all the chips around 3,3 except one then make a path that goes
@@ -966,7 +994,7 @@ def test_route_around():
     print(nodes_fixed)
 
 
-def test_internal_io_routes(params):
+def test_internal_io_routes(params: TA_PARAMS) -> None:
     algorithm, _n_vertices, _n_m_vertices = params
     unittest_setup()
     set_config("Machine", "versions", VersionStrings.BIG.text)
@@ -975,10 +1003,11 @@ def test_internal_io_routes(params):
     writer.set_machine(machine)
     vertex = _make_input_output_vertices(writer, 1, 1, 3, "app_vertex")
     placements = Placements()
-    for i, m_vertex in enumerate(vertex.splitter.get_out_going_vertices(None)):
+    for i, m_vertex in enumerate(vertex.splitter.get_out_going_vertices("")):
         placements.add_placement(Placement(m_vertex, 0, 1, i))
 
-    for i, m_vertex in enumerate(vertex.splitter.get_in_coming_vertices(None)):
+    for i, m_vertex in enumerate(
+            vertex.splitter.get_in_coming_vertices("")):
         placements.add_placement(Placement(m_vertex, 0, 0, i))
     writer.set_placements(placements)
     routing_tables = _route_and_time(algorithm)
diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index 374bace8d..69c8c742f 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -11,7 +11,7 @@
 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-from typing import Dict, Optional, Sequence, Tuple
+from typing import Dict, Iterable, Optional, Sequence, Tuple
 
 from spinn_utilities.overrides import overrides
 
@@ -45,7 +45,9 @@ def get_in_coming_vertices(
             self, partition_id: str) -> Sequence[MachineVertex]:
         return self.governed_app_vertex.machine_vertices
 
-    def machine_vertices_for_recording(self, variable_to_record):
+    @overrides(AbstractSplitterCommon.machine_vertices_for_recording)
+    def machine_vertices_for_recording(
+            self, variable_to_record: str) -> Iterable[MachineVertex]:
         return list(self.governed_app_vertex.machine_vertices)
 
     @overrides(AbstractSplitterCommon.get_out_going_slices)
@@ -63,8 +65,12 @@ def reset_called(self) -> None:
 
 class MockAppVertex(ApplicationVertex):
 
-    def __init__(self, splitter=None, fixed_keys_by_partition=None,
-                 fixed_key=None, fixed_machine_keys_by_partition=None):
+    def __init__(self, splitter: Optional[AbstractSplitterCommon] = None,
+                 fixed_keys_by_partition:Optional[
+                     Dict[str, BaseKeyAndMask]] = None,
+                 fixed_key: Optional[BaseKeyAndMask] = None,
+                 fixed_machine_keys_by_partition:  Optional[
+                     Dict[Tuple[MachineVertex, str], BaseKeyAndMask]]=None):
         super(MockAppVertex, self).__init__(splitter=splitter)
         self.__fixed_keys_by_partition = fixed_keys_by_partition
         self.__fixed_key = fixed_key
@@ -98,8 +104,10 @@ def get_machine_fixed_key_and_mask(
 class TestMacVertex(MachineVertex):
 
     def __init__(
-            self, label=None, app_vertex=None,
-            vertex_slice=None, n_keys_required=None):
+            self, label: Optional[str] = None,
+            app_vertex: Optional[ApplicationVertex] = None,
+            vertex_slice: Optional[Slice] = None,
+            n_keys_required: Optional[Dict[str, int]] = None):
         super(TestMacVertex, self).__init__(
             label=label, app_vertex=app_vertex, vertex_slice=vertex_slice)
         self.__n_keys_required = n_keys_required
@@ -257,7 +265,8 @@ def check_fixed(m_vertex: MachineVertex, part_id: str, key: int) -> bool:
     return True
 
 
-def check_keys_for_application_partition_pairs(routing_info, app_mask):
+def check_keys_for_application_partition_pairs(
+        routing_info: RoutingInfo, app_mask: int) -> None:
     # Check the key for each application vertex/ parition pair is the same
     # The bits that should be the same are all but the bottom 12
     for part in PacmanDataView.iterate_partitions():
@@ -277,7 +286,7 @@ def check_keys_for_application_partition_pairs(routing_info, app_mask):
                 assert (key & app_mask) != 0
 
 
-def test_global_allocator():
+def test_global_allocator() -> None:
     unittest_setup()
 
     # Allocate something and check it does the right thing
@@ -295,7 +304,7 @@ def test_global_allocator():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def test_flexible_allocator_no_fixed():
+def test_flexible_allocator_no_fixed() -> None:
     unittest_setup()
 
     # Allocate something and check it does the right thing
@@ -309,7 +318,7 @@ def test_flexible_allocator_no_fixed():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def test_fixed_only():
+def test_fixed_only() -> None:
     unittest_setup()
     create_graphs_only_fixed(overlap=False)
     flexible_allocate([])
@@ -317,7 +326,7 @@ def test_fixed_only():
     assert len(list(routing_info)) == 4
 
 
-def test_overlap():
+def test_overlap() -> None:
     # This should work here; overlap is allowed provided routes don't overlap
     # (which is found elsewhere)
     unittest_setup()
@@ -325,7 +334,7 @@ def test_overlap():
     flexible_allocate([])
 
 
-def test_no_edge():
+def test_no_edge() -> None:
     unittest_setup()
     create_graphs_no_edge()
     flexible_allocate([])
@@ -333,7 +342,7 @@ def test_no_edge():
     assert len(list(routing_info)) == 0
 
 
-def test_flexible_allocator_with_fixed():
+def test_flexible_allocator_with_fixed() -> None:
     unittest_setup()
     # Allocate something and check it does the right thing
     create_graphs1(True)
@@ -346,7 +355,7 @@ def test_flexible_allocator_with_fixed():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def create_big(with_fixed):
+def create_big(with_fixed: bool) -> None:
     # This test shows how easy it is to trip up the allocator with a retina
     # Create a single "big" vertex
     fixed_key = None
@@ -386,7 +395,7 @@ def create_big(with_fixed):
         mid_app_vertex.remember_machine_vertex(mid_mac_vertex)
 
 
-def test_big_flexible_no_fixed():
+def test_big_flexible_no_fixed() -> None:
     unittest_setup()
     create_big(False)
 
@@ -399,7 +408,7 @@ def test_big_flexible_no_fixed():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def test_big_global_no_fixed():
+def test_big_global_no_fixed() -> None:
     unittest_setup()
     create_big(False)
     routing_info = global_allocate([])
@@ -416,7 +425,7 @@ def test_big_global_no_fixed():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def test_big_flexible_fixed():
+def test_big_flexible_fixed() -> None:
     unittest_setup()
     create_big(True)
 
@@ -428,7 +437,7 @@ def test_big_flexible_fixed():
     check_keys_for_application_partition_pairs(routing_info, app_mask)
 
 
-def test_big_global_fixed():
+def test_big_global_fixed() -> None:
     unittest_setup()
     create_big(True)
     routing_info = global_allocate([])

From 45a0d4314e73744a57113a3c6232274724070cf7 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 3 Mar 2025 09:55:52 +0000
Subject: [PATCH 11/14] typing

---
 .../test_zoned_routing_allocator.py           |  1 +
 .../test_tags_board_addresses.py              | 24 ++++++---
 unittests/test_cfg_checker.py                 |  2 +-
 unittests/test_fixed_route_router.py          | 50 ++++++++-----------
 unittests/utilities_tests/test_json_utils.py  | 23 +--------
 5 files changed, 42 insertions(+), 58 deletions(-)

diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index 69c8c742f..9ec598bce 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -114,6 +114,7 @@ def __init__(
 
     @overrides(MachineVertex.get_n_keys_for_partition)
     def get_n_keys_for_partition(self, partition_id: str) -> int:
+        assert self.__n_keys_required is not None
         return self.__n_keys_required[partition_id]
 
     @property
diff --git a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
index 70d7d147d..338c0ccfe 100644
--- a/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
+++ b/unittests/operations_tests/tag_allocator_tests/test_tags_board_addresses.py
@@ -14,9 +14,14 @@
 
 import unittest
 from collections import defaultdict
+from typing import Dict, Set
+
 from spinn_utilities.config_holder import set_config
+
+from spinn_machine import Machine
 from spinn_machine.version.version_strings import VersionStrings
 from spinn_machine.virtual_machine import virtual_machine_by_boards
+
 from pacman.config_setup import unittest_setup
 from pacman.data import PacmanDataView
 from pacman.data.pacman_data_writer import PacmanDataWriter
@@ -69,13 +74,13 @@ def test_ip_tags(self) -> None:
             placement = placements.get_placement_of_vertex(vertex)
             print(placement, "has tag", iptags[0])
 
-    def do_too_many_ip_tags_for_1_board(self, machine):
+    def do_too_many_ip_tags_for_1_board(self, machine: Machine) -> None:
         writer = PacmanDataWriter.mock()
         n_extra_vertices = 3
         writer.set_machine(machine)
         eth_chips = machine.ethernet_connected_chips
         eth_chip = eth_chips[0]
-        eth_chip_2 = machine.get_chip_at(eth_chip.x + 1, eth_chip.y + 1)
+        eth_chip_2 = machine[eth_chip.x + 1, eth_chip.y + 1]
         eth_procs = list(eth_chip.placable_processors_ids)
         eth2_procs = list(eth_chip_2.placable_processors_ids)
         proc = eth2_procs[-1]
@@ -103,10 +108,11 @@ def do_too_many_ip_tags_for_1_board(self, machine):
         writer.set_plan_n_timesteps(1000)
         tags = basic_tag_allocator()
 
-        tags_by_board = defaultdict(set)
+        tags_by_board: Dict[str, Set] = defaultdict(set)
         for vertices in (eth_vertices, eth2_vertices):
             for vertex in vertices:
                 iptags = tags.get_ip_tags_for_vertex(vertex)
+                assert iptags is not None
                 self.assertEqual(
                     len(iptags), 1, "Incorrect number of tags assigned")
                 placement = placements.get_placement_of_vertex(vertex)
@@ -116,8 +122,10 @@ def do_too_many_ip_tags_for_1_board(self, machine):
                     "Tag used more than once")
                 tags_by_board[iptags[0].board_address].add(iptags[0].tag)
 
+        ip_address = eth_chip.ip_address
+        assert ip_address is not None
         self.assertEqual(
-            len(tags_by_board[eth_chip.ip_address]), len(eth_chip.tag_ids),
+            len(tags_by_board[ip_address]), len(eth_chip.tag_ids),
             "Wrong number of tags assigned to first Ethernet")
 
     def test_fixed_tag(self) -> None:
@@ -139,10 +147,10 @@ def test_fixed_tag(self) -> None:
         self.assertEqual(5, len(list(tags.ip_tags)))
         self.assertEqual(5, len(list(tags.ip_tags_vertices)))
 
-    def do_fixed_repeat_tag(self, machine):
+    def do_fixed_repeat_tag(self, machine: Machine) -> None:
         writer = PacmanDataWriter.mock()
         writer.set_machine(machine)
-        chip00 = machine.get_chip_at(0, 0)
+        chip00 = machine[0, 0]
         procs = chip00.placable_processors_ids
         placements = Placements()
         for i in range(3):
@@ -177,10 +185,10 @@ def test_fixed_repeat_tag_3_boards(self) -> None:
         machine = virtual_machine_by_boards(3)
         self.do_fixed_repeat_tag(machine)
 
-    def do_reverse(self, machine):
+    def do_reverse(self, machine: Machine) -> None:
         writer = PacmanDataWriter.mock()
         writer.set_machine(machine)
-        chip00 = machine.get_chip_at(0, 0)
+        chip00 = machine[0, 0]
         processor = chip00.placable_processors_ids[0]
         placements = Placements()
         vertex = SimpleMachineVertex(
diff --git a/unittests/test_cfg_checker.py b/unittests/test_cfg_checker.py
index b0a7d02e5..39cbeae8f 100644
--- a/unittests/test_cfg_checker.py
+++ b/unittests/test_cfg_checker.py
@@ -23,7 +23,7 @@
 class TestCfgChecker(unittest.TestCase):
 
     @classmethod
-    def setUpClass(cls):
+    def setUpClass(cls) -> None:
         unittest_setup()
 
     def test_cfg_check(self) -> None:
diff --git a/unittests/test_fixed_route_router.py b/unittests/test_fixed_route_router.py
index b85a46393..0a3d0ae17 100644
--- a/unittests/test_fixed_route_router.py
+++ b/unittests/test_fixed_route_router.py
@@ -13,32 +13,37 @@
 # limitations under the License.
 
 import pytest
+from typing import Dict, Set, Tuple
+
 from spinn_utilities.config_holder import set_config
-from spinn_machine import virtual_machine
+
+from spinn_machine import Machine, RoutingEntry, virtual_machine
 from spinn_machine.version import FIVE
+
 from pacman.config_setup import unittest_setup
 from pacman.data.pacman_data_writer import PacmanDataWriter
+from pacman.model.graphs.machine import SimpleMachineVertex
 from pacman.model.placements import Placements, Placement
 from pacman.operations.fixed_route_router import fixed_route_router
 from pacman.exceptions import PacmanRoutingException
 
 
-class DestinationVertex(object):
-    pass
-
-
-def _get_destinations(machine, fixed_route_tables, source_x, source_y):
+def _get_destinations(
+        machine: Machine,
+        fixed_route_tables: Dict[Tuple[int, int], RoutingEntry],
+        source_x: int, source_y: int) -> Set[Tuple[int, int, int]]:
     to_search = list([(source_x, source_y)])
     visited = set()
-    destinations = set()
+    destinations: Set[Tuple[int, int, int]] = set()
     while to_search:
         x, y = to_search.pop()
         assert (x, y) not in visited
         entry = fixed_route_tables[x, y]
         for link in entry.link_ids:
             assert machine.is_link_at(x, y, link)
-            chip = machine.get_chip_at(x, y)
+            chip = machine[x, y]
             link_obj = chip.router.get_link(link)
+            assert link_obj is not None
             to_search.append((link_obj.destination_x, link_obj.destination_y))
         for processor_id in entry.processor_ids:
             destinations.add((x, y, processor_id))
@@ -46,20 +51,20 @@ def _get_destinations(machine, fixed_route_tables, source_x, source_y):
     return destinations
 
 
-def _check_setup(width, height):
+def _check_setup(width: int, height: int) -> None:
     machine = virtual_machine(width=width, height=height)
     writer = PacmanDataWriter.mock()
     writer.set_machine(machine)
     ethernet_chips = machine.ethernet_connected_chips
     writer.set_placements(Placements(
-        Placement(DestinationVertex(), ethernet_chip.x, ethernet_chip.y, 1)
+        Placement(SimpleMachineVertex(None), ethernet_chip.x, ethernet_chip.y, 1)
         for ethernet_chip in ethernet_chips))
 
-    fixed_route_tables = fixed_route_router(DestinationVertex)
+    fixed_route_tables = fixed_route_router(SimpleMachineVertex)
 
     for x, y in machine.chip_coordinates:
         assert (x, y) in fixed_route_tables
-        chip = machine.get_chip_at(x, y)
+        chip = machine[x, y]
         destinations = _get_destinations(machine, fixed_route_tables, x, y)
         assert len(destinations) == 1
         assert (
@@ -80,10 +85,10 @@ def _check_setup(width, height):
      (True, False),
      (False, True),
      (True, True)])
-def test_all_working(
-        width, height,  version, with_down_links, with_down_chips):
+def test_all_working(width: int, height: int,  version: int,
+                     with_down_links: bool, with_down_chips: bool) -> None:
     unittest_setup()
-    set_config("Machine", "version", version)
+    set_config("Machine", "version", str(version))
     temp_machine = virtual_machine(width=width, height=height)
     down_links = None
     if with_down_links:
@@ -103,20 +108,9 @@ def test_all_working(
     _check_setup(width, height)
 
 
-def test_unreachable():
+def test_unreachable() -> None:
     unittest_setup()
-    set_config("Machine", "version", FIVE)
+    set_config("Machine", "version", str(FIVE))
     set_config("Machine", "down_chips", "0,2:1,3:1,4")
     with pytest.raises(PacmanRoutingException):
         _check_setup(8, 8)
-
-
-if __name__ == '__main__':
-    _iterations = [
-        (False, False),
-        (True, False),
-        (False, True)]
-    _sizes = [2, 8, 12, 16]
-    for (_down_links, _down_chips) in _iterations:
-        for _size in _sizes:
-            test_all_working(_size, _size, _down_links, _down_chips)
diff --git a/unittests/utilities_tests/test_json_utils.py b/unittests/utilities_tests/test_json_utils.py
index abcdc165b..5b51caba0 100644
--- a/unittests/utilities_tests/test_json_utils.py
+++ b/unittests/utilities_tests/test_json_utils.py
@@ -30,26 +30,7 @@ class TestJsonUtils(unittest.TestCase):
     def setUp(self) -> None:
         unittest_setup()
 
-    def _compare_constraint(self, c1, c2, seen=None):
-        if seen is None:
-            seen = []
-        if c1 == c2:
-            return
-        if c1.__class__ != c2.__class__:
-            raise AssertionError("{} != {}".format(
-                c1.__class__, c2.__class__))
-        self._compare_vertex(c1.vertex, c2.vertex, seen)
-
-    def _compare_vertex(self, v1, v2, seen=None):
-        if seen is None:
-            seen = []
-        self.assertEqual(v1.label, v2.label)
-        if v1.label in seen:
-            return
-        self.assertEqual(v1.sdram_required, v2.sdram_required)
-        seen.append(v1.label)
-
-    def _compare_placement(self, p1, p2, seen=None):
+    def _compare_placement(self, p1: Placement, p2: Placement) -> None:
         self.assertEqual(p1.x, p2.x)
         self.assertEqual(p1.y, p2.y)
         self.assertEqual(p1.p, p2.p)
@@ -59,7 +40,7 @@ def _compare_placement(self, p1, p2, seen=None):
     # Composite JSON round-trip testing schemes
     # ------------------------------------------------------------------
 
-    def placement_there_and_back(self, there):
+    def placement_there_and_back(self, there: Placement) -> None:
         j_object = placement_to_json(there)
         j_str = json.dumps(j_object)
         j_object2 = json.loads(j_str)

From 4df3ad3b2a3f59cdf7205d5dd9ea02b68fde27b4 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 3 Mar 2025 10:04:34 +0000
Subject: [PATCH 12/14] flake8

---
 .../placer_algorithms_tests/test_application_placer.py      | 6 +++---
 .../router_algorithms_tests/test_routers.py                 | 6 ++++--
 .../test_zoned_routing_allocator.py                         | 4 ++--
 unittests/test_fixed_route_router.py                        | 5 +++--
 4 files changed, 12 insertions(+), 9 deletions(-)

diff --git a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
index 66bf5d187..6b72c5241 100644
--- a/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
+++ b/unittests/operations_tests/placer_algorithms_tests/test_application_placer.py
@@ -42,8 +42,8 @@ def __init__(self, n_groups: int, n_machine_vertices: int, sdram: int = 0):
         super().__init__()
         self.__n_groups = n_groups
         self.__n_machine_vertices = n_machine_vertices
-        self.__same_chip_groups: List[Tuple[Sequence[MachineVertex],
-                AbstractSDRAM]] = list()
+        self.__same_chip_groups: List[
+            Tuple[Sequence[MachineVertex], AbstractSDRAM]] = list()
         self.__sdram = sdram
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
@@ -107,7 +107,7 @@ def n_atoms(self) -> int:
 
 def _make_vertices(
         writer: PacmanDataWriter, n_atoms: int, n_groups: int,
-        n_machine_vertices: int, label: str, sdram: int=0) -> MockAppVertex:
+        n_machine_vertices: int, label: str, sdram: int = 0) -> MockAppVertex:
     vertex = MockAppVertex(n_atoms, label)
     vertex.splitter = MockSplitter(n_groups, n_machine_vertices, sdram)
     writer.add_vertex(vertex)
diff --git a/unittests/operations_tests/router_algorithms_tests/test_routers.py b/unittests/operations_tests/router_algorithms_tests/test_routers.py
index 932266226..bf263a253 100644
--- a/unittests/operations_tests/router_algorithms_tests/test_routers.py
+++ b/unittests/operations_tests/router_algorithms_tests/test_routers.py
@@ -130,7 +130,8 @@ def __init__(self, n_incoming_machine_vertices: int,
         self.__incoming_machine_vertices: List[List[MachineVertex]] = [
             list() for _ in range(n_incoming_machine_vertices)]
         self.__outgoing_machine_vertices: List[MachineVertex] = list()
-        self.__internal_multicast_partitions: List[MulticastEdgePartition] = list()
+        self.__internal_multicast_partitions: List[
+            MulticastEdgePartition] = list()
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
     def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
@@ -349,7 +350,8 @@ def __init__(self, n_incoming: int, n_outgoing: int):
         self.__n_outgoing: int = n_outgoing
         self.__incoming_machine_vertices: List[MachineVertex] = list()
         self.__outgoing_machine_vertices: List[MachineVertex] = list()
-        self.__internal_multicast_partitions: List[MulticastEdgePartition] = list()
+        self.__internal_multicast_partitions: List[
+            MulticastEdgePartition] = list()
 
     @overrides(AbstractSplitterCommon.create_machine_vertices)
     def create_machine_vertices(self, chip_counter: ChipCounter) -> None:
diff --git a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
index 9ec598bce..aa43bde6a 100644
--- a/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
+++ b/unittests/operations_tests/routing_info_algorithms_tests/test_zoned_routing_allocator.py
@@ -66,11 +66,11 @@ def reset_called(self) -> None:
 class MockAppVertex(ApplicationVertex):
 
     def __init__(self, splitter: Optional[AbstractSplitterCommon] = None,
-                 fixed_keys_by_partition:Optional[
+                 fixed_keys_by_partition: Optional[
                      Dict[str, BaseKeyAndMask]] = None,
                  fixed_key: Optional[BaseKeyAndMask] = None,
                  fixed_machine_keys_by_partition:  Optional[
-                     Dict[Tuple[MachineVertex, str], BaseKeyAndMask]]=None):
+                     Dict[Tuple[MachineVertex, str], BaseKeyAndMask]] = None):
         super(MockAppVertex, self).__init__(splitter=splitter)
         self.__fixed_keys_by_partition = fixed_keys_by_partition
         self.__fixed_key = fixed_key
diff --git a/unittests/test_fixed_route_router.py b/unittests/test_fixed_route_router.py
index 0a3d0ae17..35ac8975b 100644
--- a/unittests/test_fixed_route_router.py
+++ b/unittests/test_fixed_route_router.py
@@ -56,8 +56,9 @@ def _check_setup(width: int, height: int) -> None:
     writer = PacmanDataWriter.mock()
     writer.set_machine(machine)
     ethernet_chips = machine.ethernet_connected_chips
-    writer.set_placements(Placements(
-        Placement(SimpleMachineVertex(None), ethernet_chip.x, ethernet_chip.y, 1)
+    writer.set_placements(
+        Placements(Placement(
+            SimpleMachineVertex(None), ethernet_chip.x, ethernet_chip.y, 1)
         for ethernet_chip in ethernet_chips))
 
     fixed_route_tables = fixed_route_router(SimpleMachineVertex)

From 744448d7a92382a168efd0a2d87d59a2235b5426 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 3 Mar 2025 10:08:43 +0000
Subject: [PATCH 13/14] more flake8

---
 unittests/test_fixed_route_router.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/unittests/test_fixed_route_router.py b/unittests/test_fixed_route_router.py
index 35ac8975b..c09fc12dc 100644
--- a/unittests/test_fixed_route_router.py
+++ b/unittests/test_fixed_route_router.py
@@ -59,7 +59,7 @@ def _check_setup(width: int, height: int) -> None:
     writer.set_placements(
         Placements(Placement(
             SimpleMachineVertex(None), ethernet_chip.x, ethernet_chip.y, 1)
-        for ethernet_chip in ethernet_chips))
+                   for ethernet_chip in ethernet_chips))
 
     fixed_route_tables = fixed_route_router(SimpleMachineVertex)
 

From 6a6153ca670b3eed041b80b9756d69a4da7b06f6 Mon Sep 17 00:00:00 2001
From: "Christian Y. Brenninkmeijer"
 <christian.brenninkmeijer@manchester.ac.uk>
Date: Mon, 3 Mar 2025 10:11:06 +0000
Subject: [PATCH 14/14] no need to double mypy unittests

---
 .github/workflows/python_actions.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.github/workflows/python_actions.yml b/.github/workflows/python_actions.yml
index 7a4aa4e4d..0c75241d5 100644
--- a/.github/workflows/python_actions.yml
+++ b/.github/workflows/python_actions.yml
@@ -27,5 +27,4 @@ jobs:
       flake8-packages: pacman unittests pacman_test_objects
       pylint-packages: pacman pacman_test_objects
       mypy-full-packages: pacman pacman_test_objects unittests
-      mypy-packages: unittests
     secrets: inherit