code: def test_interact():
      interactor = Interactor(runOptions=RunOptions.ON_ACTION)
      value = None
  
      def retain(func):
          """Retain result for post-call analysis"""
  
          @wraps(func)
          def wrapper(*args, **kwargs):
              nonlocal value
              value = func(*args, **kwargs)
              return value
  
          return wrapper
  
      @retain
      def a(x, y=5):
          return x, y
  
      with pytest.raises(ValueError):
          interactor(a)
  
      host = interactor(a, x=10)
      for child in "x", "y":
          assert child in host.names
  
      host = interactor(a, x=10, y={"type": "list", "limits": [5, 10]})
      testParam = host.child("y")
      assert testParam.type() == "list"
      assert testParam.opts["limits"] == [5, 10]
  
      myval = 5
      a_interact = InteractiveFunction(
          a, closures=dict(x=lambda: myval)
      )
      host = interactor(a_interact)
      assert "x" not in host.names
      host.activate()
      assert value == (5, 5)
      myval = 10
      host.activate()
      assert value == (10, 5)
  
      host = interactor(
          a,
          x=10,
          y=50,
          ignores=["x"],
          runOptions=(RunOptions.ON_CHANGED, RunOptions.ON_CHANGING),
      )
      for child in "x", "Run":
          assert child not in host.names
  
      host["y"] = 20
      assert value == (10, 20)
      host.child("y").sigValueChanging.emit(host.child("y"), 100)
      assert value == (10, 100)
  
      with interactor.optsContext(titleFormat=str.upper):
          host = interactor(a, x={"title": "different", "value": 5})
          titles = [p.title() for p in host]
          for ch in "different", "Y":
              assert ch in titles
  
      with interactor.optsContext(titleFormat="Group only"):
          host = interactor(a, x=1)
          assert host.title() == "Group only"
          assert [p.title() is None for p in host]
  
      with interactor.optsContext(runOptions=RunOptions.ON_CHANGED):
          host = interactor(a, x=5)
          host["y"] = 20
          assert value == (5, 20)
          assert "Run" not in host.names
  
      @retain
      def kwargTest(a, b=5, **c):
          return a + b - c.get("test", None)
  
      host = interactor(kwargTest, a=10, test=3)
      for ch in "a", "b", "test":
          assert ch in host.names
      host.activate()
      assert value == 12
  
      host = GP.create(name="test deco", type="group")
      interactor.setOpts(parent=host)
  
      @interactor.decorate()
      @retain
      def a(x=5):
          return x
  
      assert "a" in host.names
      assert "x" in host.child("a").names
      host.child("a").activate()
      assert value == 5
  
      @interactor.decorate(nest=False, runOptions=RunOptions.ON_CHANGED)
      @retain
      def b(y=6):
          return y
  
      assert "b" not in host.names
      assert "y" in host.names
      host["y"] = 7
      assert value == 7
  
      def raw(x=5):
          return x
  
      @retain
      def override(**kwargs):
          return raw(**kwargs)
  
      host = interactor(
          wraps(raw)(override), runOptions=RunOptions.ON_CHANGED
      )
      assert "x" in host.names
      host["x"] = 100
      assert value == 100
  
imports: from functools import wraps
  import numpy
  import pyqtgraph
  import pytest
  from pyqtgraph import functions
  from pyqtgraph.parametertree import InteractiveFunction, Interactor, interact, RunOptions
  from pyqtgraph.parametertree import Parameter
  from pyqtgraph.parametertree.Parameter import PARAM_TYPES
  from pyqtgraph.parametertree.parameterTypes import GroupParameter
  from pyqtgraph.Qt import QtGui
label_desc: Use image node_id 4 for calling a global function with example usage: test_interact() and returns: wrapper, x,  y, unknown, x, y, x, raw, value