class_docstr_tok: []
code: def _check_bad_column_name(self):
      source = self.data_source
  
      if not isinstance(source, ColumnDataSource) or isinstance(
          source, WebDataSource
      ):
          return
  
      colnames = source.column_names
  
      props = self.glyph.properties_with_values(include_defaults=False)
      specs = self.glyph.dataspecs().keys() & props.keys()
  
      missing = []
  
      for spec in sorted(specs):
          if (
              isinstance(props[spec], Field)
              and (field := props[spec].field) not in colnames
          ):
              if close := get_close_matches(field, colnames, n=1):
                  missing.append(
                      f"{spec}={field!r} [closest match: {close[0]!r}]"
                  )
              else:
                  missing.append(f"{spec}={field!r} [no close matches]")
  
      if missing:
          return f"{', '.join(missing)} {{renderer: {self}}}"
  
file_path: bokeh/src/bokeh/models/renderers/glyph_renderer.py
imports: from __future__ import annotations
  import logging
  from difflib import get_close_matches
  from typing import TYPE_CHECKING, Any, Literal
  from bokeh.core.property.vectorization import Field
  from ...core.properties import Auto, Bool, Either, Instance, InstanceDefault, Nullable, Required
  from ...core.validation import error
  from ...core.validation.errors import BAD_COLUMN_NAME, CDSVIEW_FILTERS_WITH_CONNECTED
  from ..filters import AllIndices
  from ..glyphs import ConnectedXYGlyph, Glyph
  from ..graphics import Decoration, Marking
  from ..sources import CDSView, ColumnDataSource, DataSource, WebDataSource
  from .renderer import DataRenderer
label_desc: Use image node_id 3 for calling the GlyphRenderer obj's underlying member method code with example usage: obj._check_bad_column_name() and returns: str, str, self, str