code: def match(obj: Model, selector: SelectorType) -> bool:
      """Test whether a given Bokeh model matches a given selector.
  
      Args:
          obj (Model) : object to test
          selector (JSON-like) : query selector
  
      Returns:
          bool : True if the object matches, False otherwise
  
      In general, the selectors have the form:
  
      .. code-block:: python
  
          { attrname : predicate }
  
      Where a predicate is constructed from the operators ``EQ``, ``GT``, etc.
      and is used to compare against values of model attributes named
      ``attrname``.
  
      For example:
  
      .. code-block:: python
  
          >>> from bokeh.plotting import figure
          >>> p = figure(width=400)
  
          >>> match(p, {'width': {EQ: 400}})
          True
  
          >>> match(p, {'width': {GT: 500}})
          False
  
      There are two selector keys that are handled especially. The first
      is 'type', which will do an isinstance check:
  
      .. code-block:: python
  
          >>> from bokeh.plotting import figure
          >>> from bokeh.models import Axis
          >>> p = figure()
  
          >>> match(p.xaxis[0], {'type': Axis})
          True
  
          >>> match(p.title, {'type': Axis})
          False
  
      There is also a ``'tags'`` attribute that ``Model`` objects have, that
      is a list of user-supplied values. The ``'tags'`` selector key can be
      used to query against this list of tags. An object matches if any of the
      tags in the selector match any of the tags on the object:
  
      .. code-block:: python
  
          >>> from bokeh.plotting import figure
          >>> p = figure(tags = ["my plot", 10])
  
          >>> match(p, {'tags': "my plot"})
          True
  
          >>> match(p, {'tags': ["my plot", 10]})
          True
  
          >>> match(p, {'tags': ["foo"]})
          False
  
      """
      for key, val in selector.items():
          # test attributes
          if isinstance(key, str):
              # special case 'type'
              if key == "type":
                  # type supports IN, check for that first
                  if isinstance(val, dict) and list(val.keys()) == [IN]:
                      if not any(isinstance(obj, x) for x in val[IN]):
                          return False
                  # otherwise just check the type of the object against val
                  elif not isinstance(obj, val):
                      return False
  
              # special case 'tag'
              elif key == "tags":
                  if isinstance(val, str):
                      if val not in obj.tags:
                          return False
                  else:
                      try:
                          if not set(val) & set(obj.tags):
                              return False
                      except TypeError:
                          if val not in obj.tags:
                              return False
  
              # if the object doesn't have the attr, it doesn't match
              elif not hasattr(obj, key):
                  return False
  
              # if the value to check is a dict, recurse
              else:
                  attr = getattr(obj, key)
                  if isinstance(val, dict):
                      if not match(attr, val):
                          return False
  
                  else:
                      if attr != val:
                          return False
  
          # test OR conditionals
          elif key is OR:
              if not _or(obj, val):
                  return False
  
          # test operands
          elif key in _operators:
              if not _operators[key](obj, val):
                  return False
  
          else:
              raise ValueError("malformed query selector")
  
      return True
  
imports: from __future__ import annotations
  import logging
  from typing import TYPE_CHECKING, Any, Callable, Iterable, Union
  from ..model import Model
label_desc: Use image node_id 3 for calling a global function with example usage: match(obj, selector) and returns: True, False, False, False, False, False, False, False, False, False, False