o
    wvXjàÚ  ã                   @   s   d Z ddlmZmZ ddlZddl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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mZ ddlmZ ddlm Z 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*m+Z+m,Z,m-Z-m.Z. ddl/m0Z0 ddl1m2Z2m3Z3 zddl4m5Z5 W n e6y±   ddlm5Z5 Y nw dZ7eoºedƒ Z8dd„ Z9dd„ Z:dd „ Z;e#j<j=eG d!d"„ d"e>ƒƒƒZ?d#d$„ Z@e?jAd%d&�eG d'd(„ d(e?ƒƒƒZBG d)d%„ d%eBƒZCG d*d+„ d+e?ƒZDe? A¡ eG d,d-„ d-eDƒƒƒZEe? A¡ eG d.d/„ d/eDƒƒƒZFe? A¡ G d0d1„ d1e?ƒƒZ(d2d3„ ZGe? A¡ eG d4d5„ d5e?ƒƒƒZHe? A¡ eG d6d7„ d7e?ƒƒƒZId8d9„ ZJeJZKd=d;d<„ZLeLZMdS )>zmComposing task work-flows.

.. seealso:

    You should import these from :mod:`celery` and not this module.
é    )Úabsolute_importÚunicode_literalsN)Údeque)Údeepcopy)Úpartial)Úreduce)Ú
itemgetter)ÚfxrangeÚreprcall)Úcached_property)Úuuid)Úbarrier)Úcurrent_app)ÚPY3Úpython_2_unicode_compatible)Ú
try_import)ÚGroupResultÚallow_join_result)Úabstract©ÚChainMap)Ú_regen)Úchunks)Úis_listÚ
maybe_listÚregenÚseq_concat_itemÚseq_concat_seq)Úgetitem_property)Úremove_repeating_from_taskÚtruncate)ÚMutableSequence)	Ú	SignatureÚchainÚxmapÚxstarmapr   ÚgroupÚchordÚ	signatureÚmaybe_signatureÚ
simplejsonc                 C   s„   zt | jƒ}W n/ ty6   z| j ¡ }W n ttfy$   |  Y  Y S w |dkr2t| jƒd  Y S |  Y S w |dkr@| jd S | S )z"Unroll group with only one member.é   r   )ÚlenÚtasksÚ	TypeErrorÚ__length_hint__ÚAttributeErrorÚlist)r&   Úsize© r3   úJ/var/www/html/myproject/venv/lib/python3.10/site-packages/celery/canvas.pyÚmaybe_unroll_group3   s   ÿ"úr5   c                 C   s   t | d| ƒS )NÚname)Úgetattr©Útaskr3   r3   r4   Útask_name_fromC   ó   r:   c                 C   s   |j |  d¡d� |S )z?Used by custom signatures in .from_dict, to keep common fields.Ú
chord_size)r<   )ÚupdateÚget)ÚfieldsÚsigr3   r3   r4   Ú_upgradeG   s   rA   c                       sÞ  e Zd ZdZi Zd ZZed\dd„ƒZed\dd„ƒZ				d]‡ fdd	„	Z
d
d„ Zdd„ Zd^dd„Zd_dd„Zd`dd„Zd^dd„ZeZ		dadd„ZeZd_dd„Zd\dd„Zdd„ Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Zd.d/„ Zd0d1„ Z d2d3„ Z!d4d5„ Z"d6d7„ Z#d8d9„ Z$d:d;„ Z%e&r›d<d=„ Z'e(d>d?„ ƒZ)e*d@dA„ ƒZ+e*dBdC„ ƒZ,e*dDdE„ ƒZ-e*dFdG„ ƒZ.e/dHdIƒZ0e/dJdKƒZ1e/dLdMƒZ2e/dNdOƒZ3e/dPdQƒZ4e/dRdSƒZ5e/dTdUƒZ6e/dVdWƒZ7e/dXdYƒZ8e/dZd[ƒZ9‡  Z:S )br"   a.  Task Signature.

    Class that wraps the arguments and execution options
    for a single task invocation.

    Used as the parts in a :class:`group` and other constructs,
    or to pass tasks around as callbacks while being compatible
    with serializers with a strict type subset.

    Signatures can also be created from tasks:

    - Using the ``.signature()`` method that has the same signature
      as ``Task.apply_async``:

        .. code-block:: pycon

            >>> add.signature(args=(1,), kwargs={'kw': 2}, options={})

    - or the ``.s()`` shortcut that works for star arguments:

        .. code-block:: pycon

            >>> add.s(1, kw=2)

    - the ``.s()`` shortcut does not allow you to specify execution options
      but there's a chaning `.set` method that returns the signature:

        .. code-block:: pycon

            >>> add.s(2, 2).set(countdown=10).set(expires=30).delay()

    Note:
        You should use :func:`~celery.signature` to create new signatures.
        The ``Signature`` class is the type returned by that function and
        should be used for ``isinstance`` checks for signatures.

    See Also:
        :ref:`guide-canvas` for the complete guide.

    Arguments:
        task (Union[Type[celery.app.task.Task], str]): Either a task
            class/instance, or the name of a task.
        args (Tuple): Positional arguments to apply.
        kwargs (Dict): Keyword arguments to apply.
        options (Dict): Additional options to :meth:`Task.apply_async`.

    Note:
        If the first argument is a :class:`dict`, the other
        arguments will be ignored and the values in the dict will be used
        instead::

            >>> s = signature('tasks.add', args=(2, 2))
            >>> signature(s)
            {'task': 'tasks.add', args=(2, 2), kwargs={}, options={}}
    Nc                    s   ‡ ‡fdd„}|S )Nc                    s   | ˆ j ˆp| j< | S ©N)ÚTYPESÚ__name__)Úsubclass©Úclsr6   r3   r4   Ú_inner�   s   z'Signature.register_type.<locals>._innerr3   )rG   r6   rH   r3   rF   r4   Úregister_type‹   s   zSignature.register_typec                 C   s:   |  d¡}|r| j| }|| ur|j||d�S t||d�S )NÚsubtask_type©Úapp)r>   rC   Ú	from_dictr"   )rG   ÚdrL   ÚtypÚ
target_clsr3   r3   r4   rM   “   s   

zSignature.from_dictFc	              	      sŠ   || _ t|tƒrtt| ƒ |¡ d S z|j}
W n ty"   |}
Y nw || _tt| ƒj|
t	|p0dƒ|p4i t|p8i fi |	¤Ž||d d� d S )Nr3   )r9   ÚargsÚkwargsÚoptionsrJ   Ú	immutabler<   )
Ú_appÚ
isinstanceÚdictÚsuperr"   Ú__init__r6   r0   Ú_typeÚtuple)Úselfr9   rQ   rR   rS   ÚtyperJ   rT   rL   ÚexÚ	task_name©Ú	__class__r3   r4   rY   œ   s"   

ÿ

úzSignature.__init__c                 O   s$   |   ||d¡\}}}| j|i |¤ŽS )z0Call the task directly (in the current process).N)Ú_merger]   )r\   Úpartial_argsÚpartial_kwargsrQ   rR   Ú_r3   r3   r4   Ú__call__µ   s   zSignature.__call__c                 O   s   |   ||¡S )z5Shortcut to :meth:`apply_async` using star arguments.©Úapply_async)r\   rc   rd   r3   r3   r4   Údelayº   ó   zSignature.delayc                 K   sT   |r|nd}|r
|ni }dd„ |  ¡ D ƒ}|  |||¡\}}}| jj||fi |¤ŽS )zˆCall task locally.

        Same as :meth:`apply_async` but executed the task inline instead
        of sending a task message.
        r3   c                 S   ó   i | ]\}}|d ur||“qS rB   r3   ©Ú.0ÚkÚvr3   r3   r4   Ú
<dictcomp>Ç   ó    z#Signature.apply.<locals>.<dictcomp>)Úitemsrb   r]   Úapply)r\   rQ   rR   rS   r3   r3   r4   rs   ¾   s
   zSignature.applyc                 K   s”   |r|nd}|r
|ni }dd„ |  ¡ D ƒ}z| j}W n
 ty$   Y dS w |s+|s+|r6|  |||¡\}}}n| j| j| j}}}|||fi |¤ŽS )aß  Apply this task asynchronously.

        Arguments:
            args (Tuple): Partial args to be prepended to the existing args.
            kwargs (Dict): Partial kwargs to be merged with existing kwargs.
            options (Dict): Partial options to be merged
                with existing options.

        Returns:
            ~@AsyncResult: promise of future evaluation.

        See also:
            :meth:`~@Task.apply_async` and the :ref:`guide-calling` guide.
        r3   c                 S   rk   rB   r3   rl   r3   r3   r4   rp   Þ   rq   z)Signature.apply_async.<locals>.<dictcomp>N)rr   Ú_apply_asyncÚ
IndexErrorrb   rQ   rR   rS   )r\   rQ   rR   Ú
route_namerS   Ú_applyr3   r3   r4   rh   Ì   s   
þzSignature.apply_asyncc                 C   sª   |r|nd}|r
|ni }|r|ni }| j r+|s+| j| j|r't| jfi |¤ŽfS | jfS |r6t|ƒt| jƒ n| j|rCt| jfi |¤Žn| j|rQt| jfi |¤ŽfS | jfS ©Nr3   )rT   rQ   rR   rW   rS   r[   )r\   rQ   rR   rS   Úforcer3   r3   r4   rb   í   s$   
ÿÿÿþþþzSignature._mergec              	   K   sŒ   |r|nd}|r
|ni }|s|s|r|   |||¡\}}}n| j| j| j}}}tj| jt|ƒ|t|ƒ| j	| j
| jdœ| jd�}| j|_|S )a7  Create a copy of this signature.

        Arguments:
            args (Tuple): Partial args to be prepended to the existing args.
            kwargs (Dict): Partial kwargs to be merged with existing kwargs.
            options (Dict): Partial options to be merged with
                existing options.
        r3   )r9   rQ   rR   rS   rJ   r<   rT   rK   )rb   rQ   rR   rS   r"   rM   r9   r[   r   rJ   r<   rT   rU   rZ   )r\   rQ   rR   Úoptsr(   r3   r3   r4   Úcloneù   s"   	úùzSignature.clonec                 C   s†   | j }z|d }W n ty   |ptƒ  }|d< Y nw |r"||d< |r(||d< d|vr2| jj|d< |r8||d< |r>||d< |  |¡S )a6  Finalize the signature by adding a concrete task id.

        The task won't be called and you shouldn't call the signature
        twice after freezing it as that'll result in two task messages
        using the same task id.

        Returns:
            ~@AsyncResult: promise of future evaluation.
        Útask_idÚroot_idÚ	parent_idÚreply_toÚgroup_idr'   )rS   ÚKeyErrorr   rL   ÚoidÚAsyncResult)r\   Ú_idr€   r'   r}   r~   rz   Útidr3   r3   r4   Úfreeze  s"   ÿ
zSignature.freezec                 C   s6   |   ¡ }|dur||_|dur||_|dur||_|S )z£Replace the args, kwargs or options set for this signature.

        These are only replaced if the argument for the section is
        not :const:`None`.
        N)r{   rQ   rR   rS   )r\   rQ   rR   rS   r(   r3   r3   r4   Úreplace8  s   zSignature.replacec                 K   s"   |dur	|   |¡ | j |¡ | S )uÅ   Set arbitrary execution options (same as ``.options.update(â€¦)``).

        Returns:
            Signature: This is a chaining method call
                (i.e., it will return ``self``).
        N)Úset_immutablerS   r=   )r\   rT   rS   r3   r3   r4   ÚsetG  s   
zSignature.setc                 C   s
   || _ d S rB   ©rT   )r\   rT   r3   r3   r4   rˆ   S  ó   
zSignature.set_immutablec                 C   s,   | j  |g ¡}t|tƒs|g }| j |< |S rB   )rS   Ú
setdefaultrV   r!   )r\   Úkeyrr   r3   r3   r4   Ú_with_list_optionV  s   
zSignature._with_list_optionc                 C   s    |   |¡}||vr| |¡ |S rB   )rŽ   Úappend©r\   r�   Úvaluerr   r3   r3   r4   Úappend_to_list_option\  s   

zSignature.append_to_list_optionc                 C   s   |   |¡}| t|ƒ¡ d S rB   )rŽ   Úextendr   r�   r3   r3   r4   Úextend_list_optionb  s   
zSignature.extend_list_optionc                 C   ó   |   d|¡S )zÁAdd callback task to be applied if this task succeeds.

        Returns:
            Signature: the argument passed, for chaining
                or use with :func:`~functools.reduce`.
        Úlink©r’   ©r\   Úcallbackr3   r3   r4   r–   f  ó   zSignature.linkc                 C   r•   )zÆAdd callback task to be applied on error in task execution.

        Returns:
            Signature: the argument passed, for chaining
                or use with :func:`~functools.reduce`.
        Ú
link_errorr—   ©r\   Úerrbackr3   r3   r4   r›   o  rš   zSignature.link_errorc                 C   s   |   |¡ | S )a2  Version of :meth:`link_error` that supports chaining.

        on_error chains the original signature, not the errback so::

            >>> add.s(2, 2).on_error(errback.s()).delay()

        calls the ``add`` task, not the ``errback`` task, but the
        reverse is true for :meth:`link_error`.
        )r›   rœ   r3   r3   r4   Úon_errorx  s   

zSignature.on_errorc                 C   s6   t tj t | ggdd„ t| j d¡ƒpg D ƒ¡¡ƒS )zhReturn a recursive list of dependencies.

        "unchain" if you will, but with links intact.
        c                 s   s   � | ]}|  ¡ V  qd S rB   )Úflatten_links)rm   r–   r3   r3   r4   Ú	<genexpr>Œ  s   € ÿz*Signature.flatten_links.<locals>.<genexpr>r–   )r1   Ú	itertoolsr#   Úfrom_iterabler   rS   r>   ©r\   r3   r3   r4   rŸ   …  s   ÿþzSignature.flatten_linksc                 C   s˜  t | tƒrt| || jd�S t |tƒr5t|ƒ}t | tƒr-|  ¡ }|s#|S tt||ƒ| jd�S t| || jd�S t | tƒsLt |tƒrLtt	| f| ¡ ƒ| jd�S t |tƒr_tt	|  ¡ | ¡ ƒ| jd�S t | tƒrp|  
¡ }|j|B |_|S t |tƒrÊt | tƒrÂ| jr™t | jd tƒr™|  
¡ }t|jd || jd�|jd< |S | jr¶t | jd tƒr¶|  
¡ }|jd j|B |jd _|S tt|  ¡ |ƒ| jd�S t| || jd�S tS )N)ÚbodyrL   rK   éÿÿÿÿ)rV   r&   r'   rU   r5   Ú_chainÚunchain_tasksr   rL   r   r{   r¤   r"   r-   ÚNotImplemented)r\   Úotherr-   r@   r3   r3   r4   Ú__or__�  sb   


ÿÿ
ÿÿ
ÿÿ


ÿÿÿzSignature.__or__c                 C   sŠ   | j }|j}| j d¡ptƒ }| d ¡�'}|j ||¡}|jj	|d| j
dd|i|¤Ž|jd� | |¡W  d   ƒ S 1 s>w   Y  d S )Nr|   r9   )Ú
connectionr3   )r]   rL   rS   r>   r   Úproducer_or_acquireÚbackendÚon_task_callÚcontrolÚelectionr{   r«   rƒ   )r\   r]   rL   r…   ÚproducerÚpropsr3   r3   r4   r°   Æ  s   
þ$ûzSignature.electionc                 O   s(   | j ||i dd�\}}}t| d ||ƒS )NT)ry   r9   )rb   r
   )r\   rQ   rR   re   r3   r3   r4   r
   Ò  s   zSignature.reprcallc                 C   s   | |t | ƒ< t| ƒS rB   )ÚidrW   )r\   Úmemor3   r3   r4   Ú__deepcopy__Ö  s   zSignature.__deepcopy__c                 C   s   |   ¡  ¡ S rB   )rh   r>   r£   r3   r3   r4   Ú
__invert__Ú  r;   zSignature.__invert__c                 C   s   t t| ƒffS rB   )r(   rW   r£   r3   r3   r4   Ú
__reduce__Ý  s   zSignature.__reduce__c                 C   s   t | ƒS rB   )rW   r£   r3   r3   r4   Ú__json__â  ó   zSignature.__json__c                 C   s   |   ¡ S rB   )r
   r£   r3   r3   r4   Ú__repr__å  r¹   zSignature.__repr__c                 c   s6   � t  | ¡D ]\}}t|tƒr| ¡ n||fV  qd S rB   )rW   rr   rV   ÚbytesÚdecode)r\   rn   ro   r3   r3   r4   rr   é  s   €ÿzSignature.itemsc                 C   s   | j S rB   r8   r£   r3   r3   r4   r6   í  s   zSignature.namec                 C   s   | j p
| jj| d  S ©Nr9   )rZ   rL   r-   r£   r3   r3   r4   r]   ò  s   zSignature.typec                 C   s
   | j ptS rB   )rU   r   r£   r3   r3   r4   rL   ö  s   
zSignature.appc                 C   s&   z| j jW S  ty   | jj Y S w rB   )r]   rƒ   r�   rL   r£   r3   r3   r4   rƒ   ú  s
   
ÿzSignature.AsyncResultc                 C   s0   z| j jW S  ty   t| jj| d ƒ Y S w r½   )r]   rh   r�   Ú_partialrL   Ú	send_taskr£   r3   r3   r4   rt     s
   
ÿzSignature._apply_asynczoptions.task_idz	Task UUIDzoptions.parent_idzTask parent UUID.zoptions.root_idzTask root UUID.r9   zName of task.rQ   zPositional arguments to task.rR   zKeyword arguments to task.rS   zTask execution options.rJ   zType of signaturer<   zSize of chord (if applicable)rT   z+Flag set if no longer accepts new argumentsrB   )NNNNNNFN©NN)NNN)NNNF©NNNNN);rD   Ú
__module__Ú__qualname__Ú__doc__rC   rU   rZ   ÚclassmethodrI   rM   rY   rf   ri   rs   rh   rb   r{   r   r†   Ú_freezer‡   r‰   rˆ   rŽ   r’   r”   r–   r›   rž   rŸ   rª   r°   r
   rµ   r¶   r·   r¸   rº   ÚJSON_NEEDS_UNICODE_KEYSrr   Úpropertyr6   r   r]   rL   rƒ   rt   r   r³   r~   r}   r9   rQ   rR   rS   rJ   r<   rT   Ú__classcell__r3   r3   r`   r4   r"   M   s†    8þ


!

ÿ 

		6












ÿÿr"   c                 C   sJ   |r	t dd i| ƒS d| vrt d|i| ƒS |d ur#t d| d | i| ƒS d S )Nr#   r   )rS   r-   Úuse_linkr3   r3   r4   Ú_prepare_chain_from_options  s   )ÿørË   r#   )r6   c                	   @   s¨   e Zd ZeddƒZeddd„ƒZdd„ Zdd	„ Zd
d„ Z	dd„ Z
ddd„Z			ddd„Z		d dd„Zddddddddejf	dd„Zddd„Zedd„ ƒZdd„ ZdS )!r¦   úkwargs.taskszTasks in chain.Nc                    s^   |d d }|r t |tƒrt|ƒ }|d d< ‡ fdd„|D ƒ}t|t|fdˆ i|d ¤ŽƒS )NrR   r-   c                    ó   g | ]}t |ˆ d �‘qS ©rK   )r)   )rm   r9   rK   r3   r4   Ú
<listcomp>Z  ó    z$_chain.from_dict.<locals>.<listcomp>rL   rS   )rV   r[   r1   rA   r¦   )rG   rN   rL   r-   r3   rK   r4   rM   T  s   
z_chain.from_dictc                 O   sb   t |ƒdkrt|d ƒrt|d ƒn|}tj| ddd|ifi |¤Ž | dd ¡| _d| _d | _d S )Nr+   r   zcelery.chainr3   r-   rÊ   r#   )	r,   r   r   r"   rY   ÚpopÚ	_use_linkrJ   Ú_frozen©r\   r-   rS   r3   r3   r4   rY   ]  s   $ÿÿÿ
z_chain.__init__c                 O   s   | j r	|  ||¡S d S rB   )r-   rh   )r\   rQ   rR   r3   r3   r4   rf   g  s   ÿz_chain.__call__c                    s@   t ‰tjˆ g|¢R i |¤Ž}‡ ‡fdd„|jd D ƒ|jd< |S )Nc                    s   g | ]
}ˆ|ˆ j d d�‘qS )T)rL   r{   )rU   )rm   r@   ©r\   Úto_signaturer3   r4   rÏ   n  s    ÿÿz _chain.clone.<locals>.<listcomp>r-   )r)   r"   r{   rR   ©r\   rQ   rR   r(   r3   rÕ   r4   r{   k  s   þz_chain.clonec                 C   s<   dd„ | j D ƒ}| j dg ¡D ]}|D ]}| |¡ qq|S )Nc                 S   s   g | ]}|  ¡ ‘qS r3   ©r{   ©rm   Útr3   r3   r4   rÏ   w  s    z(_chain.unchain_tasks.<locals>.<listcomp>r›   )r-   rS   r>   r›   )r\   r-   r@   r9   r3   r3   r4   r§   t  s   ÿz_chain.unchain_tasksc                 K   s”   |r|nd}|r
|ng }| j }|jjr0tƒ � | j||fi |¤ŽW  d   ƒ S 1 s+w   Y  | j||fd|i|rEt| jfi |¤Ž¤ŽS | j¤ŽS )Nr3   rL   )rL   ÚconfÚtask_always_eagerr   rs   ÚrunrW   rS   )r\   rQ   rR   rS   rL   r3   r3   r4   rh   }  s    ÿÿÿz_chain.apply_asyncc                 K   sÌ   |r|nd}|r
|ng }|p| j }| j}|d u r |jjdkr d}|r.| js.t|ƒt| jƒ n| j}|  ||| j|
||||||¡
\}}|rd|rN|d  	d|¡ | 
¡ }t|||ƒ}|jdi |¤Ž |d S d S )Nr3   r+   Tr   r–   )rL   rÒ   rÛ   Útask_protocolrT   r[   rQ   Úprepare_stepsr-   r”   rÑ   rË   rh   )r\   rQ   rR   r€   r'   r|   r–   r›   Ú	publisherr±   r}   r~   rL   rS   rÊ   r-   ÚresultsÚ
first_taskr3   r3   r4   rÝ   ˆ  s0   
ÿÿÿþùz
_chain.runc                 C   s:   | j | j| j| j||d | j|||dd� \}}| _|d S )NFrØ   r   )rß   rQ   rR   r-   rL   rÓ   )r\   r„   r€   r'   r}   r~   re   rá   r3   r3   r4   r†   ¤  s
   þz_chain.freezeTc              	   C   sþ  |p| j }| j}|d u r|jjdkrd}t|ƒ}|j}|j}d }d }g g }}d}|rû|ƒ }| | }}t|tj	ƒsA|||d�}t|t
ƒrJt|ƒ}|rZ|rU| ||¡}n| ¡ }n|rft|ƒt|jƒ |_t|tƒrq||jƒ q)t|t
ƒrž|rž| ¡  | ¡  zt|||j||d�}W n ty�   t||||d�}Y nw |rª|j|||	|
d�}n|j|d�}|d7 }|rÅ|r½| |¡ |rÅ|jsÅ||_|rÓt|ƒD ]}| |¡ qË| |¡ | |¡ ||}}t|tƒrù|j ¡  |}|jr÷|j}|jsñ|}|s+||fS )	Nr+   Tr   rK   )r¤   r|   r}   rL   )r¤   r}   rL   )r}   r€   r'   ©r}   )rL   rÒ   rÛ   rÞ   r   rÑ   r“   rV   r   ÚCallableSignaturer&   r5   r{   r[   rQ   r¦   r-   r'   r|   r0   r†   r–   Úparentr   r›   r�   r­   Úensure_chords_allowed)r\   rQ   rR   r-   r}   r~   r›   rL   Úlast_task_idr€   Ú
chord_bodyr{   rM   rÊ   ÚstepsÚ	steps_popÚsteps_extendÚ	prev_taskÚprev_resrá   Úir9   Úis_first_taskÚis_last_taskÚresr�   Únoder3   r3   r4   rß   ®  sˆ   






þ
þû
þ






ÿªWz_chain.prepare_stepsc           	      K   s‚   |r|nd}|r
|ni }d ||f}\}}| j D ]&}| ||¡j|o&| ¡ ffi t| jfi |¤Ž¤Ž}||d|_}\}}q|S )Nr3   rÀ   )r-   r{   rs   r>   rW   rS   rå   )	r\   rQ   rR   rS   ÚlastÚfargsÚfkwargsr9   rñ   r3   r3   r4   rs   "  s   
ÿÿz_chain.applyc                 C   s:   | j }|d u rz| jd j }W n	 ty   Y nw |ptS ©Nr   )rU   r-   ÚLookupErrorr   ©r\   rL   r3   r3   r4   rL   ,  s   ÿz
_chain.appc                 C   sB   | j sd t| ƒjt| ƒ¡S t| j d d d dd„ | j D ƒ¡ƒS )Nz<{0}@{1:#x}: empty>r   r9   z | c                 s   s   � | ]}t |ƒV  qd S rB   )ÚreprrÙ   r3   r3   r4   r    <  s   € z"_chain.__repr__.<locals>.<genexpr>)r-   Úformatr]   rD   r³   r   Újoinr£   r3   r3   r4   rº   6  s   ÿþz_chain.__repr__rB   rÀ   )NNNNNNNNNNNNrÁ   )rD   rÂ   rÃ   r   r-   rÅ   rM   rY   rf   r{   r§   rh   rÝ   r†   r"   rß   rs   rÈ   rL   rº   r3   r3   r3   r4   r¦   O  s0    

	
	
þ
ÿ
ý
t

	r¦   c                       s    e Zd ZdZ‡ fdd„Z‡  ZS )r#   a  Chain tasks together.

    Each tasks follows one another,
    by being applied as a callback of the previous task.

    Note:
        If called with only one argument, then that argument must
        be an iterable of tasks to chain: this allows us
        to use generator expressions.

    Example:
        This is effectively :math:`((2 + 2) + 4)`:

        .. code-block:: pycon

            >>> res = chain(add.s(2, 2), add.s(4))()
            >>> res.get()
            8

        Calling a chain will return the result of the last task in the chain.
        You can get to the other tasks by following the ``result.parent``'s:

        .. code-block:: pycon

            >>> res.parent.get()
            4

        Using a generator expression:

        .. code-block:: pycon

            >>> lazy_chain = chain(add.s(i) for i in range(10))
            >>> res = lazy_chain(3)

    Arguments:
        *tasks (Signature): List of task signatures to chain.
            If only one argument is passed and that argument is
            an iterable, then that'll be used as the list of signatures
            to chain instead.  This means that you can use a generator
            expression.

    Returns:
        ~celery.chain: A lazy signature that can be called to apply the first
            task in the chain.  When that task succeeds the next task in the
            chain is applied, and so on.
    c                    sf   |s$|r$t |ƒdkst|d ƒr$t |ƒdkr|d n|}ttj|tƒ ƒS tt| ƒj| g|¢R i |¤ŽS )Nr+   r   )r,   r   r   ÚoperatorÚor_r#   rX   Ú__new__)rG   r-   rR   r`   r3   r4   rþ   p  s
   zchain.__new__)rD   rÂ   rÃ   rÄ   rþ   rÉ   r3   r3   r`   r4   r#   ?  s    0c                   @   s:   e Zd ZdZeddƒZed
dd„ƒZdd„ Zddd	„Z	dS )Ú_basemapNr9   Úitc                 C   s&   t || |  |d ¡d|i|d ¤ŽƒS ©NrR   rL   rS   )rA   Ú_unpack_args©rG   rN   rL   r3   r3   r4   rM     ó    ÿz_basemap.from_dictc                 K   s,   t j| | jd|t|ƒdœfddi|¤Ž d S )Nr3   ©r9   r   rT   T)r"   rY   Ú
_task_namer   )r\   r9   r   rS   r3   r3   r4   rY   …  s   þþ
þz_basemap.__init__c                 K   sX   |r|nd}|r
|ni }|   | j¡\}}| jjd|t|ƒdœfdt| j d¡ƒi|¤ŽS )Nr3   r  rv   r9   )r  rR   r]   rh   r1   r:   r>   )r\   rQ   rR   rz   r9   r   r3   r3   r4   rh   ‹  s   ÿþþz_basemap.apply_asyncrB   rÀ   )
rD   rÂ   rÃ   r  r   r  rÅ   rM   rY   rh   r3   r3   r3   r4   rÿ   {  s    
rÿ   c                   @   ó   e Zd ZdZdZdd„ ZdS )r$   z–Map operation for tasks.

    Note:
        Tasks executed sequentially in process, this is not a
        parallel operation like :class:`group`.
    z
celery.mapc                 C   ó(   |   | j¡\}}d |jtt|ƒdƒ¡S )Nz[{0}(x) for x in {1}]éd   ©r  rR   rú   r9   r    rù   ©r\   r9   r   r3   r3   r4   rº   ¢  ó   ÿzxmap.__repr__N©rD   rÂ   rÃ   rÄ   r  rº   r3   r3   r3   r4   r$   –  s    r$   c                   @   r  )r%   z.Map operation for tasks, using star arguments.zcelery.starmapc                 C   r  )Nz[{0}(*x) for x in {1}]r	  r
  r  r3   r3   r4   rº   ¯  r  zxstarmap.__repr__Nr  r3   r3   r3   r4   r%   ¨  s    r%   c                   @   sZ   e Zd ZdZedddƒZeddd„ƒZdd	„ Zd
d„ Z	ddd„Z
dd„ Zeddd„ƒZdS )r   z)Partition of tasks into chunks of size n.r9   r   ÚnNc                 C   s&   t |t|  |d ¡d|i|d ¤ŽƒS r  )rA   r   r  r  r3   r3   r4   rM   »  s   ÿÿÿÿzchunks.from_dictc                 K   s,   t j| dd|t|ƒ|dœfddi|¤Ž d S )Nzcelery.chunksr3   )r9   r   r  rT   T)r"   rY   r   )r\   r9   r   r  rS   r3   r3   r4   rY   Â  s   þý
ýzchunks.__init__c                 K   s   | j di |¤ŽS rx   rg   )r\   rS   r3   r3   r4   rf   É  s   zchunks.__call__c                 K   s@   |r|nd}|r
|ni }|   ¡ j||fdt| j d¡ƒi|¤ŽS )Nr3   rv   r9   )r&   rh   r:   rR   r>   )r\   rQ   rR   rz   r3   r3   r4   rh   Ì  s   ÿþþzchunks.apply_asyncc                    s:   ˆ   ˆ j¡\‰}}t‡ ‡fdd„tt|ƒ|ƒD ƒˆ jd�S )Nc                 3   s    � | ]}t ˆ|ˆ jd �V  qdS )rK   N)r%   rU   )rm   Úpart©r\   r9   r3   r4   r    ×  s   € ÿzchunks.group.<locals>.<genexpr>rK   )r  rR   r&   Ú_chunksÚiterrU   )r\   r   r  r3   r  r4   r&   Ô  s   ÿþzchunks.groupc                 C   s   | ||||d�ƒ S )NrK   r3   )rG   r9   r   r  rL   r3   r3   r4   Úapply_chunksÛ  s   zchunks.apply_chunksrB   rÀ   )rD   rÂ   rÃ   rÄ   r   r  rÅ   rM   rY   rf   rh   r&   r  r3   r3   r3   r4   r   µ  s    
r   c                    sZ   t | tƒrt| ˆ d�} t | ttfƒr| j} | S t | tjƒr"| g} | S ‡ fdd„| D ƒ} | S )NrK   c                    rÍ   rÎ   )r(   rÙ   rK   r3   r4   rÏ   é  rÐ   z _maybe_group.<locals>.<listcomp>)rV   rW   r(   r&   r¦   r-   r   rä   )r-   rL   r3   rK   r4   Ú_maybe_groupà  s   
üÿr  c                   @   sÖ   e Zd ZdZeddƒZed)dd„ƒZdd„ Zd	d
„ Z	d*dd„Z
		d+dd„Zd,dd„Zdd„ Zdd„ Zdd„ Zejejeefdd„Z			d-dd„Zdd„ Z		d.dd „ZeZd!d"„ Zd#d$„ Zd%d&„ Zed'd(„ ƒZdS )/r&   aq  Creates a group of tasks to be executed in parallel.

    A group is lazy so you must call it to take action and evaluate
    the group.

    Note:
        If only one argument is passed, and that argument is an iterable
        then that'll be used as the list of tasks instead: this
        allows us to use ``group`` with generator expressions.

    Example:
        >>> lazy_group = group([add.s(2, 2), add.s(4, 4)])
        >>> promise = lazy_group()  # <-- evaluate: returns lazy result.
        >>> promise.get()  # <-- will wait for the task to return
        [4, 8]

    Arguments:
        *tasks (List[Signature]): A list of signatures that this group will
            call. If there's only one argument, and that argument is an
            iterable, then that'll define the list of signatures instead.
        **options (Any): Execution options applied to all tasks
            in the group.

    Returns:
        ~celery.group: signature that when called will then call all of the
            tasks in the group (and return a :class:`GroupResult` instance
            that can be used to inspect the state of the group).
    rÌ   zTasks in group.Nc                 C   s&   t |t|d d fd|i|d ¤ŽƒS )NrR   r-   rL   rS   )rA   r&   r  r3   r3   r4   rM     r  zgroup.from_dictc                 O   sr   t |ƒdkr&|d }t|tƒr|j}t|tjƒr| ¡ g}t|tƒs&t|ƒ}t	j
| ddd|ifi |¤Ž d| _d S )Nr+   r   zcelery.groupr3   r-   r&   )r,   rV   r&   r-   r   rä   r{   r   r   r"   rY   rJ   rÔ   r3   r3   r4   rY     s   


ÿÿ
zgroup.__init__c                 O   s   | j |fi |¤ŽS rB   rg   )r\   rc   rS   r3   r3   r4   rf   #  s   zgroup.__call__ç      ð?c                 C   s0   t |||dd�}| jD ]
}|jt|ƒd� q| S )NT)Ú
repeatlast)Ú	countdown)r	   r-   r‰   Únext)r\   ÚstartÚstopÚstepr   r9   r3   r3   r4   Úskew&  s   
z
group.skewTc                 K   s   |r|nd}|d urt dƒ‚|d urt dƒ‚| j}|jjr'| j||fi |¤ŽS | js.|  ¡ S |  |¡\}}	}
|  | jg |	|
|¡}t	ƒ }t
| j||||f||dœ|¤Žƒ}| jj|	||d�}| ¡  t|ƒdkrrt|d tƒrr|d }|j}|r~|r~| |¡ |S )Nr3   z%Cannot add link to group: use a chordz5Cannot add link to group: do that on individual tasks©rQ   rR   )Úready_barrierr+   r   )r.   rL   rÛ   rÜ   rs   r-   r†   Ú_freeze_gidÚ	_preparedr   r1   Ú_apply_tasksr   Úfinalizer,   rV   Úcurrent_worker_taskÚ	add_trail)r\   rQ   rR   Úadd_to_parentr±   r–   r›   rS   rL   r€   r}   r-   Úprá   ÚresultÚparent_taskr3   r3   r4   rh   ,  s8   ÿÿÿ
zgroup.apply_asyncc                    sn   ˆ rˆ nd‰ ˆr
ˆni ‰| j }| js|  ¡ S |  ˆ¡\‰}}|  | jg |||¡}| |‡ ‡‡fdd„|D ƒ¡S )Nr3   c                    s&   g | ]\}}|j dˆ ˆd œˆ¤Ž‘qS )r  r3   )rs   )rm   r@   re   ©rQ   rR   rS   r3   r4   rÏ   X  s    ÿzgroup.apply.<locals>.<listcomp>)rL   r-   r†   r  r   r   )r\   rQ   rR   rS   rL   r€   r}   r-   r3   r)  r4   rs   P  s   ÿzgroup.applyc                 C   ó   | j D ]}| |¡ qd S rB   ©r-   rˆ   ©r\   rT   r9   r3   r3   r4   rˆ   \  s   
ÿzgroup.set_immutablec                 C   s    |  ¡ jdd�}| jd  |¡S )NTrŠ   r   )r{   r‰   r-   r–   ©r\   r@   r3   r3   r4   r–   `  s   z
group.linkc                 C   sJ   z
|  ¡ jdd�}W n ty   d|d< t |¡}Y nw | jd  |¡S )NTrŠ   rT   r   )r{   r‰   r0   r"   rM   r-   r›   r-  r3   r3   r4   r›   e  s   üzgroup.link_errorc
                 c   sš   � |D ]G}
||
|ƒr|
  ¡ }
n||
|d�}
||
tƒr1|
 |
j||||¡}|D ]	\}}||fV  q&q|r@|
js@|	|ƒ|	|
jƒ |
_|
|
j||d�fV  qd S )NrK   )r€   r}   )r{   r&   r   r-   rT   rQ   r†   )r\   r-   rc   r€   r}   rL   rä   rM   rV   r[   r9   ÚunrollÚtaskNÚresNr3   r3   r4   r   o  s    €


ÿÿ
îzgroup._preparedc	              
   k   s¤   � |p| j }| |¡�=}|D ]1\}
}|
jd|d|
j d¡p|||dœ|	¤Ž |r<|js<|js<| jd7  _|j|dd� |V  qW d   ƒ d S 1 sKw   Y  d S )NFr'   )r±   r%  r'   rQ   rR   r+   T)Úweakr3   )	rL   r¬   rh   rS   r>   Ú	cancelledÚreadyr2   Úthen)r\   r-   r±   rL   r&  r%  r'   rQ   rR   rS   r@   rñ   r3   r3   r4   r!  ‡  s    €

þýñ"ÿzgroup._apply_tasksc                 C   s8   t | jfi |¤Ž}| dtƒ ¡ |d< }||| d¡fS )Nr|   r€   r}   )rW   rS   rÑ   r   r>   )r\   rS   r€   r3   r3   r4   r  Ÿ  s   
ÿzgroup._freeze_gidc           
      C   s²   | j }z|d }W n ty   |ptƒ  }|d< Y nw |r"||d< |r(||d< | d|¡}| d|¡}g }t|  |||||¡ƒ}	t| jtƒrO|| jd d …< n|| _| j	 
||	¡S )Nr|   r€   r'   r}   r~   )rS   r�   r   rŒ   r1   Ú_freeze_unrollrV   r-   r!   rL   r   )
r\   r„   r€   r'   r}   r~   rz   ÚgidÚ	new_tasksrá   r3   r3   r4   r†   §  s(   ÿ
ÿzgroup.freezec                 c   sh   � t | jƒ}|r2t| ¡ | jd� ¡ }t|tƒr| |j¡ n| 	|¡ |j
||||d�V  |sd S d S )NrK   )r€   r'   r}   r~   )r   r-   r)   ÚpopleftrU   r{   rV   r&   Ú
extendleftr�   r†   )r\   r7  r€   r'   r}   r~   Ústackr9   r3   r3   r4   r5  Ä  s   €


þúzgroup._freeze_unrollc                 C   s$   | j rt| j d d d | ¡ƒS dS )Nr   r9   zgroup({0.tasks!r})zgroup(<empty>))r-   r   rú   r£   r3   r3   r4   rº   Ò  s   þzgroup.__repr__c                 C   s
   t | jƒS rB   )r,   r-   r£   r3   r3   r4   Ú__len__Ù  r‹   zgroup.__len__c                 C   sB   | j }|d u rz| jd j}W n	 ty   Y nw |d ur|S tS rö   )rU   r-   rL   r÷   r   rø   r3   r3   r4   rL   Ü  s   ÿz	group.apprB   )r  Nr  )NNTNNNrÀ   )NNNNNNNrÁ   )rD   rÂ   rÃ   rÄ   r   r-   rÅ   rM   rY   rf   r  rh   rs   rˆ   r–   r›   r   rä   r"   rV   r[   r   r!  r  r†   rÆ   r5  rº   r;  rÈ   rL   r3   r3   r3   r4   r&   í  sB    


ÿ
$
ý
þ
ÿr&   c                   @   sä   e Zd ZdZed-dd„ƒZed.dd„ƒZ		d/dd	„Zd-d
d„Z			d0dd„Z
			d1dd„Z		d2dd„Zd-dd„Zdd„ Z			d3dd„Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Zed%d&„ ƒZd-d'd(„Zed)d*ƒZed+d,ƒZdS )4r'   aL  Barrier synchronization primitive.

    A chord consists of a header and a body.

    The header is a group of tasks that must complete before the callback is
    called.  A chord is essentially a callback for a group of tasks.

    The body is applied with the return values of all the header
    tasks as a list.

    Example:

        The chord:

        .. code-block:: pycon

            >>> res = chord([add.s(2, 2), add.s(4, 4)])(sum_task.s())

        is effectively :math:`\Sigma ((2 + 2) + (4 + 4))`:

        .. code-block:: pycon

            >>> res.get()
            12
    Nc                 C   s<   |  ¡ }| jdi |d ¤Ž\}|d< t|| |d|i|¤ŽƒS )NrR   rL   r3   )Úcopyr  rA   )rG   rN   rL   rS   rQ   r3   r3   r4   rM     s   zchord.from_dictc                 K   s   | |f|fS rB   r3   )Úheaderr¤   rR   r3   r3   r4   r  
  s   zchord._unpack_argsúcelery.chordc              
   K   sT   |r|nd}|r
|ni }t j| |||t||ƒt||d�dœfd|i|¤Ž d| _d S )Nr3   rK   )rR   r=  r¤   rL   r'   )r"   rY   r  r)   rJ   )r\   r=  r¤   r9   rQ   rR   rL   rS   r3   r3   r4   rY     s   

ÿþýý
zchord.__init__c                 K   s    | j d|r	d|ini fi |¤ŽS )Nr3   r¤   rg   )r\   r¤   rS   r3   r3   r4   rf     s    zchord.__call__c           
      C   sœ   t | jtƒst| j| jd�| _| jj||| jd�}| jj||||d�}|}tƒ }	|rG|j|	v r3tdƒ‚|	 	|j¡ |j
d u rB||_
n|j
}|s*| jj| _|S )NrK   )r~   r}   r'   )r}   r'   r€   zRecursive result parents)rV   r-   r&   rL   r†   r¤   r‰   r³   ÚRuntimeErrorÚaddrå   )
r\   r„   r€   r'   r}   r~   Úheader_resultÚbody_resultrò   Úseenr3   r3   r4   r†     s*   ÿÿ

ù
zchord.freezec	                 K   s  |r|nd}|r
|ni }|r| j st|ƒt| jƒ n| j}| dd ¡p'| jd }
t| jd fi |¤Ž}|
jdi |	¤Ž}
|  |
¡}t| j	t
ƒrK| j	 ¡ nt
| j	|d�}|jjrvtƒ � | j||f|
|dœ|	¤ŽW  d   ƒ S 1 sqw   Y  | j||
|fd|i|	¤ŽS )Nr3   r¤   rR   rK   )r¤   r|   r|   )rT   r[   rQ   rÑ   rR   rW   r{   Ú_get_apprV   r-   r&   rÛ   rÜ   r   rs   rÝ   )r\   rQ   rR   r|   r±   rà   r«   ÚrouterÚ
result_clsrS   r¤   rL   r-   r3   r3   r4   rh   :  s0   ÿÿÿ
ÿ
ÿÿ ÿzchord.apply_asyncTc                 K   sn   |r|nd}|r
|ni }|d u r| j n|}t| jtƒr | j ¡ nt| j| jd�}|j| ||¡j|d�fd�S )Nr3   rK   )Ú	propagate)rQ   )r¤   rV   r-   r&   r{   rL   rs   r>   )r\   rQ   rR   rG  r¤   rS   r-   r3   r3   r4   rs   N  s   ÿÿzchord.applyc                 c   sz   � t |ƒ}|r;| ¡ }t|tƒr| |j¡ n t|tƒr.t|jd tƒr.| |jd j¡ n	|d u r4|n|V  |sd S d S )Nr¥   )r   r8  rV   r&   r“   r-   r¦   )r\   r-   r‘   r:  r9   r3   r3   r4   Ú_traverse_tasksY  s   €
ùzchord._traverse_tasksc                 C   s*   t | jtƒr
| jjn| j}t|  |d¡ƒS )Nr+   )rV   r-   r&   ÚsumrH  )r\   r-   r3   r3   r4   r/   d  s   ÿzchord.__length_hint__r+   Fc
                 K   sú   |p|   |¡}|j d¡ptƒ }|j d¡}|  ¡ |_|
r&t| jfi |
¤Žn| j}
|
r7|
 dd ¡ |j |
¡ |j	|	|d�}|
 dd ¡ |
 dd ¡ |
 dd ¡ |j	|||d�}t
|ƒdkrs|jj|||||d� ||d|i|
¤Ž}n| g ¡ ||_|S )	Nr|   r}   rã   r#   r'   )r€   r'   r}   r   )Úintervalr  Úmax_retries)rD  rS   r>   r   r/   r<   rW   rÑ   r=   r†   r,   r­   Úapply_chordri   rå   )r\   r=  r¤   rc   rL   rJ  r  rK  Úeagerr|   rS   r€   r}   ÚbodyresrA  r3   r3   r4   rÝ   i  s2   
û
z	chord.runc              	   O   sP   t j| g|¢R i |¤Ž}zt|jd dd�|jd< W |S  ttfy'   Y |S w )Nr¤   TrØ   )r"   r{   r)   rR   r0   r�   r×   r3   r3   r4   r{   ‘  s   
ÿþþzchord.clonec                 C   ó   | j  |¡ |S rB   )r¤   r–   r˜   r3   r3   r4   r–   ›  ó   z
chord.linkc                 C   rO  rB   )r¤   r›   rœ   r3   r3   r4   r›   Ÿ  rP  zchord.link_errorc                 C   r*  rB   r+  r,  r3   r3   r4   rˆ   £  s   
ÿzchord.set_immutablec              	   C   s~   | j r:t| j tƒr+t| j jd d d | j jd  | j¡t| j jdd … | jd�¡ƒS dt| j d | j  | j¡ƒ S d | ¡S )Nr   r9   z%({0} | {1!r})r+   rK   ú%z!<chord without body: {0.tasks!r}>)	r¤   rV   r¦   r   r-   rú   r
   r#   rU   r£   r3   r3   r4   rº   ¨  s   þþÿ
zchord.__repr__c                 C   s   |   | j¡S rB   )rD  r¤   r£   r3   r3   r4   rL   ¶  rj   z	chord.appc                 C   sl   | j }|d u r.z| jj}W n ty   | j}Y nw t|ƒr#|d j }|d u r.|d ur.|j }|d ur4|S tS rö   )rU   r-   r0   r,   r   )r\   r¤   rL   r-   r3   r3   r4   rD  º  s   
ÿ
zchord._get_appzkwargs.headerzTasks in chord header.zkwargs.bodyzBody task of chord.rB   rÀ   )Nr>  NNNrÁ   )NNNNNNNN)NNTN)NNr+   NFN)rD   rÂ   rÃ   rÄ   rÅ   rM   Ústaticmethodr  rY   rf   r†   rh   rs   rH  r/   rÝ   r{   r–   r›   rˆ   rº   r   rL   rD  r   r-   r¤   r3   r3   r3   r4   r'   ç  sH    
ÿ

ÿ
þ
ÿ

þ(



r'   c                 O   sL   |  d¡}t| tƒrt| tjƒr|  ¡ S tj| |d�S t| g|¢R i |¤ŽS )zçCreate new signature.

    - if the first argument is a signature already then it's cloned.
    - if the first argument is a dict, then a Signature version is returned.

    Returns:
        Signature: The resulting signature.
    rL   rK   )r>   rV   rW   r   rä   r{   r"   rM   )ÚvariesrQ   rR   rL   r3   r3   r4   r(   Ë  s   
	
r(   Fc                 C   sF   | dur!t | tjƒr|r|  ¡ } n	t | tƒrt| ƒ} |dur!|| _| S )a¯  Ensure obj is a signature, or None.

    Arguments:
        d (Optional[Union[abstract.CallableSignature, Mapping]]):
            Signature or dict-serialized signature.
        app (celery.Celery):
            App to bind signature to.
        clone (bool):
            If d' is already a signature, the signature
           will be cloned when this flag is enabled.

    Returns:
        Optional[abstract.CallableSignature]
    N)rV   r   rä   r{   rW   r(   rU   )rN   rL   r{   r3   r3   r4   r)   ß  s   €
r)   )NF)NrÄ   Ú
__future__r   r   r¡   rü   Úcollectionsr   r<  r   Ú	functoolsr   r¾   r   r   Úkombu.utils.functionalr	   r
   Úkombu.utils.objectsr   Úkombu.utils.uuidr   Úviner   Úcelery._stater   Úcelery.fiver   r   Úcelery.localr   Úcelery.resultr   r   Úcelery.utilsr   Úcelery.utils.collectionsr   Úcelery.utils.functionalr   r   r  r   r   r   r   r   Úcelery.utils.objectsr   Úcelery.utils.textr   r    Úcollections.abcr!   ÚImportErrorÚ__all__rÇ   r5   r:   rA   rä   ÚregisterrW   r"   rË   rI   r¦   r#   rÿ   r$   r%   r  r&   r'   r(   Úsubtaskr)   Úmaybe_subtaskr3   r3   r3   r4   Ú<module>   sˆ   þ   J
9 o<* y c
