o
    DfF                     @   sP   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ZG d	d
 d
eZ	dS )    N   )widgets   )Field)UnboundField)unset_value)	FieldListc                       s   e Zd ZdZe Z						d fdd	Zedfdd	Z	d
d Z
dddZdd ZdedfddZefddZdd Zdd Zdd Zdd Zedd Z  ZS ) r   a/  
    Encapsulate an ordered list of multiple instances of the same field type,
    keeping data as a list.

    >>> authors = FieldList(StringField('Name', [validators.DataRequired()]))

    :param unbound_field:
        A partially-instantiated field definition, just like that would be
        defined on a form directly.
    :param min_entries:
        if provided, always have at least this many entries on the field,
        creating blank ones if the provided input does not specify a sufficient
        amount.
    :param max_entries:
        accept no more than this many entries as input, even if more exist in
        formdata.
    :param separator:
        A string which will be suffixed to this field's name to create the
        prefix to enclosed list entries. The default is fine for most uses.
    Nr   - c           	         sz   t  j||fd|i| | jrtdt|tsJ d|| _|| _|| _d| _	|
dd| _|| _|j
dd| _d S )	NdefaultRFieldList does not accept any filters. Instead, define them on the enclosed field.z(Field must be unbound, not a field class_prefix 	separatorr	   )super__init__filters	TypeError
isinstancer   unbound_fieldmin_entriesmax_entries
last_indexgetr   
_separatorkwargs_field_separator)	selfr   label
validatorsr   r   r   r   r   	__class__r
   L/home/ubuntu/webapp/venv/lib/python3.10/site-packages/wtforms/fields/list.pyr   #   s"   zFieldList.__init__c              	   C   s  |rt dg | _|tu s|s"z|  }W n t y!   | j}Y nw || _|r`tt| | j|}| j	r<|d | j	 }t
|}|D ]}zt|}W n tyU   t}Y nw | j|||d qBn|D ]}| || qbt| j| jk r| | t| j| jk ssd S d S )Nr   )index)r   entriesr   r   object_datasortedset_extract_indicesnamer   iternextStopIteration
_add_entrylenr   )r   formdatadataextra_filtersindicesidatar$   obj_datar
   r
   r#   process?   s<   

zFieldList.processc                 c   sR    t |d }|D ]}||r&||d | jdd }| r&t|V  q	dS )a&  
        Yield indices of any keys with given prefix.

        formdata must be an object which will produce keys when iterated.  For
        example, if field 'foo' contains keys 'foo-0-bar', 'foo-1-baz', then
        the numbers 0 and 1 will be yielded, but not necessarily in order.
        r   Nr   )r/   
startswithsplitr   isdigitint)r   prefixr0   offsetkr
   r
   r#   r)   b   s   

zFieldList._extract_indicesc                 C   sl   g | _ | jD ]}|| | j |j  qtdd | j D s"g | _ t| j|}| || t	| j dkS )z
        Validate this FieldList.

        Note that FieldList validation differs from normal field validation in
        that FieldList validates all its enclosed fields first before running any
        of its own validators.
        c                 s   s    | ]}|V  qd S Nr
   ).0xr
   r
   r#   	<genexpr>   s    z%FieldList.validate.<locals>.<genexpr>r   )
errorsr%   validateappendany	itertoolschainr    _run_validation_chainr/   )r   formextra_validatorssubfieldrG   r
   r
   r#   rC   q   s   

zFieldList.validatec                 C   s   t ||d }zt|}W n ty   tg }Y nw t|td }tdtfi }g }t| j	|D ]\}}	| }
|	|
_
||
d ||
j
 q2t||| d S )N_faker1   )getattrr+   r   rF   rG   repeattypeobjectzipr%   r1   populate_objrD   setattr)r   objr*   valuesivalues
candidatesrL   outputfieldr1   fake_objr
   r
   r#   rR      s   zFieldList.populate_objc                 C   s   | j rt| j| j k sJ d|d u r| jd }|| _| j | j | }| j | j | }| jjd || j	|| j
| jd}||| | j| |S )Nz?You cannot have more than max_entries entries in this FieldListr   )rI   r*   r;   id_metatranslations)r   r/   r%   r   
short_namer   r[   r   bindr   meta_translationsr6   rD   )r   r0   r1   r$   r*   r[   rY   r
   r
   r#   r.      s*   
zFieldList._add_entryc                 C   s   | j |dS )z
        Create a new entry with optional default data.

        Entries added in this way will *not* receive formdata however, and can
        only receive object data.
        r1   )r.   )r   r1   r
   r
   r#   append_entry   s   zFieldList.append_entryc                 C   s   | j  }|  jd8  _|S )z4Removes the last entry from the list and returns it.r   )r%   popr   )r   entryr
   r
   r#   	pop_entry   s   
zFieldList.pop_entryc                 C   
   t | jS r>   )r+   r%   r   r
   r
   r#   __iter__      
zFieldList.__iter__c                 C   rg   r>   )r/   r%   rh   r
   r
   r#   __len__   rj   zFieldList.__len__c                 C   s
   | j | S r>   r%   )r   r$   r
   r
   r#   __getitem__   rj   zFieldList.__getitem__c                 C   s   dd | j D S )Nc                 S   s   g | ]}|j qS r
   rb   )r?   fr
   r
   r#   
<listcomp>   s    z"FieldList.data.<locals>.<listcomp>rl   rh   r
   r
   r#   r1      s   zFieldList.data)NNr   Nr	   r
   )r
   )__name__
__module____qualname____doc__r   
ListWidgetwidgetr   r   r6   r)   rC   rR   r.   rc   rf   ri   rk   rm   propertyr1   __classcell__r
   r
   r!   r#   r      s,    #
	r   )
rF   r   r   corer   r   wtforms.utilsr   __all__r   r
   r
   r
   r#   <module>   s    