<commit_before># Copyright (C) 2007 <NAME>, aconrad(dot.)tlv(at@)magic(dot.)fr
#
# This module is part of FormAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

import cgi
import logging
logger = logging.getLogger('formalchemy.' + __name__)

from copy import copy, deepcopy
import datetime

import helpers as h
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm.attributes import ScalarAttributeImpl, ScalarObjectAttributeImpl, CollectionAttributeImpl
from sqlalchemy.orm.properties import CompositeProperty
# from sqlalchemy.orm.exc import UnmappedClassError
from sqlalchemy.exceptions import InvalidRequestError # 0.4 support
import fatypes, validators
from i18n import _

__all__ = ['Field', 'FieldRenderer', 'query_options',
           'TextFieldRenderer', 'TextAreaFieldRenderer',
           'PasswordFieldRenderer', 'HiddenFieldRenderer',
           'DateFieldRenderer', 'TimeFieldRenderer',
           'DateTimeFieldRendererRenderer',
           'CheckBoxFieldRenderer', 'CheckBoxSet']

class FieldRenderer(object):
    """
    This should be the super class of all Renderer classes.

    Renderers generate the html corresponding to a single Field,
    and are also responsible for deserializing form data into
    Python objects.

    Subclasses should override `render` and `deserialize`.
    See their docstrings for details.
    """
    def __init__(self, field):
        self.field = field
        assert isinstance(self.field, AbstractField)

    def name(self):
        """Name of rendered input element"""
        clsname = self.field.model.__class__.__name__
        pk = _pk(self.field.model)
        assert pk != ''
        if pk is None:
            pk = ''
        return '%s-%s-%s' % (clsname, pk, self.field.name)
    name = property(name)

    def _value(self):
        """Submitted value, or field value if none"""
        if self._params is not None:
            v = self._serialized_value()
        else:
            v = None
        return v or self.field.value
    _value = property(_value)

    def render(self, **kwargs):
        """
        Render the field.  Use `self.name` to get a unique name for the
        input element and id.  `self._value` may also be useful if
        you are not rendering multiple input elements.

        This default implementation is one of last resort, only
        used if !FormAlchemy failed to find a better renderer.
        Subclasses should not call this method.
        """
        return h.text_field(self.name, value=self._value, **kwargs)

    def render_readonly(self, **kwargs):
        """render a string representation of the field value
        """
        value = self.field.raw_value
        if value is None:
            return ''
        if isinstance(value, list):
            return ', '.join([str(item) for item in value])
        return str(value)

    def _params(self):
        return self.field.parent.data
    _params = property(_params)

    def _serialized_value(self):
        """
        Returns the appropriate value to deserialize for field's
        datatype, from the user-submitted data.  Only called
        internally, so, if you are overriding `deserialize`,
        you can use or ignore `_serialized_value` as you please.

        This is broken out into a separate method so multi-input
        renderers can stitch their values back into a single one
        to have that can be handled by the default deserialize.

        Do not attempt to deserialize here; return value should be a
        string (corresponding to the output of `str` for your data
        type), or for a collection type, a a list of strings.

        The default _serialized_value returns the submitted value(s)<commit_msg>don't try to handle unicode data but avoid failure when value is unicode<commit_after># Copyright (C) 2007 <NAME>, aconrad(dot.)tlv(at@)magic(dot.)fr
#
# This module is part of FormAlchemy and is released under
# the MIT License: http://www.opensource.org/licenses/mit-license.php

import cgi
import logging
logger = logging.getLogger('formalchemy.' + __name__)

from copy import copy, deepcopy
import datetime

import helpers as h
from sqlalchemy.orm import class_mapper
from sqlalchemy.orm.attributes import ScalarAttributeImpl, ScalarObjectAttributeImpl, CollectionAttributeImpl
from sqlalchemy.orm.properties import CompositeProperty
# from sqlalchemy.orm.exc import UnmappedClassError
from sqlalchemy.exceptions import InvalidRequestError # 0.4 support
import fatypes, validators
from i18n import _

__all__ = ['Field', 'FieldRenderer', 'query_options',
           'TextFieldRenderer', 'TextAreaFieldRenderer',
           'PasswordFieldRenderer', 'HiddenFieldRenderer',
           'DateFieldRenderer', 'TimeFieldRenderer',
           'DateTimeFieldRendererRenderer',
           'CheckBoxFieldRenderer', 'CheckBoxSet']

class FieldRenderer(object):
    """
    This should be the super class of all Renderer classes.

    Renderers generate the html corresponding to a single Field,
    and are also responsible for deserializing form data into
    Python objects.

    Subclasses should override `render` and `deserialize`.
    See their docstrings for details.
    """
    def __init__(self, field):
        self.field = field
        assert isinstance(self.field, AbstractField)

    def name(self):
        """Name of rendered input element"""
        clsname = self.field.model.__class__.__name__
        pk = _pk(self.field.model)
        assert pk != ''
        if pk is None:
            pk = ''
        return '%s-%s-%s' % (clsname, pk, self.field.name)
    name = property(name)

    def _value(self):
        """Submitted value, or field value if none"""
        if self._params is not None:
            v = self._serialized_value()
        else:
            v = None
        return v or self.field.value
    _value = property(_value)

    def render(self, **kwargs):
        """
        Render the field.  Use `self.name` to get a unique name for the
        input element and id.  `self._value` may also be useful if
        you are not rendering multiple input elements.

        This default implementation is one of last resort, only
        used if !FormAlchemy failed to find a better renderer.
        Subclasses should not call this method.
        """
        return h.text_field(self.name, value=self._value, **kwargs)

    def render_readonly(self, **kwargs):
        """render a string representation of the field value
        """
        value = self.field.raw_value
        if value is None:
            return ''
        if isinstance(value, basestring):
            # FIXME this is a bad way to handle UnicodeEncodeError
            # FA need to implement a default charset and try to encode value
            # there
            return value
        if isinstance(value, list):
            return ', '.join([str(item) for item in value])
        return str(value)

    def _params(self):
        return self.field.parent.data
    _params = property(_params)

    def _serialized_value(self):
        """
        Returns the appropriate value to deserialize for field's
        datatype, from the user-submitted data.  Only called
        internally, so, if you are overriding `deserialize`,
        you can use or ignore `_serialized_value` as you please.

        This is broken out into a separate method so multi-input
        renderers can stitch their values back into a single one
        to have that can be handled by the default deserialize.

        Do not attempt to deserialize here; return value should be a
        string (corresponding to the output of `str` for your data
        type), or for a collection type, a a list of strings.

        The default _serialized_value returns the submitted value(s)
{'fraction_non_alphanumeric': 0.07650972364380758, 'fraction_numerical': 0.0020470829068577278, 'mean_word_length': 2.727706247019552, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '771302', 'n_tokens_mistral': 2081, 'n_tokens_neox': 2007, 'n_words': 796}