class_docstr: `FunctionMaker` is the class to `create` `Function` instances.
  
  This class has the fgraph, the rewriter, and the linker. When
  copying a `Function`, there is no need to duplicate the
  `FunctionMaker` instance. Deepcopy still copies both, which can
  variable in re-compilation.
  
  Parameters
  ----------
  inputs : list of SymbolicInput instances
  outputs : list of SymbolicOutput instances
      Outputs may also be a single Variable (not a list), in which case the
      functions produced by FunctionMaker will return their output value
      directly.
  mode : Mode instance
      Telling FunctionMaker how to rewrite and link. None means to use the
      `config.mode`.
  accept_inplace : bool
      True iff it is acceptable to have inplace operations in the graph from
      the inputs to the outputs.
  on_unused_input : {'raise', 'warn', 'ignore', None}
      What to do if a variable in the 'inputs' list is not used in the graph.
      Possible values are:
      - 'raise': raise an error
      - 'warn': log a warning
      - 'ignore': do not do anything
      - None: Use the value in the PyTensor flags on_unused_input.
  name : str
      An optional name for this function. If used, the profile mode will
      print the time spent in this function.
code: def check_unused_inputs(inputs, outputs, on_unused_input):
      if on_unused_input is None:
          on_unused_input = config.on_unused_input
  
      if on_unused_input == "ignore":
          return
  
      # There should be two categories of variables in inputs:
      #  - variables that have to be provided (used_inputs)
      #  - shared variables that will be updated
      used_inputs = list(
          ancestors(
              (
                  [o.variable for o in outputs]
                  + [
                      i.update
                      for i in inputs
                      if getattr(i, "update", False)
                  ]
              ),
              blockers=[i.variable for i in inputs],
          )
      )
  
      msg = (
          "pytensor.function was asked to create a function computing "
          "outputs given certain inputs, but the provided input "
          "variable at index %i is not part of the computational graph "
          "needed to compute the outputs: %s.\n%s"
      )
      warn_msg = (
          "To make this warning into an error, you can pass the "
          "parameter on_unused_input='raise' to pytensor.function. "
          "To disable it completely, use on_unused_input='ignore'."
      )
      err_msg = (
          "To make this error into a warning, you can pass the "
          "parameter on_unused_input='warn' to pytensor.function. "
          "To disable it completely, use on_unused_input='ignore'."
      )
  
      for i in inputs:
          if (i.variable not in used_inputs) and (i.update is None):
              if on_unused_input == "warn":
                  warnings.warn(
                      msg % (inputs.index(i), i.variable, warn_msg),
                      stacklevel=6,
                  )
              elif on_unused_input == "raise":
                  raise UnusedInputError(
                      msg % (inputs.index(i), i.variable, err_msg)
                  )
              else:
                  raise ValueError(
                      "Invalid value for keyword on_unused_input of pytensor.function: "
                      f"'{on_unused_input}'.\n"
                      "Valid values are 'raise', 'warn', and 'ignore'."
                  )
  
imports: import copy
  import copyreg
  import logging
  import time
  import warnings
  from itertools import chain
  from typing import TYPE_CHECKING, Optional
  import numpy
  import pytensor
  import pytensor.compile.profiling
  from pytensor.compile.io import In, SymbolicInput, SymbolicOutput
  from pytensor.compile.ops import deep_copy_op, view_op
  from pytensor.configdefaults import config
  from pytensor.graph.basic import Constant, Variable, ancestors, clone_get_equiv, graph_inputs
  from pytensor.graph.destroyhandler import DestroyHandler
  from pytensor.graph.features import AlreadyThere, Feature, PreserveVariableAttributes
  from pytensor.graph.fg import FunctionGraph
  from pytensor.graph.op import HasInnerGraph
  from pytensor.graph.utils import InconsistencyError, get_variable_trace_string
  from pytensor.link.basic import Container
  from pytensor.link.utils import raise_with_op
label_desc: Use image node_id 3 for calling the FunctionMaker obj's underlying member method code with example usage: obj.check_unused_inputs(inputs, outputs, on_unused_input) without return types