code: def assert_shape_match(
      shape1: type_utils.Shape, shape2: type_utils.Shape
  ) -> None:
      """Ensure shape1 matches the pattern given by shape2.
  
      Ex:
        assert_shape_match((64, 64, 3), (None, None, 3))
  
      Args:
        shape1 (tuple): Static shape
        shape2 (tuple): Dynamic shape (can contain None)
      """
      if shape1 is None or shape2 is None:
          if shape1 != shape2:
              raise ValueError(
                  f"Shapes {shape1} and {shape2} must have the same rank"
              )
          return
      rank1 = len(shape1)
      rank2 = len(shape2)
      if rank1 != rank2:
          raise ValueError(
              f"Shapes {shape1} and {shape2} must have the same rank"
          )
      for dimension1, dimension2 in zip(shape1, shape2):
          if dimension1 is None or dimension2 is None:
              continue
          if dimension1 != dimension2:
              raise ValueError(
                  f"Shapes {shape1} and {shape2} are incompatible"
              )
  
imports: from __future__ import annotations
  import collections
  import contextlib
  from typing import Any, Union
  import numpy
  from tensorflow_datasets.core.utils import py_utils
  from tensorflow_datasets.core.utils import tree_utils
  from tensorflow_datasets.core.utils import type_utils
  from tensorflow_datasets.core.utils.lazy_imports_utils import tensorflow
label_desc: Use image node_id 2 for calling a global function with example usage: assert_shape_match(shape1, shape2) without return types