a
    µb  ã                   @   sx   d dl Z d dlZd dlZd dlmZ e e¡Zddd„ZG dd„ dƒZ	G dd„ dƒZ
d	d
„ Zdd„ Zdd„ Zdd„ ZdS )é    N)ÚRecordModifiedErrorc                    s   ‡ ‡fdd„}|S )a  A decorator which can be used to mark functions as deprecated.
    replacement is a callable that will be called with the same args
    as the decorated function.
    >>> import pytest
    >>> @deprecated()
    ... def foo1(x):
    ...     return x
    ...
    >>> pytest.warns(DeprecationWarning, foo1, 1)
    1
    >>> def newfun(x):
    ...     return 0
    ...
    >>> @deprecated(newfun, '1.1')
    ... def foo2(x):
    ...     return x
    ...
    >>> pytest.warns(DeprecationWarning, foo2, 1)
    0
    >>>
    c                    s   ‡ ‡‡fdd„}|S )Nc                     sj   dˆ j  }ˆd ur|dˆ 7 }ˆd ur2|dˆ 7 }tj|tdd� tˆƒrXˆ| i |¤ŽS ˆ | i |¤ŽS d S )Nz%s is deprecatedzwill be removed in version %s;z; use %s insteadé   )Ú
stacklevel)Ú__name__ÚwarningsÚwarnÚDeprecationWarningÚcallable)ÚargsÚkwargsÚmsg)ÚoldfunÚreplacementÚversion© úN/home/httpd/docs/test/DocsMgr/lib/python3.9/site-packages/concurrency/utils.pyÚinner"   s    
z(deprecated.<locals>.outer.<locals>.innerr   )r   r   ©r   r   )r   r   Úouter!   s    zdeprecated.<locals>.outerr   )r   r   r   r   r   r   Ú
deprecated
   s    r   c                   @   s8   e Zd ZdZdZi Zdd„ Zdd„ Zdd„ Zd	d
„ Z	dS )ÚConcurrencyTestMixina¼  
    Mixin class to test Models that use `VersionField`

    this class offer a simple test scenario. Its purpose is to discover
    some conflict in the `save()` inheritance::

        from concurrency.utils import ConcurrencyTestMixin
        from myproject.models import MyModel

        class MyModelTest(ConcurrencyTestMixin, TestCase):
            concurrency_model = TestModel0
            concurrency_kwargs = {'username': 'test'}

    Nc                 K   s,   t | jƒ}| |¡ | jjjf i |¤Žd S )Nr   )ÚdictÚconcurrency_kwargsÚupdateÚconcurrency_modelÚobjectsZget_or_create)Úselfr   r
   r   r   r   Ú_get_concurrency_targetF   s    

z,ConcurrencyTestMixin._get_concurrency_targetc                 C   sp   dd l m} |  ¡ }|  ¡ }| |¡}| |¡}||ksHJ d||f ƒ‚| ¡  |jd us^J ‚|  t|j¡ d S )Nr   z+got same row with different version (%s/%s))Úconcurrency.apiÚapir   Úget_revision_of_objectZsaveÚpkÚassertRaisesr   )r   r   ÚtargetZtarget_copyZv1Zv2r   r   r   Útest_concurrency_conflictM   s    

z.ConcurrencyTestMixin.test_concurrency_conflictc                 C   s6   dd l m} |  ¡ }| |¡}|  t|ƒd| ¡ d S )Nr   zversion is not null %s)r   r   r   r    ÚassertFalseÚbool)r   r   r#   r   r   r   r   Útest_concurrency_safetyY   s    
z,ConcurrencyTestMixin.test_concurrency_safetyc                 C   sD   | j }|  t|dƒd| j  ¡ |jj}|  ||jjv d| j  ¡ d S )NÚ_concurrencymetaz&%s is not under concurrency managementz$%s: version field not in meta.fields)r   Ú
assertTrueÚhasattrr(   ÚfieldZ_metaÚfields)r   r#   Zrevision_fieldr   r   r   Útest_concurrency_management`   s    ÿÿz0ConcurrencyTestMixin.test_concurrency_management)
r   Ú
__module__Ú__qualname__Ú__doc__r   r   r   r$   r'   r-   r   r   r   r   r   3   s   r   c                   @   s   e Zd ZdS )ÚConcurrencyAdminTestMixinN)r   r.   r/   r   r   r   r   r1   k   s   r1   c                 C   s   | j jj| jd�S )z3
    Reload model instance from the database
    # )r!   )Ú	__class__r   Úgetr!   )Zmodel_instancer   r   r   Úrefetcho   s    r4   c                 C   sJ   t  | ¡r| }nt| ƒr| }n| j}z|jW S  tyD   |j Y S 0 dS )zN Returns the classname of an object r a class

    :param o:
    :return:
    N)ÚinspectÚisclassr	   r2   r/   ÚAttributeErrorr   )Úor#   r   r   r   Úget_classnamev   s    
r9   c                 C   sT   g }t | dƒr*| | j¡ | t| ƒ¡ nt | ¡r:| jS |sJtd|  ƒ‚d |¡S )a'  Returns the fully qualified class name of an object or a class

    :param o: object or class
    :return: class name

    >>> import concurrency.fields
    >>> fqn('str')
    Traceback (most recent call last):
    ...
    ValueError: Invalid argument `str`
    >>> class A:
    ...     def method(self):
    ...         pass
    >>> str(fqn(A))
    'concurrency.utils.A'

    >>> str(fqn(A()))
    'concurrency.utils.A'

    >>> str(fqn(concurrency.fields))
    'concurrency.fields'

    >>> str(fqn(A.method))
    'concurrency.utils.A.method'


    r.   zInvalid argument `%s`Ú.)	r*   Úappendr.   r9   r5   Úismoduler   Ú
ValueErrorÚjoin)r8   Úpartsr   r   r   Úfqnˆ   s    

r@   c                 C   sF   t ƒ }| D ]2}t|dƒr2t|tƒs2| t|ƒ¡ q
| |¡ q
t |ƒS )a  
    flatten(sequence) -> list

    Returns a single, flat list which contains all elements retrieved
    from the sequence and all recursively contained sub-sequences
    (iterables).

    :param sequence: any object that implements iterable protocol (see: :ref:`typeiter`)
    :return: list

    Examples:

    >>> from adminactions.utils import flatten
    >>> [1, 2, [3,4], (5,6)]
    [1, 2, [3, 4], (5, 6)]

    >>> flatten([[[1,2,3], (42,None)], [4,5], [6], 7, (8,9,10)])
    [1, 2, 3, 42, None, 4, 5, 6, 7, 8, 9, 10]Ú__iter__)Úlistr*   Ú
isinstanceÚstrÚextendÚflattenr;   )ÚiterableÚresultÚelr   r   r   rF   ¹   s    rF   )NN)r5   Úloggingr   Zconcurrency.exceptionsr   Ú	getLoggerr   Úloggerr   r   r1   r4   r9   r@   rF   r   r   r   r   Ú<module>   s   

)81