<commit_before>"""Selection classes.

Represents an enumeration using a widget.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

from collections import OrderedDict
from threading import Lock

from .widget import DOMWidget, register
from IPython.utils.traitlets import (
    Unicode, Bool, Any, Dict, TraitError, CaselessStrEnum, Tuple
)
from IPython.utils.py3compat import unicode_type
from IPython.utils.warn import DeprecatedClass

#-----------------------------------------------------------------------------
# SelectionWidget
#-----------------------------------------------------------------------------
class _Selection(DOMWidget):
    """Base class for Selection widgets
    
    ``values`` can be specified as a list or dict. If given as a list,
    it will be transformed to a dict of the form ``{str(value):value}``.
    """
    
    value = Any(help="Selected value")
    value_name = Unicode(help="The name of the selected value", sync=True)
    values = Any(sync=True, help="""List of (key, value) tuples the user can select.
    
    The keys of this list are the strings that will be displayed in the UI,
    representing the actual Python choices.
    
    The keys of this list are also available as value_names.
    """)
    
    values_dict = Dict()
    values_names = Tuple(sync=True)
    values_values = Tuple()

    disabled = Bool(False, help="Enable or disable user changes", sync=True)
    description = Unicode(help="Description of the value this widget represents", sync=True)
        
    def __init__(self, *args, **kwargs):
        self.value_lock = Lock()
        self.values_lock = Lock()
        self.on_trait_change(self._values_readonly_changed, ['values_dict', 'values_names', 'values_values', '_values'])
        if 'values' in kwargs:
            self.values = kwargs.pop('values')
        DOMWidget.__init__(self, *args, **kwargs)
        self._value_in_values()
    
    def _make_values(self, x):
        # If x is a dict, convert it to list format.
        if isinstance(x, (OrderedDict, dict)):
            return [(k, v) for k, v in x.items()]
        
        # Make sure x is a list or tuple.
        if not isinstance(x, (list, tuple)):
            raise ValueError('x')
        
        # If x is an ordinary list, use the values as names.
        for y in x:
            if not isinstance(y, (list, tuple)) or len(y) < 2:
                return [(i, i) for i in x]
        
        # Value is already in the correct format.
        return x

    def _values_changed(self, name, old, new):
        """Handles when the values tuple has been changed.

        Setting values implies setting value names from the keys of the dict.
        """        
        if self.values_lock.acquire(False):
            try:
                self.values = self._make_values(new)
                self.values_dict = {i[0]: i[1] for i in self.values}
                self.values_names = [i[0] for i in self.values]
                self.values_values = [i[1] for i in self.values]
                self._value_in_values()
            finally:
                self.values_lock.release()
        
    def _value_in_values(self):
        # ensure that the chosen value is one of the choices
        if self.values_values:
            if self.value not in self.values_values:
                self.value = next(iter(self.values_values))
    
    def _values_readonly_changed(self, name, old, new):
        if not self.values_lock.locked():
            raise TraitError("`.%s` is a read-only trait. Use the `.values` tuple instead." % name)

    def _value_changed(self, name, old, new):<commit_msg>Don't magically convert values to a list of tuples.<commit_after>"""Selection classes.

Represents an enumeration using a widget.
"""
#-----------------------------------------------------------------------------
# Copyright (c) 2013, the IPython Development Team.
#
# Distributed under the terms of the Modified BSD License.
#
# The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------

#-----------------------------------------------------------------------------
# Imports
#-----------------------------------------------------------------------------

from collections import OrderedDict
from threading import Lock

from .widget import DOMWidget, register
from IPython.utils.traitlets import (
    Unicode, Bool, Any, Dict, TraitError, CaselessStrEnum, Tuple
)
from IPython.utils.py3compat import unicode_type
from IPython.utils.warn import DeprecatedClass

#-----------------------------------------------------------------------------
# SelectionWidget
#-----------------------------------------------------------------------------
class _Selection(DOMWidget):
    """Base class for Selection widgets
    
    ``values`` can be specified as a list or dict. If given as a list,
    it will be transformed to a dict of the form ``{str(value):value}``.
    """
    
    value = Any(help="Selected value")
    value_name = Unicode(help="The name of the selected value", sync=True)
    values = Any(help="""List of (key, value) tuples or dict of values that the 
        user can select.
    
    The keys of this list are the strings that will be displayed in the UI,
    representing the actual Python choices.
    
    The keys of this list are also available as value_names.
    """)
    
    values_dict = Dict()
    values_names = Tuple(sync=True)
    values_values = Tuple()

    disabled = Bool(False, help="Enable or disable user changes", sync=True)
    description = Unicode(help="Description of the value this widget represents", sync=True)
        
    def __init__(self, *args, **kwargs):
        self.value_lock = Lock()
        self.values_lock = Lock()
        self.on_trait_change(self._values_readonly_changed, ['values_dict', 'values_names', 'values_values', '_values'])
        if 'values' in kwargs:
            self.values = kwargs.pop('values')
        DOMWidget.__init__(self, *args, **kwargs)
        self._value_in_values()
    
    def _make_values(self, x):
        # If x is a dict, convert it to list format.
        if isinstance(x, (OrderedDict, dict)):
            return [(k, v) for k, v in x.items()]
        
        # Make sure x is a list or tuple.
        if not isinstance(x, (list, tuple)):
            raise ValueError('x')
        
        # If x is an ordinary list, use the values as names.
        for y in x:
            if not isinstance(y, (list, tuple)) or len(y) < 2:
                return [(i, i) for i in x]
        
        # Value is already in the correct format.
        return x

    def _values_changed(self, name, old, new):
        """Handles when the values tuple has been changed.

        Setting values implies setting value names from the keys of the dict.
        """        
        if self.values_lock.acquire(False):
            try:
                self.values = new
                
                values = self._make_values(new)
                self.values_dict = {i[0]: i[1] for i in values}
                self.values_names = [i[0] for i in values]
                self.values_values = [i[1] for i in values]
                self._value_in_values()
            finally:
                self.values_lock.release()
        
    def _value_in_values(self):
        # ensure that the chosen value is one of the choices
        if self.values_values:
            if self.value not in self.values_values:
                self.value = next(iter(self.values_values))
    
    def _values_readonly_changed(self, name, old, new):
        if not self.values_lock.locked():
            raise TraitError("`.%s` is a read-only trait. Use the `.values` tuple instead." % name)

    def _value_changed(self, name, old, new):
{'fraction_non_alphanumeric': 0.19575187062515087, 'fraction_numerical': 0.0024137098720733766, 'mean_word_length': 1.6801423027166882, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2258899', 'n_tokens_mistral': 2151, 'n_tokens_neox': 2107, 'n_words': 765}