code: def _check_cursor_is_dbapi2_compliant(cursor) -> None:
      # These aren't all the methods required by the specification, but it's all the ones
      # we care about.
      for attr in (
          "execute",
          "executemany",
          "fetchone",
          "fetchall",
          "description",
      ):
          if not hasattr(cursor, attr):
              raise ValueError(
                  "Your database connector created a `Cursor` object without a "
                  f"{attr!r} method, but this method is required by the Python DB API2 "
                  "specification. Check that your database connector is DB API2-"
                  "compliant. To learn more, read https://peps.python.org/pep-0249/."
              )
  
file_path: ray/python/ray/data/datasource/sql_datasource.py
imports: import math
  from contextlib import contextmanager
  from typing import Any, Callable, Iterable, Iterator, List, Optional
  from ray.data.block import Block, BlockAccessor, BlockMetadata
  from ray.data.datasource.datasource import Datasource, ReadTask
  from ray.util.annotations import PublicAPI
label_desc: Use image node_id 3 for calling a global function with example usage: _check_cursor_is_dbapi2_compliant(cursor) without return types