o
    Y۷i                     @  s   d Z ddlmZ ddlmZmZ ddlmZmZm	Z	m
Z
 zddlmZ W n ey7   G dd dZe ZY nw e	dZeeZG d	d
 d
ZeededdddZdddZdS ) zFPublic helpers for describing dataclass-style defaults on FFI proxies.    )annotations)_MISSING_TYPEMISSING)AnyCallableTypeVarcast)KW_ONLYc                   @  s   e Zd ZdZdS )_KW_ONLY_Sentinel N)__name__
__module____qualname__	__slots__r   r   r   O/home/ubuntu/vllm_env/lib/python3.10/site-packages/tvm_ffi/dataclasses/field.pyr
      s    r
   _FieldValuec                   @  s*   e Zd ZdZdZdededdddZdS )Fielda]  (Experimental) Descriptor placeholder returned by :func:`tvm_ffi.dataclasses.field`.

    A ``Field`` mirrors the object returned by :func:`dataclasses.field`, but it
    is understood by :func:`tvm_ffi.dataclasses.c_class`.  The decorator inspects
    the ``Field`` instances, records the ``default_factory`` and later replaces
    the field with a property that forwards to the underlying C++ attribute.

    Users should not instantiate ``Field`` directly - use :func:`field` instead,
    which guarantees that ``name`` and ``default_factory`` are populated in a
    way the decorator understands.
    )default_factoryinitkw_onlynameNTr   r   r   r   r   
str | Noner   )Callable[[], _FieldValue] | _MISSING_TYPEr   boolr   bool | _MISSING_TYPEreturnNonec                C  s   || _ || _|| _|| _dS )z0Do not call directly; use :func:`field` instead.Nr   )selfr   r   r   r   r   r   r   __init__4   s   	
zField.__init__)
r   r   r   r   r   r   r   r   r   r   )r   r   r   __doc__r   r   r   r   r   r   r   r   %   s    r   T)defaultr   r   r   r!   _FieldValue | _MISSING_TYPEr   r   r   r   r   r   r   c                 C  sx   | t ur|t urtdt|tstd|t ur(t|ts(tdt|j| t ur0t| }t|||d}t	t
|S )a
  (Experimental) Declare a dataclass-style field on a :func:`c_class` proxy.

    Use this helper exactly like :func:`dataclasses.field` when defining the
    Python side of a C++ class.  When :func:`c_class` processes the class body it
    replaces the placeholder with a property and arranges for ``default`` or
    ``default_factory`` to be respected by the synthesized ``__init__``.

    Parameters
    ----------
    default
        A literal default value that populates the field when no argument
        is given. At most one of ``default`` or ``default_factory`` may be
        given.
    default_factory
        A zero-argument callable that produces the default.  This matches the
        semantics of :func:`dataclasses.field` and is useful for mutable
        defaults such as ``list`` or ``dict``.
    init
        If ``True`` the field is included in the generated ``__init__``.
        If ``False`` the field is omitted from input arguments of ``__init__``.
    kw_only
        If ``True``, the field is a keyword-only argument in ``__init__``.
        If ``MISSING``, inherits from the class-level ``kw_only`` setting or
        from a preceding ``KW_ONLY`` sentinel annotation.

    Note
    ----
    The decision to forward a field to the C++ ``__ffi_init__`` constructor
    depends on its configuration:

    *   If ``init=True``, the field's value (from user input or defaults)
        is forwarded.

    *   If ``init=False``:

        -   With a ``default`` or ``default_factory``, its computed value is
            forwarded. The user cannot provide this value via Python ``__init__``.

        -   Without a ``default`` or ``default_factory``, the field is *not*
            forwarded to C++ ``__ffi_init__`` and must be initialized by the
            C++ constructor.

    Returns
    -------
    Field
        A placeholder object that :func:`c_class` will consume during class
        registration.

    Examples
    --------
    ``field`` integrates with :func:`c_class` to express defaults the same way a
    Python ``dataclass`` would:

    .. code-block:: python

        @c_class("testing.TestCxxClassBase")
        class PyBase:
            v_i64: int
            v_i32: int = field(default=16)


        obj = PyBase(v_i64=4)
        obj.v_i32  # -> 16

    Use ``kw_only=True`` to make a field keyword-only:

    .. code-block:: python

        @c_class("testing.TestCxxClassBase")
        class PyBase:
            v_i64: int
            v_i32: int = field(kw_only=True)


        obj = PyBase(4, v_i32=8)  # v_i32 must be keyword

    z3Cannot specify both `default` and `default_factory`z`init` must be a boolz`kw_only` must be a bool, got )r   r   r   )r   
ValueError
isinstancer   	TypeErrortyper   _make_default_factoryr   r   r   )r!   r   r   r   retr   r   r   fieldC   s   T

r)   valuer   Callable[[], Any]c                   s   d fdd}|S )z4Make a default factory that returns the given value.r   r   c                     s    S )Nr   r   r*   r   r   factory   s   z&_make_default_factory.<locals>.factoryN)r   r   r   )r*   r-   r   r,   r   r'      s   r'   N)
r!   r"   r   r   r   r   r   r   r   r   )r*   r   r   r+   )r    
__future__r   dataclassesr   r   typingr   r   r   r   r	   ImportErrorr
   r   r&   _KW_ONLY_TYPEr   r)   r'   r   r   r   r   <module>   s&   
 `