o
    in                     @   s4  d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	 dd	lm
Z
 dd
lmZ ddlmZ ddlmZ ddlmZ ddlmZ G dd deZejjdddG dd deZejjdddG dd deZejjdddG dd deZejjdddeddG dd deZdS )zDescriptor properties are more "auxiliary" properties
that exist as configurational elements, but don't participate
as actively in the load/persist ORM loop.

   )
attributes)
properties)query)MapperProperty)PropComparator)	_none_set   )event)exc)schema)sql)util)
expressionc                   @   s    e Zd ZdZdZdZdd ZdS )DescriptorPropertyzS:class:`.MapperProperty` which proxies access to a
        user-defined descriptor.NFc                    s   G fdddt }jd u r!t jjd } |r!|_jd u r@fdd}fdd}fdd}t|||d	_tjj	jjj fd
dj
d}|j|_ jj| d S )Nc                       sP   e Zd ZdZdZdZe fddZdd Ze	 dr&e
jf fdd		Zd
S d
S )z7DescriptorProperty.instrument_class.<locals>._ProxyImplFTc                    s    j S N)uses_objectsselfprop Z/var/www/edux/Edux_v2/venv/lib/python3.10/site-packages/sqlalchemy/orm/descriptor_props.pyr   ,   s   zDDescriptorProperty.instrument_class.<locals>._ProxyImpl.uses_objectsc                 S   s
   || _ d S r   key)r   r   r   r   r   __init__0      
z@DescriptorProperty.instrument_class.<locals>._ProxyImpl.__init__get_historyc                    s     |||S r   )r   )r   statedict_passiver   r   r   r   5   s   zCDescriptorProperty.instrument_class.<locals>._ProxyImpl.get_historyN)__name__
__module____qualname__accepts_scalar_loaderexpire_missing
collectionpropertyr   r   hasattrr   PASSIVE_OFFr   r   r   r   r   
_ProxyImpl'   s    
r)   c                    s   t |  j| d S r   )setattrname)objvaluer   r   r   fsetA      z1DescriptorProperty.instrument_class.<locals>.fsetc                    s   t |  j d S r   )delattrr+   r,   r   r   r   fdelD      z1DescriptorProperty.instrument_class.<locals>.fdelc                    s   t |  jS r   )getattrr+   r1   r   r   r   fgetG      z1DescriptorProperty.instrument_class.<locals>.fget)r5   r.   r2   c                      s
     S r   )_comparator_factoryr   )mapperr   r   r   <lambda>P   s   
 z5DescriptorProperty.instrument_class.<locals>.<lambda>)docoriginal_property)object
descriptorr4   class_r   _is_userland_descriptorr&   r   create_proxied_attributeparentr:   implclass_managerinstrument_attribute)r   r8   r)   descr.   r2   r5   
proxy_attrr   )r8   r   r   r   instrument_class$   s*   



z#DescriptorProperty.instrument_class)r    r!   r"   __doc__r:   r   rG   r   r   r   r   r      s
    r   zsqlalchemy.orm.propertiesT)
add_to_allc                       s   e Zd ZdZejdd fddZ fddZdd	 Zd
d Z	ej
dd Zej
dd Zedd Zdd Zdd Zej
dd ZejfddZdd ZG dd dejZG dd deZd d! Z  ZS )"CompositePropertyzDefines a "composite" mapped attribute, representing a collection
    of columns as one attribute.

    :class:`.CompositeProperty` is constructed using the :func:`.composite`
    function.

    .. seealso::

        :ref:`mapper_composite`

    )0.7z:class:`.AttributeExtension` is deprecated in favor of the :class:`.AttributeEvents` listener interface.  The :paramref:`.composite.extension` parameter will be removed in a future release.)	extensionc                    s   t t|   || _|| _|dd| _|dd| _|dd| _|	d| j
j| _d|v r5|	d| _t|  |   dS )aQ  Return a composite column-based property for use with a Mapper.

        See the mapping documentation section :ref:`mapper_composite` for a
        full usage example.

        The :class:`.MapperProperty` returned by :func:`.composite`
        is the :class:`.CompositeProperty`.

        :param class\_:
          The "composite type" class, or any classmethod or callable which
          will produce a new instance of the composite object given the
          column values in order.

        :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.  See the same flag on :func:`.column_property`.

        :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 comparator_factory:  a class which extends
          :class:`.CompositeProperty.Comparator` which provides custom SQL
          clause generation for comparison operations.

        :param doc:
          optional string that will be applied as the doc on the
          class-bound descriptor.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.MapperProperty.info` attribute of this object.

        :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.

        active_historyFdeferredgroupNcomparator_factoryinfo)superrJ   r   attrscomposite_classgetrM   rN   rO   pop	__class__
ComparatorrP   rQ   r   set_creation_order_create_descriptor)r   r>   rS   kwargsrW   r   r   r   f   s   :
zCompositeProperty.__init__c                    s   t t| | |   d S r   )rR   rJ   rG   _setup_event_handlersr   r8   r\   r   r   rG      s   z"CompositeProperty.instrument_classc                 C   s   |    dS )zInitialization which occurs after the :class:`.CompositeProperty`
        has been associated with its parent mapper.

        N)_setup_arguments_on_columnsr   r   r   r   do_init   s   zCompositeProperty.do_initc                    s6    fdd} fdd} fdd}t ||| _dS )ztCreate the Python descriptor that will serve as
        the access point on instances of the mapped class.

        c                    s   t  }t  }j|vr; fddjD }j|vr;|jd us(t|s;j| |j< |jj	
|d jg |jd S )Nc                    s   g | ]}t  |qS r   )r4   .0r   instancer   r   
<listcomp>   s    
zFCompositeProperty._create_descriptor.<locals>.fget.<locals>.<listcomp>)r   instance_dictinstance_stater   _attribute_keysr   
issupersetrT   managerdispatchrefreshrU   )rd   r   r   valuesr   rc   r   r5      s   




	z2CompositeProperty._create_descriptor.<locals>.fgetc                    s   t | }t | }|j j }| jt j}|jjD ]
}|||||j	}q|| j< |d u r> j
D ]}t| |d  q3d S t j
| D ]
\}}t| || qFd S r   )r   rf   rg   rj   r   rU   NO_VALUErk   setrB   rh   r*   zip__composite_values__)rd   r-   r   r   attrpreviousfnr   r   r   r   r.      s    




z2CompositeProperty._create_descriptor.<locals>.fsetc                    s^   t | }t | }| jt j}|j j }|j|||j	  j
D ]}t| |d  q$d S r   )r   rg   rf   rV   r   rn   rj   rk   removerB   rh   r*   )rd   r   r   rs   rr   r   r   r   r   r2      s   


z2CompositeProperty._create_descriptor.<locals>.fdelN)r&   r=   )r   r5   r.   r2   r   r   r   rZ      s   	z$CompositeProperty._create_descriptorc                    s    fdd j D S )Nc                       g | ]
}t  jj|jqS r   )r4   rA   r>   r   rb   r   r   r   r   re          z:CompositeProperty._comparable_elements.<locals>.<listcomp>propsr   r   r   r   _comparable_elements      z&CompositeProperty._comparable_elementsc                 C   sx   g }| j D ]4}t|tr| jj|dd}nt|tjr"| jj| }nt|tj	r,|j
}ntd|f || q|S )NF)_configure_mappersz[Composite expects Column objects or mapped attributes/attribute names as arguments, got: %r)rS   
isinstancestrrA   get_propertyr   Column_columntopropertyr   InstrumentedAttributer&   sa_excArgumentErrorappend)r   rz   rr   r   r   r   r   rz      s   

zCompositeProperty.propsc                 C      dd | j D S )Nc                 S   s   g | ]
}t |tjr|qS r   )r~   r   r   )rb   ar   r   r   re     rx   z-CompositeProperty.columns.<locals>.<listcomp>)rS   r   r   r   r   columns     zCompositeProperty.columnsc                 C   s4   | j D ]}| j|_| jr| j|_d|_| j|_qdS )zwPropagate configuration arguments made on this composite
        to the target columns, for those that apply.

        ))rN   T)
instrumentTN)rz   rM   rN   strategy_keyrO   )r   r   r   r   r   r_     s   

z-CompositeProperty._setup_arguments_on_columnsc                    s    fdd} fdd}fdd fdd}fd	d
}t jjd|dd t jjd|dd t jjd|ddd t jjd|ddd t jjd|ddd dS )z>Establish events that populate/expire the composite attribute.c                        | |dd d S )NF
is_refreshr   r   args_load_refresh_handlerr   r   load_handler   r/   z=CompositeProperty._setup_event_handlers.<locals>.load_handlerc                    r   )NTr   r   r   r   r   r   refresh_handler#  r/   z@CompositeProperty._setup_event_handlers.<locals>.refresh_handlerc                    sV    j }|sj|v rd S jD ]	}||vr d S qj fddjD  |j< d S )Nc                    s   g | ]} j | qS r   )dictra   r   r   r   re   4      zZCompositeProperty._setup_event_handlers.<locals>._load_refresh_handler.<locals>.<listcomp>)r   r   rh   rT   )r   r   r   r   kr   r   r   r   &  s   
zFCompositeProperty._setup_event_handlers.<locals>._load_refresh_handlerc                    s0   |d u st  j|r| j jd  d S d S r   )ro   rh   intersectionr   rV   r   )r   keysr   r   r   expire_handler7  s   z?CompositeProperty._setup_event_handlers.<locals>.expire_handlerc                    s   |j  jd dS )zAfter an insert or update, some columns may be expired due
            to server side defaults, or re-populated due to client side
            defaults.  Pop out the composite value here so that it
            recreates.

            N)r   rV   r   )r8   
connectionr   r   r   r   insert_update_handler;  s   zFCompositeProperty._setup_event_handlers.<locals>.insert_update_handlerafter_insertT)rawafter_updateload)r   	propagaterl   expireN)r	   listenrA   )r   r   r   r   r   r   )r   r   r   r]     s(   



z'CompositeProperty._setup_event_handlersc                 C   r   )Nc                 S   s   g | ]}|j qS r   r   rw   r   r   r   re   Y  s    z5CompositeProperty._attribute_keys.<locals>.<listcomp>ry   r   r   r   r   rh   W  r   z!CompositeProperty._attribute_keysc                 C   s   g }g }d}| j D ]5}|j}|j| j||}	|	 rd}|	 }
|
r*||
 n|d |	j	r9||	j	 q	|d q	|rPt
| j| gd| j| gS t
d| j| gdS )z>Provided for userland code that uses attributes.get_history().FTNr   )rz   r   rj   rB   r   has_changesnon_deletedextendr   deletedr   HistoryrT   )r   r   r   r   addedr   has_historyr   r   histr   r   r   r   r   [  s,   



zCompositeProperty.get_historyc                 C      |  | |S r   rP   r^   r   r   r   r7   {  r6   z%CompositeProperty._comparator_factoryc                       s$   e Zd Z fddZdd Z  ZS )z!CompositeProperty.CompositeBundlec                    s&   || _ ttj| j|jg|R   d S r   )r&   rR   rJ   CompositeBundler   r   )r   	property_exprr\   r   r   r     s   z*CompositeProperty.CompositeBundle.__init__c                    s    fdd}|S )Nc                    s   j j fddD  S )Nc                    s   g | ]}| qS r   r   )rb   procrowr   r   re     s    zXCompositeProperty.CompositeBundle.create_row_processor.<locals>.proc.<locals>.<listcomp>)r&   rT   r   procsr   r   r   r     s   zDCompositeProperty.CompositeBundle.create_row_processor.<locals>.procr   )r   r   r   labelsr   r   r   r   create_row_processor  s   z6CompositeProperty.CompositeBundle.create_row_processor)r    r!   r"   r   r   __classcell__r   r   r\   r   r   ~  s    r   c                   @   sV   e Zd ZdZdZedd Zdd Zdd Zd	d
 Z	e
jdd Zdd Zdd ZdS )zCompositeProperty.Comparatora  Produce boolean, comparison, and other operators for
        :class:`.CompositeProperty` attributes.

        See the example in :ref:`composite_operations` for an overview
        of usage , as well as the documentation for :class:`.PropComparator`.

        .. seealso::

            :class:`.PropComparator`

            :class:`.ColumnOperators`

            :ref:`types_operators`

            :attr:`.TypeEngine.comparator_factory`

        Nc                 C   s   |   S r   )__clause_element__r   r   r   r   clauses  s   z$CompositeProperty.Comparator.clausesc                 C   s   t j| jddiS )NrO   F)r   
ClauseListr{   r   r   r   r   r     s
   z/CompositeProperty.Comparator.__clause_element__c                 C   s   t | j|  S r   )rJ   r   r   r   r   r   r   r   _query_clause_element  s   
z2CompositeProperty.Comparator._query_clause_elementc                 C   sT   |d u rdd | j jD }nt|| j jr| }n
td| j |f t| j|S )Nc                 S   s   g | ]}d qS r   r   ra   r   r   r   re     s    zDCompositeProperty.Comparator._bulk_update_tuples.<locals>.<listcomp>z)Can't UPDATE composite attribute %s to %r)	r   rh   r~   rT   rq   r   r   rp   r{   )r   r-   rm   r   r   r   _bulk_update_tuples  s   
z0CompositeProperty.Comparator._bulk_update_tuplesc                    s$    j r fdd jjD S  jjS )Nc                    rv   r   )r4   _adapt_to_entityentityr   rw   r   r   r   re     s    zECompositeProperty.Comparator._comparable_elements.<locals>.<listcomp>)r   r   r{   r   r   r   r   r{     s
   
z1CompositeProperty.Comparator._comparable_elementsc                    s^   |d u rd gt  jj }n| }dd t jj|D } jr* fdd|D }tj| S )Nc                 S   s   g | ]\}}||kqS r   r   )rb   r   br   r   r   re     s    z7CompositeProperty.Comparator.__eq__.<locals>.<listcomp>c                    s   g | ]}  |qS r   )adapter)rb   xr   r   r   re     r   )lenr   r{   rq   rp   r   r   and_)r   otherrm   comparisonsr   r   r   __eq__  s   
z#CompositeProperty.Comparator.__eq__c                 C   s   t | |S r   )r   not_r   )r   r   r   r   r   __ne__  r3   z#CompositeProperty.Comparator.__ne__)r    r!   r"   rH   __hash__r&   r   r   r   r   r   memoized_propertyr{   r   r   r   r   r   r   rX     s    

	rX   c                 C   s   t | jjjd | j S )N.)r   rA   r>   r    r   r   r   r   r   __str__  s   zCompositeProperty.__str__)r    r!   r"   rH   r   deprecated_paramsr   rG   r`   rZ   r   r{   rz   r&   r   r_   r]   rh   r   r(   r   r7   r   Bundler   r   rX   r   r   r   r   r\   r   rJ   X   s0    	A;


:
 IrJ   c                       s(   e Zd ZdZdd Z fddZ  ZS )ConcreteInheritedPropertya4  A 'do nothing' :class:`.MapperProperty` that disables
    an attribute on a concrete subclass that is only present
    on the inherited mapper, not the concrete classes' mapper.

    Cases where this occurs include:

    * When the superclass mapper is mapped against a
      "polymorphic union", which includes all attributes from
      all subclasses.
    * When a relationship() is configured on an inherited mapper,
      but not on the subclass mapper.  Concrete mappers require
      that relationship() is configured explicitly on each
      subclass.

    c                 C   s:   d }| j  D ]}|j| j }t|ts|j} |S q|S r   )rA   iterate_to_root_propsr   r~   r   rP   )r   r8   comparator_callablempr   r   r   r7     s   
z-ConcreteInheritedProperty._comparator_factoryc                    s<   t t    fddG  fdddt}|  _d S )Nc                      s   t d j j jf )NzgConcrete %s does not implement attribute %r at the instance level.  Add this property explicitly to %s.)AttributeErrorrA   r   r   r   r   r   warn  s
   z0ConcreteInheritedProperty.__init__.<locals>.warnc                       s2   e Zd ZfddZfddZ fddZdS )zDConcreteInheritedProperty.__init__.<locals>.NoninheritedConcretePropc                    
      d S r   r   )sr,   r-   r   r   r   __set__  r   zLConcreteInheritedProperty.__init__.<locals>.NoninheritedConcreteProp.__set__c                    r   r   r   )r   r,   r   r   r   
__delete__  r   zOConcreteInheritedProperty.__init__.<locals>.NoninheritedConcreteProp.__delete__c                    s   |d u r j S   d S r   )r=   )r   r,   ownerr   r   r   r   __get__  s   
zLConcreteInheritedProperty.__init__.<locals>.NoninheritedConcreteProp.__get__N)r    r!   r"   r   r   r   r   r   r   r   NoninheritedConcreteProp  s    r   )rR   r   r   r<   r=   )r   r   r\   r   r   r     s   z"ConcreteInheritedProperty.__init__)r    r!   r"   rH   r7   r   r   r   r   r\   r   r     s    
r   c                       sZ   e Zd Z					d fdd	Zedd Zejdd Zdd	 Z	d
d Z
dd Z  ZS )SynonymPropertyNc                    sR   t t|   || _|| _|| _|| _|p|r|jpd| _|r"|| _	t
|  dS )a  Denote an attribute name as a synonym to a mapped property,
        in that the attribute will mirror the value and expression behavior
        of another attribute.

        e.g.::

            class MyClass(Base):
                __tablename__ = 'my_table'

                id = Column(Integer, primary_key=True)
                job_status = Column(String(50))

                status = synonym("job_status")


        :param name: the name of the existing mapped property.  This
          can refer to the string name ORM-mapped attribute
          configured on the class, including column-bound attributes
          and relationships.

        :param descriptor: a Python :term:`descriptor` that will be used
          as a getter (and potentially a setter) when this attribute is
          accessed at the instance level.

        :param map_column: **For classical mappings and mappings against
          an existing Table object only**.  if ``True``, the :func:`.synonym`
          construct will locate the :class:`_schema.Column`
          object upon the mapped
          table that would normally be associated with the attribute name of
          this synonym, and produce a new :class:`.ColumnProperty` that instead
          maps this :class:`_schema.Column`
          to the alternate name given as the "name"
          argument of the synonym; in this way, the usual step of redefining
          the mapping of the :class:`_schema.Column`
          to be under a different name is
          unnecessary. This is usually intended to be used when a
          :class:`_schema.Column`
          is to be replaced with an attribute that also uses a
          descriptor, that is, in conjunction with the
          :paramref:`.synonym.descriptor` parameter::

            my_table = Table(
                "my_table", metadata,
                Column('id', Integer, primary_key=True),
                Column('job_status', String(50))
            )

            class MyClass(object):
                @property
                def _job_status_descriptor(self):
                    return "Status: %s" % self._job_status


            mapper(
                MyClass, my_table, properties={
                    "job_status": synonym(
                        "_job_status", map_column=True,
                        descriptor=MyClass._job_status_descriptor)
                }
            )

          Above, the attribute named ``_job_status`` is automatically
          mapped to the ``job_status`` column::

            >>> j1 = MyClass()
            >>> j1._job_status = "employed"
            >>> j1.job_status
            Status: employed

          When using Declarative, in order to provide a descriptor in
          conjunction with a synonym, use the
          :func:`sqlalchemy.ext.declarative.synonym_for` helper.  However,
          note that the :ref:`hybrid properties <mapper_hybrids>` feature
          should usually be preferred, particularly when redefining attribute
          behavior.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.InspectionAttr.info` attribute of this object.

            .. versionadded:: 1.0.0

        :param comparator_factory: A subclass of :class:`.PropComparator`
          that will provide custom comparison behavior at the SQL expression
          level.

          .. note::

            For the use case of providing an attribute which redefines both
            Python-level and SQL-expression level behavior of an attribute,
            please refer to the Hybrid attribute introduced at
            :ref:`mapper_hybrids` for a more effective technique.

        .. seealso::

            :ref:`synonyms` - Overview of synonyms

            :func:`.synonym_for` - a helper oriented towards Declarative

            :ref:`mapper_hybrids` - The Hybrid Attribute extension provides an
            updated approach to augmenting attribute behavior more flexibly
            than can be achieved with synonyms.

        N)rR   r   r   r+   
map_columnr=   rP   rH   r:   rQ   r   rY   )r   r+   r   r=   rP   r:   rQ   r\   r   r   r     s   pzSynonymProperty.__init__c                 C   s   t | jj| jjjS r   )r4   rA   r>   r+   rB   r   r   r   r   r   r     r|   zSynonymProperty.uses_objectsc                 C   sH   t | jj| j}t|drt|jts!t	d| jjj
| j|f |jS )Nr&   zGsynonym() attribute "%s.%s" only supports ORM mapped attributes, got %r)r4   rA   r>   r+   r'   r~   r&   r   r   InvalidRequestErrorr    )r   rr   r   r   r   _proxied_property  s   z!SynonymProperty._proxied_propertyc                 C   s,   | j }| jr| ||}|S |||}|S r   )r   rP   )r   r8   r   compr   r   r   r7     s   z#SynonymProperty._comparator_factoryc                 O   s"   t | jj| j}|jj|i |S r   )r4   rA   r>   r+   rB   r   )r   argkwrr   r   r   r   r     s   zSynonymProperty.get_historyc                 C   s   | j rW| j|jjvrtd| j|jj| jf |jj| j |jv r?|j|jj| j  j| jkr?td| j| j| j| jf t	
|jj| j }|j| j||dd | j|_|| _d S )Nz>Can't compile synonym '%s': no column on table '%s' named '%s'zpCan't call map_column=True for synonym %r=%r, a ColumnProperty already exists keyed to the name %r for column %rT)init	setparent)r   r   persist_selectablecr   r   r+   descriptionr   r   ColumnProperty_configure_property_mapped_by_synonymrA   )r   rA   r   r   r   r   r   
set_parent  s<   

zSynonymProperty.set_parent)NNNNN)r    r!   r"   r   r&   r   r   r   r   r7   r   r   r   r   r   r\   r   r     s    |

	r   rK   z:func:`.comparable_property` is deprecated and will be removed in a future release.  Please refer to the :mod:`~sqlalchemy.ext.hybrid` extension.c                       s,   e Zd ZdZ	d fdd	Zdd Z  ZS )ComparablePropertyz;Instruments a Python property for use in query expressions.Nc                    sF   t t|   || _|| _|p|r|jpd| _|r|| _t	|  dS )a	  Provides a method of applying a :class:`.PropComparator`
        to any Python descriptor attribute.


        Allows any Python descriptor to behave like a SQL-enabled
        attribute when used at the class level in queries, allowing
        redefinition of expression operator behavior.

        In the example below we redefine :meth:`.PropComparator.operate`
        to wrap both sides of an expression in ``func.lower()`` to produce
        case-insensitive comparison::

            from sqlalchemy.orm import comparable_property
            from sqlalchemy.orm.interfaces import PropComparator
            from sqlalchemy.sql import func
            from sqlalchemy import Integer, String, Column
            from sqlalchemy.ext.declarative import declarative_base

            class CaseInsensitiveComparator(PropComparator):
                def __clause_element__(self):
                    return self.prop

                def operate(self, op, other):
                    return op(
                        func.lower(self.__clause_element__()),
                        func.lower(other)
                    )

            Base = declarative_base()

            class SearchWord(Base):
                __tablename__ = 'search_word'
                id = Column(Integer, primary_key=True)
                word = Column(String)
                word_insensitive = comparable_property(lambda prop, mapper:
                                CaseInsensitiveComparator(
                                    mapper.c.word, mapper)
                            )


        A mapping like the above allows the ``word_insensitive`` attribute
        to render an expression like::

            >>> print(SearchWord.word_insensitive == "Trucks")
            lower(search_word.word) = lower(:lower_1)

        :param comparator_factory:
          A PropComparator subclass or factory that defines operator behavior
          for this property.

        :param descriptor:
          Optional when used in a ``properties={}`` declaration.  The Python
          descriptor or property to layer comparison behavior on top of.

          The like-named descriptor will be automatically retrieved from the
          mapped class if left blank in a ``properties`` declaration.

        :param info: Optional data dictionary which will be populated into the
            :attr:`.InspectionAttr.info` attribute of this object.

            .. versionadded:: 1.0.0

        N)
rR   r   r   r=   rP   rH   r:   rQ   r   rY   )r   rP   r=   r:   rQ   r\   r   r   r     s   BzComparableProperty.__init__c                 C   r   r   r   r^   r   r   r   r7   '  r6   z&ComparableProperty._comparator_factory)NNN)r    r!   r"   rH   r   r7   r   r   r   r\   r   r     s
    Jr   N)rH    r   r   r   
interfacesr   r   r   r   r	   r
   r   r   r   r   r   langhelpersdependency_forrJ   r   r   deprecated_clsr   r   r   r   r   <module>   s<   <   5 C