code: def unify(self, *, other, name="TensorSpec.unify"):
      # Unify type
      if self.type is None:
          dtype = other.type
      elif other.type is None:
          dtype = self.type
      elif util.is_iterable(x=self.type):
          if util.is_iterable(x=other.type):
              if set(self.type) <= set(other.type):
                  dtype = self.type
              elif set(other.type) <= set(self.type):
                  dtype = other.type
              else:
                  raise TensorforceError.mismatch(
                      name=name,
                      argument="type",
                      value1=self.type,
                      value2=other.type,
                  )
          elif other.type in self.type:
              dtype = other.type
          else:
              raise TensorforceError.mismatch(
                  name=name,
                  argument="type",
                  value1=self.type,
                  value2=other.type,
              )
      elif util.is_iterable(x=other.type):
          if self.type in other.type:
              dtype = self.type
          else:
              raise TensorforceError.mismatch(
                  name=name,
                  argument="type",
                  value1=self.type,
                  value2=other.type,
              )
      elif self.type == other.type:
          dtype = self.type
      else:
          raise TensorforceError.mismatch(
              name=name,
              argument="type",
              value1=self.type,
              value2=other.type,
          )
  
      # Unify shape
      if self.shape is None:
          shape = other.shape
      elif other.shape is None:
          shape = self.shape
      else:
          reverse_shape = list()
          start = len(self.shape) - 1
          if self.shape[-1] is None:
              reverse_shape.extend(other.shape[len(self.shape) - 1 :])
              start = len(self.shape) - 2
          elif other.shape[-1] is None:
              reverse_shape.extend(self.shape[len(other.shape) - 1 :])
              start = len(other.shape) - 2
          elif len(self.shape) != len(other.shape):
              raise TensorforceError.mismatch(
                  name=name,
                  argument="rank",
                  value1=self.rank,
                  value2=other.rank,
              )
          for n in range(start, -1, -1):
              if self.shape[n] == 0:
                  reverse_shape.append(other.shape[n])
              elif other.shape[n] == 0:
                  reverse_shape.append(self.shape[n])
              elif self.shape[n] == -1 and other.shape[n] > 0:
                  reverse_shape.append(other.shape[n])
              elif other.shape[n] == -1 and self.shape[n] > 0:
                  reverse_shape.append(self.shape[n])
              elif self.shape[n] == other.shape[n]:
                  reverse_shape.append(self.shape[n])
              else:
                  raise TensorforceError.mismatch(
                      name=name,
                      argument="shape",
                      value1=self.shape,
                      value2=other.shape,
                  )
          shape = tuple(reversed(reverse_shape))
  
      # Unify min_value
      if dtype == "bool":
          min_value = None
      elif self.type != "bool" and self.min_value is not None:
          if other.type != "bool" and other.min_value is not None:
              if isinstance(self.min_value, np.ndarray) or isinstance(
                  other.min_value, np.ndarray
              ):
                  min_value = np.minimum(
                      self.min_value, other.min_value
                  )
              elif self.min_value < other.min_value:
                  min_value = other.min_value
              else:
                  min_value = self.min_value
          else:
              min_value = self.min_value
      elif other.type != "bool" and other.min_value is not None:
          min_value = other.min_value
      else:
          min_value = None
  
      # Unify max_value
      if dtype == "bool":
          max_value = None
      elif self.type != "bool" and self.max_value is not None:
          if other.type != "bool" and other.max_value is not None:
              if isinstance(self.max_value, np.ndarray) or isinstance(
                  other.max_value, np.ndarray
              ):
                  max_value = np.maximum(
                      self.max_value, other.max_value
                  )
              elif self.max_value < other.max_value:
                  max_value = other.max_value
              else:
                  max_value = self.max_value
          else:
              max_value = self.max_value
      elif other.type != "bool" and other.max_value is not None:
          max_value = other.max_value
      else:
          max_value = None
      if min_value is not None and max_value is not None:
          if isinstance(min_value, np.ndarray) or isinstance(
              max_value, np.ndarray
          ):
              if (min_value > max_value).any():
                  raise TensorforceError.mismatch(
                      name=name,
                      argument="min/max_value",
                      value1=min_value,
                      value2=max_value,
                  )
          else:
              if min_value > max_value:
                  raise TensorforceError.mismatch(
                      name=name,
                      argument="min/max_value",
                      value1=min_value,
                      value2=max_value,
                  )
  
      # Unify num_values
      if dtype != "int" and (
          not isinstance(dtype, tuple) or "int" not in dtype
      ):
          num_values = None
      elif self.type == "int" and self.num_values is not None:
          if other.type == "int" and other.num_values is not None:
              if self.num_values == 0:
                  num_values = other.num_values
              elif other.num_values == 0:
                  num_values = self.num_values
              elif self.num_values == other.num_values:
                  num_values = self.num_values
              else:
                  raise TensorforceError.mismatch(
                      name=name,
                      argument="num_values",
                      value1=self.num_values,
                      value2=other.num_values,
                  )
          else:
              num_values = self.num_values
      elif other.type == "int" and other.num_values is not None:
          num_values = other.num_values
      else:
          num_values = None
      if num_values is not None:
          min_value = None
          max_value = None
  
      # Unified tensor spec
      return TensorSpec(
          type=dtype,
          shape=shape,
          min_value=min_value,
          max_value=max_value,
          num_values=num_values,
      )
  
imports: from functools import total_ordering
  import numpy
  import tensorflow
  from tensorforce import TensorforceError, util
  from tensorforce.core.utils import tf_util
label_desc: Use image node_id 15 for calling the TensorSpec obj's underlying member method code with example usage: obj.unify() and returns: TensorSpec