o
    ;iq                     @   s  d dl Z d dlZd dlZd dlmZmZ d dlmZmZ d dlm	Z	m
Z
mZm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 ddlmZ dZdZejrad dlZG dd de j Z!eG dd dZ"e#dZ$ej%dddZ&ej%dddZ'ee
g e	f e
e	ge	f f Z(e
e	ge	f Z)d[de"de*ddfddZ+G dd dej,e$e&e'f Z-d e.e	 d!e/de0e1e-f fd"d#Z2d$e	d!e/de0e1e
d%e	f f fd&d'Z3G d(d) d)Z4	d\dd*d+ee* de4fd,d-Z5d\d.eee1  de6ej7 fd/d0Z8	d\d1ddddd2d3e1d4ee1 d.eee1  d5e*d6e*de
ee-e$e&e&f e
e$e&f f ge-e$e&e&f f fd7d8Z9	d\d1ddddd9d3e1d4ee1 d5e*d.eee1  d6e*de
ee-e$e&e&f e
e$e&f f ge-e$e&e&f f fd:d;Z:	d\dddd<d4ee1 d.eee1  d6e*de
ee-e(f ge-f fd=d>Z;	d\dddd<d4ee1 d.eee1  d6e*de
ee-e(f ge-f fd?d@Z<dAddddBdCe/dDe=d4ee1 d.eee1  d6e*de
ee-e(f ge-f fdEdFZ>	d\ddGdHe*de
ee-e)f ge-f fdIdJZ?d\de
e)ge-f fdKdLZ@	d\dMe/dNe/de
ee-e$e&e&f e
e$e&f f ge-e$e&e&f f fdOdPZA	d\dddQdRee/ dSee/ de
ee
e$e&f e-e$e&e&f f ge-e$e&e&f f fdTdUZB	d]dVe/dWe*dXe*de
ee
e$e&f e-e$e&e&f f ge-e$e&e&f f fdYdZZCdS )^    N)	CoroutineIterable)asdict	dataclass)AnyCallableOptionalUnion)api_pb2   )	_Function)synchronizer)deprecation_warning)callable_has_non_self_params)config)InvalidErrori  i'	 c                   @   sf   e Zd ZdZdZdZdZdZdZdZ	dZ
d	Zed
efddZed
efddZed
efddZdS )_PartialFunctionFlags                @         i   returnc                   C   s
   t d S )Nr   )r    r   r   K/home/ubuntu/.local/lib/python3.10/site-packages/modal/_partial_function.pyall3   s   
z_PartialFunctionFlags.allc                   C   s   t jt jB t jB S N)r   ENTER_PRE_SNAPSHOTENTER_POST_SNAPSHOTEXITr   r   r   r   lifecycle_flags7   s   z%_PartialFunctionFlags.lifecycle_flagsc                   C   s   t jt jB S r   )r   CALLABLE_INTERFACEWEB_INTERFACEr   r   r   r   interface_flags?   s   z%_PartialFunctionFlags.interface_flagsN)__name__
__module____qualname__r    r!   r"   r$   r%   BATCHED
CONCURRENT	CLUSTEREDHTTP_WEB_INTERFACEstaticmethodintr   r#   r&   r   r   r   r   r       s     r   c                   @   s   e Zd ZU dZeej ed< dZee	 ed< dZ
ee	 ed< dZee ed< dZee ed< dZee ed< dZee ed< dZee ed	< dZee ed
< dZee	 ed< dZeej ed< dddZdS )_PartialFunctionParamsNwebhook_configis_generatorforce_buildbatch_max_sizebatch_wait_mscluster_sizemax_concurrent_inputstarget_concurrent_inputsbuild_timeoutrdmahttp_configotherr   c                 C   sN   t | D ]\}}|dur$t| |ddurtd| dt| || qdS )z%Update self with params set in other.NzCannot set `z` twice.)r   itemsgetattrr   setattr)selfr<   keyvalr   r   r   updateR   s   z_PartialFunctionParams.update)r<   r0   r   N)r'   r(   r)   r1   r   r
   WebhookConfig__annotations__r2   boolr3   r4   r/   r5   r6   r7   r8   r9   r:   r;   
HTTPConfigrC   r   r   r   r   r0   D   s   
 r0   P
ReturnTypeT)	covariantOriginalReturnTypeFparamsis_flashr   c                 C   s@   dt dd fdd}dt dd fdd}|r||  d S ||  d S )NrL   r   c                 S   s(   | j d ur	td| jd u rtdd S )Nz@modal.concurrent(max_inputs=...) is not yet supported for Flash functions. Use `@modal.concurrent(target_inputs=...)` instead.zA`@modal.concurrent()` missing required argument: `target_inputs`.)r7   	TypeErrorr8   rL   r   r   r   -_verify_concurrent_params_with_flash_settingsc   s   

zOverify_concurrent_params.<locals>._verify_concurrent_params_with_flash_settingsc                 S   s   | j d u r	tdd S )Nz>`@modal.concurrent()` missing required argument: `max_inputs`.)r7   rN   rO   r   r   r   _verify_concurrent_paramsl   s   
z;verify_concurrent_params.<locals>._verify_concurrent_params)r0   )rL   rM   rP   rQ   r   r   r   verify_concurrent_paramsb   s
   	rR   c                	   @   s   e Zd ZU dZeeeef  ed< dZ	ee
 ed< eed< eed< deeeef e
f dedefdd	Zdeded
ejfddZdddZ	ddededed
dfddZd
eeef fddZd
efddZdd
eeeef fddZdS )_PartialFunctionz}Object produced by a decorator in the `modal` namespace

    The object will eventually by consumed by an App decorator.
    raw_fNuser_clsflagsrL   objc                 C   s<   t |tr|| _d | _n|| _d | _|| _|| _|   d S r   )
isinstancetyperU   rT   rV   rL   validate_flag_composition)r@   rW   rV   rL   r   r   r   __init__   s   
z_PartialFunction.__init__r   c                 C   s&   |  j |O  _ | j| |   | S )zBImplement decorator composition by combining the flags and params.)rV   rL   rC   rZ   )r@   rV   rL   r   r   r   stack   s   z_PartialFunction.stackc                 C   s\   | j t @ }| j t @ }|r|rtd| j tj@ }| j tj@ }|r*|r,tddS dS )z=Validate decorator composition based on PartialFunctionFlags.zBInterface decorators cannot be combined with lifecycle decorators.zECallable decorators cannot be combined with web interface decorators.N)rV   r   r&   r#   r   r%   r$   )r@   uses_interface_flagsuses_lifecycle_flagshas_web_interfacehas_callable_interfacer   r   r   rZ      s   z*_PartialFunction.validate_flag_compositionFdecorator_namerequire_syncrequire_nullaryc                 C   s   ddl m} | jt @ }| jt @ }| jdur%|s|r%td| d| jp*| j}t	|t
r8td| dt	||rEtd| d| jdurvt| jsWtd	| d
|rgt| jrgtd| d|rxt| jrztd| ddS dS dS )zZEnforce compatibility with the wrapped object; called from individual decorator functions.r   )_ClsNzCannot apply `@modal.z:` to a class. Hint: consider applying to a method instead.zCannot stack `@modal.zD` on top of `@app.function`. Hint: swap the order of the decorators.zA` on top of `@app.cls()`. Hint: swap the order of the decorators.zThe object wrapped by `@modal.z` must be callable.zThe `@modal.z2` decorator can't be applied to an async function.zFunctions decorated by `@modal.z` can't have parameters.)clsrd   rV   r   r#   r&   rU   r   rT   rX   r   callableinspectiscoroutinefunctionr   )r@   ra   rb   rc   rd   r^   r]   wrapped_objectr   r   r   validate_obj_compatibility   s2   






z+_PartialFunction.validate_obj_compatibilityc                 C   s   | j d usJ | j S r   )rT   r@   r   r   r   
_get_raw_f   s   z_PartialFunction._get_raw_fc                 C   s    | j jd u rdS | j jjtjkS )NF)rL   r1   rY   r
   WEBHOOK_TYPE_UNSPECIFIEDrk   r   r   r   _is_web_endpoint   s   z!_PartialFunction._is_web_endpointc                 C   sD   | j d usJ | j j}|r t|drt|d| S | j ||S | S )N_modal_functions)rT   r'   hasattrr>   __get__)r@   rW   objtypekr   r   r   rq      s   
z_PartialFunction.__get__)r   N)FFr   )r'   r(   r)   __doc__r   r   rH   rI   rE   rU   rY   r   r0   r	   r[   typing_extensionsSelfr\   rZ   strrF   rj   rl   rn   r   rK   rq   r   r   r   r   rS   v   s8   
 


$rS   rU   rV   c                 C   sp   ddl m} i }t|  D ]'}|tur5|j D ]\}}t||r4t	t
t|}|j|@ r4|||< qq|S )zPGrabs all method on a user class, and returns partials. Includes legacy methods.r   )PartialFunction)partial_functionrx   reversedmroobject__dict__r=   rX   typingcastrS   r   _translate_inrV   )rU   rV   rx   partial_functions
parent_clsrs   v_partial_functionr   r   r   "_find_partial_methods_for_user_cls   s   

r   user_obj.c                    s$   t  } fddt|| D S )z<Grabs all methods for an object, and binds them to the classc                    s(   i | ]\}}|j d ur||j  qS r   )rT   rq   ).0rs   pfr   r   r   
<dictcomp>  s
    
z+_find_callables_for_obj.<locals>.<dictcomp>)rY   r   r=   )r   rV   rU   r   r   r   _find_callables_for_obj   s   
r   c                   @   s\   e Zd Zej				dddZej				dd	dZej		
		dddZdd ZdS )_MethodDecoratorTypefuncmmodal.partial_function.PartialFunction[typing_extensions.Concatenate[Any, P], ReturnType, OriginalReturnType]r   Imodal.partial_function.PartialFunction[P, ReturnType, OriginalReturnType]c                 C      d S r   r   r@   r   r   r   r   __call__	  s   z_MethodDecoratorType.__call__PCallable[typing_extensions.Concatenate[Any, P], Coroutine[Any, Any, ReturnType]]Vmodal.partial_function.PartialFunction[P, ReturnType, Coroutine[Any, Any, ReturnType]]c                 C   r   r   r   r   r   r   r   r        ;Callable[typing_extensions.Concatenate[Any, P], ReturnType]Amodal.partial_function.PartialFunction[P, ReturnType, ReturnType]c                 C   r   r   r   r   r   r   r   r     r   c                 C   r   r   r   r   r   r   r   r     s    N)r   r   r   r   )r   r   r   r   )r   r   r   r   )r'   r(   r)   r~   overloadr   r   r   r   r   r     s(    r   r2   r2   c                   s:   | durt ddttdtf tf dtf fdd}|S )zDecorator for methods that should be transformed into a Modal Function registered against this class's App.

    **Usage:**

    ```python
    @app.cls(cpu=8)
    class MyCls:

        @modal.method()
        def f(self):
            ...
    ```
    Nz`Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.method()`.rW   .r   c                    sr   t j} d u rt| tr| jn| }t|pt| t d}t| tr,| 	||}nt| ||}|
d |S )Nr   method)r   r$   rX   rS   rT   rg   isgeneratorfunctionisasyncgenfunctionr0   r\   rj   )rW   rV   rf   rL   r   r   r   r   wrapper6  s   


z_method.<locals>.wrapper)r   r	   r   r   rS   )_warn_parentheses_missingr2   r   r   r   r   _method  s   &r   custom_domainsc                 C   s>   t | tr	J dg }| d ur| D ]}|tj|d q|S )Nz<custom_domains must be `Iterable[str]` but is `str` instead.)name)rX   rw   appendr
   CustomDomainConfig)r   _custom_domainscustom_domainr   r   r   _parse_custom_domainsJ  s   r   GET)r   labelr   docsrequires_proxy_authr   r   r   r   c             
      s   t | trtd| d| durtdtjtj|||pdtdtjt	||d}t
j t|dd	tttttf tttf f d
ttttf f fdd}|S )a   Convert a function into a basic web endpoint by wrapping it with a FastAPI App.

    Modal will internally use [FastAPI](https://fastapi.tiangolo.com/) to expose a
    simple, single request handler. If you are defining your own `FastAPI` application
    (e.g. if you want to define multiple routes), use `@modal.asgi_app` instead.

    The endpoint created with this decorator will automatically have
    [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) enabled
    and can leverage many of FastAPI's features.

    For more information on using Modal with popular web frameworks, see our
    [guide on web endpoints](https://modal.com/docs/guide/webhooks).

    *Added in v0.73.82*: This function replaces the deprecated `@web_endpoint` decorator.
    zSPositional arguments are not allowed. Suggestion: `@modal.fastapi_endpoint(method="")`.NzjPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.fastapi_endpoint()`. 
dev_suffixrY   r   web_endpoint_docsrequested_suffixephemeral_suffix
async_moder   r   r1   rW   r   c                    2   t | tr|  }nt|  }|d |S )Nfastapi_endpointrX   rS   r\   rj   rW   r   rV   rL   r   r   r     
   

z"_fastapi_endpoint.<locals>.wrapper)rX   rw   r   r
   rD   WEBHOOK_TYPE_FUNCTIONr   getWEBHOOK_ASYNC_MODE_AUTOr   r   r%   r0   r	   rS   rH   rI   r   )r   r   r   r   r   r   r1   r   r   r   r   _fastapi_endpointT  s4   



r   )r   r   r   r   r   c             
      s   t | tr	td| durtdtdd tjtj|||pdtdtj	t
||d}tj t|d	d
tttttf tttf f dttttf f fdd}|S )a  Register a basic web endpoint with this application.

    DEPRECATED: This decorator has been renamed to `@modal.fastapi_endpoint`.

    This is the simple way to create a web endpoint on Modal. The function
    behaves as a [FastAPI](https://fastapi.tiangolo.com/) handler and should
    return a response object to the caller.

    Endpoints created with `@modal.web_endpoint` are meant to be simple, single
    request handlers and automatically have
    [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) enabled.
    For more flexibility, use `@modal.asgi_app`.

    To learn how to use Modal with popular web frameworks, see the
    [guide on web endpoints](https://modal.com/docs/guide/webhooks).
    zVPositional arguments are not allowed. Suggestion: `@modal.web_endpoint(method="GET")`.NzfPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.web_endpoint()`.)i        zRThe `@modal.web_endpoint` decorator has been renamed to `@modal.fastapi_endpoint`.r   r   r   r   rW   r   c                    r   )Nweb_endpointr   r   r   r   r   r     r   z_web_endpoint.<locals>.wrapper)rX   rw   r   r   r
   rD   r   r   r   r   r   r   r%   r0   r	   rS   rH   rI   r   )r   r   r   r   r   r   r1   r   r   r   r   _web_endpoint  s6   


r   )r   r   r   c                      t | trtd| d| durtdtjtj|pdtdtjt	||d}t
j t|dd	tttf d
tf fdd}|S )a~  Decorator for registering an ASGI app with a Modal function.

    Asynchronous Server Gateway Interface (ASGI) is a standard for Python
    synchronous and asynchronous apps, supported by all popular Python web
    libraries. This is an advanced decorator that gives full flexibility in
    defining one or more web endpoints on Modal.

    **Usage:**

    ```python
    from typing import Callable

    @app.function()
    @modal.asgi_app()
    def create_asgi() -> Callable:
        ...
    ```

    To learn how to use Modal with popular web frameworks, see the
    [guide on web endpoints](https://modal.com/docs/guide/webhooks).
    zJPositional arguments are not allowed. Suggestion: `@modal.asgi_app(label="r   NzbPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.asgi_app()`.r   r   rY   r   r   r   r   r   r   rW   r   c                    8   t | tr|  }nt|  }|jdddd |S )Nasgi_appTrb   rc   r   r   r   r   r   r     
   
z_asgi_app.<locals>.wrapper)rX   rw   r   r
   rD   WEBHOOK_TYPE_ASGI_APPr   r   r   r   r   r%   r0   r	   rS   NullaryFuncOrMethodr   r   r   r   r1   r   r   r   r   	_asgi_app  $   
	
 r   c                   r   )a  Decorator for registering a WSGI app with a Modal function.

    Web Server Gateway Interface (WSGI) is a standard for synchronous Python web apps.
    It has been [succeeded by the ASGI interface](https://asgi.readthedocs.io/en/latest/introduction.html#wsgi-compatibility)
    which is compatible with ASGI and supports additional functionality such as web sockets.
    Modal supports ASGI via [`asgi_app`](https://modal.com/docs/reference/modal.asgi_app).

    **Usage:**

    ```python
    from typing import Callable

    @app.function()
    @modal.wsgi_app()
    def create_wsgi() -> Callable:
        ...
    ```

    To learn how to use this decorator with popular web frameworks, see the
    [guide on web endpoints](https://modal.com/docs/guide/webhooks).
    zJPositional arguments are not allowed. Suggestion: `@modal.wsgi_app(label="r   NzbPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.wsgi_app()`.r   r   r   r   rW   r   c                    r   )Nwsgi_appTr   r   r   r   r   r   r   B  r   z_wsgi_app.<locals>.wrapper)rX   rw   r   r
   rD   WEBHOOK_TYPE_WSGI_APPr   r   r   r   r   r%   r0   r	   rS   r   r   r   r   r   	_wsgi_app  r   r   g      @)startup_timeoutr   r   r   portr   c             
      s   t | tr| dk s| dkrtd|dkrtdtjtj|p dtdtjt	|| ||d}t
j t|d	d
tttf dtf fdd}|S )aB  Decorator that registers an HTTP web server inside the container.

    This is similar to `@asgi_app` and `@wsgi_app`, but it allows you to expose a full HTTP server
    listening on a container port. This is useful for servers written in other languages like Rust,
    as well as integrating with non-ASGI frameworks like aiohttp and Tornado.

    **Usage:**

    ```python
    import subprocess

    @app.function()
    @modal.web_server(8000)
    def my_file_server():
        subprocess.Popen("python -m http.server -d / 8000", shell=True)
    ```

    The above example starts a simple file server, displaying the contents of the root directory.
    Here, requests to the web endpoint will go to external port 8000 on the container. The
    `http.server` module is included with Python, but you could run anything here.

    Internally, the web server is transparently converted into a web endpoint by Modal, so it has
    the same serverless autoscaling behavior as other web endpoints.

    For more info, see the [guide on web endpoints](https://modal.com/docs/guide/webhooks).
    r   i  zRFirst argument of `@web_server` must be a local port, such as `@web_server(8000)`.r   zAThe `startup_timeout` argument of `@web_server` must be positive.r   r   )rY   r   r   r   r   web_server_portweb_server_startup_timeoutr   r   rW   r   c                    r   )N
web_serverTr   r   r   r   r   r   r     r   z_web_server.<locals>.wrapper)rX   r/   r   r
   rD   WEBHOOK_TYPE_WEB_SERVERr   r   r   r   r   r%   r0   r	   rS   r   )r   r   r   r   r   r1   r   r   r   r   _web_serverM  s$   "
 r   )snapr   c                   sJ   | durt d|rtjntj t dtttf dtf fdd}|S )zDecorator for methods which should be executed when a new container is started.

    See the [lifeycle function guide](https://modal.com/docs/guide/lifecycle-functions#enter) for more information.Nz_Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.enter()`.rW   r   c                    r   )Nenterr   r   r   r   r   r     s
   

z_enter.<locals>.wrapper)r   r   r    r!   r0   r	   rS   NullaryMethod)r   r   r   r   r   r   _enter  s    	r   c                    s@   | durt dtj t dtttf dtf fdd}|S )zDecorator for methods which should be executed when a container is about to exit.

    See the [lifeycle function guide](https://modal.com/docs/guide/lifecycle-functions#exit) for more information.Nz^Positional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.exit()`.rW   r   c                    r   )Nexitr   r   r   r   r   r     s
   

z_exit.<locals>.wrapper)r   r   r"   r0   r	   rS   r   )r   r   r   r   r   _exit  s    r   max_batch_sizewait_msc                   s   | durt d|dk rt d|tkrt dt d|dk r$t d|tkr0t d	t dtjtjB  t||d
dttt	t
t
f tt	t
f f dtt	t
t
f f fdd}|S )a|  Decorator for functions or class methods that should be batched.

    **Usage**

    ```python
    # Stack the decorator under `@app.function()` to enable dynamic batching
    @app.function()
    @modal.batched(max_batch_size=4, wait_ms=1000)
    async def batched_multiply(xs: list[int], ys: list[int]) -> list[int]:
        return [x * y for x, y in zip(xs, ys)]

    # call batched_multiply with individual inputs
    # batched_multiply.remote.aio(2, 100)

    # With `@app.cls()`, apply the decorator to a method (this may change in the future)
    @app.cls()
    class BatchedClass:
        @modal.batched(max_batch_size=4, wait_ms=1000)
        def batched_multiply(self, xs: list[int], ys: list[int]) -> list[int]:
            return [x * y for x, y in zip(xs, ys)]
    ```

    See the [dynamic batching guide](https://modal.com/docs/guide/dynamic-batching) for more information.
    NzaPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.batched()`.r   z*max_batch_size must be a positive integer.z&max_batch_size cannot be greater than .r   z'wait_ms must be a non-negative integer.zwait_ms cannot be greater than )r4   r5   rW   r   c                    r   )Nbatchedr   r   r   r   r   r     r   z_batched.<locals>.wrapper)r   MAX_MAX_BATCH_SIZEMAX_BATCH_WAIT_MSr   r$   r*   r0   r	   rS   rH   rI   r   )r   r   r   r   r   r   r   _batched  s(   !
r   )
max_inputstarget_inputsr   r   c                   s   | durt d|dur|dur||krt dtj t||ddtttttf tttf f dttttf f fdd}|S )	a  Decorator that allows individual containers to handle multiple inputs concurrently.

    The concurrency mechanism depends on whether the function is async or not:
    - Async functions will run inputs on a single thread as asyncio tasks.
    - Synchronous functions will use multi-threading. The code must be thread-safe.

    Input concurrency will be most useful for workflows that are IO-bound
    (e.g., making network requests) or when running an inference server that supports
    dynamic batching.

    When `target_inputs` is set, Modal's autoscaler will try to provision resources
    such that each container is running that many inputs concurrently, rather than
    autoscaling based on `max_inputs`. Containers may burst up to up to `max_inputs`
    if resources are insufficient to remain at the target concurrency, e.g. when the
    arrival rate of inputs increases. This can trade-off a small increase in average
    latency to avoid larger tail latencies from input queuing.

    **Examples:**
    ```python
    # Stack the decorator under `@app.function()` to enable input concurrency
    @app.function()
    @modal.concurrent(max_inputs=100)
    async def f(data):
        # Async function; will be scheduled as asyncio task
        ...

    # With `@app.cls()`, apply the decorator at the class level, not on individual methods
    @app.cls()
    @modal.concurrent(max_inputs=100, target_inputs=80)
    class C:
        @modal.method()
        def f(self, data):
            # Sync function; must be thread-safe
            ...

    ```

    *Added in v0.73.148:* This decorator replaces the `allow_concurrent_inputs` parameter
    in `@app.function()` and `@app.cls()`.

    NzdPositional arguments are not allowed. Did you forget parentheses? Suggestion: `@modal.concurrent()`.z>`target_inputs` parameter cannot be greater than `max_inputs`.)r7   r8   rW   r   c                    r   )N
concurrentr   r   r   r   r   r   ?  r   z_concurrent.<locals>.wrapper)	r   r   r+   r0   r	   rS   rH   rI   r   )r   r   r   r   r   r   r   _concurrent  s   2
r   size	broadcastr:   c                    sn   |sJ d| dkrt dtj t| |ddtttttf tttf f dttttf f fdd}|S )	a  Provision clusters of colocated and networked containers for the Function.

    Parameters:
    size: int
        Number of containers spun up to handle each input.
    broadcast: bool = True
        If True, inputs will be sent simultaneously to each container. Otherwise,
        inputs will be sent only to the rank-0 container, which is responsible for
        delegating to the workers.
    z-broadcast=False has not been implemented yet!r   z#cluster size must be greater than 0)r6   r:   rW   r   c                    r   )N	clusteredr   r   r   r   r   r   f  r   z_clustered.<locals>.wrapper)	
ValueErrorr   r,   r0   r	   rS   rH   rI   r   )r   r   r:   r   r   r   r   
_clusteredM  s   
r   )Fr   )TF)Denumrg   r~   collections.abcr   r   dataclassesr   r   r   r   r   r	   ru   modal_protor
   
_functionsr   _utils.async_utilsr   _utils.deprecationr   _utils.function_utilsr   r   	exceptionr   r   r   TYPE_CHECKINGmodal.partial_functionmodalIntFlagr   r0   	ParamSpecrH   TypeVarrI   rK   r   r   rF   rR   GenericrS   rY   r/   dictrw   r   r   r   r   listr   r   r   r   r   r   floatr   r   r   r   r   r   r   r   r   r   <module>   sr  $
"x&

"-

A	

F

;

=

A

?
P