def op_functions_and_classes(ops_module):
    """Enumerate pairs of op function and op classes in a module.

    Will return for instance `(ExpandDims, expand_dims)`, `(Sum, sum)`, ...

    Args:
        ops_module: the module to explore.

    Returns:
        iterable returning tuples with function and class pairs.
    """
    # Go through all symbols.
    for op_class_name in dir(ops_module):
        op_class = getattr(ops_module, op_class_name)
        # Find the ones that are classes that extend `Operation`.
        if isinstance(op_class, type) and Operation in op_class.__mro__:
            # Infer what the corresponding op function name should be.
            op_function_name = to_snake_case(op_class_name)
            # With some exceptions.
            op_function_name = {
                "batch_norm": "batch_normalization",
                "rms_norm": "rms_normalization",
                "search_sorted": "searchsorted",
            }.get(op_function_name, op_function_name)
            # Check if that function exist. Some classes are abstract super
            # classes for multiple operations and should be ignored.
            op_function = getattr(ops_module, op_function_name, None)
            if op_function is not None:
                # We have a pair, return it.
                yield op_function, op_class
Enumerate pairs of op function and op classes in a module.

    Will return for instance `(ExpandDims, expand_dims)`, `(Sum, sum)`, ...

    Args:
        ops_module: the module to explore.

    Returns:
        iterable returning tuples with function and class pairs.
    
keras/src/ops/ops_test.py