# Path: jacquard/users/settings.py
# def get_settings(user_id, storage, directory=None):
#     """
#     Look up the current settings dict for a given user ID.
# 
#     This takes, in order of preference:
# 
#     1. The global defaults,
#     2. Any experiment settings for experiments the user is in,
#     3. User-specific overrides.
#     """
#     with storage.transaction(read_only=True) as store:
#         session = Session(store)
# 
#         defaults = store.get("defaults", {})
#         bucket_id = user_bucket(user_id)
#         bucket = session.get(Bucket, bucket_id, default=EMPTY)
# 
#         if bucket.needs_constraints():
#             user_entry = directory.lookup(user_id)
#         else:
#             user_entry = None
# 
#         bucket_settings = bucket.get_settings(user_entry)
# 
#         overrides = store.get("overrides/{user_id}".format(user_id=user_id), {})
# 
#     return {**defaults, **bucket_settings, **overrides}
# 
# Path: jacquard/storage/utils.py
# def retrying(fn):
#     """Decorator: reissues the function if it raises Retry."""
#     logger = logging.getLogger("jacquard.storage.retrying")
# 
#     @functools.wraps(fn)
#     def wrapper(*args, **kwargs):
#         while True:
#             try:
#                 return fn(*args, **kwargs)
#             except Retry:
#                 callable_name = getattr(fn, "__name__", "anonymous function")
#                 logger.debug("Retry issued from %s, reissuing", callable_name)
# 
#     return wrapper
# 
# Path: jacquard/commands.py
# class BaseCommand(metaclass=abc.ABCMeta):
#     """
#     Abstract base class for subcommands.
# 
#     Subclasses *must* override `handle` and *may* also provide a `help` string
#     and/or override `add_arguments`.
#     """
# 
#     def add_arguments(self, parser):
#         """Add argument definitions to a given argparse `ArgumentParser`."""
#         pass
# 
#     @abc.abstractmethod
#     def handle(self, config, options):
#         """
#         Run command.
# 
#         `config` is the system configuration from `jacquard.config` and
#         `options` is a `Namespace`-like object of command-line options,
#         generally defined from `add_arguments` with a few standard options
#         such as `verbose` thrown in for good measure.
#         """
#         raise NotImplementedError
# 
# class CommandError(Exception):
#     """
#     Generic, user-visible error.
# 
#     Where this is raised with a message, the message will generally be printed
#     to standard error without a backtrace.
#     """
# 
#     pass


import sys
import contextlib
import yaml
from jacquard.users import get_settings
from jacquard.storage import retrying
from jacquard.commands import BaseCommand, CommandError
        parser.add_argument("user", help="user to override for")
        parser.add_argument("setting", help="setting key")
        mutex_group = parser.add_mutually_exclusive_group(required=False)
        mutex_group.add_argument("value", help="value to set", nargs="?")
        mutex_group.add_argument(
            "-d", "--delete", help="clear the associated value", action="store_true"
        )

    @retrying
    def handle(self, config, options):
        """Run command."""
        with config.storage.transaction() as store:
            key = "overrides/{user_id}".format(user_id=options.user)

            overrides = dict(store.get(key, {}))

            if options.delete:
                with contextlib.suppress(KeyError):
                    del overrides[options.setting]

                if overrides == {}:
                    with contextlib.suppress(KeyError):
                        del store[key]
                else:
                    store[key] = overrides

            elif options.value:
                try:
                    value = yaml.safe_load(options.value)
                except ValueError:

# Path: jacquard/users/settings.py
# def get_settings(user_id, storage, directory=None):
#     """
#     Look up the current settings dict for a given user ID.
# 
#     This takes, in order of preference:
# 
#     1. The global defaults,
#     2. Any experiment settings for experiments the user is in,
#     3. User-specific overrides.
#     """
#     with storage.transaction(read_only=True) as store:
#         session = Session(store)
# 
#         defaults = store.get("defaults", {})
#         bucket_id = user_bucket(user_id)
#         bucket = session.get(Bucket, bucket_id, default=EMPTY)
# 
#         if bucket.needs_constraints():
#             user_entry = directory.lookup(user_id)
#         else:
#             user_entry = None
# 
#         bucket_settings = bucket.get_settings(user_entry)
# 
#         overrides = store.get("overrides/{user_id}".format(user_id=user_id), {})
# 
#     return {**defaults, **bucket_settings, **overrides}
# 
# Path: jacquard/storage/utils.py
# def retrying(fn):
#     """Decorator: reissues the function if it raises Retry."""
#     logger = logging.getLogger("jacquard.storage.retrying")
# 
#     @functools.wraps(fn)
#     def wrapper(*args, **kwargs):
#         while True:
#             try:
#                 return fn(*args, **kwargs)
#             except Retry:
#                 callable_name = getattr(fn, "__name__", "anonymous function")
#                 logger.debug("Retry issued from %s, reissuing", callable_name)
# 
#     return wrapper
# 
# Path: jacquard/commands.py
# class BaseCommand(metaclass=abc.ABCMeta):
#     """
#     Abstract base class for subcommands.
# 
#     Subclasses *must* override `handle` and *may* also provide a `help` string
#     and/or override `add_arguments`.
#     """
# 
#     def add_arguments(self, parser):
#         """Add argument definitions to a given argparse `ArgumentParser`."""
#         pass
# 
#     @abc.abstractmethod
#     def handle(self, config, options):
#         """
#         Run command.
# 
#         `config` is the system configuration from `jacquard.config` and
#         `options` is a `Namespace`-like object of command-line options,
#         generally defined from `add_arguments` with a few standard options
#         such as `verbose` thrown in for good measure.
#         """
#         raise NotImplementedError
# 
# class CommandError(Exception):
#     """
#     Generic, user-visible error.
# 
#     Where this is raised with a message, the message will generally be printed
#     to standard error without a backtrace.
#     """
# 
#     pass


# Path: jacquard/users/commands.py
import sys
import contextlib
import yaml
from jacquard.users import get_settings
from jacquard.storage import retrying
from jacquard.commands import BaseCommand, CommandError

        parser.add_argument("user", help="user to override for")
        parser.add_argument("setting", help="setting key")
        mutex_group = parser.add_mutually_exclusive_group(required=False)
        mutex_group.add_argument("value", help="value to set", nargs="?")
        mutex_group.add_argument(
            "-d", "--delete", help="clear the associated value", action="store_true"
        )

    @retrying
    def handle(self, config, options):
        """Run command."""
        with config.storage.transaction() as store:
            key = "overrides/{user_id}".format(user_id=options.user)

            overrides = dict(store.get(key, {}))

            if options.delete:
                with contextlib.suppress(KeyError):
                    del overrides[options.setting]

                if overrides == {}:
                    with contextlib.suppress(KeyError):
                        del store[key]
                else:
                    store[key] = overrides

            elif options.value:
                try:
                    value = yaml.safe_load(options.value)
                except ValueError:

                    raise CommandError(