<commit_before>import json

from pyxform import constants
from pyxform.utils import is_valid_xml_tag, node, unicode
from pyxform.xls2json import print_pyobj_to_json
from pyxform.question_type_dictionary import QUESTION_TYPE_DICT
from pyxform.errors import PyXFormError


def _overlay(over, under):
    if type(under) == dict:
        result = under.copy()
        result.update(over)
        return result
    return over if over else under


class SurveyElement(dict):
    """
    SurveyElement is the base class we'll looks for the following keys
    in kwargs: name, label, hint, type, bind, control, parent,
    children, and question_type_dictionary.
    """

    # the following are important keys for the underlying dict that
    # describes this survey element
    FIELDS = {
        u"name": unicode,
        constants.COMPACT_TAG: unicode, # used for compact (sms) representation
        u"sms_field": unicode,
        u"sms_option": unicode,
        u"label": unicode,
        u"hint": unicode,
        u"guidance_hint": unicode,
        u"default": unicode,
        u"type": unicode,
        u"appearance": unicode,
        u"parameters": unicode,
        u"intent": unicode,
        u"jr:count": unicode,
        u"bind": dict,
        u"instance": dict,
        u"control": dict,
        u"media": dict,
        # this node will also have a parent and children, like a tree!
        u"parent": lambda: None,
        u"children": list,
        u"itemset": unicode,
        u"choice_filter": unicode,
        u"query": unicode,
        u"autoplay": unicode,
        u"flat": lambda: False,
    }

    def _default(self):
        # TODO: need way to override question type dictionary
        defaults = QUESTION_TYPE_DICT
        return defaults.get(self.get(u"type"), {})

    def __getattr__(self, key):
        """
        Get attributes from FIELDS rather than the class.
        """
        if key in self.FIELDS:
            question_type_dict = self._default()
            under = question_type_dict.get(key, None)
            over = self.get(key)
            if not under:
                return over
            return _overlay(over, under)
        raise AttributeError(key)

    @property
    def __name__(self):
        return "SurveyElement"

    def __setattr__(self, key, value):<commit_msg>Make SurveyElement hashable.<commit_after>import json

from pyxform import constants
from pyxform.utils import is_valid_xml_tag, node, unicode
from pyxform.xls2json import print_pyobj_to_json
from pyxform.question_type_dictionary import QUESTION_TYPE_DICT
from pyxform.errors import PyXFormError


def _overlay(over, under):
    if type(under) == dict:
        result = under.copy()
        result.update(over)
        return result
    return over if over else under


class SurveyElement(dict):
    """
    SurveyElement is the base class we'll looks for the following keys
    in kwargs: name, label, hint, type, bind, control, parent,
    children, and question_type_dictionary.
    """

    # the following are important keys for the underlying dict that
    # describes this survey element
    FIELDS = {
        u"name": unicode,
        constants.COMPACT_TAG: unicode, # used for compact (sms) representation
        u"sms_field": unicode,
        u"sms_option": unicode,
        u"label": unicode,
        u"hint": unicode,
        u"guidance_hint": unicode,
        u"default": unicode,
        u"type": unicode,
        u"appearance": unicode,
        u"parameters": unicode,
        u"intent": unicode,
        u"jr:count": unicode,
        u"bind": dict,
        u"instance": dict,
        u"control": dict,
        u"media": dict,
        # this node will also have a parent and children, like a tree!
        u"parent": lambda: None,
        u"children": list,
        u"itemset": unicode,
        u"choice_filter": unicode,
        u"query": unicode,
        u"autoplay": unicode,
        u"flat": lambda: False,
    }

    def _default(self):
        # TODO: need way to override question type dictionary
        defaults = QUESTION_TYPE_DICT
        return defaults.get(self.get(u"type"), {})

    def __getattr__(self, key):
        """
        Get attributes from FIELDS rather than the class.
        """
        if key in self.FIELDS:
            question_type_dict = self._default()
            under = question_type_dict.get(key, None)
            over = self.get(key)
            if not under:
                return over
            return _overlay(over, under)
        raise AttributeError(key)

    def __hash__(self):
        return hash(id(self))

    @property
    def __name__(self):
        return "SurveyElement"

    def __setattr__(self, key, value):
{'fraction_non_alphanumeric': 0.09272649936197362, 'fraction_numerical': 0.0004253509145044662, 'mean_word_length': 2.395667870036101, 'pattern_counts': {'":': 46, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '5363680', 'n_tokens_mistral': 1393, 'n_tokens_neox': 1343, 'n_words': 411}