<commit_before>"""
Defines the different options that can be used throughout the system.  Often,
classes and methods will accept a variable set of keyword arguments.  As
opposed to hard-coding these options everywhere and updating them, they
will map to one of the classes defined in this module.
"""

from collections import OrderedDict
from projex.text import nativestring as nstr
from projex.lazymodule import lazy_import

orb = lazy_import('orb')

class Options(object):
    """"
    Defines a unique instance of information that will be bundled when
    calling different methods within the connections class.

    The ContextOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    """
    DEFAULTS = {}

    def __init__(self, **kwds):
        # update from the other database option instance
        other_options = kwds.pop('options', None)
        if isinstance(other_options, ContextOptions):
            for key, default in self.DEFAULTS.items():
                kwds.setdefault(key, other_options.raw_values.get(key, default))

        self.__dict__['raw_values'] = {}
        for key, value in self.DEFAULTS.items():
            self.raw_values[key] = kwds.get(key, value)

    def __str__(self):
        """
        Returns a string for this instance.

        :return     <str>
        """
        opts = []
        for key, default in self.DEFAULTS.items():
            val = getattr(self, key)
            if val == default:
                continue
            opts.append('{0}:{1}'.format(key, val))
        return '<{0} {1}>'.format(type(self).__name__, ' '.join(opts))

    def __getattr__(self, key):
        try:
            return self.raw_values[key]
        except KeyError:
            raise AttributeError(key)

    def __setattr__(self, key, value):
        if key in self.raw_values:
            self.raw_values[key] = value
        else:
            raise AttributeError(key)

    def __hash__(self):
        """
        Returns a hash representation for this instance.

        :return     <hash>
        """
        return hash(nstr(self))

    def assigned(self):
        """
        Returns a dictionary of assigned values for this context option.

        :return     {<str> key: <variant> value, ..}
        """
        return {k: v for k, v in self.raw_values.items() if self.DEFAULTS[k] != v}

    def copy(self):
        """
        Returns a copy of this database option set.

        :return     <orb.ContextOptions>
        """
        return type(self)(**self.raw_values)

    def isNull(self):
        """
        Returns whether or not this option set has been modified.

        :return     <bool>
        """
        return self.raw_values.values() == self.DEFAULTS.values()

    def update(self, options):
        """
        Updates this lookup set with the inputted options.

        :param      options | <dict>
        """
        self.raw_values.update({k: v for k, v in options.items() if k in self.DEFAULTS})

    def toDict(self):
        """
        Returns a dictionary representation of this database option set.

        :return     <dict>
        """
        return self.raw_values.copy()

    @classmethod
    def fromDict(cls, data):
        """
        Returns a new lookup options instance based on the inputted data
        dictionary.

        :param      data | <dict>


        :return     <LookupOptions>
        """
        return cls(**data)


class ContextOptions(Options):
    """"
    Defines a unique instance of information that will be bundled when
    calling different methods within the connections class.
    
    The ContextOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    """
    DEFAULTS = {
        # database options
        'namespace': None,
        'flags': 0,
        'autoIncrement': True,
        'deleteFlags': orb.DeleteFlags.all(),
        'useCache': False,
        'context': None,
        'database': None,

        # output options
        'inflated': True,
        'format': 'object',

        # context options
        'locale': None,
        'timezone': None,
        'request': None,

        # debug options
        'force': False,
        'dryRun': False
    }

    @property
    def database(self):
        return self.raw_values['database'] or orb.system.database()

    @property
    def locale(self):
        """
        Returns the locale for this context, either by the specified locale or the root manager.

        :return     <str>
        """
        return self.raw_values['locale'] or orb.system.locale(self)

    @property
    def timezone(self):
        """
        Returns the timezone for this context, either by the specified zone or from the root manager.

        :return     <str>
        """
        return self.raw_values['timezone'] or orb.system.timezone(self)

    def update(self, options):
        """
        Updates this lookup set with the inputted options.

        :param      options | <dict>
        """
        if 'options' in options:
            options = options['options'].raw_values
        super(ContextOptions, self).update(options)

# ------------------------------------------------------------------------------

class LookupOptions(object):
    """
    Defines a unique instance of information that will be bundled when
    calling different query based methods in the connection class.
    
    The LookupOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    
    :param      columns       | [<str>, ..] || None (default: None)<commit_msg>fixed how the context options are updated to merge together multiple levels<commit_after>"""
Defines the different options that can be used throughout the system.  Often,
classes and methods will accept a variable set of keyword arguments.  As
opposed to hard-coding these options everywhere and updating them, they
will map to one of the classes defined in this module.
"""

from collections import OrderedDict
from projex.text import nativestring as nstr
from projex.lazymodule import lazy_import

orb = lazy_import('orb')

class Options(object):
    """"
    Defines a unique instance of information that will be bundled when
    calling different methods within the connections class.

    The ContextOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    """
    DEFAULTS = {}

    def __init__(self, **kwds):
        # update from the other database option instance
        other_options = kwds.pop('options', None)
        if isinstance(other_options, ContextOptions):
            for key, default in self.DEFAULTS.items():
                kwds.setdefault(key, other_options.raw_values.get(key, default))

        self.__dict__['raw_values'] = {}
        for key, value in self.DEFAULTS.items():
            self.raw_values[key] = kwds.get(key, value)

    def __str__(self):
        """
        Returns a string for this instance.

        :return     <str>
        """
        opts = []
        for key, default in self.DEFAULTS.items():
            val = getattr(self, key)
            if val == default:
                continue
            opts.append('{0}:{1}'.format(key, val))
        return '<{0} {1}>'.format(type(self).__name__, ' '.join(opts))

    def __getattr__(self, key):
        try:
            return self.raw_values[key]
        except KeyError:
            raise AttributeError(key)

    def __setattr__(self, key, value):
        if key in self.raw_values:
            self.raw_values[key] = value
        else:
            raise AttributeError(key)

    def __hash__(self):
        """
        Returns a hash representation for this instance.

        :return     <hash>
        """
        return hash(nstr(self))

    def assigned(self):
        """
        Returns a dictionary of assigned values for this context option.

        :return     {<str> key: <variant> value, ..}
        """
        return {k: v for k, v in self.raw_values.items() if self.DEFAULTS[k] != v}

    def copy(self):
        """
        Returns a copy of this database option set.

        :return     <orb.ContextOptions>
        """
        return type(self)(**self.raw_values)

    def isNull(self):
        """
        Returns whether or not this option set has been modified.

        :return     <bool>
        """
        return self.raw_values.values() == self.DEFAULTS.values()

    def update(self, options):
        """
        Updates this lookup set with the inputted options.

        :param      options | <dict>
        """
        self.raw_values.update({k: v for k, v in options.items() if k in self.DEFAULTS})

    def toDict(self):
        """
        Returns a dictionary representation of this database option set.

        :return     <dict>
        """
        return self.raw_values.copy()

    @classmethod
    def fromDict(cls, data):
        """
        Returns a new lookup options instance based on the inputted data
        dictionary.

        :param      data | <dict>


        :return     <LookupOptions>
        """
        return cls(**data)


class ContextOptions(Options):
    """"
    Defines a unique instance of information that will be bundled when
    calling different methods within the connections class.
    
    The ContextOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    """
    DEFAULTS = {
        # database options
        'namespace': None,
        'flags': 0,
        'autoIncrement': True,
        'deleteFlags': orb.DeleteFlags.all(),
        'useCache': False,
        'database': None,

        # output options
        'inflated': True,
        'format': 'object',

        # context options
        'context': None,
        'locale': None,
        'timezone': None,
        'request': None,

        # debug options
        'force': False,
        'dryRun': False
    }

    @property
    def database(self):
        return self.raw_values['database'] or orb.system.database()

    @property
    def locale(self):
        """
        Returns the locale for this context, either by the specified locale or the root manager.

        :return     <str>
        """
        return self.raw_values['locale'] or orb.system.locale(self)

    @property
    def timezone(self):
        """
        Returns the timezone for this context, either by the specified zone or from the root manager.

        :return     <str>
        """
        return self.raw_values['timezone'] or orb.system.timezone(self)

    def update(self, options):
        """
        Updates this lookup set with the inputted options.

        :param      options | <dict>
        """
        new_options = {}
        if 'options' in options:
            new_options.update(options['options'].raw_values)
        new_options.update(options)
        super(ContextOptions, self).update(new_options)

# ------------------------------------------------------------------------------

class LookupOptions(object):
    """
    Defines a unique instance of information that will be bundled when
    calling different query based methods in the connection class.
    
    The LookupOptions class will accept a set of keyword arguments to
    control how the action on the database will be affected.  The options are:
    
    :param      columns       | [<str>, ..] || None (default: None)
{'fraction_non_alphanumeric': 0.10671019847065899, 'fraction_numerical': 0.0008591803419537761, 'mean_word_length': 2.0535152151101785, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2182001', 'n_tokens_mistral': 3074, 'n_tokens_neox': 3014, 'n_words': 1087}