<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 logging
logger = logging.getLogger('formalchemy.' + __name__)
from copy import copy

from sqlalchemy import __version__
if __version__.split('.') < [0, 4, 1]:
    raise ImportError('Version 0.4.1 or later of SQLAlchemy required')

import sqlalchemy.types as types
from sqlalchemy.orm.attributes import InstrumentedAttribute, ScalarAttributeImpl
from sqlalchemy.orm import compile_mappers, object_session

import utils


compile_mappers() # initializes InstrumentedAttributes

def prettify(text):
    """
    Return `text` prettify-ed.
    >>> prettify("my_column_name")
    "My column name"
    """
    return text.replace("_", " ").capitalize()

try:
    from sqlalchemy.orm.attributes import _managed_attributes
except ImportError:
    from sqlalchemy.orm.attributes import manager_of_class
    def _managed_attributes(cls):
        return manager_of_class(cls).values()

class ModelRender(object):
    """The `ModelRender` class.

    This this is the superclass for all classes needing to deal with `model`
    access and support rendering capabilities.

    Methods:
      * bind(self)
    """

    def __init__(self, model, session=None, data={}):
        self.model = self.session = None
        self._render_attrs = None

        self.rebind(model, session, data)
        from fields import AttributeWrapper
        
        for iattr in _managed_attributes(type(self.model)):
            if hasattr(iattr.property, 'mapper') and len(iattr.property.mapper.primary_key) != 1:
                logger.warn('ignoring multi-column property %s' % iattr.impl.key)
            else:
                setattr(self, iattr.impl.key, AttributeWrapper(iattr, self))
                
    def render_attrs(self):
        if self._render_attrs:
            return self._render_attrs
        return self.get_attrs()
    render_attrs = property(render_attrs)
                
    def configure(self, pk=False, exclude=[], include=[], options=[]):
        """configure render_attrs and any extra args for template"""
        self._render_attrs = self.get_attrs(pk, exclude, include, options)

    def bind(self, model, session=None, data={}):
        """return a copy of this object, bound to model and session"""
        # two steps so bind's error checking can work
        mr = copy(self)
        mr.rebind(model, session, data)
        for iattr in _managed_attributes(type(self.model)):
            setattr(mr, iattr.impl.key, getattr(self, iattr.impl.key).bind(mr))
        if self._render_attrs:
            mr._render_attrs = [attr.bind(mr) for attr in self._render_attrs]
        return mr

    def rebind(self, model=None, session=None, data=None):
        """rebind this object to model and session.  no return value"""
        if model:
            if isinstance(model, type):
                try:
                    model = model()
                    # take object out of session, if present
                    s = object_session(model)
                    if s:
                        s.expunge(model)
                except:
                    raise Exception('%s appears to be a class, not an instance, but FormAlchemy cannot instantiate it' % model)
            if self.model and type(self.model) != type(model):
                raise ValueError('You can only bind to another object of the same type you originally bound to (%s), not %s' % (type(self.model), type(model)))
            self.model = model
        self.data = data
        if session:
            self.session = session
        elif model:
            self.session = object_session(model)
        if self.session and object_session(self.model):
            if self.session is not object_session(self.model):
                raise Exception('Thou shalt not rebind to different session than the one the model belongs to')

    def sync(self):
        for attr in self.render_attrs:
            attr.sync()

    def _raw_attrs(self):
        from fields import AttributeWrapper
        wrappers = [attr for attr in self.__dict__.itervalues()
                    if isinstance(attr, AttributeWrapper)]
        # sort by name for reproducibility
        wrappers.sort(key=lambda wrapper: wrapper.name)
        return wrappers
    
    def get_attrs(self, pk=False, exclude=[], include=[], options=[]):
        """Return a list of filtered attributes.

        Keyword arguments:
          * `pk=False` - Include primary key attributes if set to `True`.
          * `exclude=[]` - An iterable containing attributes to exclude.
          * `include=[]` - An iterable containing attributes to include.
          * `options=[]` - An iterable containing options to apply to attributes.

        Note that when `include` is non-empty, it will
        take precedence over the other options.

        """
        if include and exclude:
            raise Exception('Specify at most one of include, exclude')

        if pk not in [True, False]:
            # help people who meant include=[X] but just wrote X
            raise ValueError('pk option must be True or False, not %s' % pk)
            
        for lst in ['include', 'exclude', 'options']:
            try:
                utils.validate_columns(eval(lst))
            except:
                raise ValueError('%s parameter should be an iterable of AttributeWrapper objects; was %s' % (lst, eval(lst)))

        if not include:
            ignore = list(exclude)
            if not pk:
                ignore.extend([wrapper for wrapper in self._raw_attrs() if wrapper.is_pk() and not wrapper.is_collection()])
            ignore.extend([wrapper for wrapper in self._raw_attrs() if wrapper.is_raw_foreign_key()])<commit_msg>cleanup<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 logging
logger = logging.getLogger('formalchemy.' + __name__)
from copy import copy

from sqlalchemy import __version__
if __version__.split('.') < [0, 4, 1]:
    raise ImportError('Version 0.4.1 or later of SQLAlchemy required')

import sqlalchemy.types as types
from sqlalchemy.orm.attributes import InstrumentedAttribute, ScalarAttributeImpl
from sqlalchemy.orm import compile_mappers, object_session

import utils


compile_mappers() # initializes InstrumentedAttributes

def prettify(text):
    """
    Return `text` prettify-ed.
    >>> prettify("my_column_name")
    "My column name"
    """
    return text.replace("_", " ").capitalize()

try:
    from sqlalchemy.orm.attributes import _managed_attributes
except ImportError:
    from sqlalchemy.orm.attributes import manager_of_class
    def _managed_attributes(cls):
        return manager_of_class(cls).values()

class ModelRender(object):
    """The `ModelRender` class.

    This this is the superclass for all classes needing to deal with `model`
    access and support rendering capabilities.

    Methods:
      * bind(self)
    """

    def __init__(self, model, session=None, data={}):
        self.model = self.session = None
        self._render_attrs = None

        self.rebind(model, session, data)
        from fields import AttributeWrapper
        
        for iattr in _managed_attributes(type(self.model)):
            if hasattr(iattr.property, 'mapper') and len(iattr.property.mapper.primary_key) != 1:
                logger.warn('ignoring multi-column property %s' % iattr.impl.key)
            else:
                setattr(self, iattr.impl.key, AttributeWrapper(iattr, self))
                
    def render_attrs(self):
        if self._render_attrs:
            return self._render_attrs
        return self.get_attrs()
    render_attrs = property(render_attrs)
                
    def configure(self, pk=False, exclude=[], include=[], options=[]):
        """configure render_attrs and any extra args for template"""
        self._render_attrs = self.get_attrs(pk, exclude, include, options)

    def bind(self, model, session=None, data={}):
        """return a copy of this object, bound to model and session"""
        # two steps so bind's error checking can work
        mr = copy(self)
        mr.rebind(model, session, data)
        for iattr in _managed_attributes(type(self.model)):
            setattr(mr, iattr.impl.key, getattr(self, iattr.impl.key).bind(mr))
        if self._render_attrs:
            mr._render_attrs = [attr.bind(mr) for attr in self._render_attrs]
        return mr

    def rebind(self, model=None, session=None, data=None):
        """rebind this object to model and session.  no return value"""
        if model:
            if isinstance(model, type):
                try:
                    model = model()
                except:
                    raise Exception('%s appears to be a class, not an instance, but FormAlchemy cannot instantiate it' % model)
                # take object out of session, if present
                s = object_session(model)
                if s:
                    s.expunge(model)
            if self.model and type(self.model) != type(model):
                raise ValueError('You can only bind to another object of the same type you originally bound to (%s), not %s' % (type(self.model), type(model)))
            self.model = model
        self.data = data
        if session:
            self.session = session
        elif model:
            self.session = object_session(model)
        if self.session and object_session(self.model):
            if self.session is not object_session(self.model):
                raise Exception('Thou shalt not rebind to different session than the one the model belongs to')

    def sync(self):
        for attr in self.render_attrs:
            attr.sync()

    def _raw_attrs(self):
        from fields import AttributeWrapper
        wrappers = [attr for attr in self.__dict__.itervalues()
                    if isinstance(attr, AttributeWrapper)]
        # sort by name for reproducibility
        wrappers.sort(key=lambda wrapper: wrapper.name)
        return wrappers
    
    def get_attrs(self, pk=False, exclude=[], include=[], options=[]):
        """Return a list of filtered attributes.

        Keyword arguments:
          * `pk=False` - Include primary key attributes if set to `True`.
          * `exclude=[]` - An iterable containing attributes to exclude.
          * `include=[]` - An iterable containing attributes to include.
          * `options=[]` - An iterable containing options to apply to attributes.

        Note that when `include` is non-empty, it will
        take precedence over the other options.

        """
        if include and exclude:
            raise Exception('Specify at most one of include, exclude')

        if pk not in [True, False]:
            # help people who meant configure(include=[X]) but just wrote configure(X), resulting in pk getting the positional argument
            raise ValueError('pk option must be True or False, not %s' % pk)
            
        for lst in ['include', 'exclude', 'options']:
            try:
                utils.validate_columns(eval(lst))
            except:
                raise ValueError('%s parameter should be an iterable of AttributeWrapper objects; was %s' % (lst, eval(lst)))

        if not include:
            ignore = list(exclude)
            if not pk:
                ignore.extend([wrapper for wrapper in self._raw_attrs() if wrapper.is_pk() and not wrapper.is_collection()])
            ignore.extend([wrapper for wrapper in self._raw_attrs() if wrapper.is_raw_foreign_key()])
{'fraction_non_alphanumeric': 0.09563003818413238, 'fraction_numerical': 0.0018667798048366568, 'mean_word_length': 2.420197330237957, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 11, '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': '2314423', 'n_tokens_mistral': 3245, 'n_tokens_neox': 3121, 'n_words': 1052}