# Buggy code
def _serialize(
    cls, var: Any
) -> Any:  # Unfortunately there is no support for recursive types in mypy
    """Helper function of depth first search for serialization.

    The serialization protocol is:

    (1) keeping JSON supported types: primitives, dict, list;
    (2) encoding other types as ``{TYPE: 'foo', VAR: 'bar'}``, the deserialization
        step decode VAR according to TYPE;
    (3) Operator has a special field CLASS to record the original class
        name for displaying in UI.
    """
    try:
        if cls._is_primitive(var):
            # enum.IntEnum is an int instance, it causes json dumps error so we use its value.
            if isinstance(var, enum.Enum):
                return var.value
            return var
        elif isinstance(var, dict):
            return cls._encode(
                {str(k): cls._serialize(v) for k, v in var.items()}, type_=DAT.DICT
            )
        elif isinstance(var, k8s.V1Pod):
            json_pod = PodGenerator.serialize_pod(var)
            return cls._encode(json_pod, type_=DAT.POD)
        elif isinstance(var, list):
            return [cls._serialize(v) for v in var]
        elif isinstance(var, k8s.V1Pod):
            json_pod = PodGenerator.serialize_pod(var)
            return cls._encode(json_pod, type_=DAT.POD)
        elif isinstance(var, DAG):
            return SerializedDAG.serialize_dag(var)
        elif isinstance(var, BaseOperator):
            return SerializedBaseOperator.serialize_operator(var)
        elif isinstance(var, cls._datetime_types):
            return cls._encode(var.timestamp(), type_=DAT.DATETIME)
        elif isinstance(var, datetime.timedelta):
            return cls._encode(var.total_seconds(), type_=DAT.TIMEDELTA)
        elif isinstance(var, Timezone):
            return cls._encode(str(var.name), type_=DAT.TIMEZONE)
        elif isinstance(var, relativedelta.relativedelta):
            encoded = {
                k: v for k, v in var.__dict__.items() if not k.startswith("_") and v
            }
            if var.weekday and var.weekday.n:
                # Every n'th Friday for example
                encoded["weekday"] = [var.weekday.weekday, var.weekday.n]
            elif var.weekday:
                encoded["weekday"] = [var.weekday.weekday]
            return cls._encode(encoded, type_=DAT.RELATIVEDELTA)
        elif callable(var):
            return str(get_python_source(var))
        elif isinstance(var, set):
            # FIXME: casts set to list in customized serialization in future.
            return cls._encode([cls._serialize(v) for v in var], type_=DAT.SET)
        elif isinstance(var, tuple):
            # FIXME: casts tuple to list in customized serialization in future.
            return cls._encode([cls._serialize(v) for v in var], type_=DAT.TUPLE)
        elif isinstance(var, TaskGroup):
            return SerializedTaskGroup.serialize_task_group(var)
        else:
            log.debug("Cast type %s to str in serialization.", type(var))
            return str(var)
    except Exception:  # pylint: disable=broad-except
        log.error("Failed to stringify.", exc_info=True)
        return FAILED


# Traceback (ModuleNotFoundError)
$ airflow db check
Traceback (most recent call last):
File "/.../bin/airflow", line 8, in <module>
sys.exit(main())
File "/.../lib/python3.6/site-packages/airflow/__main__.py", line 40, in main
args.func(args)
File "/.../lib/python3.6/site-packages/airflow/cli/cli_parser.py", line 52, in command
func = import_string(import_path)
File "/.../lib/python3.6/site-packages/airflow/utils/module_loading.py", line 32, in import_string
module = import_module(module_path)
File "/.../lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 994, in _gcd_import
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/.../lib/python3.6/site-packages/airflow/cli/commands/db_command.py", line 24, in <module>
from airflow.utils import cli as cli_utils, db
File "/.../lib/python3.6/site-packages/airflow/utils/db.py", line 26, in <module>
from airflow.jobs.base_job import BaseJob  # noqa: F401 # pylint: disable=unused-import
File "/.../lib/python3.6/site-packages/airflow/jobs/__init__.py", line 22, in <module>
import airflow.jobs.scheduler_job  # noqa
File "/.../lib/python3.6/site-packages/airflow/jobs/scheduler_job.py", line 50, in <module>
from airflow.models.serialized_dag import SerializedDagModel
File "/.../lib/python3.6/site-packages/airflow/models/serialized_dag.py", line 35, in <module>
from airflow.serialization.serialized_objects import SerializedDAG
File "/.../lib/python3.6/site-packages/airflow/serialization/serialized_objects.py", line 37, in <module>
from airflow.kubernetes.pod_generator import PodGenerator
File "/.../lib/python3.6/site-packages/airflow/kubernetes/pod_generator.py", line 35, in <module>
from kubernetes.client import models as k8s
ModuleNotFoundError: No module named 'kubernetes'

# Fixed code
def _serialize(
    cls, var: Any
) -> Any:  # Unfortunately there is no support for recursive types in mypy
    """Helper function of depth first search for serialization.

    The serialization protocol is:

    (1) keeping JSON supported types: primitives, dict, list;
    (2) encoding other types as ``{TYPE: 'foo', VAR: 'bar'}``, the deserialization
        step decode VAR according to TYPE;
    (3) Operator has a special field CLASS to record the original class
        name for displaying in UI.
    """
    try:
        if cls._is_primitive(var):
            # enum.IntEnum is an int instance, it causes json dumps error so we use its value.
            if isinstance(var, enum.Enum):
                return var.value
            return var
        elif isinstance(var, dict):
            return cls._encode(
                {str(k): cls._serialize(v) for k, v in var.items()}, type_=DAT.DICT
            )
        elif HAS_KUBERNETES and isinstance(var, k8s.V1Pod):
            json_pod = PodGenerator.serialize_pod(var)
            return cls._encode(json_pod, type_=DAT.POD)
        elif isinstance(var, list):
            return [cls._serialize(v) for v in var]
        elif HAS_KUBERNETES and isinstance(var, k8s.V1Pod):
            json_pod = PodGenerator.serialize_pod(var)
            return cls._encode(json_pod, type_=DAT.POD)
        elif isinstance(var, DAG):
            return SerializedDAG.serialize_dag(var)
        elif isinstance(var, BaseOperator):
            return SerializedBaseOperator.serialize_operator(var)
        elif isinstance(var, cls._datetime_types):
            return cls._encode(var.timestamp(), type_=DAT.DATETIME)
        elif isinstance(var, datetime.timedelta):
            return cls._encode(var.total_seconds(), type_=DAT.TIMEDELTA)
        elif isinstance(var, Timezone):
            return cls._encode(str(var.name), type_=DAT.TIMEZONE)
        elif isinstance(var, relativedelta.relativedelta):
            encoded = {
                k: v for k, v in var.__dict__.items() if not k.startswith("_") and v
            }
            if var.weekday and var.weekday.n:
                # Every n'th Friday for example
                encoded["weekday"] = [var.weekday.weekday, var.weekday.n]
            elif var.weekday:
                encoded["weekday"] = [var.weekday.weekday]
            return cls._encode(encoded, type_=DAT.RELATIVEDELTA)
        elif callable(var):
            return str(get_python_source(var))
        elif isinstance(var, set):
            # FIXME: casts set to list in customized serialization in future.
            return cls._encode([cls._serialize(v) for v in var], type_=DAT.SET)
        elif isinstance(var, tuple):
            # FIXME: casts tuple to list in customized serialization in future.
            return cls._encode([cls._serialize(v) for v in var], type_=DAT.TUPLE)
        elif isinstance(var, TaskGroup):
            return SerializedTaskGroup.serialize_task_group(var)
        else:
            log.debug("Cast type %s to str in serialization.", type(var))
            return str(var)
    except Exception:  # pylint: disable=broad-except
        log.error("Failed to stringify.", exc_info=True)
        return FAILED