code: def deprecated(
      since_or_msg: Version | str,
      old: str | None = None,
      new: str | None = None,
      extra: str | None = None,
  ) -> None:
      """Issue a nicely formatted deprecation warning."""
  
      if isinstance(since_or_msg, tuple):
          if old is None or new is None:
              raise ValueError(
                  "deprecated entity and a replacement are required"
              )
  
          if len(since_or_msg) != 3 or not all(
              isinstance(x, int) and x >= 0 for x in since_or_msg
          ):
              raise ValueError(
                  f"invalid version tuple: {since_or_msg!r}"
              )
  
          major, minor, patch = since_or_msg
          since = f"{major}.{minor}.{patch}"
          message = f"{old!r} was deprecated in Bokeh {since} and will be removed, use {new!r} instead."
          if extra is not None:
              message += " " + extra.strip()
      else:
          if not (old is None and new is None and extra is None):
              raise ValueError(
                  "deprecated(message) signature doesn't allow extra arguments"
              )
  
          message = since_or_msg
  
      warn(message, BokehDeprecationWarning)
  
imports: from __future__ import annotations
  import logging
  from typing import TYPE_CHECKING, overload
  from .warnings import BokehDeprecationWarning, warn
label_desc: Use image node_id 3 for calling a global function with example usage: deprecated(since_or_msg, old, new, extra) without return types