code: def astype(self, dtype):
          
          if dtype is None:
              # Need to filter this out since Numpy iterprets it as 'float'
              raise ValueError('`None` is not a valid data type')
  
          dtype = np.dtype(dtype)
          if dtype == self.dtype:
              return self
  
          if is_numeric_dtype(self.dtype):
              # Caching for real and complex versions (exact dtype mappings)
              if dtype == self.__real_dtype:
                  if self.__real_space is None:
                      self.__real_space = self._astype(dtype)
                  return self.__real_space
              elif dtype == self.__complex_dtype:
                  if self.__complex_space is None:
                      self.__complex_space = self._astype(dtype)
                  return self.__complex_space
              else:
                  return self._astype(dtype)
          else:
              return self._astype(dtype)
docs: Return a copy of this space with new ``dtype``.
  
          Parameters
          ----------
          dtype :
              Scalar data type of the returned space. Can be provided
              in any way the `numpy.dtype` constructor understands, e.g.
              as built-in type or as a string. Data types with non-trivial
              shapes are not allowed.
  
          Returns
          -------
          newspace : `TensorSpace`
              Version of this space with given data type.