code: def max_evals(max_evals):
      """Decorator to enforce a maximum number of function evaluations.
  
      Throws a MaximumEvaluationsException during evaluations after
      the maximum is reached. Adds a field ``f.num_evals`` which tracks
      the number of evaluations that have been performed.
  
      >>> @max_evals(1)
      ... def f(x): return 2
      >>> f(2)
      2
      >>> f(1) #doctest:+SKIP
      Traceback (most recent call last):
      ...
      MaximumEvaluationsException
      >>> try:
      ...    f(1)
      ... except MaximumEvaluationsException as e:
      ...    e.max_evals
      1
  
      """
  
      def wrapper(f):
          @wraps(f)
          def wrapped_f(*args, **kwargs):
              if wrapped_f.num_evals >= max_evals:
                  raise MaximumEvaluationsException(max_evals)
              else:
                  wrapped_f.num_evals += 1
                  return f(*args, **kwargs)
  
          wrapped_f.num_evals = 0
          return wrapped_f
  
      return wrapper
  
imports: import collections
  import functools
  import threading
  import operator
label_desc: Use image node_id 4 for calling a global function with example usage: max_evals(max_evals) and returns: wrapper, wrapped_f, f