diff --git a/b_asic/operation.py b/b_asic/operation.py
index 61c3e50d569e6194edfbb5c3caa393e14319d2ec..e39e9d6910e3d211988b7cc0913a012b8c81af83 100644
--- a/b_asic/operation.py
+++ b/b_asic/operation.py
@@ -407,7 +407,9 @@ class Operation(GraphComponent, SignalSourceProvider):
     @abstractmethod
     def get_plot_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         """
         Return a tuple containing coordinates for the two polygons outlining
         the latency and execution time of the operation.
@@ -418,7 +420,9 @@ class Operation(GraphComponent, SignalSourceProvider):
     @abstractmethod
     def get_io_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         """
         Return a tuple containing coordinates for inputs and outputs, respectively.
         These maps to the polygons and are corresponding to a start time of 0
@@ -434,7 +438,7 @@ class Operation(GraphComponent, SignalSourceProvider):
     @abstractmethod
     def get_input_coordinates(
         self,
-    ) -> Tuple[Tuple[float]]:
+    ) -> Tuple[Tuple[float, float], ...]:
         """
         Return coordinates for inputs.
         These maps to the polygons and are corresponding to a start time of 0
@@ -450,7 +454,7 @@ class Operation(GraphComponent, SignalSourceProvider):
     @abstractmethod
     def get_output_coordinates(
         self,
-    ) -> Tuple[Tuple[float]]:
+    ) -> Tuple[Tuple[float, float], ...]:
         """
         Return coordinates for outputs.
         These maps to the polygons and are corresponding to a start time of 0
@@ -953,7 +957,7 @@ class AbstractOperation(Operation, AbstractGraphComponent):
         return self.output(0)
 
     @property
-    def destination(self) -> OutputPort:
+    def destination(self) -> InputPort:
         if self.input_count != 1:
             diff = "more" if self.input_count > 1 else "less"
             raise TypeError(
@@ -1082,14 +1086,18 @@ class AbstractOperation(Operation, AbstractGraphComponent):
 
     def get_plot_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         # Doc-string inherited
         return (
             self._get_plot_coordinates_for_latency(),
             self._get_plot_coordinates_for_execution_time(),
         )
 
-    def _get_plot_coordinates_for_execution_time(self) -> Tuple[Tuple[float]]:
+    def _get_plot_coordinates_for_execution_time(
+        self,
+    ) -> Tuple[Tuple[float, float], ...]:
         # Always a rectangle, but easier if coordinates are returned
         execution_time = self._execution_time  # Copy for type checking
         if execution_time is None:
@@ -1108,7 +1116,9 @@ class AbstractOperation(Operation, AbstractGraphComponent):
                 f"All latencies must be set: {self.latency_offsets}"
             )
 
-    def _get_plot_coordinates_for_latency(self) -> Tuple[Tuple[float]]:
+    def _get_plot_coordinates_for_latency(
+        self,
+    ) -> Tuple[Tuple[float, float], ...]:
         self._check_all_latencies_set()
         # Points for latency polygon
         latency = []
@@ -1132,7 +1142,7 @@ class AbstractOperation(Operation, AbstractGraphComponent):
 
         return tuple(latency)
 
-    def get_input_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         self._check_all_latencies_set()
         return tuple(
@@ -1143,7 +1153,7 @@ class AbstractOperation(Operation, AbstractGraphComponent):
             for k in range(len(self.inputs))
         )
 
-    def get_output_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         self._check_all_latencies_set()
         return tuple(
@@ -1156,6 +1166,8 @@ class AbstractOperation(Operation, AbstractGraphComponent):
 
     def get_io_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         # Doc-string inherited
         return self.get_input_coordinates(), self.get_output_coordinates()
diff --git a/b_asic/signal.py b/b_asic/signal.py
index e8aacbfc4a68ee9db22026e1b3ae2cdf302a2c1e..06dc2cf05ee79c9af3946d6779b75a5924e3f2be 100644
--- a/b_asic/signal.py
+++ b/b_asic/signal.py
@@ -47,10 +47,8 @@ class Signal(AbstractGraphComponent):
 
     def __init__(
         self,
-        source: Optional[Union["OutputPort", "Signal", "Operation"]] = None,
-        destination: Optional[
-            Union["InputPort", "Signal", "Operation"]
-        ] = None,
+        source: Optional["OutputPort"] = None,
+        destination: Optional["InputPort"] = None,
         bits: Optional[int] = None,
         name: Name = Name(""),
     ):
@@ -104,7 +102,10 @@ class Signal(AbstractGraphComponent):
             If Operation, it must have a single output, otherwise a TypeError is
             raised. That output is used to extract the OutputPort.
         """
-        if hasattr(source, "source"):
+        # import here to avoid cyclic imports
+        from b_asic.operation import Operation
+
+        if isinstance(source, (Signal, Operation)):
             # Signal or Operation
             source = source.source
 
diff --git a/b_asic/special_operations.py b/b_asic/special_operations.py
index 93021ee427abdffaa7b0c7ff95dca784aa57b87d..c0609dd595296483a894271114c279dd21cfde8e 100644
--- a/b_asic/special_operations.py
+++ b/b_asic/special_operations.py
@@ -57,7 +57,9 @@ class Input(AbstractOperation):
 
     def get_plot_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         # Doc-string inherited
         return (
             (
@@ -78,11 +80,11 @@ class Input(AbstractOperation):
             ),
         )
 
-    def get_input_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         return tuple()
 
-    def get_output_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         return ((0, 0.5),)
 
@@ -121,18 +123,20 @@ class Output(AbstractOperation):
 
     def get_plot_coordinates(
         self,
-    ) -> Tuple[Tuple[Tuple[float]], Tuple[Tuple[float]]]:
+    ) -> Tuple[
+        Tuple[Tuple[float, float], ...], Tuple[Tuple[float, float], ...]
+    ]:
         # Doc-string inherited
         return (
             ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
             ((0, 0), (0, 1), (0.25, 1), (0.5, 0.5), (0.25, 0), (0, 0)),
         )
 
-    def get_input_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_input_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         return ((0, 0.5),)
 
-    def get_output_coordinates(self) -> Tuple[Tuple[float]]:
+    def get_output_coordinates(self) -> Tuple[Tuple[float, float], ...]:
         # doc-string inherited
         return tuple()