
    K:g                        U d Z ddlZddlZddlZddlmZ ddlmZ ddlm	Z	m
Z
mZmZmZ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  G d d      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z  G d de      Z! G d de      Z" G d de      Z#eee e!e"e#fD  ci c]  } | jH                  |  c} Z% G d de      Z&deeee   f   d e	d!e&fd"Z'deeee   f   d e	d!e&fd#Z(dd$ee   d e	d!e&fd%Z)d&d'd(ed)e*d!efd*Z+d+e	d!efd,Z,d+e	d!e-fd-Z.d+e-d!e-fd.Z/d+e-d!e-fd/Z0d0e-d!e-fd1Z1ee-e2e3e*eeeejh                  ej                  f	   Z5ee6d2<    G d3 d4e      Z7	 d+e5d!e7fd5Z8d6e5d7e5d!e7fd8Z9d!e7fd9Z:dd+e5d:ee5   d!e7fd;Z;d<e5d=e5d!e7fd>Z<d6e5d7e5d!e7fd?Z=d+e5d@e5d!e7fdAZ>d+e5d@e5d!e7fdBZ?d!e7fdCZ@dDe5d6e5dEe5d!e7fdFZAdDe5d!e7fdGZBdHe5dIe5dEe5d!e7fdJZCddDe5dKee5   d!e7fdLZDddDe5dMee5   dNee5   d!e7fdOZEdDe5d!e7fdPZFdQe5d!e7fdRZGd!e7fdSZHd+e5d!e7fdTZIdUe5d!e7fdVZJd!e7fdWZKddXe5dYe5dZee5   d!e7fd[ZLdd+e5d:ee5   d!e7fd\ZMdDe5d!e7fd]ZNd^e5d!e7fd_ZOd`e5dae5dbe5d!e7fdcZPd+e5d!e7fddZQdee5d!e7fdfZRdHe5dIe5d!e7fdgZSdHe5dIe5d!e7fdhZTdHe5dIe5die5d!e7fdjZUd e5d!e7fdkZVdle5dme5d!e7fdnZWdle5d!e7fdoZXdd6e5dpee5   d!e7fdqZYdle5d!e7fdrZZd6e5d7e5d!e7fdsZ[dle5dte5due5d!e7fdvZ\d6e5d7e5d!e7fdwZ]d^e5d!e7fdxZ^d+e5dye5d!e7fdzZ_dDe5d!e7fd{Z`d!e7fd|Zad+e5d!e7fd}Zbdpe5dUe5d!e7fd~Zcd!e7fdZddle5de5d!e7fdZedle5de5d!e7fdZfdle5de5de5d!e7fdZgdle5de5de5de5d!e7f
dZhdle5d6e5d!e7fdZidle5dme5d!e7fdZjd+e5de5d!e7fdZkd+e5de5d!e7fdZld+e5de5d!e7fdZmddXe5dYe5dZee5   d!e7fdZnd^e5d!e7fdZodDe5de5d!e7fdZpdDe5de5d!e7fdZqd+e5d!e7fdZrddle5de5de5dee5   d!e7f
dZsd6e5d7e5d!e7fdZtd`e5de5de5de5d!e7f
dZud+e5d!e7fdZvde5d!e7fdZwd!e7fdZxdDe5d!e7fdZydle5d!e7fdZzd!e7fdZ{dle5d!e7fdZ|d<e5d!e7fdZ}ddDe5dee5   d!e7fdZ~ddDe5dee5   d!e7fdZdde5de5dee5   d!e7fdZdde5de5dee5   d!e7fdZd`e5de5d!e7fdZdDe5d!e7fdZyc c} w )z
This module exports building blocks for constructing Airtable formulas,
including function call proxies for all formula functions as of Dec '23.

See :doc:`formulas` for more information.
    N)Decimal)Fraction)AnyClassVarIterableListOptionalSetUnion)Self)	TypeAlias)Fields)CircularFormulaError)date_to_iso_strdatetime_to_iso_strc                       e Zd ZdZdeddfdZdefdZdefdZdedd fd	Z	dedd fd
Z
dedd fdZdedefdZddZddZdeddfdZdeddfdZdeddfdZdeddfdZdeddfdZdeddfdZy)FormulaaE  
    Represents an Airtable formula that can be combined with other formulas
    or converted to a string. On its own, this class simply wraps a ``str``
    so that it will be not be modified or escaped as if it were a value.

    >>> Formula("{Column} = 1")
    Formula('{Column} = 1')
    >>> str(_)
    '{Column} = 1'
    valuereturnNc                     || _         y Nr   selfr   s     P/var/www/html/lionshead/venv/lib/python3.12/site-packages/pyairtable/formulas.py__init__zFormula.__init__#   s	    
    c                     | j                   S r   r   r   s    r   __str__zFormula.__str__&   s    zzr   c                 N    | j                   j                   d| j                  dS )N())	__class____name__r   r   s    r   __repr__zFormula.__repr__)   s$    ..))*!DJJ>;;r   otherc                 ,    t        | t        |            S r   )AND
to_formular   r'   s     r   __and__zFormula.__and__,       4E*++r   c                 ,    t        | t        |            S r   )ORr*   r+   s     r   __or__zFormula.__or__/   s    $
5)**r   c                 ,    t        | t        |            S r   )XORr*   r+   s     r   __xor__zFormula.__xor__2   r-   r   c                 `    t        |t        |             sy|j                  | j                  k(  S NF)
isinstancetyper   r+   s     r   __eq__zFormula.__eq__5   s&    %d,{{djj((r   c                     t        |       S r   )NOTr   s    r   
__invert__zFormula.__invert__:   s    4yr   c                     | S )zP
        Return a new formula with nested boolean statements flattened.
         r   s    r   flattenzFormula.flatten=   s	     r   
Comparisonc                     t        | |      S )zZ
        Build an :class:`~pyairtable.formulas.EQ` comparison using this formula.
        )EQr   s     r   eqz
Formula.eqC        $r   c                     t        | |      S )zZ
        Build an :class:`~pyairtable.formulas.NE` comparison using this formula.
        )NEr   s     r   nez
Formula.neI   rC   r   c                     t        | |      S )zY
        Build a :class:`~pyairtable.formulas.GT` comparison using this formula.
        )GTr   s     r   gtz
Formula.gtO   rC   r   c                     t        | |      S )zZ
        Build an :class:`~pyairtable.formulas.LT` comparison using this formula.
        )LTr   s     r   ltz
Formula.ltU   rC   r   c                     t        | |      S )zZ
        Build a :class:`~pyairtable.formulas.GTE` comparison using this formula.
        )GTEr   s     r   gtezFormula.gte[        4r   c                     t        | |      S )z[
        Build an :class:`~pyairtable.formulas.LTE` comparison using this formula.
        )LTEr   s     r   ltezFormula.ltea   rP   r   )r   r   )r%   
__module____qualname____doc__strr   r    r&   r   r,   r0   r3   boolr8   r;   r>   rB   rF   rI   rL   rO   rS   r=   r   r   r   r      s    	c d  <# <,S ,Y ,+C +I +,S ,Y ,)C )D )
                  r   r   c                       e Zd ZdZdefdZy)Fieldz"
    Represents a field name.
    r   c                 ,    t        | j                        S r   )
field_namer   r   s    r   r    zField.__str__m   s    $**%%r   N)r%   rT   rU   rV   rW   r    r=   r   r   rZ   rZ   h   s    & &r   rZ   c                   ^    e Zd ZU dZdZee   ed<   dedefdZ	dede
fd	Zdefd
ZdefdZy)r?   zG
    Represents a logical condition that compares two expressions.
     operatorlvalrvalc                 |    | j                   s"t        | j                  j                   d      || _        || _        y )Nz.operator is not defined)r_   NotImplementedErrorr$   r%   r`   ra   r   r`   ra   s      r   r   zComparison.__init__x   s<    }}%>>**++CD  		r   r'   r   c                     t        |t              sy| j                  | j                  | j                  f|j                  |j                  |j                  fk(  S r5   )r6   r?   r`   r_   ra   r+   s     r   r8   zComparison.__eq__   sI    %,		4==$))4JJNNJJ9
 
 	
r   c                     d | j                   | j                  fD        \  }}t        | j                   t              rd| dn|}t        | j                  t              rd| dn|}| | j                   | S )Nc              3   2   K   | ]  }t        |        y wr   to_formula_str.0vs     r   	<genexpr>z%Comparison.__str__.<locals>.<genexpr>   s     H1GAnQ'1G   r"   r#   )r`   ra   r6   r?   r_   rd   s      r   r    zComparison.__str__   sl    H$))TYY1GH
d(J?4&{T(J?4&{Ttf--r   c                 h    | j                   j                   d| j                  d| j                  dS )Nr"   , r#   )r$   r%   r`   ra   r   s    r   r&   zComparison.__repr__   s.    ..))*!DII=499-qIIr   N)r%   rT   rU   rV   r_   r   rW   __annotations__r   r   rX   r8   r    r&   r=   r   r   r?   r?   q   sW     !Hhsm S  
C 
D 
. .J# Jr   r?   c                       e Zd ZdZdZy)rA   z.
    Produces an ``lval = rval`` formula.
    =Nr%   rT   rU   rV   r_   r=   r   r   rA   rA           Hr   rA   c                       e Zd ZdZdZy)rE   z/
    Produces an ``lval != rval`` formula.
    z!=Nrt   r=   r   r   rE   rE           Hr   rE   c                       e Zd ZdZdZy)rH   z.
    Produces an ``lval > rval`` formula.
    >Nrt   r=   r   r   rH   rH      ru   r   rH   c                       e Zd ZdZdZy)rN   z/
    Produces an ``lval >= rval`` formula.
    z>=Nrt   r=   r   r   rN   rN      rw   r   rN   c                       e Zd ZdZdZy)rK   z.
    Produces an ``lval < rval`` formula.
    <Nrt   r=   r   r   rK   rK      ru   r   rK   c                       e Zd ZdZdZy)rR   z/
    Produces an ``lval <= rval`` formula.
    z<=Nrt   r=   r   r   rR   rR      rw   r   rR   c            	           e Zd ZU dZeed<   ee   ed<   dedee   ddfdZ	de
defdZdefd	Zdefd
Zddeee      dd fdZedede
de
defd       Zy)Compoundzs
    Represents a boolean logical operator (AND, OR, etc.) wrapping around
    one or more component formulas.
    r_   
componentsr   Nc                     t        |t              st        |      }t        |      dk(  rt        d      || _        || _        y )Nr   z*Compound() requires at least one component)r6   listlen
ValueErrorr_   r   )r   r_   r   s      r   r   zCompound.__init__   s>    
 *d+j)Jz?aIJJ $r   r'   c                     t        |t              sy| j                  | j                  f|j                  |j                  fk(  S r5   )r6   r   r_   r   r+   s     r   r8   zCompound.__eq__   s6    %*t/ENNEDTDT3UUUr   c                 j    dj                  d | j                  D              }| j                   d| dS )Nrp   c              3   2   K   | ]  }t        |        y wr   )rW   )rk   cs     r   rm   z#Compound.__str__.<locals>.<genexpr>   s     %Foc!forn   r"   r#   )joinr   r_   )r   joined_componentss     r   r    zCompound.__str__   s4     II%Fdoo%FF--"3!4A66r   c                 R    | j                    dt        | j                        dd  dS )Nr"      r#   )r_   reprr   r   s    r   r&   zCompound.__repr__   s*    --$t"7""=!>a@@r   memoc                   |r|n	t               }|j                  t        |              g }| j                  D ]  }t        |      |v rt	        |      t        |t              rE|j                  | j                  k(  r,|j                  |j                  |      j                         p|j                  |j                                 t        | j                  |      S )zJ
        Reduces the depth of nested AND, OR, and NOT statements.
        )r   )setaddidr   r   r6   r   r_   extendr>   append)r   r   	flatteneditems       r   r>   zCompound.flatten   s     tD#%	OOD$x4*400$)dmmt}}.L  4!8!C!CD  0 $ y11r   fieldsc                     t        |      }t        |      dk(  r/t        |d   x}d      rt        |t              r|gn
t        |      }|r&|j                  d |j                         D                | ||      S )Nr   r   __iter__c              3   L   K   | ]  \  }}t        t        |      |        y wr   )rA   rZ   )rk   krl   s      r   rm   z!Compound.build.<locals>.<genexpr>   s     F~VaE!Ha~s   "$)r   r   hasattrr6   rW   r   items)clsr_   r   r   r   firsts         r   buildzCompound.build   sg    Z u:?wa'8u*E)%5UG4;ELLFv||~FF8U##r   r   )r%   rT   rU   rV   rW   rq   r   r   r   r   r   rX   r8   r    r&   r	   r
   intr>   classmethodSelfTyper   r=   r   r   r   r      s    
 MW%% W%% 
	%VC VD V
7 7A# A2xC1 2Z 2" $S $s $c $h $ $r   r   r   r   r   c                  4    t        j                  dg| i |S )z
    Join one or more logical conditions into an AND compound condition.
    Keyword arguments will be treated as field names.

    >>> AND(EQ("foo", 1), EQ(Field("bar"), 2), baz=3)
    AND(EQ('foo', 1), EQ(Field('bar'), 2), EQ(Field('baz'), 3))
    r)   r   r   r   r   s     r   r)   r)     s     >>%7*777r   c                  4    t        j                  dg| i |S )z
    Join one or more logical conditions into an OR compound condition.
    Keyword arguments will be treated as field names.

    >>> OR(EQ("foo", 1), EQ(Field("bar"), 2), baz=3)
    OR(EQ('foo', 1), EQ(Field('bar'), 2), EQ(Field('baz'), 3))
    r/   r   r   s     r   r/   r/     s     >>$66v66r   	componentc          	         |j                         D cg c]  \  }}t        t        |      |       }}}| r|j                  |        t	        |      x}dk7  rt        d|       t        j                  d|      S c c}}w )a  
    Wrap one logical condition in a negation compound.
    Keyword arguments will be treated as field names.

    Can be called with either a formula or with a single
    kewyord argument, but not both.

    >>> NOT(EQ("foo", 1))
    NOT(EQ('foo', 1))

    >>> NOT(foo=1)
    NOT(EQ(Field('foo'), 1))

    If not called with exactly one condition, will throw an exception:

    >>> NOT(EQ("foo", 1), EQ("bar", 2))
    Traceback (most recent call last):
    TypeError: NOT() takes from 0 to 1 positional arguments but 2 were given

    >>> NOT(EQ("foo", 1), bar=2)
    Traceback (most recent call last):
    ValueError: NOT() requires exactly one condition; got 2

    >>> NOT(foo=1, bar=2)
    Traceback (most recent call last):
    ValueError: NOT() requires exactly one condition; got 2

    >>> NOT()
    Traceback (most recent call last):
    ValueError: NOT() requires exactly one condition; got 0
    r   z*NOT() requires exactly one condition; got r:   )r   rA   rZ   r   r   r   r   r   )r   r   r   rl   r   counts         r   r:   r:     sx    @ ;A,,.I.ABuQxO.EIYU!EeWMNN>>%'' Js   A=F)	match_anyfield_valuesr   c                `   g }| j                         D ]\  \  }}t        |t              r t        |      dk(  rt        |d      |d   }}nt
        }|j                   |t        |      |             ^ t        |      dk(  rt        d      t        |      dk(  r|d   S |rt        | S t        | S )a  
    Create one or more equality expressions for each provided value,
    treating keys as field names and values as values (not formula expressions).

    If more than one assertion is included, the expressions are
    grouped together into using ``AND()`` (all values must match).
    If ``match_any=True``, expressions are grouped with ``OR()``.

        >>> match({"First Name": "John", "Age": 21})
        AND(EQ(Field('First Name'), 'John'),
            EQ(Field('Age'), 21))

        >>> match({"First Name": "John", "Age": 21}, match_any=True)
        OR(EQ(Field('First Name'), 'John'),
           EQ(Field('Age'), 21))

    To use comparisons other than equality, use a 2-tuple of ``(operator, value)``
    as the value for a particular field. For example:

        >>> match({"First Name": "John", "Age": (">=", 21)})
        AND(EQ(Field('First Name'), 'John'),
            GTE(Field('Age'), 21))

    If you need more advanced matching you can build formula expressions using lower
    level primitives.

    Args:
        field_values: mapping of column names to values
            (or to 2-tuples of the format ``(operator, value)``).
        match_any:
            If ``True``, matches if *any* of the provided values match.
            Otherwise, all values must match.
       r   r   zBmatch() requires at least one field-value pair or keyword argument)r   r6   tupler   COMPARISONS_BY_OPERATORrA   r   rZ   r   r/   r)   )r   r   expressionskeyvalcmps         r   matchr   A  s    D "$K &&(Sc5!c#h!m.s1v6ACC3uSz3/0 ) ;1P
 	
 ;11~;r   r   c                    t        | t              r| S t        | t              r| r
t               S t	               S t        | t
        t        t        t        f      rt        t        |             S t        | t              rt        t        |             S t        | t        j                        rt        t        |             S t        | t        j                        rt        t        |             S ddl}t        | |j"                  j$                  j&                        rt'        | j(                        S t+        | t-        |             )a  
    Converts the given value into a Formula object.

    When given a Formula object, it returns the object as-is:

    >>> to_formula(EQ(F.Formula("a"), "b"))
    EQ(Formula('a'), 'b')

    When given a scalar value, it simply wraps that value's string representation
    in a Formula object:

    >>> to_formula(1)
    Formula('1')
    >>> to_formula('foo')
    Formula("'foo'")

    Boolean and date values receive custom function calls:

    >>> to_formula(True)
    TRUE()
    >>> to_formula(False)
    FALSE()
    >>> to_formula(datetime.date(2023, 12, 1))
    DATETIME_PARSE('2023-12-01')
    >>> to_formula(datetime.datetime(2023, 12, 1, 12, 34, 56))
    DATETIME_PARSE('2023-12-01T12:34:56.000Z')
    r   N)r6   r   rX   TRUEFALSEr   floatr   r   rW   quoteddatetimeDATETIME_PARSEr   dater   pyairtable.ormormr   rZ   r\   	TypeErrorr7   )r   
pyairtables     r   r*   r*   w  s    8 %!%tv+EG+%#ugx89s5z""%ve}%%%**+1%899%'oe455 %..445U%%&&
E4;
''r   c                 *    t        t        |             S )a  
    Converts the given value into a string representation that can be used
    in an Airtable formula expression.

    >>> to_formula_str(EQ(F.Formula("a"), "b"))
    "a='b'"
    >>> to_formula_str(True)
    'TRUE()'
    >>> to_formula_str(False)
    'FALSE()'
    >>> to_formula_str(3)
    '3'
    >>> to_formula_str(3.5)
    '3.5'
    >>> to_formula_str(Decimal("3.14159265"))
    '3.14159265'
    >>> to_formula_str(Fraction("4/19"))
    '4/19'
    >>> to_formula_str("asdf")
    "'asdf'"
    >>> to_formula_str("Jane's")
    "'Jane\'s'"
    >>> to_formula_str(datetime.date(2023, 12, 1))
    "DATETIME_PARSE('2023-12-01')"
    >>> to_formula_str(datetime.datetime(2023, 12, 1, 12, 34, 56))
    "DATETIME_PARSE('2023-12-01T12:34:56.000Z')"
    )rW   r*   r   s    r   ri   ri     s    8 z% !!r   c                 h    | j                  dd      j                  dd      } dj                  |       S )z
    Wrap string in quotes. This is needed when referencing a string inside a formula.
    Quotes are escaped.

    >>> quoted("John")
    "'John'"
    >>> quoted("Guest's Name")
    "'Guest\\'s Name'"
    \z\\'\'z'{}')replaceformatr   s    r   r   r     s0     MM$&..sE:E==r   c                 l    t        j                  dt        d       t        j                  dd|       }|S )ao  
    Ensure any quotes are escaped. Already escaped quotes are ignored.

    This function has been deprecated.
    Use :func:`~pyairtable.formulas.quoted` instead.

    Args:
        value: text to be escaped

    Usage:
        >>> escape_quotes(r"Player's Name")
        "Player\\'s Name"
        >>> escape_quotes(r"Player\'s Name")
        "Player\\'s Name"
    z2escape_quotes is deprecated; use quoted() instead.r   )category
stacklevelz(?<!\\)'r   )warningswarnDeprecationWarningresub)r   escaped_values     r   escape_quotesr     s3      MM<#
 FF<6Mr   namec                 ,    d| j                  dd      z  S )z
    Create a reference to a field. Quotes are escaped.

    Args:
        name: field name

    Usage:
        >>> field_name("First Name")
        '{First Name}'
        >>> field_name("Guest's Name")
        "{Guest's Name}"
    z{%s}}z\})r   )r   s    r   r\   r\     s      DLLe,,,r   FunctionArgc                   H    e Zd ZdZdedefdZdedefdZ	defdZ
defd	Zy
)FunctionCalla  
    Represents a function call in an Airtable formula, and converts
    all arguments to that function into Airtable formula expressions.

    >>> FunctionCall("WEEKDAY", datetime.date(2024, 1, 1))
    WEEKDAY(datetime.date(2024, 1, 1))
    >>> str(_)
    "WEEKDAY(DATETIME_PARSE('2024-01-01'))"

    pyAirtable exports shortcuts like :meth:`~pyairtable.formulas.WEEKDAY`
    for all formula functions known at time of publishing.
    r   argsc                      || _         || _        y r   )r   r   )r   r   r   s      r   r   zFunctionCall.__init__  s    		r   r'   r   c                     t        |t              sy| j                  | j                  f|j                  |j                  fk(  S r5   )r6   r   r   r   r+   s     r   r8   zFunctionCall.__eq__!  s4    %.		499%%**ejj)AAAr   c                 j    dj                  d | j                  D              }| j                   d| dS )Nrp   c              3   2   K   | ]  }t        |        y wr   rh   rj   s     r   rm   z'FunctionCall.__str__.<locals>.<genexpr>'  s     E9aq 19rn   r"   r#   r   r   r   )r   joined_argss     r   r    zFunctionCall.__str__&  s1    iiE499EE))Ak]!,,r   c                 j    dj                  d | j                  D              }| j                   d| dS )Nrp   c              3   2   K   | ]  }t        |        y wr   )r   rj   s     r   rm   z(FunctionCall.__repr__.<locals>.<genexpr>+  s     $@iT!Wirn   r"   r#   r   )r   joined_args_reprs     r   r&   zFunctionCall.__repr__*  s4    99$@dii$@@))A./q11r   N)r%   rT   rU   rV   rW   r   r   r   rX   r8   r    r&   r=   r   r   r   r     sH    S  BC BD B
- -2# 2r   r   c                    t        d|       S )z%
    Returns the absolute value.
    ABSr   r   s    r   r   r   q       u%%r   numbernumbersc                    t        d| g| S )z-
    Returns the average of the numbers.
    AVERAGEr   r   r   s     r   r   r   x  s     	64G44r   c                      t        d      S )z 
    Returns a blank value.
    BLANKr   r=   r   r   r   r            r   significancec                ,    t        d| gd |fD         S )z
    Returns the nearest integer multiple of significance that is greater than or equal to the value. If no significance is provided, a significance of 1 is assumed.
    CEILINGc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zCEILING.<locals>.<genexpr>  s     +W~!A~   r   r   r   s     r   r   r     s     	5X+W~+WXXr   texttextsc                    t        d| g| S )zE
    Joins together the text arguments into a single text value.
    CONCATENATEr   )r   r   s     r   r   r     s     t4e44r   c                    t        d| g| S )z,
    Count the number of numeric items.
    COUNTr   r   s     r   r   r     s     2'22r   valuesc                    t        d| g| S )zb
    Count the number of non-empty values. This function counts both numeric and text values.
    COUNTAr   r   r   s     r   r   r     s     %1&11r   c                    t        d| g| S )zE
    Count the number of all elements including text and blanks.
    COUNTALLr   r   s     r   r  r    s     
E3F33r   c                      t        d      S )z?
    Returns the date and time a given record was created.
    CREATED_TIMEr   r=   r   r   r  r    s     ''r   r   unitsc                    t        d| ||      S )z
    Adds specified "count" units to a datetime. (See `list of shared unit specifiers <https://support.airtable.com/hc/en-us/articles/226061308>`__. For this function we recommend using the full unit specifier for your desired unit.)
    DATEADDr   )r   r   r  s      r   r  r    s     	477r   c                    t        d|       S )z8
    Formats a datetime into a string (YYYY-MM-DD).
    DATESTRr   r   s    r   r  r         	4((r   date1date2c                    t        d| ||      S )z
    Returns the difference between datetimes in specified units. The difference between datetimes is determined by subtracting [date2] from [date1]. This means that if [date2] is later than [date1], the resulting value will be negative.
    DATETIME_DIFFr   )r  r  r  s      r   r  r    s     u==r   output_formatc                ,    t        d| gd |fD         S )a  
    Formats a datetime into a specified string. See an `explanation of how to use this function with date fields <https://support.airtable.com/hc/en-us/articles/215646218>`__ or a list of `supported format specifiers <https://support.airtable.com/hc/en-us/articles/216141218>`__.
    DATETIME_FORMATc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   z"DATETIME_FORMAT.<locals>.<genexpr>  s     2_oQRQ^1or   r   )r   r  s     r   r  r    s     )4`2_}o2_``r   input_formatlocalec                .    t        d| gd ||fD         S )z
    Interprets a text string as a structured date, with optional input format and locale parameters. The output format will always be formatted 'M/D/YYYY h:mm a'.
    r   c              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   z!DATETIME_PARSE.<locals>.<genexpr>  s     1e=SWXWd!=Sr   r   )r   r  r  s      r   r   r     s"     ($f1elF=S1effr   c                    t        d|       S )zZ
    Returns the day of the month of a datetime in the form of a number between 1-31.
    DAYr   r	  s    r   r  r    s     t$$r   component_stringc                    t        d|       S )z
    Replaces certain characters with encoded equivalents for use in constructing URLs or URIs. Does not encode the following characters: ``-_.~``
    ENCODE_URL_COMPONENTr   )r  s    r   r  r    s     .0@AAr   c                      t        d      S )z6
    Returns a generic Error value (``#ERROR!``).
    ERRORr   r=   r   r   r  r    r   r   c                    t        d|       S )za
    Returns the smallest even integer that is greater than or equal to the specified value.
    EVENr   r   s    r   r  r         &&r   powerc                    t        d|       S )zA
    Computes **Euler's number** (e) to the specified power.
    EXPr   )r!  s    r   r#  r#    r   r   c                      t        d      S )zG
    Logical value false. False is represented numerically by a 0.
    r   r   r=   r   r   r   r     r   r   string_to_findwhere_to_searchstart_from_positionc                .    t        d| |gd |fD         S )z
    Finds an occurrence of stringToFind in whereToSearch string starting from an optional startFromPosition.(startFromPosition is 0 by default.) If no occurrence of stringToFind is found, the result will be 0.
    FINDc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zFIND.<locals>.<genexpr>  s     BuNcghgt1Ncr   r   r%  r&  r'  s      r   r)  r)    s"     vBuObNcBuvvr   c                ,    t        d| gd |fD         S )z
    Returns the nearest integer multiple of significance that is less than or equal to the value. If no significance is provided, a significance of 1 is assumed.
    FLOORc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zFLOOR.<locals>.<genexpr>  s     )U^q}!^r   r   r   s     r   r-  r-    s     V)Ul^)UVVr   c                    t        d|       S )R
    Calculates the number of days between the current date and another date.
    FROMNOWr   r	  s    r   r1  r1    r
  r   r   c                    t        d|       S )zZ
    Returns the hour of a datetime as a number between 0 (12:00am) and 23 (11:00pm).
    HOURr   r   s    r   r3  r3    s     ))r   
expressionif_trueif_falsec                    t        d| ||      S )z
    Returns value1 if the logical argument is true, otherwise it returns value2. Can also be used to make `nested IF statements <https://support.airtable.com/hc/en-us/articles/221564887-Nested-IF-formulas>`__.
    IFr   )r5  r6  r7  s      r   r9  r9    s     j'8<<r   c                    t        d|       S )zY
    Returns the greatest integer that is less than or equal to the specified value.
    INTr   r   s    r   r;  r;     r   r   exprc                    t        d|       S )z9
    Returns true if the expression causes an error.
    ISERRORr   )r<  s    r   r>  r>  '  r
  r   c                    t        d| |      S )zQ
    Determines if [date1] is later than [date2]. Returns 1 if yes, 0 if no.
    IS_AFTERr   r  r  s     r   r@  r@  .  s     
E511r   c                    t        d| |      S )zS
    Determines if [date1] is earlier than [date2]. Returns 1 if yes, 0 if no.
    	IS_BEFOREr   rA  s     r   rC  rC  5  s     UE22r   unitc                    t        d| ||      S )zo
    Compares two dates up to a unit and determines whether they are identical. Returns 1 if yes, 0 if no.
    IS_SAMEr   )r  r  rD  s      r   rF  rF  <  s     	5%66r   c                      t        dg|  S )zx
    Returns the date and time of the most recent modification made by a user in a non-computed field in the table.
    LAST_MODIFIED_TIMEr   )r   s    r   rH  rH  C  s     ,6v66r   stringhow_manyc                    t        d| |      S )zG
    Extract how many characters from the beginning of the string.
    LEFTr   rI  rJ  s     r   rL  rL  J  s     11r   c                    t        d|       S )z)
    Returns the length of a string.
    LENr   rI  s    r   rO  rO  Q  s     v&&r   basec                ,    t        d| gd |fD         S )zi
    Computes the logarithm of the value in provided base. The base defaults to 10 if not specified.
    LOGc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zLOG.<locals>.<genexpr>\  s     (LFqamFr   r   )r   rQ  s     r   rS  rS  X  s     vM(LTF(LMMr   c                    t        d|       S )z#
    Makes a string lowercase.
    LOWERr   rP  s    r   rV  rV  _       ((r   c                    t        d| g| S )z3
    Returns the largest of the given numbers.
    MAXr   r   s     r   rY  rY  f       v000r   where_to_startr   c                    t        d| ||      S )zK
    Extract a substring of count characters starting at whereToStart.
    MIDr   )rI  r[  r   s      r   r]  r]  m  s     v~u==r   c                    t        d| g| S )z4
    Returns the smallest of the given numbers.
    MINr   r   s     r   r_  r_  t  rZ  r   c                    t        d|       S )zJ
    Returns the minute of a datetime as an integer between 0 and 59.
    MINUTEr   r4  s    r   ra  ra  {       (++r   divisorc                    t        d| |      S )zP
    Returns the remainder after dividing the first argument by the second.
    MODr   )r   rc  s     r   re  re    s     ug..r   c                    t        d|       S )z\
    Returns the month of a datetime as a number between 1 (January) and 12 (December).
    MONTHr   r	  s    r   rg  rg         &&r   c                      t        d      S )zY
    While similar to the TODAY() function, NOW() returns the current date AND time.
    NOWr   r=   r   r   rj  rj    s     r   c                    t        d|       S )zp
    Rounds positive value up the the nearest odd number and negative value down to the nearest odd number.
    ODDr   r   s    r   rl  rl    r   r   c                    t        d| |      S )z=
    Computes the specified base to the specified power.
    POWERr   )rQ  r!  s     r   rn  rn    s     u--r   c                      t        d      S )z/
    Returns the ID of the current record.
    	RECORD_IDr   r=   r   r   rp  rp    s     $$r   regexc                    t        d| |      S )zH
    Returns the first substring that matches a regular expression.
    REGEX_EXTRACTr   rI  rq  s     r   rs  rs    s     77r   c                    t        d| |      S )zF
    Returns whether the input text matches a regular expression.
    REGEX_MATCHr   rt  s     r   rv  rv    s     vu55r   replacementc                    t        d| ||      S )zN
    Substitutes all matching substrings with a replacement string value.
    REGEX_REPLACEr   )rI  rq  rw  s      r   ry  ry    s     DDr   start_characternumber_of_charactersc                     t        d| |||      S )zi
    Replaces the number of characters beginning with the start character with the replacement text.
    REPLACEr   )rI  rz  r{  rw  s       r   r}  r}    s     	6?<PR]^^r   c                    t        d| |      S )z:
    Repeats string by the specified number of times.
    REPTr   )rI  r   s     r   r  r    s     //r   c                    t        d| |      S )z@
    Extract howMany characters from the end of the string.
    RIGHTr   rM  s     r   r  r    s     22r   	precisionc                    t        d| |      S )a  
    Rounds the value to the number of decimal places given by "precision." (Specifically, ROUND will round to the nearest integer at the specified precision, with ties broken by `rounding half up toward positive infinity <https://en.wikipedia.org/wiki/Rounding#Round_half_up>`__.)
    ROUNDr   r   r  s     r   r  r    s     	22r   c                    t        d| |      S )z
    Rounds the value to the number of decimal places given by "precision," always `rounding down <https://en.wikipedia.org/wiki/Rounding#Rounding_to_integer>`__.
    	ROUNDDOWNr   r  s     r   r  r    s     UI66r   c                    t        d| |      S )z
    Rounds the value to the number of decimal places given by "precision," always `rounding up <https://en.wikipedia.org/wiki/Rounding#Rounding_to_integer>`__.
    ROUNDUPr   r  s     r   r  r    s     	5)44r   c                .    t        d| |gd |fD         S )z
    Searches for an occurrence of stringToFind in whereToSearch string starting from an optional startFromPosition. (startFromPosition is 0 by default.) If no occurrence of stringToFind is found, the result will be empty.
    SEARCHc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zSEARCH.<locals>.<genexpr>  s     DwPe1ijivQPer   r   r+  s      r   r  r    s"     ./xDwQdPeDwxxr   c                    t        d|       S )zJ
    Returns the second of a datetime as an integer between 0 and 59.
    SECONDr   r4  s    r   r  r    rb  r   locale_modifierc                    t        d| |      S )z
    Sets a specific locale for a datetime. **Must be used in conjunction with DATETIME_FORMAT.** A list of supported locale modifiers can be found `here <https://support.airtable.com/hc/en-us/articles/220340268>`__.
    
SET_LOCALEr   )r   r  s     r   r  r    s     dO<<r   tz_identifierc                    t        d| |      S )a  
    Sets a specific timezone for a datetime. **Must be used in conjunction with DATETIME_FORMAT.** A list of supported timezone identifiers can be found `here <https://support.airtable.com/hc/en-us/articles/216141558-Supported-timezones-for-SET-TIMEZONE>`__.
    SET_TIMEZONEr   )r   r  s     r   r  r     s     m<<r   c                    t        d|       S )z:
    Returns the square root of a nonnegative number.
    SQRTr   r   s    r   r  r    r   r   old_textnew_textindexc                0    t        d| ||gd |fD         S )zC
    Replaces occurrences of old_text in string with new_text.
    
SUBSTITUTEc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zSUBSTITUTE.<locals>.<genexpr>  s     Chw!Z[ZgAwr   r   )rI  r  r  r  s       r   r  r    s#     fhiChPUwChiir   c                    t        d| g| S )zI
    Sum together the numbers. Equivalent to number1 + number2 + ...
    SUMr   r   s     r   r  r    rZ  r   patternresultpattern_resultsc                     t        d| ||g| S )a  
    Takes an expression, a list of possible values for that expression, and for each one, a value that the expression should take in that case. It can also take a default value if the expression input doesn't match any of the defined patterns. In many cases, SWITCH() can be used instead `of a nested IF() formula <https://support.airtable.com/hc/en-us/articles/360041812413>`__.
    SWITCHr   )r5  r  r  r  s       r   r  r    s     *gvPPPr   c                    t        d|       S )zA
    Returns the argument if it is text and blank otherwise.
    Tr   r   s    r   r  r  #  s     U##r   	timestampc                    t        d|       S )z@
    Formats a datetime into a time-only string (HH:mm:ss).
    TIMESTRr   )r  s    r   r  r  *  s     	9--r   c                      t        d      S )z
    While similar to the NOW() function: TODAY() returns the current date (not the current time, if formatted, time will return 12:00am).
    TODAYr   r=   r   r   r  r  1  r   r   c                    t        d|       S )r0  TONOWr   r	  s    r   r  r  8  rh  r   c                    t        d|       S )z@
    Removes whitespace at the beginning and end of string.
    TRIMr   rP  s    r   r  r  ?  s     ''r   c                      t        d      S )zR
    Logical value true. The value of true is represented numerically by a 1.
    r   r   r=   r   r   r   r   F  s     r   c                    t        d|       S )z!
    Makes string uppercase.
    UPPERr   rP  s    r   r  r  M  rW  r   c                    t        d|       S )u$  
    Converts the text string to a number. Some exceptions apply—if the string contains certain mathematical operators(-,%) the result may not return as expected. In these scenarios we recommend using a combination of VALUE and REGEX_REPLACE to remove non-digit values from the string:
    VALUEr   )r   s    r   r  r  T  rh  r   start_day_of_weekc                ,    t        d| gd |fD         S )z
    Returns the day of the week as an integer between 0 (Sunday) and 6 (Saturday). You may optionally provide a second argument (either ``"Sunday"`` or ``"Monday"``) to start weeks on that day. If omitted, weeks start on Sunday by default.
    WEEKDAYc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zWEEKDAY.<locals>.<genexpr>_       *[6IQ]16Ir   r   r   r  s     r   r  r  [        	4\*[7H6I*[\\r   c                ,    t        d| gd |fD         S )z
    Returns the week number in a year. You may optionally provide a second argument (either ``"Sunday"`` or ``"Monday"``) to start weeks on that day. If omitted, weeks start on Sunday by default.
    WEEKNUMc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zWEEKNUM.<locals>.<genexpr>f  r  r   r   r  s     r   r  r  b  r  r   
start_datenum_daysholidaysc                .    t        d| |gd |fD         S )z
    Returns a date that is numDays working days after startDate. Working days exclude weekends and an optional list of holidays, formatted as a comma-separated string of ISO-formatted dates.
    WORKDAYc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zWORKDAY.<locals>.<genexpr>m  s     :bjTUTa1jr   r   )r  r  r  s      r   r  r  i  s      	:xc:bxj:bccr   end_datec                .    t        d| |gd |fD         S )z
    Counts the number of working days between startDate and endDate. Working days exclude weekends and an optional list of holidays, formatted as a comma-separated string of ISO-formatted dates.
    WORKDAY_DIFFc              3   &   K   | ]	  }||  y wr   r=   rj   s     r   rm   zWORKDAY_DIFF.<locals>.<genexpr>t  s     ?g:aYZYf:r   r   )r  r  r  s      r   r  r  p  s      
Hh?gH:?ghhr   r   c                    t        d| g| S )zB
    Returns true if an **odd** number of arguments are true.
    r2   r   )r5  r   s     r   r2   r2   w  s     z8K88r   c                    t        d|       S )z4
    Returns the four-digit year of a datetime.
    YEARr   r	  s    r   r  r  ~  s     %%r   r   )NN)rV   r   r   r   decimalr   	fractionsr   typingr   r   r   r   r	   r
   r   typing_extensionsr   r   r   pyairtable.api.typesr   pyairtable.exceptionsr   pyairtable.utilsr   r   r   rZ   r?   rA   rE   rH   rN   rK   rR   r_   r   r   r)   r/   r:   rX   r   r*   rW   ri   r   r   r\   r   r   r   r   rq   r   r   r   r   r   r   r   r   r  r  r  r  r  r  r   r  r  r  r  r#  r   r)  r-  r1  r3  r9  r;  r>  r@  rC  rF  rH  rL  rO  rS  rV  rY  r]  r_  ra  re  rg  rj  rl  rn  rp  rs  rv  ry  r}  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r2   r  )r   s   0r   <module>r     s	    	    F F F . ' ' 6 AN  N b&G &J JD   *  *  :<RS"c8RS8R3<<,8RS :$w :$z8U7HW$556 8# 8( 87E'8G#445 7 7 7%(8G$ %(# %(( %(P 6; 3 3d 3w 3l/(c /(g /(d"# "# "> #  #    2-S -S -& 	MM
Y 
27 2B>B&{ &, &5K 5k 5l 5!| !Y; Yh{.C YR^ Y5k 5k 5l 53+ 3K 3L 32+ 2; 2< 24K 4[ 4\ 4(l (8+ 8{ 8; 8l 8)+ )\ )> >[ > >T` >a+ ah{6K aZf ag gH[4I gZbcnZo g  K g%k % %B; Bl B!| !' '< '&{ &, &!| !w w{ wYabmYn w  ~J wW WH[,A WP\ W)+ )\ )*; *l *=; = = =S_ =&{ &, &)+ )\ )2K 2 2< 23[ 3 3L 37; 7{ 7+ 7\ 77 7 72 2 2< 2' '< 'N N8K#8 N| N)+ )\ )1 1+ 1, 1> >[ > >T` >1 1+ 1, 1,[ , ,/{ /[ / /' '< '\ &{ &, &. .K .| .%< %8+ 8k 8 86 6K 6| 6E+ Ek E E[g E_K _+ _U` _oz _  CO _0 0k 0 03+ 3 3L 33 3 3L 37[ 7[ 7 75; 5; 5l 5y; y y[cdo[p y  @L y,[ , ,=[ =; =l =={ =; =l =' '< 'j{ jk j[ jYabmYn j  ~J j1 1+ 1, 1Q{ Q[ Q+ Qdo Q  uA Q$[ $ $.{ ., .!| !' '< '( (L ( l  )+ )\ )' '< ']+ ](;2G ]Vb ]]+ ](;2G ]Vb ]d d{ dh{F[ djv di[ iK i8T_K` io{ i9K 9+ 9, 9&{ &, &w Ts   :Q2