<commit_before>"""
Useful form fields for use with SQLAlchemy ORM.
"""
from operator import attrgetter
from sqlalchemy.orm.util import identity_key

from wtforms import widgets
from wtforms.fields import Field
from wtforms.validators import ValidationError



__all__ = (
    'QuerySelectField', 'ModelSelectField',
)


class QuerySelectField(Field):
    """
    Will display a select drop-down field to choose between ORM results in a
    sqlalchemy `Query`.  The `data` property actually will store/keep an ORM
    model instance, not the ID. Submitting a choice which is not in the query
    will result in a validation error.

    This field only works for queries on models whose primary key column(s)
    have a consistent string representation. This means it mostly only works
    for those composed of string, unicode, and integer types. For the most
    part, the primary keys will be auto-detected from the model, alternately
    pass a one-argument callable to `get_pk` which can return a unique
    comparable key.

    The `query` property on the field can be set from within a view to assign
    a query per-instance to the field. If the property is not set, the
    `query_factory` callable passed to the field constructor will be called to
    obtain a query.

    Specifying `label_attr` in the constructor will use that property of the
    model instance for display in the list, else the model object's `__str__`
    or `__unicode__` will be used.

    If `allow_blank` is set to `True`, then a blank choice will be added to the
    top of the list. Selecting this choice will result in the `data` property
    being `None`. The label for this blank choice can be set by specifying the
    `blank_text` parameter.

    The `pk_attr` parameter is deprecated and will likely be removed in a
    future release.
    """
    widget = widgets.Select()

    def __init__(self, label=u'', validators=None, query_factory=None,
                 get_pk=None, label_attr='', allow_blank=False, blank_text=u'',
                 pk_attr=None, **kwargs):
        super(QuerySelectField, self).__init__(label, validators, **kwargs)
        self.query_factory = query_factory
        if pk_attr is not None:
            self.get_pk = attrgetter(pk_attr)
        elif get_pk is None:
            self.get_pk = get_pk_from_identity
        else:
            self.get_pk = get_pk

        self.label_attr = label_attr
        self.allow_blank = allow_blank
        self.blank_text = blank_text
        self.query = None
        self._object_list = None

    def _get_data(self):
        if self._formdata is not None:
            for pk, obj in self._get_object_list():
                if pk == self._formdata:
                    self._set_data(obj)
                    break
        return self._data

    def _set_data(self, data):
        self._data = data
        self._formdata = None

    data = property(_get_data, _set_data)

    def _get_object_list(self):
        if self._object_list is None:
            query = self.query or self.query_factory()
            get_pk = self.get_pk
            self._object_list = list((unicode(get_pk(obj)), obj) for obj in query)<commit_msg>ext.sqlalchemy fields: Added deprecation warnings and import-catch for sqlalchemy.<commit_after>"""
Useful form fields for use with SQLAlchemy ORM.
"""
import operator
import warnings

from wtforms import widgets
from wtforms.fields import Field
from wtforms.validators import ValidationError

try:
    from sqlalchemy.orm.util import identity_key
    has_identity_key = True
except ImportError:
    has_identity_key = False
    


__all__ = (
    'QuerySelectField', 'ModelSelectField',
)


class QuerySelectField(Field):
    """
    Will display a select drop-down field to choose between ORM results in a
    sqlalchemy `Query`.  The `data` property actually will store/keep an ORM
    model instance, not the ID. Submitting a choice which is not in the query
    will result in a validation error.

    This field only works for queries on models whose primary key column(s)
    have a consistent string representation. This means it mostly only works
    for those composed of string, unicode, and integer types. For the most
    part, the primary keys will be auto-detected from the model, alternately
    pass a one-argument callable to `get_pk` which can return a unique
    comparable key.

    The `query` property on the field can be set from within a view to assign
    a query per-instance to the field. If the property is not set, the
    `query_factory` callable passed to the field constructor will be called to
    obtain a query.

    Specifying `label_attr` in the constructor will use that property of the
    model instance for display in the list, else the model object's `__str__`
    or `__unicode__` will be used.

    If `allow_blank` is set to `True`, then a blank choice will be added to the
    top of the list. Selecting this choice will result in the `data` property
    being `None`. The label for this blank choice can be set by specifying the
    `blank_text` parameter.

    The `pk_attr` parameter is deprecated and will likely be removed in a
    future release.
    """
    widget = widgets.Select()

    def __init__(self, label=u'', validators=None, query_factory=None,
                 get_pk=None, label_attr='', allow_blank=False, blank_text=u'',
                 pk_attr=None, **kwargs):
        super(QuerySelectField, self).__init__(label, validators, **kwargs)
        self.query_factory = query_factory
        if pk_attr is not None:
            warnings.warn('pk_attr= will be removed in WTForms 1.0, use get_pk= instead.', DeprecationWarning)
            self.get_pk = operator.attrgetter(pk_attr)
        elif get_pk is None:
            if not has_identity_key:
                raise Exception('The sqlalchemy identity_key function could not be imported.')
            self.get_pk = get_pk_from_identity
        else:
            self.get_pk = get_pk

        self.label_attr = label_attr
        self.allow_blank = allow_blank
        self.blank_text = blank_text
        self.query = None
        self._object_list = None

    def _get_data(self):
        if self._formdata is not None:
            for pk, obj in self._get_object_list():
                if pk == self._formdata:
                    self._set_data(obj)
                    break
        return self._data

    def _set_data(self, data):
        self._data = data
        self._formdata = None

    data = property(_get_data, _set_data)

    def _get_object_list(self):
        if self._object_list is None:
            query = self.query or self.query_factory()
            get_pk = self.get_pk
            self._object_list = list((unicode(get_pk(obj)), obj) for obj in query)
{'fraction_non_alphanumeric': 0.06483937518420277, 'fraction_numerical': 0.0002947244326554671, 'mean_word_length': 2.696623093681917, 'pattern_counts': {'":': 0, '<': 3, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1763688', 'n_tokens_mistral': 1922, 'n_tokens_neox': 1854, 'n_words': 751}