U
     5i&                     @   s   d dl 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	 ddl
mZ G dd dZG d	d
 d
eZG dd deZdS )    N)appsNOT_PROVIDED)timezone   )MigrationLoaderc                   @   sR   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dd Z
dd ZdS )MigrationQuestionerz
    Give the autodetector responses to questions it might have.
    This base class has a built-in noninteractive mode, but the
    interactive subclass is what the command-line arguments will use.
    Nc                 C   s    |pi | _ |pt | _|| _d S N)defaultssetspecified_appsdry_run)selfr
   r   r    r   C/tmp/pip-unpacked-wheel-gcyiijx6/django/db/migrations/questioner.py__init__   s    
zMigrationQuestioner.__init__c                 C   s  || j krdS zt|}W n" tk
r>   | jdd Y S X t|j\}}|dkrf| jddS zt	
|}W n" tk
r   | jdd Y S X t|ddrttj|j}n0t|drt|jdkrdS tt|jd }td	d
 |D  S dS )z2Should we create an initial migration for the app?Task_initialFN__file____path__r   r   c                 s   s    | ]}|d kr| dV  qdS )z__init__.pyz.pyN)endswith).0xr   r   r   	<genexpr>5   s      z2MigrationQuestioner.ask_initial.<locals>.<genexpr>)r   r   Zget_app_configLookupErrorr
   getr   migrations_modulelabel	importlibimport_moduleImportErrorgetattroslistdirpathdirnamer   hasattrlenr   listany)r   	app_labelZ
app_configZmigrations_import_path_r   	filenamesr   r   r   r      s(    

zMigrationQuestioner.ask_initialc                 C   s   dS )#Adding a NOT NULL field to a model.Nr   r   
field_name
model_namer   r   r   ask_not_null_addition7   s    z)MigrationQuestioner.ask_not_null_additionc                 C   s   dS )"Changing a NULL field to NOT NULL.Nr   r-   r   r   r   ask_not_null_alteration<   s    z+MigrationQuestioner.ask_not_null_alterationc                 C   s   | j ddS )Was this field really renamed?
ask_renameFr
   r   )r   r/   old_namenew_namefield_instancer   r   r   r4   A   s    zMigrationQuestioner.ask_renamec                 C   s   | j ddS )Was this model really renamed?ask_rename_modelFr5   )r   old_model_statenew_model_stater   r   r   r:   E   s    z$MigrationQuestioner.ask_rename_modelc                 C   s   | j ddS )z)Should these migrations really be merged?	ask_mergeFr5   r   r)   r   r   r   r=   I   s    zMigrationQuestioner.ask_mergec                 C   s   dS )(Adding an auto_now_add field to a model.Nr   r-   r   r   r   ask_auto_now_add_additionM   s    z-MigrationQuestioner.ask_auto_now_add_addition)NNN)__name__
__module____qualname____doc__r   r   r0   r2   r4   r:   r=   r@   r   r   r   r   r      s   
r   c                   @   sX   e Zd ZdddZdd ZdddZd	d
 Zdd Zdd Zdd Z	dd Z
dd ZdS )InteractiveMigrationQuestionerNc                 C   sJ   t d| }|s|d k	r|S |r0|d  dkr:t d}q|d  dkS )Nz%s r   ZynzPlease answer yes or no: y)inputlower)r   questiondefaultresultr   r   r   _boolean_inputU   s    
z-InteractiveMigrationQuestioner._boolean_inputc                 C   s   t | t|D ]\}}t d|d |f  qtd}zt|}W n tk
rV   Y n"X d|  k rpt|krxn n|S td}q6d S )Nz %s) %sr   zSelect an option: r   zPlease select a valid option: )print	enumeraterG   int
ValueErrorr&   )r   rI   choicesichoicerK   valuer   r   r   _choice_input]   s    z,InteractiveMigrationQuestioner._choice_input c              
   C   s   t d |rt d| d t d t d |r<d|}nd}t|}|sT|rT|}|sbt d q,|d	krvtd
 q,zt|i ttdW S  tt	fk
r } zt d|  W 5 d}~X Y q,X q,dS )z
        Prompt for a default value.

        The ``default`` argument allows providing a custom default value (as a
        string) which will be shown to the user and used as the return value
        if the user doesn't provide any other input.
        z/Please enter the default value as valid Python.zAccept the default 'z/' by pressing 'Enter' or provide another value.zxThe datetime and django.utils.timezone modules are available, so it is possible to provide e.g. timezone.now as a value.zType 'exit' to exit this promptz[default: {}] >>> z>>> z;Please enter some code, or 'exit' (without quotes) to exit.exitr   )datetimer   zInvalid input: %sN)
rM   formatrG   sysrW   evalrX   r   SyntaxError	NameError)r   rJ   promptcodeer   r   r   _ask_defaultl   s.    

z+InteractiveMigrationQuestioner._ask_defaultc                 C   sD   | j s@| d| d| dddg}|dkr8td n|  S dS )	r,   z.It is impossible to add a non-nullable field 'z' to z{ without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:bProvide a one-off default now (will be set on all existing rows with a null value for this column)6Quit and manually define a default value in models.py.      Nr   rU   rZ   rW   ra   r   r.   r/   rS   r   r   r   r0      s    z4InteractiveMigrationQuestioner.ask_not_null_additionc                 C   sR   | j sN| d| d| ddddg}|dkr2tS |dkrFtd n|  S d	S )
r1   z-It is impossible to change a nullable field 'z' on z to non-nullable without providing a default. This is because the database needs something to populate existing rows.
Please select a fix:rb   zIgnore for now. Existing rows that contain NULL values will have to be handled manually, for example with a RunPython or RunSQL operation.rc   rd   re   N)r   rU   r   rZ   rW   ra   rg   r   r   r   r2      s    z6InteractiveMigrationQuestioner.ask_not_null_alterationc                 C   s"   d}|  ||||||jjf dS )r3   z(Was %s.%s renamed to %s.%s (a %s)? [y/N]F)rL   	__class__rA   )r   r/   r6   r7   r8   msgr   r   r   r4      s    z)InteractiveMigrationQuestioner.ask_renamec                 C   s    d}|  ||j|j|jf dS )r9   z(Was the model %s.%s renamed to %s? [y/N]F)rL   r)   name)r   r;   r<   ri   r   r   r   r:      s    z/InteractiveMigrationQuestioner.ask_rename_modelc                 C   s   |  ddS )Nz
Merging will only work if the operations printed above do not conflict
with each other (working on different fields or models)
Should these migration branches be merged? [y/N]F)rL   r>   r   r   r   r=      s    z(InteractiveMigrationQuestioner.ask_mergec                 C   sH   | j sD| d| d| dddg}|dkr8td n| jdd	S d
S )r?   z#It is impossible to add the field 'z' with 'auto_now_add=True' to zf without providing a default. This is because the database needs something to populate existing rows.
zDProvide a one-off default now which will be set on all existing rowsrc   rd   re   ztimezone.now)rJ   Nrf   rg   r   r   r   r@      s    z8InteractiveMigrationQuestioner.ask_auto_now_add_addition)N)rV   )rA   rB   rC   rL   rU   ra   r0   r2   r4   r:   r=   r@   r   r   r   r   rE   S   s   

%rE   c                   @   s$   e Zd Zdd Zdd Zdd ZdS )!NonInteractiveMigrationQuestionerc                 C   s   t d d S Nre   rZ   rW   r-   r   r   r   r0      s    z7NonInteractiveMigrationQuestioner.ask_not_null_additionc                 C   s   t S r	   r   r-   r   r   r   r2      s    z9NonInteractiveMigrationQuestioner.ask_not_null_alterationc                 C   s   t d d S rl   rm   r-   r   r   r   r@      s    z;NonInteractiveMigrationQuestioner.ask_auto_now_add_additionN)rA   rB   rC   r0   r2   r@   r   r   r   r   rk      s   rk   )rX   r   r!   rZ   Zdjango.appsr   Zdjango.db.modelsr   Zdjango.utilsr   loaderr   r   rE   rk   r   r   r   r   <module>   s   F 