def safe_reseed(obj, seeder, reseed_spaces=True):
    """
    Calls obj.reseed(seed_seq) method if available;
    If a obj.seed() method is available, call obj.seed(seed_val),
    where seed_val is generated by the seeder.
    Otherwise, does nothing.

    Parameters
    ----------
    obj : object
        Object to be reseeded.
    seeder: seeding.Seeder
        Seeder object from which to generate random seeds.
    reseed_spaces: bool, default = True.
        If False, do not try to reseed observation_space and action_space (if
        they exist as attributes of `obj`).

    Returns
    -------
    True if reseeding was done, False otherwise.
    """
    reseeded = False
    try:
        obj.reseed(seeder)
        reseeded = True
    except AttributeError:
        seed_val = seeder.rng.integers(2 ** 32).item()
        try:
            obj.seed(seed_val)
            reseeded = True
        except AttributeError:
            reseeded = False

    # check if the object has observation and action spaces to be reseeded.
    if reseed_spaces:
        try:
            safe_reseed(obj.observation_space, seeder)
            safe_reseed(obj.action_space, seeder)
        except AttributeError:
            pass

    return reseeded