code: def __call__(self, x, out=None):
      x = astensor(x)
  
      if out is not None:
          if not isinstance(out, ExecutableTuple):
              raise TypeError(
                  f"out should be ExecutableTuple object, got {type(out)} instead"
              )
          if len(out) != self._n_outputs:
              raise TypeError(
                  f"out should be an ExecutableTuple object with {self._n_outputs} elements, got {len(out)} instead"
              )
  
      func = getattr(spspecial, self._func_name)
      res = func(np.ones(x.shape, dtype=x.dtype))
      res_tensors = self.new_tensors(
          [x],
          kws=[
              {
                  "side": f"{self._func_name}[{i}]",
                  "dtype": output.dtype,
                  "shape": output.shape,
              }
              for i, output in enumerate(res)
          ],
      )
  
      if out is None:
          return ExecutableTuple(res_tensors)
  
      for res_tensor, out_tensor in zip(res_tensors, out):
          out_tensor.data = res_tensor.data
      return out
  
imports: import scipy.special
  from ...core import ExecutableTuple
  from ...None import opcodes
  from ..datasource import tensor
  from ..arithmetic.core import TensorUnaryOp, TensorBinOp, TensorMultiOp
  from ..array_utils import np, cp, issparse, sparse, convert_order, as_same_device, device
label_desc: Use image node_id 2 for calling the TensorTupleOp obj's underlying member method code with example usage: obj.__call__(x, out) and returns: out, ExecutableTuple