# Buggy code
def run(
    self,
    config,
    instance=None,
    cutoff=None,
    memory_limit=None,
    seed=12345,
    instance_specific="0",
):
    """
    runs target algorithm <self.ta> with configuration <config> on
    instance <instance> with instance specifics <specifics>
    for at most <cutoff> seconds and random seed <seed>

    Parameters
    ----------
        config : dictionary (or similar)
            dictionary param -> value
        instance : str
            problem instance
        cutoff : int, optional
            Wallclock time limit of the target algorithm. If no value is
            provided no limit will be enforced.
        memory_limit : int, optional
            Memory limit in MB enforced on the target algorithm If no
            value is provided no limit will be enforced.
        seed : int
            random seed
        instance_specific: str
            instance specific information (e.g., domain file or solution)
    Returns
    -------
        status: enum of StatusType (int)
            {SUCCESS, TIMEOUT, CRASHED, ABORT}
        cost: float
            cost/regret/quality/runtime (float) (None, if not returned by TA)
        runtime: float
            runtime (None if not returned by TA)
        additional_info: dict
            all further additional run information
    """

    arguments = {
        "logger": logging.getLogger("pynisher"),
        "wall_time_in_s": cutoff,
        "mem_in_mb": memory_limit,
    }

    obj = pynisher.enforce_limits(**arguments)(self.func)

    if instance:
        rval = obj(config, instance, seed)
    else:
        rval = obj(config, seed)

    if isinstance(rval, tuple):
        result = rval[0]
        additional_run_info = rval[1]
    else:
        result = rval
        additional_run_info = {}

    if obj.exit_status is pynisher.TimeoutException:
        status = StatusType.TIMEOUT
        cost = 1234567890
    elif obj.exit_status is pynisher.MemorylimitException:
        status = StatusType.MEMOUT
        cost = 1234567890
    elif obj.exit_status == 0 and result is not None:
        status = StatusType.SUCCESS
        cost = result
    else:
        status = StatusType.CRASHED
        cost = 1234567890  # won't be used for the model

    runtime = float(obj.wall_clock_time)

    if self.run_obj == "runtime":
        if status != StatusType.SUCCESS:
            cost = cutoff * self.par_factor
        else:
            cost = runtime

    return status, cost, runtime, additional_run_info


# Traceback (AttributeError)
Traceback (most recent call last):
File "/home/lindauer/git/SMAC3/scripts/smac", line 20, in <module>
smac.main_cli()
File "/home/lindauer/git/SMAC3/smac/smac_cli.py", line 47, in main_cli
smbo.run(max_iters=args_.max_iterations)
File "/home/lindauer/git/SMAC3/smac/smbo/smbo.py", line 282, in run
self.incumbent = self.run_initial_design()
File "/home/lindauer/git/SMAC3/smac/smbo/smbo.py", line 239, in run_initial_design
instance_specific=self.scenario.instance_specific.get(rand_inst, "0"))
File "/home/lindauer/git/SMAC3/smac/tae/execute_ta_run.py", line 103, in start
if self._supports_memory_limit is True:
AttributeError: 'ExecuteTARunOld' object has no attribute '_supports_memory_limit'

# Fixed code
def run(
    self,
    config,
    instance=None,
    cutoff=None,
    memory_limit=None,
    seed=12345,
    instance_specific="0",
):
    """
    runs target algorithm <self.ta> with configuration <config> on
    instance <instance> with instance specifics <specifics>
    for at most <cutoff> seconds and random seed <seed>

    Parameters
    ----------
        config : dictionary (or similar)
            dictionary param -> value
        instance : str
            problem instance
        cutoff : int, optional
            Wallclock time limit of the target algorithm. If no value is
            provided no limit will be enforced.
        memory_limit : int, optional
            Memory limit in MB enforced on the target algorithm If no
            value is provided no limit will be enforced.
        seed : int
            random seed
        instance_specific: str
            instance specific information (e.g., domain file or solution)
    Returns
    -------
        status: enum of StatusType (int)
            {SUCCESS, TIMEOUT, CRASHED, ABORT}
        cost: float
            cost/regret/quality/runtime (float) (None, if not returned by TA)
        runtime: float
            runtime (None if not returned by TA)
        additional_info: dict
            all further additional run information
    """

    arguments = {
        "logger": logging.getLogger("pynisher"),
        "wall_time_in_s": cutoff,
        "mem_in_mb": memory_limit,
    }

    obj = pynisher.enforce_limits(**arguments)(self.ta)

    if instance:
        rval = obj(config, instance, seed)
    else:
        rval = obj(config, seed)

    if isinstance(rval, tuple):
        result = rval[0]
        additional_run_info = rval[1]
    else:
        result = rval
        additional_run_info = {}

    if obj.exit_status is pynisher.TimeoutException:
        status = StatusType.TIMEOUT
        cost = 1234567890
    elif obj.exit_status is pynisher.MemorylimitException:
        status = StatusType.MEMOUT
        cost = 1234567890
    elif obj.exit_status == 0 and result is not None:
        status = StatusType.SUCCESS
        cost = result
    else:
        status = StatusType.CRASHED
        cost = 1234567890  # won't be used for the model

    runtime = float(obj.wall_clock_time)

    return status, cost, runtime, additional_run_info