code: def _extend_data(
      _data: Tuple[tf.Variable, tf.Variable],
      _f: Callable[[tf.Tensor], tf.Tensor],
  ) -> Callable[[GPModel], Iterator[int]]:
      n_iterations = 3
      rng = np.random.default_rng(20220127)
      X, Y = _data
      n_features = X.shape[1]
  
      def iterate(model: GPModel) -> Iterator[int]:
          for i in range(n_iterations):
              X_new = tf.constant(rng.random((1, n_features)))
              Y_new = _f(X_new)
              X_i = tf.concat([X, X_new], axis=0)
              Y_i = tf.concat([Y, Y_new], axis=0)
  
              if isinstance(model, VGP):
                  update_vgp_data(model, (X_i, Y_i))
              else:
                  X.assign(X_i)
                  Y.assign(Y_i)
              yield i
  
      return iterate
  
imports: from typing import Any, Callable, DefaultDict, Generic, Iterator, List, Set, Tuple, Type, TypeVar, cast
  import numpy
  import pytest
  import tensorflow
  from _pytest.fixtures import SubRequest
  from check_shapes import check_shapes
  import gpflow
  from gpflow.base import RegressionData
  from gpflow.config import default_float
  from gpflow.inducing_variables import InducingPoints, InducingVariables
  from gpflow.kernels import Kernel, Matern52
  from gpflow.likelihoods import Exponential, Likelihood
  from gpflow.models import GPR, SGPR, SVGP, VGP, GPModel, training_loss_closure
  from gpflow.models.vgp import update_vgp_data
  from gpflow.posteriors import AbstractPosterior, PrecomputeCacheType
label_desc: Use image node_id 19 for calling a global function with example usage: _extend_data(_data, _f) and returns: iterate