# Buggy code
def _task_table(self, task_id):
    """Fetch and parse the task table information for a single task ID.

    Args:
        task_id_binary: A string of bytes with the task ID to get
            information about.

    Returns:
        A dictionary with information about the task ID in question.
            TASK_STATUS_MAPPING should be used to parse the "State" field
            into a human-readable string.
    """
    task_table_response = self._execute_command(
        task_id, "RAY.TASK_TABLE_GET", task_id.id()
    )
    if task_table_response is None:
        raise Exception(
            "There is no entry for task ID {} in the task table.".format(
                binary_to_hex(task_id.id())
            )
        )
    task_table_message = TaskReply.GetRootAsTaskReply(task_table_response, 0)
    task_spec = task_table_message.TaskSpec()
    task_spec = ray.local_scheduler.task_from_string(task_spec)

    task_spec_info = {
        "DriverID": binary_to_hex(task_spec.driver_id().id()),
        "TaskID": binary_to_hex(task_spec.task_id().id()),
        "ParentTaskID": binary_to_hex(task_spec.parent_task_id().id()),
        "ParentCounter": task_spec.parent_counter(),
        "ActorID": binary_to_hex(task_spec.actor_id().id()),
        "ActorCounter": task_spec.actor_counter(),
        "FunctionID": binary_to_hex(task_spec.function_id().id()),
        "Args": task_spec.arguments(),
        "ReturnObjectIDs": task_spec.returns(),
        "RequiredResources": task_spec.required_resources(),
    }

    return {
        "State": task_table_message.State(),
        "LocalSchedulerID": binary_to_hex(task_table_message.LocalSchedulerId()),
        "ExecutionDependenciesString": task_table_message.ExecutionDependencies(),
        "SpillbackCount": task_table_message.SpillbackCount(),
        "TaskSpec": task_spec_info,
    }


# Traceback (ImportError)
Traceback (most recent call last):
File "/home/ubuntu/ray/python/ray/worker.py", line 1694, in fetch_and_execute_function_to_run
function = pickle.loads(serialized_function)
File "/home/ubuntu/ray/python/ray/tune/registry.py", line 12, in <module>
from ray.tune.trainable import Trainable, wrap_function
File "/home/ubuntu/ray/python/ray/tune/__init__.py", line 6, in <module>
from ray.tune.tune import run_experiments
File "/home/ubuntu/ray/python/ray/tune/tune.py", line 8, in <module>
from ray.tune.hyperband import HyperBandScheduler
File "/home/ubuntu/ray/python/ray/tune/hyperband.py", line 8, in <module>
from ray.tune.trial_scheduler import FIFOScheduler, TrialScheduler
File "/home/ubuntu/ray/python/ray/tune/trial_scheduler.py", line 5, in <module>
from ray.tune.trial import Trial
File "/home/ubuntu/ray/python/ray/tune/trial.py", line 15, in <module>
from ray.tune.registry import _default_registry, get_registry, TRAINABLE_CLASS
ImportError: cannot import name '_default_registry'

# Fixed code
def _task_table(self, task_id):
    """Fetch and parse the task table information for a single task ID.

    Args:
        task_id_binary: A string of bytes with the task ID to get
            information about.

    Returns:
        A dictionary with information about the task ID in question.
            TASK_STATUS_MAPPING should be used to parse the "State" field
            into a human-readable string.
    """
    task_table_response = self._execute_command(
        task_id, "RAY.TASK_TABLE_GET", task_id.id()
    )
    if task_table_response is None:
        raise Exception(
            "There is no entry for task ID {} in the task table.".format(
                binary_to_hex(task_id.id())
            )
        )
    task_table_message = TaskReply.GetRootAsTaskReply(task_table_response, 0)
    task_spec = task_table_message.TaskSpec()
    task_spec = ray.local_scheduler.task_from_string(task_spec)

    task_spec_info = {
        "DriverID": binary_to_hex(task_spec.driver_id().id()),
        "TaskID": binary_to_hex(task_spec.task_id().id()),
        "ParentTaskID": binary_to_hex(task_spec.parent_task_id().id()),
        "ParentCounter": task_spec.parent_counter(),
        "ActorID": binary_to_hex(task_spec.actor_id().id()),
        "ActorCreationID": binary_to_hex(task_spec.actor_creation_id().id()),
        "ActorCreationDummyObjectID": binary_to_hex(
            task_spec.actor_creation_dummy_object_id().id()
        ),
        "ActorCounter": task_spec.actor_counter(),
        "FunctionID": binary_to_hex(task_spec.function_id().id()),
        "Args": task_spec.arguments(),
        "ReturnObjectIDs": task_spec.returns(),
        "RequiredResources": task_spec.required_resources(),
    }

    execution_dependencies_message = (
        TaskExecutionDependencies.GetRootAsTaskExecutionDependencies(
            task_table_message.ExecutionDependencies(), 0
        )
    )
    execution_dependencies = [
        ray.local_scheduler.ObjectID(
            execution_dependencies_message.ExecutionDependencies(i)
        )
        for i in range(execution_dependencies_message.ExecutionDependenciesLength())
    ]

    # TODO(rkn): The return fields ExecutionDependenciesString and
    # ExecutionDependencies are redundant, so we should remove
    # ExecutionDependencies. However, it is currently used in monitor.py.

    return {
        "State": task_table_message.State(),
        "LocalSchedulerID": binary_to_hex(task_table_message.LocalSchedulerId()),
        "ExecutionDependenciesString": task_table_message.ExecutionDependencies(),
        "ExecutionDependencies": execution_dependencies,
        "SpillbackCount": task_table_message.SpillbackCount(),
        "TaskSpec": task_spec_info,
    }