'Provide a column-level property for use with a Mapper.
Column-based properties can normally be applied to the mapper\'s
``properties`` dictionary using the :class:`.Column` element directly.
Use this function when the given column is not directly present within the
mapper\'s selectable; examples include SQL expressions, functions, and
scalar SELECT queries.
Columns that aren\'t present in the mapper\'s selectable won\'t be persisted
by the mapper and are effectively "read-only" attributes.
:param \*cols:
list of Column objects to be mapped.
:param active_history=False:
When ``True``, indicates that the "previous" value for a
scalar attribute should be loaded when replaced, if not
already loaded. Normally, history tracking logic for
simple non-primary-key scalar values only needs to be
aware of the "new" value in order to perform a flush. This
flag is available for applications that make use of
:func:`.attributes.get_history` or :meth:`.Session.is_modified`
which also need to know
the "previous" value of the attribute.
.. versionadded:: 0.6.6
:param comparator_factory: a class which extends
:class:`.ColumnProperty.Comparator` which provides custom SQL clause
generation for comparison operations.
:param group:
a group name for this property when marked as deferred.
:param deferred:
when True, the column property is "deferred", meaning that
it does not load immediately, and is instead loaded when the
attribute is first accessed on an instance.  See also
:func:`~sqlalchemy.orm.deferred`.
:param doc:
optional string that will be applied as the doc on the
class-bound descriptor.
:param expire_on_flush=True:
Disable expiry on flush.   A column_property() which refers
to a SQL expression (and not a single table-bound column)
is considered to be a "read only" property; populating it
has no effect on the state of data, and it can only return
database state.   For this reason a column_property()\'s value
is expired whenever the parent object is involved in a
flush, that is, has any kind of "dirty" state within a flush.
Setting this parameter to ``False`` will have the effect of
leaving any existing value present after the flush proceeds.
Note however that the :class:`.Session` with default expiration
settings still expires
all attributes after a :meth:`.Session.commit` call, however.
.. versionadded:: 0.7.3
:param info: Optional data dictionary which will be populated into the
:attr:`.MapperProperty.info` attribute of this object.
.. versionadded:: 0.8
:param extension:
an
:class:`.AttributeExtension`
instance, or list of extensions, which will be prepended
to the list of attribute listeners for the resulting
descriptor placed on the class.
**Deprecated.** Please see :class:`.AttributeEvents`.'

def __init__(self, *columns, **kwargs):

    self._orig_columns = [expression._labeled(c) for c in columns]
    self.columns = [expression._labeled(_orm_full_deannotate(c)) for c in columns]
    self.group = kwargs.pop('group', None)
    self.deferred = kwargs.pop('deferred', False)
    self.instrument = kwargs.pop('_instrument', True)
    self.comparator_factory = kwargs.pop('comparator_factory', self.__class__.Comparator)
    self.descriptor = kwargs.pop('descriptor', None)
    self.extension = kwargs.pop('extension', None)
    self.active_history = kwargs.pop('active_history', False)
    self.expire_on_flush = kwargs.pop('expire_on_flush', True)
    if ('info' in kwargs):
        self.info = kwargs.pop('info')
    if ('doc' in kwargs):
        self.doc = kwargs.pop('doc')
    else:
        for col in reversed(self.columns):
            doc = getattr(col, 'doc', None)
            if (doc is not None):
                self.doc = doc
                break
        else:
            self.doc = None
    if kwargs:
        raise TypeError(('%s    received    unexpected    keyword    argument(s):    %s' % (self.__class__.__name__, ',    '.join(sorted(kwargs.keys())))))
    util.set_creation_order(self)
    self.strategy_class = self._strategy_lookup(('deferred', self.deferred), ('instrument', self.instrument))
