code: def is_compatible_space(space, base_space):
      
      if isinstance(base_space, ProductSpace):
          return False
  
      if isinstance(space, ProductSpace):
          if not space.is_power_space:
              return False
          elif len(space) == 0:
              return False
          else:
              return is_compatible_space(space[0], base_space)
      else:
          if hasattr(space, 'astype') and hasattr(base_space, 'dtype'):
              # TODO: maybe only the shape should play a role?
              comp_space = space.astype(base_space.dtype)
          else:
              comp_space = space
  
          return comp_space == base_space
docs: Check compatibility of a (power) space with a base space.
  
      Compatibility here means that the spaces are equal or ``space``
      is a non-empty power space of ``base_space`` up to different
      data types.
  
      Parameters
      ----------
      space, base_space : `LinearSpace`
          Spaces to check for compatibility. ``base_space`` cannot be a
          `ProductSpace`.
  
      Returns
      -------
      is_compatible : bool
          ``True`` if
  
          - ``space == base_space`` or
          - ``space.astype(base_space.dtype) == base_space``, provided that
            these properties exist, or
          - ``space`` is a power space of nonzero length and one of the three
            situations applies to ``space[0]`` (recursively).
  
          Otherwise ``False``.
  
      Examples
      --------
      Scalar spaces:
  
      >>> base = odl.rn(2)
      >>> is_compatible_space(odl.rn(2), base)
      True
      >>> is_compatible_space(odl.rn(3), base)
      False
      >>> is_compatible_space(odl.rn(2, dtype='float32'), base)
      True
  
      Power spaces:
  
      >>> is_compatible_space(odl.rn(2) ** 2, base)
      True
      >>> is_compatible_space(odl.rn(2) * odl.rn(3), base)  # no power space
      False
      >>> is_compatible_space(odl.rn(2, dtype='float32') ** 2, base)
      True