# Buggy code
def submit_task(
    self,
    function_id,
    args,
    actor_id=None,
    actor_handle_id=None,
    actor_counter=0,
    is_actor_checkpoint_method=False,
    execution_dependencies=None,
):
    """Submit a remote task to the scheduler.

    Tell the scheduler to schedule the execution of the function with ID
    function_id with arguments args. Retrieve object IDs for the outputs of
    the function from the scheduler and immediately return them.

    Args:
        function_id: The ID of the function to execute.
        args: The arguments to pass into the function. Arguments can be
            object IDs or they can be values. If they are values, they must
            be serializable objecs.
        actor_id: The ID of the actor that this task is for.
        actor_counter: The counter of the actor task.
        is_actor_checkpoint_method: True if this is an actor checkpoint
            task and false otherwise.
    """
    with log_span("ray:submit_task", worker=self):
        check_main_thread()
        if actor_id is None:
            assert actor_handle_id is None
            actor_id = ray.local_scheduler.ObjectID(NIL_ACTOR_ID)
            actor_handle_id = ray.local_scheduler.ObjectID(NIL_ACTOR_ID)
        else:
            assert actor_handle_id is not None
        # Put large or complex arguments that are passed by value in the
        # object store first.
        args_for_local_scheduler = []
        for arg in args:
            if isinstance(arg, ray.local_scheduler.ObjectID):
                args_for_local_scheduler.append(arg)
            elif isinstance(arg, ray.actor.ActorHandleParent):
                args_for_local_scheduler.append(put(ray.actor.wrap_actor_handle(arg)))
            elif ray.local_scheduler.check_simple_value(arg):
                args_for_local_scheduler.append(arg)
            else:
                args_for_local_scheduler.append(put(arg))

        # By default, there are no execution dependencies.
        if execution_dependencies is None:
            execution_dependencies = []

        # Look up the various function properties.
        function_properties = self.function_properties[self.task_driver_id.id()][
            function_id.id()
        ]

        # Submit the task to local scheduler.
        task = ray.local_scheduler.Task(
            self.task_driver_id,
            ray.local_scheduler.ObjectID(function_id.id()),
            args_for_local_scheduler,
            function_properties.num_return_vals,
            self.current_task_id,
            self.task_index,
            actor_id,
            actor_handle_id,
            actor_counter,
            is_actor_checkpoint_method,
            execution_dependencies,
            function_properties.resources,
        )
        # Increment the worker's task index to track how many tasks have
        # been submitted by the current task so far.
        self.task_index += 1
        self.local_scheduler_client.submit(task)

        return task.returns()


# 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 submit_task(
    self,
    function_id,
    args,
    actor_id=None,
    actor_handle_id=None,
    actor_counter=0,
    is_actor_checkpoint_method=False,
    actor_creation_id=None,
    actor_creation_dummy_object_id=None,
    execution_dependencies=None,
):
    """Submit a remote task to the scheduler.

    Tell the scheduler to schedule the execution of the function with ID
    function_id with arguments args. Retrieve object IDs for the outputs of
    the function from the scheduler and immediately return them.

    Args:
        function_id: The ID of the function to execute.
        args: The arguments to pass into the function. Arguments can be
            object IDs or they can be values. If they are values, they must
            be serializable objecs.
        actor_id: The ID of the actor that this task is for.
        actor_counter: The counter of the actor task.
        is_actor_checkpoint_method: True if this is an actor checkpoint
            task and false otherwise.
        actor_creation_id: The ID of the actor to create, if this is an
            actor creation task.
        actor_creation_dummy_object_id: If this task is an actor method,
            then this argument is the dummy object ID associated with the
            actor creation task for the corresponding actor.
        execution_dependencies: The execution dependencies for this task.

    Returns:
        The return object IDs for this task.
    """
    with log_span("ray:submit_task", worker=self):
        check_main_thread()
        if actor_id is None:
            assert actor_handle_id is None
            actor_id = ray.local_scheduler.ObjectID(NIL_ACTOR_ID)
            actor_handle_id = ray.local_scheduler.ObjectID(NIL_ACTOR_HANDLE_ID)
        else:
            assert actor_handle_id is not None

        if actor_creation_id is None:
            actor_creation_id = ray.local_scheduler.ObjectID(NIL_ACTOR_ID)

        if actor_creation_dummy_object_id is None:
            actor_creation_dummy_object_id = ray.local_scheduler.ObjectID(NIL_ID)

        # Put large or complex arguments that are passed by value in the
        # object store first.
        args_for_local_scheduler = []
        for arg in args:
            if isinstance(arg, ray.local_scheduler.ObjectID):
                args_for_local_scheduler.append(arg)
            elif isinstance(arg, ray.actor.ActorHandleParent):
                args_for_local_scheduler.append(put(ray.actor.wrap_actor_handle(arg)))
            elif ray.local_scheduler.check_simple_value(arg):
                args_for_local_scheduler.append(arg)
            else:
                args_for_local_scheduler.append(put(arg))

        # By default, there are no execution dependencies.
        if execution_dependencies is None:
            execution_dependencies = []

        # Look up the various function properties.
        function_properties = self.function_properties[self.task_driver_id.id()][
            function_id.id()
        ]

        # Submit the task to local scheduler.
        task = ray.local_scheduler.Task(
            self.task_driver_id,
            ray.local_scheduler.ObjectID(function_id.id()),
            args_for_local_scheduler,
            function_properties.num_return_vals,
            self.current_task_id,
            self.task_index,
            actor_creation_id,
            actor_creation_dummy_object_id,
            actor_id,
            actor_handle_id,
            actor_counter,
            is_actor_checkpoint_method,
            execution_dependencies,
            function_properties.resources,
        )
        # Increment the worker's task index to track how many tasks have
        # been submitted by the current task so far.
        self.task_index += 1
        self.local_scheduler_client.submit(task)

        return task.returns()