o
    "ch؉                     @  s  U d dl mZ d dlZd dlZd dlmZmZmZmZm	Z	 d dl
mZ ddlmZ G dd de	Zed	d
dZd`ddZdaddZddgfdbddZdcddddZddgfdbddZd`d d!Zd`d"d#Zd`d$d%Zd`d&d'Zd`d(d)Zd`d*d+Zded/d0Zddgfdfd3d4Zd`d5d6Zdgd8d9Zdhd=d>Z did@dAZ!djdCdDZ"dkdFdGZ#dldIdJZ$dmdLdMZ%dndNdOZ&dodpdSdTZ'dUZ(dVe)dW< dqdYdZZ*drd^d_Z+dS )s    )annotationsN)AnyTypeVarCallableOptional
NamedTuple)	TypeAlias   )pandasc                   @  s^   e Zd ZU ded< dZded< dZded< dZded< dZded	< dZded
< dZ	ded< dS )RemediationstrnameNzOptional[str]immediate_msgnecessary_msgzOptional[Callable[[Any], Any]]necessary_fnoptional_msgoptional_fn	error_msg)
__name__
__module____qualname____annotations__r   r   r   r   r   r    r   r   T/home/air/goalskill/back/venv/lib/python3.10/site-packages/openai/lib/_validators.pyr      s   
 r   OptionalDataFrameTzOptional[pd.DataFrame])bounddfpd.DataFramereturnc                 C  s8   d}t | |kr
dnd}dt |  d| }td|dS )z
    This validator will only print out the number of examples and recommend to the user to increase the number of examples if less than 100.
    d    z. In general, we recommend having at least a few hundred examples. We've found that performance tends to linearly increase for every doubling of the number of examplesz
- Your file contains z prompt-completion pairsnum_examplesr   r   )lenr   )r   MIN_EXAMPLESoptional_suggestionr   r   r   r   num_examples_validator   s   r&   necessary_columnr   c                   s   ddd d}d}d}d}| j vr9d	d
 | j D v r3d fdd}|}d d}d d}nd d}td||||dS )z[
    This validator will ensure that the necessary column is present in the dataframe.
    r   r   columnr   r   c                   s2    fdd| j D }| j|d   idd | S )Nc                   s    g | ]}t |  kr|qS r   r   lower.0cr(   r   r   
<listcomp>-   s     zInecessary_column_validator.<locals>.lower_case_column.<locals>.<listcomp>r   T)columnsinplace)r0   renamer*   )r   r(   colsr   r.   r   lower_case_column,   s   z5necessary_column_validator.<locals>.lower_case_columnNc                 S  s   g | ]}t | qS r   r)   r+   r   r   r   r/   7       z.necessary_column_validator.<locals>.<listcomp>c                   
    | S Nr   )r   r4   r'   r   r   lower_case_column_creator9      
z=necessary_column_validator.<locals>.lower_case_column_creatorz
- The `z ` column/key should be lowercasezLower case column name to ``z^` column/key is missing. Please make sure you name your columns/keys appropriately, then retryr'   )r   r   r   r   r   )r   r   r(   r   r   r   )r   r   r   r   )r0   r   )r   r'   r   r   r   r   r9   r   r8   r   necessary_column_validator'   s&   

r<   prompt
completionfields	list[str]c                   s   g }d}d}d}t | jdkrMfdd| jD }d}|D ]  fdd|D }t |dkr9|d  d	  d
7 }qd| | }d| }dfdd}td|||dS )zK
    This validator will remove additional columns from the dataframe.
    Nr	   c                   s   g | ]}| vr|qS r   r   r+   r?   r   r   r/   U   r5   z/additional_column_validator.<locals>.<listcomp>r    c                   s   g | ]} |v r|qS r   r   r+   )acr   r   r/   X   r5   r   z9
  WARNING: Some of the additional columns/keys contain `z<` in their name. These will be ignored, and the column/key `z`` will be used instead. This could also result from a duplicate column/key in the provided file.zh
- The input file should contain exactly two columns/keys per row. Additional columns/keys present are: z Remove additional columns/keys: xr   r   c                   s   |   S r7   r   rC   rA   r   r   r   ^   s   z1additional_column_validator.<locals>.necessary_fnadditional_columnr   r   r   r   rC   r   r   r   )r#   r0   r   )r   r?   additional_columnsr   r   r   warn_messagedupsr   )rB   r?   r   additional_column_validatorK   s*   
rK   fieldc                   s   d}d}d}|    dd  s|     rH|   dk|    B }|  j|  }d  d| }d fd
d}dt| d  d}td  |||dS )zA
    This validator will ensure that no completion is empty.
    Nc                 S  s   | dkS )Nr    r   rD   r   r   r   <lambda>q   s    z+non_empty_field_validator.<locals>.<lambda>r    z
- `z?` column/key should not contain empty strings. These are rows: rC   r   r   c                   s   | |   dk j  gdS )Nr    subset)dropnarD   rL   r   r   r   v   s   z/non_empty_field_validator.<locals>.necessary_fnRemove z rows with empty sempty_rF   rG   )applyanyisnullreset_indexindextolistr#   r   )r   rL   r   r   r   
empty_rowsempty_indexesr   rQ   r   non_empty_field_validatori   s   &r]   c                   s   | j  d}|  j|  }d}d}d}t|dkr:dt| dd  d| }dt| d	}d fdd}td|||dS )zY
    This validator will suggest to the user to remove duplicate rows if they exist.
    rN   Nr   
- There are z duplicated -z sets. These are rows: rR   z duplicate rowsrC   r   r   c                   s   | j  dS )NrN   )drop_duplicatesrD   rA   r   r   r         z.duplicated_rows_validator.<locals>.optional_fnduplicated_rowsr   r   r   r   rG   )
duplicatedrX   rY   rZ   r#   joinr   )r   r?   rb   duplicated_indexesr   r   r   r   rA   r   duplicated_rows_validator   s    rg   c                   s   d}d}d}t | }|dkr8ddd  | td	kr8d
t d d}dt d}d fdd}td|||dS )zW
    This validator will suggest to the user to remove examples that are too long.
    Nopen-ended generationdr   r   r   c                 S  s$   | j dd dd}|  j|  S )Nc                 S  s   t | jt | j dkS )Ni'  )r#   r=   r>   rD   r   r   r   rM      r5   zClong_examples_validator.<locals>.get_long_indexes.<locals>.<lambda>   )axis)rU   rX   rY   rZ   )ri   long_examplesr   r   r   get_long_indexes   s   z1long_examples_validator.<locals>.get_long_indexesr   r^   z. examples that are very long. These are rows: zf
For conditional generation, and for classification the examples shouldn't be longer than 2048 tokens.rR   z long examplesrC   c                   s8    | }|krt jdt| d| d | |S )NzeThe indices of the long examples has changed as a result of a previously applied recommendation.
The z? long examples to be dropped are now at the following indices: 
)sysstdoutwriter#   drop)rC   long_indexes_to_droprm   long_indexesr   r   r      s   
z,long_examples_validator.<locals>.optional_fnrl   rc   )ri   r   r   r   rG   )infer_task_typer#   r   )r   r   r   r   ft_typer   rt   r   long_examples_validator   s"   
rx   c                   sp  d}d}d}d}dg d}|D ]}|dkr | j jd r q| j jj|dd r,q| dd}t| }|d	krBtd
dS d$dd t| j dd}	| j |	k rad|	 d}td
|dS |	dkr|	dd}
d|
 d}t	|	dkr|d| d7 }| j jdt	|	  jj|	dd r|d|	 d7 }nd}|	dkrd| d}d% fd d!}td"||||d#S )&z
    This validator will suggest to add a common suffix to the prompt if one doesn't already exist in case of classification or conditional generation.
    Nz


### =>

) ->z

###

z

===

z

---

z

===>

z

--->

ry   rn   Fregex\nrh   common_suffixr   rC   r   suffixr   c                 S     | d  |7  < | S Nr=   r   rC   r   r   r   r   
add_suffix      z2common_prompt_suffix_validator.<locals>.add_suffixxfixzAll prompts are identical: `zt`
Consider leaving the prompts blank if you want to do open-ended generation, otherwise ensure prompts are differentr   r   r    z 
- All prompts end with suffix `r;   
   R. This suffix seems very long. Consider replacing with a shorter suffix, such as `z5
  WARNING: Some of your prompts contain the suffix `zZ` more than once. We strongly suggest that you review your prompts and add a unique suffixa  
- Your data does not contain a common separator at the end of your prompts. Having a separator string appended to the end of the prompt makes it clearer to the fine-tuned model where the completion should begin. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples. If you intend to do open-ended generation, then you should leave the prompts emptyzAdd a suffix separator `z` to all promptsc                   r6   r7   r   rD   r   suggested_suffixr   r   r      r:   z3common_prompt_suffix_validator.<locals>.optional_fncommon_completion_suffixr   r   r   r   r   rC   r   r   r   r   r   rG   )
r=   r   containsrV   replacerv   r   get_common_xfixallr#   )r   r   r   r   r   suffix_optionssuffix_optiondisplay_suggested_suffixrw   r}   common_suffix_new_line_handledr   r   r   common_prompt_suffix_validator   sT   

&r   c                   s   d}d}d}d}t | jdd  dkrtddS ddd| j k r)tddS  dkrKd  d}|t k rK|d7 }d  d}d fdd}td|||dS )zd
    This validator will suggest to remove a common prefix from the prompt if a long one exist.
       Nprefixr   r    common_prefixr~   rC   r   r   c                 S  s   | d j t|d  | d< | S r   r   r#   )rC   r   r   r   r   remove_common_prefix  s   z<common_prompt_prefix_validator.<locals>.remove_common_prefixz"
- All prompts start with prefix `r;   z. Fine-tuning doesn't require the instruction specifying the task, or a few-shot example scenario. Most of the time you should only add the input data into the prompt, and the desired output into the completionRemove prefix `z` from all promptsc                   s
   |  S r7   r   rD   r   r   r   r   r   !  r:   z3common_prompt_prefix_validator.<locals>.optional_fncommon_prompt_prefixrc   )rC   r   r   r   r   r   rG   )r   r=   r   r   r#   r   MAX_PREFIX_LENr   r   r   r   r   r   common_prompt_prefix_validator  s,   


r   c                   s   d}t | jdd t dko d dkt |k r tddS ddd| j k r1tddS d  d}d  d}d fdd}td|||dS )zh
    This validator will suggest to remove a common prefix from the completion if a long one exist.
       r   r   r    r   r~   rC   r   	ws_prefixr   c                 S  s4   | d j t|d  | d< |rd| d  | d< | S )Nr>   r   r   )rC   r   r   r   r   r   r   7  s   z@common_completion_prefix_validator.<locals>.remove_common_prefixz&
- All completions start with prefix `z_`. Most of the time you should only add the output data into the completion, without any prefixr   z` from all completionsc                   s   |  S r7   r   rD   r   r   r   r   r   r   E  ra   z7common_completion_prefix_validator.<locals>.optional_fncommon_completion_prefixrc   N)rC   r   r   r   r   r   r   r   rG   )r   r>   r#   r   r   r   r   r   r   "common_completion_prefix_validator,  s"   


r   c                   sb  d}d}d}d}t | }|dks|dkrtddS t| jdd}| j|k r6d| d	| d
}td|dS dg d}|D ]}| jjj|dd rLq>| dd}	d$dd |dkr|dd}
d|
 d
}t	|dkrx|d|	 d
7 }| jjdt	|  jj|dd r|d| d7 }nd}|dkrd|	 d}d% fd d!}td"||||d#S )&z
    This validator will suggest to add a common suffix to the completion if one doesn't already exist in case of classification or conditional generation.
    Nrh   classificationr}   r~   r   r   z All completions are identical: `zJ`
Ensure completions are different, otherwise the model will just repeat `r;   r   z [END])	rn   .z ENDz***z+++z&&&z$$$z@@@z%%%Frz   rn   r|   rC   r   r   c                 S  r   Nr>   r   r   r   r   r   r   v  r   z6common_completion_suffix_validator.<locals>.add_suffixr    z$
- All completions end with suffix `r   r   z9
  WARNING: Some of your completions contain the suffix `zU` more than once. We suggest that you review your completions and add a unique endingaH  
- Your data does not contain a common ending at the end of your completions. Having a common ending string appended to the end of the completion makes it clearer to the fine-tuned model where the completion should end. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detail and examples.zAdd a suffix ending `z` to all completionsc                   r6   r7   r   rD   r   r   r   r     r:   z7common_completion_suffix_validator.<locals>.optional_fnr   r   r   rG   )
rv   r   r   r>   r   r   r   rV   r   r#   )r   r   r   r   r   rw   r}   r   r   r   r   r   r   r   "common_completion_suffix_validatorP  sN   

&r   c                 C  s^   ddd}d}d}d}| j jdd  dks!| j jd d d	kr'd
}d}|}td|||dS )z
    This validator will suggest to add a space at the start of the completion if it doesn't already exist. This helps with tokenization.
    rC   r   r   c                 S  s   | d  dd | d< | S )Nr>   c                 S  s   |  dr	d|  S d|  S )Nr   r    )
startswith)rS   r   r   r   rM         zLcompletions_space_start_validator.<locals>.add_space_start.<locals>.<lambda>)rU   rD   r   r   r   add_space_start  s   z:completions_space_start_validator.<locals>.add_space_startNrj   r   r   z
- The completion should start with a whitespace character (` `). This tends to produce better results due to the tokenization we use. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz=Add a whitespace character to the beginning of the completioncompletion_space_startrc   rG   )r>   r   nuniquevaluesr   )r   r   r   r   r   r   r   r   !completions_space_start_validator  s   
,r   r(   r   Remediation | Nonec                   sp   d fdd}|    dd  }|    dd  }|d	 |kr6td
d  d  dd  d|dS dS )zt
    This validator will suggest to lowercase the column values, if more than a third of letters are uppercase.
    rC   r   r   c                   s   |   j  |  < | S r7   r)   rD   r.   r   r   
lower_case  s   z(lower_case_validator.<locals>.lower_casec                 S     t dd | D S )Nc                 s  $    | ]}|  r| rd V  qdS rj   N)isalphaisupperr+   r   r   r   	<genexpr>     " 9lower_case_validator.<locals>.<lambda>.<locals>.<genexpr>sumrD   r   r   r   rM         z&lower_case_validator.<locals>.<lambda>c                 S  r   )Nc                 s  r   r   )r   islowerr+   r   r   r   r     r   r   r   rD   r   r   r   rM     r   r	   r   z
- More than a third of your `z%` column/key is uppercase. Uppercase zs tends to perform worse than a mixture of case encountered in normal language. We recommend to lower case the data if that makes sense in your domain. See https://platform.openai.com/docs/guides/fine-tuning/preparing-your-dataset for more detailsz'Lowercase all your data in column/key `r;   rc   NrG   )rU   r   r   )r   r(   r   count_uppercount_lowerr   r.   r   lower_case_validator  s   
r   fname'tuple[pd.DataFrame | None, Remediation]c              
   C  s  d}d}d}d}d}t j| rQz|  ds!|  drF|  dr*dnd\}}d| d}d| d	}tj| |td
d}n|  drnd}d}t	| }	|	j
}
t|
dkrc|d7 }tj| tdd}n|  drd}d}t| d}| }tjdd |dD |tdd}W d   n1 sw   Y  n|  drtj| dtdd}t|dkrd}d}tj| tdd}na	 n_|  drz"tj| dtdd}t|dkrtj| tdd}nd }d}W n4 ty   tj| tdd}Y n!w d!}d"| v r&|d#|  d$| d"d%  d&7 }n|d#|  d'7 }W n' ttfyP   | d"d%  }d(|  d)| d*| d+}Y nw d,|  d-}td.|||d/}||fS )0z
    This function will read a file saved in .csv, .json, .txt, .xlsx or .tsv format using pandas.
     - for .xlsx it will read the first sheet
     - for .txt it will assume completions and split on newline
    Nz.csvz.tsv)CSV,)TSV	z=
- Based on your file extension, your file is formatted as a z filezYour format `z` will be converted to `JSONL`)sepdtyper    z.xlsxzH
- Based on your file extension, your file is formatted as an Excel filez/Your format `XLSX` will be converted to `JSONL`rj   z
- Your Excel file contains more than one sheet. Please either save as csv or ensure all data is present in the first sheet. WARNING: Reading only the first sheet...)r   z.txtz9
- Based on your file extension, you provided a text filez.Your format `TXT` will be converted to `JSONL`rc                 S  s   g | ]}d |gqS )r    r   )r,   liner   r   r   r/     s    z#read_any_format.<locals>.<listcomp>rn   )r0   r   .jsonlT)linesr   z^
- Your JSONL file appears to be in a JSON format. Your file will be converted to JSONL formatz/Your format `JSON` will be converted to `JSONL`z.jsonz^
- Your JSON file appears to be in a JSONL format. Your file will be converted to JSONL formatz]Your file must have one of the following extensions: .CSV, .TSV, .XLSX, .TXT, .JSON or .JSONLr   z Your file `z` ends with the extension `.z` which is not supported.z` is missing a file extension.zYour file `z!` does not appear to be in valid z9 format. Please ensure your file is formatted as a valid z file.zFile z does not exist.read_any_format)r   r   r   r   )ospathisfiler*   endswithpdread_csvr   fillna	ExcelFilesheet_namesr#   
read_excelopenread	DataFramesplit	read_json
ValueError	TypeErrorupperr   )r   r?   remediationr   r   r   r   file_extension_str	separatorxlssheetsfcontentr   r   r   r     s   


"r   c                 C  s,   t | }d}|dkrd| d}td|dS )z
    This validator will infer the likely fine-tuning format of the data, and display it to the user if it is classification.
    It will also suggest to use ada and explain train/validation split benefits.
    Nr   zK
- Based on your data it seems like you're trying to fine-tune a model for z
- For classification, we recommend you try one of the faster and cheaper models, such as `ada`
- For classification, you can estimate the expected model performance by keeping a held out dataset, which is not used for trainingr!   r"   )rv   r   )r   rw   r   r   r   r   format_inferrer_validator  s
   r   r   c                 C  sb   |j durtjd|j d|j  d td |jdur%tj|j |jdur/|| } | S )zs
    This function will apply a necessary remediation to a dataframe, or print an error message if one exists.
    Nz

ERROR in z validator: z

Aborting...rj   )	r   ro   stderrrq   r   exitr   rp   r   )r   r   r   r   r   apply_necessary_remediation(  s   




r   
input_textauto_acceptboolc                 C  s.   t j|  |rt jd dS t  dkS )NzY
Tn)ro   rp   rq   inputr*   )r   r   r   r   r   accept_suggestion6  s
   r   tuple[pd.DataFrame, bool]c                 C  sj   d}d|j  d}|j dur!t||r!|jdusJ || } d}|jdur1tjd|j d | |fS )zc
    This function will apply an optional remediation to a dataframe, based on the user input.
    Fz- [Recommended] z [Y/n]: NTz- [Necessary] rn   )r   r   r   r   ro   rp   rq   )r   r   r   optional_appliedr   r   r   r   apply_optional_remediation>  s   



r   Nonec                 C  sl   t | }d}|dkrt| }|d }n| jdd }|d }ddd}||d }tjd| d dS )z?
    Estimate the time it'll take to fine-tune the dataset
    g      ?r   g
ףp=
?T)rY   g|?5^?timefloatr   r   c                 S  sd   | dk rt | d dS | dk rt | d d dS | dk r(t | d d dS t | d d dS )	N<   r	   z secondsi  z minutesiQ z hoursz days)round)r   r   r   r   format_time]  s   z.estimate_fine_tuning_time.<locals>.format_time   z:Once your model starts training, it'll approximately take z~ to train a `curie` model, and less for `ada` and `babbage`. Queue will approximately take half an hour per job ahead of you.
N)r   r   r   r   )rv   r#   memory_usager   ro   rp   rq   )r   	ft_formatexpected_timer!   sizer   time_stringr   r   r   estimate_fine_tuning_timeP  s   



r  r   c                   sd   |rddgndg}d}	 |dkrd| dnd fdd	|D }t d
d |D s-|S |d7 }q)N_train_validr    r   Tz ()c                   s,   g | ]}t j d   d|  dqS )r   	_preparedr   )r   r   splitext)r,   r   r   index_suffixr   r   r/   r  s   , z!get_outfnames.<locals>.<listcomp>c                 s  s    | ]	}t j|V  qd S r7   )r   r   r   )r,   r   r   r   r   r   s  s    z get_outfnames.<locals>.<genexpr>rj   )rV   )r   r   suffixesicandidate_fnamesr   r  r   get_outfnamesm  s   r  tuple[int, object]c                 C  s.   | j  }d }|dkr| j  jd }||fS )Nr	   r   )r>   r   value_countsrY   )r   	n_classes	pos_classr   r   r   get_classification_hyperparamsx  s
   
r  any_remediationsc                 C  s  t | }t| jdd}t| jdd}d}d}|dkr!t||r!d}d}	|dd	}
|dd	}t|d
kr;d| dnd}d}|s\|s\tj	d| d|	 d|
 d| d	 t
|  dS t||r:t||}|rt|dkr{d|d
 v r{d|d v s}J d}tt| | tt| d }| j|dd}| |j}|ddg j|d
 ddddd |ddg j|d ddddd t| \}}|	d7 }	|dkr|	d | d7 }	n |	d!| 7 }	nt|dksJ | ddg j|d
 ddddd |rd"ndd# d$| }|r
d%|d  dnd}t|
d
krdnd&|
 d}tj	d'| d(|d
  d| |	 d)| | d t
|  dS tj	d* dS )+aQ  
    This function will write out a dataframe to a file, if the user would like to proceed, and also offer a fine-tuning command with the newly created file.
    For classification it will optionally ask the user if they would like to split the data into train/valid files, and modify the suggested command to include the valid set.
    r   r   FzQ- [Recommended] Would you like to split into training and validation set? [Y/n]: r   Tr    rn   r|   r   z Make sure to include `stop=["z;"]` so that the generated texts ends at the expected place.z@

Your data will be written to a new JSONL file. Proceed [Y/n]: zK
You can use your file for fine-tuning:
> openai api fine_tunes.create -t ""ue   

After you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `zX` for the model to start generating completions, rather than continuing with the prompt.r	   trainvalidrj   i  g?*   )r   random_stater=   r>   recordsN)r   orientforce_asciiindentz! --compute_classification_metricsz" --classification_positive_class "z --classification_n_classes rS   z to `z` and `z -v "uc   After you’ve fine-tuned a model, remember that your prompt has to end with the indicator string `z
Wrote modified filezd`
Feel free to take a look!

Now use that file when fine-tuning:
> openai api fine_tunes.create -t "z

z#Aborting... did not write the file
)rv   r   r=   r>   r   r   r#   ro   rp   rq   r  r  maxintsamplerr   rY   to_jsonr  re   )r   r   r  r   r  common_prompt_suffixr   r   r   additional_params%common_prompt_suffix_new_line_handled)common_completion_suffix_new_line_handledoptional_ending_stringfnamesMAX_VALID_EXAMPLESn_traindf_traindf_validr  r  files_stringvalid_stringseparator_reminderr   r   r   write_out_file  sn   

(
(r1  c                 C  s>   d}t | jj dkrdS t| j t| | k rdS dS )z>
    Infer the likely fine-tuning task type from the data
       r   rh   r   zconditional generation)r   r=   r   r#   r>   unique)r   CLASSIFICATION_THRESHOLDr   r   r   rv     s   rv   r   seriesr   c                 C  sn   d}	 |dkr| j t|d  d n
| j dt|d  }| dkr'	 |S ||jd kr1	 |S |jd }q)zQ
    Finds the longest common suffix or prefix of all the values in a series
    r    Tr   rj   Nr   )r   r#   r   r   )r5  r   common_xfixcommon_xfixesr   r   r   r     s   4
r   z,Callable[[pd.DataFrame], Remediation | None]r   	Validatorlist[Validator]c                   C  s2   t dd dd tttttdd dd tttt	t
gS )Nc                 S  
   t | dS r   r<   rD   r   r   r   rM        
 z get_validators.<locals>.<lambda>c                 S  r:  r   r;  rD   r   r   r   rM     r<  c                 S  r:  r   r   rD   r   r   r   rM     r<  c                 S  r:  r   r=  rD   r   r   r   rM     r<  )r&   rK   r]   r   rg   rx   r   r   r   r   r   r   r   r   r   get_validators  s    r>  
validatorswrite_out_file_funcCallable[..., Any]c                 C  s   g }|d ur| | |D ]}|| }|d ur!| | t| |} qtdd |D }tdd |D }	d}
|rPtjd |D ]}t| ||\} }|
pM|}
q@ntjd |
pY|	}|| ||| d S )Nc                 S  s$   g | ]}|j d us|jd ur|qS r7   )r   r   r,   r   r   r   r   r/     s
    z$apply_validators.<locals>.<listcomp>c                 S  s   g | ]	}|j d ur|qS r7   )r   rB  r   r   r   r/     r   Fz?

Based on the analysis we will perform the following actions:
z

No remediations found.
)appendr   rV   ro   rp   rq   r   )r   r   r   r?  r   r@  optional_remediations	validator&any_optional_or_necessary_remediationsany_necessary_appliedany_optional_appliedr   !any_optional_or_necessary_appliedr   r   r   apply_validators  s6   



rJ  )r   r   r   r   )r   r   r'   r   r   r   )r   r   r?   r@   r   r   )r>   )r   r   rL   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   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   r   r  r   r   r   r   r   )r   r   r   r   )r   )r5  r   r   r   r   r   )r   r9  )r   r   r   r   r   r   r?  r9  r   r   r@  rA  r   r   ),
__future__r   r   ro   typingr   r   r   r   r   typing_extensionsr   _extrasr
   r   r   r   r&   r<   rK   r]   rg   rx   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r1  rv   r   r8  r   r>  rJ  r   r   r   r   <module>   sF   


$

%
D
'
$
D

Y







K
