Skip to content

check


File: base/log/check.py

This file declares a family of CHECK macros.

CHECK "macros" (in Python terminology would these be check functions) terminate the program with a fatal error if the specified condition is not true.

DCHECK "macros" (in Python terminology would these be dcheck functions) terminate the program with a fatal error if the Python code is run in debug mode (the default) and the condition is not true. To disable the DCHECK macros, set the either the PYTHON_OPTIMIZE=1 or run the Python script with the -O option. This will set the debug variable to False, which will disable the DCHECK macros.

CHECK and friends are thus useful for confirming invariants in situations where continuing to run would be worse than terminating, e.g., due to risk of data corruption or security compromise. It is also more robust and portable to deliberately terminate at a particular place with a useful message and backtrace than to assume some ultimately unspecified and unreliable crashing behavior (such as a "segmentation fault").

Functions:

DCHECK

DCHECK(condition: Callable[[], bool], message: Callable[[], str] | None = None) -> None

Debug-only check removed in optimized mode.

DCHECK behaves like CHECK in debug mode and does nothing otherwise (as DLOG). It uses the __debug__ variable to determine if the code is running in debug mode and uses lazy evaluation of the condition to have no runtime overhead in release builds. However, this requires the condition to be a lambda function (see Examples).

Parameters:

  • condition (Callable[[], bool]) –

    A callable that returns the condition to check

  • message (Callable[[], str] | None, default: None ) –

    Optional callable that returns an error message

Examples:

A simple example of how to use DCHECK:

import kern_comm_lib as kern tmp_str = "Test" kern.DCHECK(lambda: tmp_str == "Test1", lambda: "String is not equal") In production, use more specific DCHECK functions like DCHECK_EQ or DCHECK_NOT_EQ for simple comparisons.

Source code in kern_comm_lib/base/log/check.py
def DCHECK(
    condition: Callable[[], bool], message: Callable[[], str] | None = None
) -> None:
  """Debug-only check removed in optimized mode.

  `DCHECK` behaves like `CHECK` in debug mode and does nothing otherwise (as
  `DLOG`). It uses the `__debug__` variable to determine if the code is running
  in debug mode and uses lazy evaluation of the condition to have no runtime
  overhead in release builds. However, this requires the condition to be a
  lambda function (see Examples).

  Args:
      condition: A callable that returns the condition to check
      message: Optional callable that returns an error message

  Examples:
    A simple example of how to use `DCHECK`:
      >>> import kern_comm_lib as kern
      >>> tmp_str = "Test"
      >>> kern.DCHECK(lambda: tmp_str == "Test1", lambda: "String is not equal")
    In production, use more specific DCHECK functions like DCHECK_EQ or DCHECK_NOT_EQ
    for simple comparisons.
  """
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    # Evaluate the condition lazily only in debug mode
    if not condition():
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      if message is None:
        print(
            f"FATAL ERROR: {filename}:{lineno}: The given condition is not true",
            file=sys.stderr,
        )
        sys.exit(1)
      print(f"FATAL ERROR: {filename}:{lineno}: {message()}", file=sys.stderr)
      sys.exit(1)

DCHECK_EQ

DCHECK_EQ(arg1: object, arg2: object) -> None

Checks if two values are equal.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_EQ(arg1: object, arg2: object) -> None:
  """Checks if two values are equal."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if arg1 != arg2:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: {arg1} is NOT equal to {arg2}",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_NOT_EQ

DCHECK_NOT_EQ(arg1: object, arg2: object) -> None

Checks if two values are equal.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_NOT_EQ(arg1: object, arg2: object) -> None:
  """Checks if two values are equal."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if arg1 == arg2:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: {arg1} is equal to {arg2}",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_NOT_NONE

DCHECK_NOT_NONE(val: object) -> None

Checks if a value is not None.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_NOT_NONE(val: object) -> None:
  """Checks if a value is not None."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if val is None:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: Value should not be None",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_LESS_THAN

DCHECK_LESS_THAN(val: int | float, cond_val: int | float) -> None

Checks if a value is less than a certain conditional value.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_LESS_THAN(val: int | float, cond_val: int | float) -> None:
  """Checks if a value is less than a certain conditional value."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if val < cond_val:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: Value MUST be less than {cond_val}",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_GREATER_THAN

DCHECK_GREATER_THAN(val: int | float, cond_val: int | float) -> None

Checks if a value is greater than a certain conditional value.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_GREATER_THAN(val: int | float, cond_val: int | float) -> None:
  """Checks if a value is greater than a certain conditional value."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if val > cond_val:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: Value MUST be greater than {cond_val}",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_IS_TYPE

DCHECK_IS_TYPE(a_val: object, a_type: type) -> None

Checks if a value is a given type.

Source code in kern_comm_lib/base/log/check.py
def DCHECK_IS_TYPE(a_val: object, a_type: type) -> None:
  """Checks if a value is a given type."""
  if __debug__:  # noqa: SIM102 (Two if statements are needed to avoid lambda evaluation)
    if not isinstance(a_val, a_type):
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: Value MUST be of type {type(a_type).__name__}",
          file=sys.stderr,
      )
      sys.exit(1)

DCHECK_IN_ENUM

DCHECK_IN_ENUM(a_val: object, an_enum_class: type[IntEnum]) -> None

Debug-only check that verifies if a value is a member of the specified enum.

Parameters:

  • a_val (object) –

    The value to check

  • an_enum_class (type[IntEnum]) –

    The enum class to check against

Source code in kern_comm_lib/base/log/check.py
def DCHECK_IN_ENUM(a_val: object, an_enum_class: type["enum.IntEnum"]) -> None:
  """Debug-only check that verifies if a value is a member of the specified enum.

  Args:
      a_val: The value to check
      an_enum_class: The enum class to check against
  """
  if __debug__:
    try:
      an_enum_class(
          a_val
      )  # This will raise ValueError if val is not in the enum
    except ValueError:
      # <editor-fold desc="Gets caller's frame information">
      # Get caller's frame information which cannot be placed in its own
      # function because it would use the wrong function's frame!
      current_frame = inspect.currentframe()
      if current_frame is None:
        print("FATAL ERROR: Current frame is None", file=sys.stderr)
        sys.exit(1)

      frame = current_frame.f_back
      if frame is None:
        print("FATAL ERROR: Caller frame is None", file=sys.stderr)
        sys.exit(1)

      filename = frame.f_code.co_filename
      lineno = frame.f_lineno
      # </editor-fold>
      print(
          f"FATAL ERROR: {filename}:{lineno}: Value {a_val} is not a valid member of enum {an_enum_class.__name__}",
          file=sys.stderr,
      )
      sys.exit(1)