
    K:g_                     v   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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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%m&Z&m'Z'm(Z( d dl)m*Z* d dl+m,Z,m-Z- d dl.m/Z/m0Z0 erd dl1m2Z2  G d d      Z3e G d d             Z4 ed       G d d             Z5y)    N)	dataclass)cached_property)TYPE_CHECKINGAnyClassVarDictIterableListMappingOptionalSetTypeUnioncast)Self)retrying)ApiTimeoutTuple)Base)Table)	FieldName
RecordDictRecordIdUpdateRecordDictWritableFields)EQOR	RECORD_ID)Comment)AnyFieldField)datetime_from_iso_strdatetime_to_iso_str)
_ClassInfoc                       e Zd ZU dZdZeed<   dZee	j                     ed<   e
d   ed<   dZeed	<   dZeed
<   eeef   ed<   eeef   ed<   e
eeef      ed<   def fdZed5d       Zedeeef   fd       Zedeeef   fd       ZdefdZdefdZdefdZdddeddfdZdefdZedddee   dedee   fd       Zedddee   dedee   fd        Z ed!edee   ddfd"       Z!d6d#ede"fd$Z#eddd%e"dee   defd&       Z$ed'dd(d)ed*edee   defd+       Z%d5d,Z&ed'dd(d-e'e   d*edee   dee   fd.       Z(ed/ee   ddfd0       Z)ed/ee   ddfd1       Z*dee+   fd2Z,d3ede+fd4Z- xZ.S )7Modela
  
    Supports creating ORM-style classes representing Airtable tables.
    For more details, see :ref:`orm`.

    A nested class or dict called ``Meta`` is required and can specify
    the following attributes:

        * ``api_key`` (required) - API key or personal access token.
        * ``base_id`` (required) - Base ID (not name).
        * ``table_name`` (required) - Table ID or name.
        * ``timeout`` - A tuple indicating a connect and read timeout. Defaults to no timeout.
        * ``typecast`` - |kwarg_typecast| Defaults to ``True``.
        * ``retry`` - An instance of `urllib3.util.Retry <https://urllib3.readthedocs.io/en/stable/reference/urllib3.util.html#urllib3.util.Retry>`_.
          If ``None`` or ``False``, requests will not be retried.
          If ``True``, the default strategy will be applied
          (see :func:`~pyairtable.retry_strategy` for details).
        * ``use_field_ids`` - Whether fields will be defined by ID, rather than name. Defaults to ``False``.
        * ``memoize`` - Whether the model should reuse models it creates between requests.
          See :ref:`Memoizing linked records` for more information.

    For example, the following two are equivalent:

    .. code-block:: python

        from pyairtable.orm import Model, fields

        class Contact(Model):
            class Meta:
                base_id = "appaPqizdsNHDvlEm"
                table_name = "Contact"
                api_key = "keyapikey"
                timeout = (5, 5)
                typecast = True

            first_name = fields.TextField("First Name")
            age = fields.IntegerField("Age")

    .. code-block:: python

        from pyairtable.orm import Model, fields

        class Contact(Model):
            Meta = {
                "base_id": "appaPqizdsNHDvlEm",
                "table_name": "Contact",
                "api_key": "keyapikey",
                "timeout": (5, 5),
                "typecast": True,
            }
            first_name = fields.TextField("First Name")
            age = fields.IntegerField("Age")

    You can implement meta attributes as callables if certain values
    need to be dynamically provided or are unavailable at import time:

    .. code-block:: python

        from pyairtable.orm import Model, fields
        from your_app.config import get_secret

        class Contact(Model):
            class Meta:
                base_id = "appaPqizdsNHDvlEm"
                table_name = "Contact"

                @staticmethod
                def api_key():
                    return get_secret("AIRTABLE_API_KEY")

            first_name = fields.TextField("First Name")
            age = fields.IntegerField("Age")
     idNcreated_time_MetametaF_deleted_fetched_fields_changed	_memoizedkwargsc                 r    t        |       | _        i | _        | j                          t	        |   di | y )N )r*   r+   r0   _validate_classsuper__init_subclass__)clsr1   	__class__s     Q/var/www/html/lionshead/venv/lib/python3.12/site-packages/pyairtable/orm/model.pyr6   zModel.__init_subclass__   s1    :!+F+    returnc                    | j                   j                  ddd      sJ | j                   j                  ddd      sJ | j                   j                  ddd      sJ | j                  j                         D cg c]  }|j	                  d      r| }}t        |      j                  t        j                  j                               }|r&t        dj                  | j                  |	            y c c}w )
Napi_keyTF)requiredcallbase_id
table_name__z5Class {cls} fields clash with existing method: {name})r7   name)r+   get__dict__keys
startswithsetintersectionr&   
ValueErrorformat__name__)r7   amodel_attributes
overriddens       r9   r4   zModel._validate_class   s     xx||I5|AAAxx||I5|AAAxx||L4e|DDD'*||'8'8':U':!!,,tBTA':U)*778K8K8MN
GNN: O    Vs   =C9C9c                     | j                   j                         D ci c]  \  }}t        |t              s|| c}}S c c}}w )a  
        Build a mapping of the model's attribute names to field descriptor instances.

        >>> class Test(Model):
        ...     first_name = TextField("First Name")
        ...     age = NumberField("Age")
        ...
        >>> Test._attribute_descriptor_map()
        >>> {
        ...     "field_name": <TextField field_name="First Name">,
        ...     "another_Field": <NumberField field_name="Age">,
        ... }
        )rE   items
isinstancer!   )r7   kvs      r9   _attribute_descriptor_mapzModel._attribute_descriptor_map   s<     "%!3!3!5N!5AAu9M1!5NNNs
   A A c                 z    | j                         j                         D ci c]  }|j                  | c}S c c}w )a  
        Build a mapping of the model's field names to field descriptor instances.

        >>> class Test(Model):
        ...     first_name = TextField("First Name")
        ...     age = NumberField("Age")
        ...
        >>> Test._field_name_descriptor_map()
        >>> {
        ...     "First Name": <TextField field_name="First Name">,
        ...     "Age": <NumberField field_name="Age">,
        ... }
        )rU   values
field_name)r7   fs     r9   _field_name_descriptor_mapz Model._field_name_descriptor_map   s8     *-)F)F)H)O)O)QR)QAa)QRRRs   8fieldsc                     	 |j                  d      | _        i | _        |j	                         D ]/  \  }}|| j                         vrt        |      t        | ||       1 i | _        y# t        $ r Y \w xY w)av  
        Construct a model instance with field values based on the given keyword args.

        >>> Contact(name="Alice", birthday=date(1980, 1, 1))
        <unsaved Contact>

        The keyword argument ``id=`` special-cased and sets the record ID, not a field value.

        >>> Contact(id="recWPqD9izdsNvlE", name="Bob")
        <Contact id='recWPqD9izdsNvlE'>
        r(   N)	popr(   KeyErrorr.   rQ   rU   AttributeErrorsetattrr/   )selfr[   keyvalues       r9   __init__zModel.__init__   s{    	jj&DG
  !,,.JC$88::$S))D#u% )   		s   A) )	A54A5c                     | j                   sd| j                  j                   dS d| j                  j                   d| j                   dS )Nz	<unsaved ><z id=)r(   r8   rL   ra   s    r9   __repr__zModel.__repr__   sG    wwt~~667q994>>**+4{!<<r:   c                 ,    t        | j                        S )zJ
        Whether the instance has been saved to Airtable already.
        )boolr(   rh   s    r9   existszModel.exists   s     DGG}r:   )forcerm   
SaveResultc                   | j                   rt        | j                   d      | j                  d      d   }| j                  s| j                  j
                  j                  || j                  j                  | j                  j                        }|d   | _        t        |d         | _
        | j                  j                          t        | j                  dt        |            S |s_| j                  st        | j                        S |j                         D ci c]#  \  }}| j                  j!                  |      r||% }}}| j                  j
                  j#                  | j                  || j                  j                  | j                  j                         | j                  j                          t        | j                  |dt        |      	      S c c}}w )
a`  
        Save the model to the API.

        If the instance does not exist already, it will be created;
        otherwise, the existing record will be updated, using only the
        fields which have been modified since it was retrieved.

        Args:
            force: If ``True``, all fields will be saved, even if they have not changed.
        z was deletedTonly_writabler[   typecastuse_field_idsr(   createdTime)createdfield_names)forcedupdatedrw   )r,   RuntimeErrorr(   	to_recordr+   tablecreaters   rt   r"   r)   r/   clearrn   rH   rQ   rD   update)ra   rm   field_valuesrecordrX   rc   s         r9   savez
Model.save   s    ==$'',788~~D~9(CwwYY__++++"ii55 , F
 TlDG 5f]6K LDMM!dggt\ARSS==!$''** *6););)=)=%J==$$Z0 E!)=   			GGYY''))11	 	 	
 	GGE4S=N
 	
s   $(G&c                     | j                   st        d      | j                  j                  }|j	                  | j                         }d| _        t        |d         S )zk
        Delete the record.

        Raises:
            ValueError: if the record does not exist.
        z-cannot be deleted because it does not have idTdeleted)r(   rJ   r+   r|   deleter,   rk   )ra   r|   results      r9   r   zModel.delete  sM     wwLMM		dgg&F9%&&r:   memoizer   c                    |j                  | j                  j                          | j                  j                  j                  di |D cg c]  }| j                  ||       c}S c c}w )z
        Retrieve all records for this model. For all supported
        keyword arguments, see :meth:`Table.all <pyairtable.Table.all>`.

        Args:
            memoize: |kwarg_orm_memoize|
        r   r3   )r   r+   request_kwargsr|   allfrom_recordr7   r   r1   r   s       r9   r   z	Model.all%  sf     	chh--. -#((..,,6v6
6 OOFGO46
 	
 
s   A+c                    |j                  | j                  j                          | j                  j                  j                  di |x}r| j                  ||      S y)z
        Retrieve the first record for this model. For all supported
        keyword arguments, see :meth:`Table.first <pyairtable.Table.first>`.

        Args:
            memoize: |kwarg_orm_memoize|
        r   Nr3   )r   r+   r   r|   firstr   r   s       r9   r   zModel.first4  sS     	chh--.)SXX^^))3F3363??67?;;r:   instancec                 p    || j                   j                  n|}|r|| j                  |j                  <   yy)zX
        If memoization is enabled, save the instance to the memoization cache.
        N)r+   r   r0   r(   )r7   r   r   s      r9   _maybe_memoizezModel._maybe_memoizeD  s3    
 '.o#((""7)1CMM(++& r:   rq   c                 <   | j                         }| j                  j                         D ci c]/  \  }}||   j                  r|s||dn||   j	                  |      1 }}}| j
                  rt        | j
                        nd}| j                  ||dS c c}}w )a  
        Build a :class:`~pyairtable.api.types.RecordDict` to represent this instance.

        This method converts internal field values into values expected by Airtable.
        For example, a ``datetime`` value from :class:`~pyairtable.orm.fields.DatetimeField`
        is converted into an ISO 8601 string.

        Args:
            only_writable: If ``True``, the result will exclude any
                values which are associated with readonly fields.
        Nr'   )r(   ru   r[   )rZ   r.   rQ   readonlyto_record_valuer)   r#   r(   )ra   rq   map_fieldrc   r[   cts          r9   r{   zModel.to_recordM  s     ..0 !% 2 2 4
 4uK((] 5=4d5k.I.I%.PP 4 	 

 8<7H7H !2!23bggbFCC
s   4Br   c                0   | j                         }|d   j                         D ci c]"  \  }}||v r||||   j                  |      nd$ }}} | |d         }||_        d|_        t        |d         |_        | j                  ||       |S c c}}w )z
        Create an instance from a record dict.

        Args:
            record: The record data from the Airtable API.
            memoize: |kwarg_orm_memoize|
        r[   Nr(   r(   Tru   )rZ   rQ   to_internal_valuer.   r-   r"   r)   r   )r7   r   r   name_field_mapr   rc   r   r   s           r9   r   zModel.from_recordb  s     779 #)"2"8"8":

 #;& $ u%77>
 #; 	 

 &,''  5f]6K L8W-%

s   'BT)fetchr   	record_idr   c                    	 t        t        | j                  |         }|r|j                  s|j                          | j                  ||       |S # t        $ r  | |      }Y Fw xY w)z
        Create an instance from a record ID.

        Args:
            record_id: |arg_record_id|
            fetch: |kwarg_orm_fetch|
            memoize: |kwarg_orm_memoize|
        r   )r   SelfTyper0   r^   r-   r   r   )r7   r   r   r   r   s        r9   from_idzModel.from_id  sc     	)HcmmI&>?H **NN8W-  	)i(H	)s   A A&%A&c                 h   | j                   st        d       | j                  j                  j                  | j                   fi | j                  j
                  }| j                  |d      }|j                  | _        | j                  j                          d| _
        |j                  | _        y)zS
        Fetch field values from the API and resets instance field values.
        z6cannot be fetched because instance does not have an idFr   TN)r(   rJ   r+   r|   rD   r   r   r.   r/   r~   r-   r)   )ra   r   unuseds      r9   r   zModel.fetch  s     wwUVV$$$TWWI		0H0HI!!&%!8~~"//r:   
record_idsc                   |s!|D cg c]  }| j                  |d       c}S t        |      }i }| j                  r(|D ]#  }	 t        t        | j                  |         ||<   % t        t        |      t        |      z
        x}rVt        d t        |      D              }|j                  | j                  ||      D ci c]  }|j                  | c}       |D cg c]  }||   	 c}S c c}w # t
        $ r Y w xY wc c}w c c}w )aW  
        Create a list of instances from record IDs. If any record IDs returned
        are invalid this will raise a KeyError, but only *after* retrieving all
        other valid records from the API.

        Args:
            record_ids: |arg_record_id|
            fetch: |kwarg_orm_fetch|
            memoize: |kwarg_orm_memoize|
        F)r   c              3   D   K   | ]  }t        t               |        y wN)r   r   ).0r   s     r9   	<genexpr>z!Model.from_ids.<locals>.<genexpr>  s     WEV	IK3EVs    )formular   )r   listr0   r   r   r^   sortedrH   r   r   r   r(   )	r7   r   r   r   r   by_id	remainingr   objs	            r9   from_idszModel.from_ids  s   $ ISTICKK	K7TT*%
*,=='	'+HcmmI6N'OE)$ ( s:U;<<9<WVIEVWWGLL(+(QR(Q(QR
 3==*Yi *==) U    S >s#   C0 C5D!D	5	D Dmodelsc                 L    t         fd|D              st        t        d |D                    |D cg c]  }|j                  r| }}|D cg c]  }|j                  s| }}|D cg c]  }|j	                  d      x}r|d    }}|D cg c]!  }|j	                  d      x}r|d   |d   d# }}|rP j
                  j                  j                  | j
                  j                   j
                  j                         |r j
                  j                  j                  | j
                  j                   j
                  j                        }t        ||      D ]"  \  }}|d   |_        t        |d	         |_        $ y
y
c c}w c c}w c c}w c c}w )z
        Save a list of model instances to the Airtable API with as few
        network requests as possible. Can accept a mixture of new records
        (which have not been saved yet) and existing records that have IDs.
        c              3   6   K   | ]  }t        |        y wr   rR   r   modelr7   s     r9   r   z#Model.batch_save.<locals>.<genexpr>       >ve:eS)v   c              3   2   K   | ]  }t        |        y wr   typer   r   s     r9   r   z#Model.batch_save.<locals>.<genexpr>       @U   Trp   r[   r(   )r(   r[   rr   ru   N)r   	TypeErrorrH   r(   r{   r+   r|   batch_updaters   rt   batch_createzipr"   r)   )	r7   r   r   create_modelsupdate_modelsr   create_recordsupdate_recordscreated_recordss	   `        r9   
batch_savezModel.batch_save  s    >v>>C@@@AA,2CF5%((FC,2?F5ehhF? '0
&///=== 8& 	 0
 '2
&///=== $<6(+;<& 	 2
 HHNN''**!hh44 ( 
 !hhnn99**!hh44 : O
 "%]O!Dv!$<%:6-;P%Q" "E ' D?0

2
s#   FFF#F- F&F!c                 "    t        d |D              st        d      t         fd|D              st        t        d |D                     j                  j
                  j                  |D cg c]  }|j                   c}       yc c}w )z
        Delete a list of model instances from Airtable.

        Raises:
            ValueError: if the model has not been saved to Airtable.
        c              3   4   K   | ]  }|j                     y wr   r   r   s     r9   r   z%Model.batch_delete.<locals>.<genexpr>  s     0588s   zcannot delete an unsaved modelc              3   6   K   | ]  }t        |        y wr   r   r   s     r9   r   z%Model.batch_delete.<locals>.<genexpr>  r   r   c              3   2   K   | ]  }t        |        y wr   r   r   s     r9   r   z%Model.batch_delete.<locals>.<genexpr>  r   r   N)r   rJ   r   rH   r+   r|   batch_deleter(   )r7   r   r   s   `  r9   r   zModel.batch_delete  so     000=>>>v>>C@@@AA##6$B6%UXX6$BC$Bs   1Bc                 `    | j                   j                  j                  | j                        S )z{
        Return a list of comments on this record.
        See :meth:`Table.comments <pyairtable.Table.comments>`.
        )r+   r|   commentsr(   rh   s    r9   r   zModel.comments  s!    
 yy''00r:   textc                 b    | j                   j                  j                  | j                  |      S )zu
        Add a comment to this record.
        See :meth:`Table.add_comment <pyairtable.Table.add_comment>`.
        )r+   r|   add_commentr(   )ra   r   s     r9   r   zModel.add_comment  s#    
 yy**477D99r:   )r;   N)F)/rL   
__module____qualname____doc__r(   str__annotations__r)   r   datetimer   r,   rk   r-   r   r   r   r   r   r6   classmethodr4   r    rU   rZ   rd   ri   rl   r   r   r
   r   r   r   r   r{   r   r   r   r	   r   r   r   r   r   r   __classcell__)r8   s   @r9   r&   r&   +   s.   GV BL 15L(8,,-4 7
HdHd)S.!!9d?##Xx/011, ,   O$sH}*= O O  S4	80C+D S S  <=# =
  %* -
T -
l -
^' ' .2 
Xd^ 
c 
d8n 
 
 *.!$:=	(	  2h 2$ 2D 2 2Dt D
 D* >B-5d^	 @ 
 "& 	
 $ 
 00 
 "&&>X&&> 	&>
 $&> 
h&> &>P $RX $R4 $R $RL D$x. DT D D1$w- 1: : :r:   r&   c                      e Zd ZU dZee   ed<   edee	e
f   fd       Z	 	 	 	 dde	de
ded	ed
ed   de
fdZede	fd       Zedee   fd       Zedeeeej(                  f      fd       Zedefd       Zede	fd       Zedefd       Zede	fd       Zedefd       Zedefd       Zedefd       Z edefd       Z!ede"e	e
f   fd       Z#y)r*   z
    Wrapper around a Model.Meta class that provides easier, typed access to
    configuration values (which may or may not be defined in the original class).
    r   r;   c                 `   t        | j                  dd       x}s"t        | j                  j                   d      t	        |t
              r|S 	 t        t        t        t        f   |j                        S # t        $ r. t        | j                  j                   dt        |             w xY w)NMetaz.Meta must be definedz#.Meta must be a dict or class; got )getattrr   r_   rL   rR   dictr   r   r   r   rE   r   r   )ra   r+   s     r9   _configz_Meta._config   s    

FD999 DJJ$7$7#88M!NOOdD!K	S)4==99 	::&&''J4PT:,W 	s   &A6 67B-NrC   defaultr>   r?   check_typesr$   c                 r   |r3|| j                   vr%t        | j                  j                   d| d      | j                   j	                  ||      }t        |      r	|r |       }|r'|%t        | j                  j                   d| d      |&t        ||      st        d|dt        |             |S )a+  
        Given a name, retrieve the model configuration with that name.

        Args:
            default: The default value to use if the name is not defined.
            required: If ``True``, raises ``ValueError`` if the name is undefined or None.
            call: If ``False``, does not execute any callables to retrieve this value;
                  it will consider the callable itself as the value.
            check_types: If set, will raise a ``TypeError`` if the value is not
                         an instance of the given type(s).
        z.Meta.z must be definedz cannot be Nonez	expected z; got )	r   rJ   r   rL   rD   callablerR   r   r   )ra   rC   r   r>   r?   r   rc   s          r9   rD   z	_Meta.get-  s    & DLL0

 3 34F4&@PQRR  w/E?tGE

 3 34F4&PQQ":e[+IifT%[MJKKr:   c                 :    t        | j                  dd            S )Nr=   Tr>   r   rD   rh   s    r9   r=   z_Meta.api_keyK      488I8566r:   c                 H    | j                  dd t        d       t        f      S )Ntimeoutr   r   )rD   r   tuplerh   s    r9   r   z_Meta.timeoutO  s*    xxdU+  
 	
r:   c                 f    | j                  ddt        d       t        t        j                  f      S )NretryTr   )rD   r   rk   r   Retryrh   s    r9   retry_strategyz_Meta.retry_strategyW  s0    xxdT8>>:  
 	
r:   c                 Z    t        | j                  | j                  | j                        S )N)r   r   )r   r=   r   r   rh   s    r9   apiz	_Meta.api_  s&    LLLL..
 	
r:   c                 :    t        | j                  dd            S )Nr@   Tr   r   rh   s    r9   r@   z_Meta.base_idg  r   r:   c                 L    | j                   j                  | j                        S r   )r   baser@   rh   s    r9   r   z
_Meta.basek  s    xx}}T\\**r:   c                 :    t        | j                  dd            S )NrA   Tr   r   rh   s    r9   rA   z_Meta.table_nameo  s    488L48899r:   c                 L    | j                   j                  | j                        S r   )r   r|   rA   rh   s    r9   r|   z_Meta.tables  s    yyt//r:   c                 :    t        | j                  dd            S )Nrs   Tr   rk   rD   rh   s    r9   rs   z_Meta.typecastw  s    DHHZH677r:   c                 :    t        | j                  dd            S )Nrt   Fr   r   rh   s    r9   rt   z_Meta.use_field_ids{  s    DHH_eH<==r:   c                 :    t        | j                  dd            S )Nr   Fr   r   rh   s    r9   r   z_Meta.memoize  s    DHHYH677r:   c                 $    d dd | j                   dS )Njson)user_localecell_format	time_zonert   )rt   rh   s    r9   r   z_Meta.request_kwargs  s       !!//	
 	
r:   )NFTN)$rL   r   r   r   r   r&   r   propertyr   r   r   r   rk   r   rD   r=   r   r   r   r   r   r   r   r   r   r@   r   r   rA   r   r|   rs   rt   r   r   r   r3   r:   r9   r*   r*     s   
 ;
c* 
 
 .2  	
  l+ 
< 7 7 7 
,/ 
 
 
tX^^/C)D E 
 
 
S 
 
 7 7 7 +d + + :C : : 0u 0 0 8$ 8 8 >t > > 8 8 8 
S#X 
 
r:   r*   T)frozenc                       e Zd ZU dZeed<   dZeed<   dZeed<   dZ	eed<    e
j                  e      Zee   ed<   d	efd
Zed	efd       Zy)rn   a  
    Represents the result of saving a record to the API. The result's
    attributes contain more granular information about the save operation:

        >>> result = model.save()
        >>> result.record_id
        'recWPqD9izdsNvlE'
        >>> result.created
        False
        >>> result.updated
        True
        >>> result.forced
        False
        >>> result.field_names
        {'Name', 'Email'}

    If none of the model's fields have changed, calling :meth:`~pyairtable.orm.Model.save`
    will not perform any API requests and will return a SaveResult with no changes.

        >>> model = YourModel()
        >>> result = model.save()
        >>> result.saved
        True
        >>> second_result = model.save()
        >>> second_result.saved
        False

    For backwards compatibility, instances of SaveResult will evaluate as truthy
    if the record was created, and falsy if the record was not created.
    r   Frv   ry   rx   )default_factoryrw   r;   c                 R    t        j                  dt        d       | j                  S )a  
        Returns ``True`` if the record was created. This is for backwards compatibility
        with the behavior of :meth:`~pyairtable.orm.Model.save` prior to the 3.0 release,
        which returned a boolean indicating whether a record was created.
        z|Model.save() now returns SaveResult instead of bool; switch to checking Model.save().created instead before the 4.0 release.   )
stacklevel)warningswarnDeprecationWarningrv   rh   s    r9   __bool__zSaveResult.__bool__  s(     	P		
 ||r:   c                 6    | j                   xs | j                  S )z
        Whether the record was saved to the API. If ``False``, this indicates there
        were no changes to the model and the :meth:`~pyairtable.orm.Model.save`
        operation was not forced.
        )rv   ry   rh   s    r9   savedzSaveResult.saved  s     ||+t||+r:   N)rL   r   r   r   r   r   rv   rk   ry   rx   dataclassesr   rH   rw   r   r   r  r  r  r3   r:   r9   rn   rn     so    > GTGTFD"3+"3"3C"HKYH$  ,t , ,r:   rn   )6r  r   r	  r   	functoolsr   typingr   r   r   r   r	   r
   r   r   r   r   r   r   typing_extensionsr   r   pyairtable.apir   pyairtable.api.apir   r   pyairtable.api.baser   pyairtable.api.tabler   pyairtable.api.typesr   r   r   r   r   pyairtable.formulasr   r   r   pyairtable.modelsr   pyairtable.orm.fieldsr    r!   pyairtable.utilsr"   r#   builtinsr$   r&   r*   rn   r3   r:   r9   <module>r     s       ! %    / # 0 $ &  2 1 % 1 G#i: i:X r
 r
 r
j $;, ;, ;,r:   