o
    wvXjá  ã                   @   sb   d Z ddlmZmZ ddlmZ dZG dd„ deƒZddd	„Z	G d
d„ deƒZ
G dd„ deƒZdS )z7Object related utilities, including introspection, etc.é    )Úabsolute_importÚunicode_literals)Úreduce)ÚBunchÚFallbackContextÚgetitem_propertyÚ
mro_lookupc                   @   s   e Zd ZdZdd„ ZdS )r   z-Object that enables you to modify attributes.c                 K   s   | j  |¡ d S ©N)Ú__dict__Úupdate)ÚselfÚkwargs© r   úQ/var/www/html/myproject/venv/lib/python3.10/site-packages/celery/utils/objects.pyÚ__init__   s   zBunch.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r   
   s    r   Nc              
   C   sŒ   |st ƒ n|}|sg n|}|  ¡ D ]2}||v r:z
|j| }|j}W n ttfy.   Y  dS w ||vr7|  S  dS ||jv rC|  S qdS )a  Return the first node by MRO order that defines an attribute.

    Arguments:
        cls (Any): Child class to traverse.
        attr (str): Name of attribute to find.
        stop (Set[Any]): A set of types that if reached will stop
            the search.
        monkey_patched (Sequence): Use one of the stop classes
            if the attributes module origin isn't in this list.
            Used to detect monkey patched attributes.

    Returns:
        Any: The attribute value, or :const:`None` if not found.
    N)ÚsetÚmror
   r   ÚAttributeErrorÚKeyError)ÚclsÚattrÚstopÚmonkey_patchedÚnodeÚvalueÚmodule_originr   r   r   r      s$   

û
ÿõr   c                   @   s(   e Zd ZdZdd„ Zdd„ Zdd„ ZdS )	r   a¹  Context workaround.

    The built-in ``@contextmanager`` utility does not work well
    when wrapping other contexts, as the traceback is wrong when
    the wrapped context raises.

    This solves this problem and can be used instead of ``@contextmanager``
    in this example::

        @contextmanager
        def connection_or_default_connection(connection=None):
            if connection:
                # user already has a connection, shouldn't close
                # after use
                yield connection
            else:
                # must've new connection, and also close the connection
                # after the block returns
                with create_new_connection() as connection:
                    yield connection

    This wrapper can be used instead for the above like this::

        def connection_or_default_connection(connection=None):
            return FallbackContext(connection, create_new_connection)
    c                 O   s"   || _ || _|| _|| _d | _d S r	   )ÚprovidedÚfallbackÚfb_argsÚ	fb_kwargsÚ_context)r   r    r!   r"   r#   r   r   r   r   M   s
   
zFallbackContext.__init__c                 C   s2   | j d ur| j S | j| ji | j¤Ž ¡  }| _|S r	   )r    r!   r"   r#   Ú	__enter__r$   )r   Úcontextr   r   r   r%   T   s   
ÿÿþzFallbackContext.__enter__c                 G   s   | j d ur| j j|Ž S d S r	   )r$   Ú__exit__)r   Úexc_infor   r   r   r'   \   s   
ÿzFallbackContext.__exit__N)r   r   r   r   r   r%   r'   r   r   r   r   r   1   s
    r   c                   @   s4   e Zd ZdZddd„Zdd„ Zddd„Zd	d
„ ZdS )r   a–  Attribute -> dict key descriptor.

    The target object must support ``__getitem__``,
    and optionally ``__setitem__``.

    Example:
        >>> from collections import defaultdict

        >>> class Me(dict):
        ...     deep = defaultdict(dict)
        ...
        ...     foo = _getitem_property('foo')
        ...     deep_thing = _getitem_property('deep.thing')


        >>> me = Me()
        >>> me.foo
        None

        >>> me.foo = 10
        >>> me.foo
        10
        >>> me['foo']
        10

        >>> me.deep_thing = 42
        >>> me.deep_thing
        42
        >>> me.deep
        defaultdict(<type 'dict'>, {'thing': 42})
    Nc                 C   s0   |  d¡\}}| _|r| d¡nd | _|| _d S )NÚ.)Ú
rpartitionÚkeyÚsplitÚpathr   )r   ÚkeypathÚdocr-   Ú_r   r   r   r   ‚   s   
zgetitem_property.__init__c                 C   s    | j rtdd„ |g| j  ƒS |S )Nc                 S   s   | | S r	   r   )ÚdÚkr   r   r   Ú<lambda>ˆ   s    z(getitem_property._path.<locals>.<lambda>)r-   r   )r   Úobjr   r   r   Ú_path‡   s   ÿzgetitem_property._pathc                 C   s   |d u r|S |   |¡ | j¡S r	   )r5   Úgetr+   )r   r4   Útyper   r   r   Ú__get__‹   s   zgetitem_property.__get__c                 C   s   ||   |¡| j< d S r	   )r5   r+   )r   r4   r   r   r   r   Ú__set__�   s   zgetitem_property.__set__r	   )r   r   r   r   r   r5   r8   r9   r   r   r   r   r   a   s    
 
r   )NN)r   Ú
__future__r   r   Ú	functoolsr   Ú__all__Úobjectr   r   r   r   r   r   r   r   Ú<module>   s   
 0