code: def from_config(func):
      if inspect.isclass(func):
          params = list(
              inspect.signature(func.__init__).parameters.values()
          )[1:]
      else:
          params = list(inspect.signature(func).parameters.values())
  
      arg_names = [p.name for p in params]
      has_defaults = [
          p.default != inspect.Parameter.empty for p in params
      ]
  
      @functools.wraps(func)
      def wrapper(*args, cfg: Any = None, **kwargs):
          if cfg is not None:
              cfg = (
                  dict(cfg)
                  if isinstance(cfg, Iterable)
                  else asdict(cfg)
              )
  
              iterator = zip(
                  arg_names[len(args) :], has_defaults[len(args) :]
              )
              for arg_name, has_default in iterator:
                  if arg_name in kwargs:
                      continue
                  elif arg_name in cfg:
                      kwargs[arg_name] = cfg[arg_name]
                  elif not has_default:
                      raise ValueError(f"'cfg.{arg_name}' undefined")
          return func(*args, **kwargs)
  
      return wrapper
  
file_path: pytorch_geometric/torch_geometric/graphgym/config.py
imports: import functools
  import inspect
  import logging
  import os
  import os.path
  import warnings
  from collections.abc import Iterable
  from dataclasses import asdict
  from typing import Any
  import torch_geometric.graphgym.register
  from torch_geometric.io import fs
label_desc: Use image node_id 9 for calling a global function with example usage: from_config(func) and returns: wrapper, func