code: def deprecate_positional_args(
      *,
      supported_number: int,
      category: typing.Type[Warning] = PendingDeprecationWarning,
      stacklevel: int = 1,
  ):
      """Mark supported_number of positional arguments as the maximum.
  
      Args:
          supported_number: Number of positional arguments
              for which no warning is raised.
          category: Type of Warning to raise
              or None to return a nulldecorator
              returning the undecorated function.
          stacklevel: See :func:`warning.warn`.
  
      Returns:
          Return a decorator raising a category warning
              on more than supported_number positional args.
  
      See also:
          https://docs.python.org/3/library/exceptions.html#FutureWarning
          https://docs.python.org/3/library/exceptions.html#DeprecationWarning
          https://docs.python.org/3/library/exceptions.html#PendingDeprecationWarning
      """
      assert (
          supported_number > 0
      ), f"supported_number at least one: {supported_number!r}"
  
      if category is None:
  
          def nulldecorator(func):
              """Return the undecorated function."""
              return func
  
          return nulldecorator
  
      assert issubclass(category, Warning)
  
      stacklevel += 1
  
      def decorator(func):
          signature = inspect.signature(func)
          argnames = [
              name
              for name, param in signature.parameters.items()
              if param.kind == inspect.Parameter.POSITIONAL_OR_KEYWORD
          ]
          log.debug(
              "deprecate positional args: %s.%s(%r)",
              func.__module__,
              func.__qualname__,
              argnames[supported_number:],
          )
  
          @functools.wraps(func)
          def wrapper(*args, **kwargs):
              if len(args) > supported_number:
                  call_args = zip(argnames, args)
                  supported = itertools.islice(
                      call_args, supported_number
                  )
                  supported = dict(supported)
                  deprecated = dict(call_args)
                  assert deprecated
                  func_name = func.__name__.lstrip("_")
                  func_name, sep, rest = func_name.partition("_legacy")
                  assert not set or not rest
                  wanted = ", ".join(
                      f"{name}={value!r}"
                      for name, value in deprecated.items()
                  )
                  warnings.warn(
                      f"The signature of {func.__name__} will be reduced"
                      f" to {supported_number} positional args"
                      f" {list(supported)}: pass {wanted}"
                      " as keyword arg(s)",
                      stacklevel=stacklevel,
                      category=category,
                  )
  
              return func(*args, **kwargs)
  
          return wrapper
  
      return decorator
  
file_path: graphviz/graphviz/_tools.py
imports: import functools
  import inspect
  import itertools
  import logging
  import os
  import pathlib
  import typing
  import warnings
label_desc: Use image node_id 9 for calling a global function with example usage: deprecate_positional_args() and returns: decorator, nulldecorator, wrapper, func, func