
    Je-                         d Z 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
mZ ddlmZ ej                  dk(  Zd Z G d d	e      Z G d
 de      Z G d de      Zd ZddZd Zedk(  r e        yy)zZ
Worker manager and workers for running files long processes in non GUI
blocking threads.
    )dequeN)
QByteArrayQObjectQProcessQThreadQTimerSignal)to_text_stringntc                 \    t        | t              r| j                         } t        | |      S )z"Qt/Python2/3 compatibility helper.)encoding)
isinstancer   datar
   )objr   s     6/usr/lib/python3/dist-packages/spyder/utils/workers.pyhandle_qbytearrayr      s$    #z"hhj#11    c                   ^     e Zd ZdZ ee      Z eeee      Z fdZd Z	d Z
d Zd Z xZS )PythonWorkerz
    Generic python worker for running python code on threads.

    For running processes (via QProcess) use the ProcessWorker.
    c                 p    t         t        |           || _        || _        || _        d| _        d| _        y)z9Generic python worker for running python code on threads.FN)superr   __init__funcargskwargs_is_finished_started)selfr   r   r   	__class__s       r   r   zPythonWorker.__init__.   s4    lD*,		!r   c                     | j                   S )z@Return True if worker status is finished otherwise return False.r   r   s    r   is_finishedzPythonWorker.is_finished7   s       r   c                 b    | j                   s#| j                  j                  |        d| _         yy)z?Start the worker (emits sig_started signal with worker as arg).TNr   sig_startedemitr"   s    r   startzPythonWorker.start;   )    }}!!$' DM r   c                     d| _         y)zMark the worker as finished.TNr!   r"   s    r   	terminatezPythonWorker.terminateA   s
     r   c                 (   d}d}	  | j                   | j                  i | j                  }| j                  s&	 | j
                  j                  | ||       d| _        yd| _        y# t        $ r}|}Y d}~Jd}~ww xY w# t        $ r
 Y d| _        yw xY w)z6Start process worker for given method args and kwargs.NT)r   r   r   	Exceptionr   sig_finishedr'   RuntimeError)r   erroroutputerrs       r   _startzPythonWorker._startE   s    	TYY		9T[[9F   !!&&tVU; !D  	E	    s(   &A& A> &	A;/A66A;>	BB)__name__
__module____qualname____doc__r	   objectr&   r.   r   r#   r(   r+   r3   __classcell__r   s   @r   r   r   %   s:    
 .K&&&1L!!!!r   r   c                        e Zd ZdZ ee      Z eeee      Z eeee      Zd fd	Z	d Z
d Zd Zd Zd Zd Zd	 Zd
 Zd Zd Z xZS )ProcessWorkerz7Process worker based on a QProcess for non blocking UI.c                    t         t        |   |       d| _        || _        d| _        d| _        d| _        d| _        t        |       | _
        t        |       | _        | j                  |       | j                  j                  d       | j                  j                  j!                  | j"                         | j                  j$                  j!                  | j&                         y)z
        Process worker based on a QProcess for non blocking UI.

        Parameters
        ----------
        cmd_list : list of str
            Command line arguments to execute.
        environ : dict
            Process environment,
        NF   )r   r<   r   _result	_cmd_list_fired_communicate_first_partial_stdoutr   r   _timerr   _process_set_environmentsetIntervaltimeoutconnect_communicatereadyReadStandardOutput_partial)r   parentcmd_listenvironr   s       r   r   zProcessWorker.__init__^   s     	mT+F3!"'#Tl g&$##D$5$56--55dmmDr   c                     d}t         r6ddl}t        |j                  j                  j                               }d|z   }|S )z$Return the encoding/codepage to use.zutf-8r   Ncp)WINctypesr
   cdllkernel32GetACP)r   encorS   codepages       r   _get_encodingzProcessWorker._get_encodingy   s<     %fkk&:&:&A&A&CDH (?Dr   c                     |r`| j                   j                         }|j                         D ]  \  }}|j                  ||        | j                   j	                  |       yy)z$Set the environment on the QProcess.N)rE   processEnvironmentitemsinsertsetProcessEnvironment)r   rO   	q_environkvs        r   rF   zProcessWorker._set_environment   sW    88:I '1  A&'MM//	:	 r   c                     | j                   j                         }t        || j                               }| j                  || _        n| xj                  |z  c_        | j
                  j                  | |d       y)zCallback for partial output.N)rE   readAllStandardOutputr   rY   rC   sig_partialr'   )r   
raw_stdoutstdouts      r   rL   zProcessWorker._partial   sf    ]]88:
":t/A/A/CD'#)D   F* dFD1r   c                     | j                   s<| j                  j                         t        j                  k(  r| j                          y| j                  r| j                  j                          yy)zCallback for communicate.N)	rB   rE   stater   
NotRunningcommunicaterA   rD   stopr"   s    r   rJ   zProcessWorker._communicate   sN    ''##%)<)<<[[KK r   c                    d| _         | j                  j                  d       | j                         }| j                  '| j                  j                         }t        ||      }n| j                  }| j                  j                         }t        ||      }|j                  |      |j                  |      g}d|d<   || _	        | j                  s#| j                  j                  | |d   |d          d| _
        |S )zRetrieve information.T   r   )rB   rE   waitForFinishedrY   rC   rc   r   readAllStandardErrorencoder?   rA   r.   r'   )r   rW   re   rf   
raw_stderrstderrresults          r   rj   zProcessWorker.communicate   s    "&%%d+!!#'<<>J&z48F))F]]779
":t4--%v}}T':;r
{{""4F2J?r   c                     | j                   j                          | j                  j                          | j                  j	                  d       y)zClose the running process.  N)rD   rk   rE   closerp   r"   s    r   rx   zProcessWorker.close   s4    %%d+r   c                 t    | j                   j                         t        j                  k(  xr | j                  S )z.Return True if worker has finished processing.)rE   rh   r   ri   rA   r"   s    r   r#   zProcessWorker.is_finished   s)    }}""$(;(;;KKr   c                     | j                   sXd| _        | j                  j                  | j                  d   | j                  dd        | j
                  j                          yy)zStart process.Nr      )rA   _partial_ouputrE   r(   r@   rD   r"   s    r   r3   zProcessWorker._start   sN    {{"&DMMq 14>>!"3EFKK r   c                 D   | j                   j                          | j                  j                         t        j
                  k(  r>	 | j                  j                          | j                  j                  d       d| _	        yd| _	        y# t        $ r
 Y d| _	        yw xY w)zTerminate running processes.rw   TN)
rD   rk   rE   rh   r   Runningrx   rp   r-   rA   r"   s    r   r+   zProcessWorker.terminate   s~    == H$4$44##%--d3 d  s   5B 	BBc                 b    | j                   s#| j                  j                  |        d| _         yy)zStart worker.TNr%   r"   s    r   r(   zProcessWorker.start   r)   r   N)r4   r5   r6   r7   r	   r8   r&   r.   rd   r   rY   rF   rL   rJ   rj   rx   r#   r3   r+   r(   r9   r:   s   @r   r<   r<   W   sd    A.K&&&1L0KE6;
26,L 	!r   r<   c                   L     e Zd ZdZd	 fd	Zd Zd
dZd Zd
dZd Z	d Z
 xZS )WorkerManager*Spyder Worker Manager for Generic Workers.c                    t         |           t               | _        t               | _        g | _        g | _        t        |       | _        t        |       | _	        d| _
        || _        t               | _        | j                  j                  d       | j                  j                  j                  | j                          | j                  j                  d       | j                  j                  j                  | j"                         y)r   r   iM  rm   N)r   r   r   _queue_queue_workers_threads_workersr   rD   _timer_worker_delete_running_threads_max_threads_bag_collectorrG   rH   rI   r3   _clean_workers)r   max_threadsr   s     r   r   zWorkerManager.__init__   s    g#gTl$*4L! !' $g$##DKK0!!--d3!!))11$2E2EFr   c                     | j                   r'| j                   j                          | j                   r'| j                  j                          y)z+Delete periodically workers in workers bag.N)r   popleftr   rk   r"   s    r   r   zWorkerManager._clean_workers   s:    !!'') !!!!&&(r   c                 4   |r| j                   j                  |       | j                   r,| j                  | j                  k  r| xj                  dz  c_        | j                   j	                         }t        d      }t        |t              rl|j                  |       |j                  j                  |j                         |j                  j                  |j                         |j                          n@t        |t              r0|j                          |j!                          |j                          | j"                  j                  |       n| j$                  j                          | j&                  rX| j&                  D ]I  }|j)                         s| j*                  j                  |       | j&                  j-                  |       K | j"                  rR| j"                  D ]C  }|j/                         s| j"                  j-                  |       | xj                  dz  c_        E t1        | j"                        dk(  rNt1        | j&                        dk(  r5| j$                  j3                          | j4                  j                          yyy)z-Start threads and check for inactive workers.r{   Nr   )r   appendr   r   r   r   r   r   moveToThreadr.   rI   quitstartedr3   r(   r<   waitr   rD   r   r#   r   remove
isFinishedlenrk   r   )r   workerthreadwts        r   r3   zWorkerManager._start   s   &&v.4#8#84;L;L#L !!Q&!((002FT]F&,/##F+##++FKK8&&v}}5FM2MM  (KK==]] ,==?''..q1MM((+,
 ==]] /<<>MM((+))Q.)/
 t}}"s4=='9Q'>KK%%++- (?"r   c                 B    t        |||      }| j                  |       |S )z$Create a new python worker instance.)r   _create_worker)r   r   r   r   r   s        r   create_python_workerz"WorkerManager.create_python_worker)  s#    dD&1F#r   c                 D    t        | ||      }| j                  |       |S )z%Create a new process worker instance.)rO   )r<   r   )r   rN   rO   r   s       r   create_process_workerz#WorkerManager.create_process_worker/  s#    tXw?F#r   c                     | j                   D ]  }|j                           | j                  D ]#  }	 |j                          |j	                          % t               | _        y# t
        $ r Y Aw xY w)zTerminate all worker processes.N)r   r+   r   r   r   r-   r   r   )r   r   r   s      r   terminate_allzWorkerManager.terminate_all5  sm    mm 	F	 mm 	F	 $g  s    A$$	A0/A0c                     |j                   j                  | j                         | j                  j	                  |       y)zCommon worker setup.N)r&   rI   r3   r   r   )r   r   s     r   r   zWorkerManager._create_workerC  s,    ""4;;/V$r   )
   r   )r4   r5   r6   r7   r   r   r3   r   r   r   r   r9   r:   s   @r   r   r      s+    4G*)).V&%r   r   c                     t        | ||       y)zPrint worker output for tests.N)print)r   r1   r0   s      r   ready_printr   J  s    	&&% r   c                 X    ddl }|j                  |       ||j                  |        y| S )z5This methods illustrates how the workers can be used.r   N)timesleepput)argsecsresult_queuer   s       r   sleeping_funcr   O  s*    JJt
r   c                  Z   ddl m}   |        }t        d      }t        d      D ]X  }|j	                  t
        dj                  |      d      }|j                  j                  t               |j                          Z |j	                  t
        d	d      }|j                  j                  t               |j                          |j                  g d
      }|j                  j                  t               |j                          t        j                  |j                                y)zMain local test.r   )qapplication   )r      zBOOM! {}   )r   zBOOM!)condainfoz--jsonN)spyder.utils.qthelpersr   r   ranger   r   formatr.   rI   r   r(   r   sysexitexec_)r   appwmir   s        r   
local_testr   Y  s    3
.C	1	%B1X ((
8I8I!8L./ ) 1##K0	
 $$]G!$DF
,
LLN%%&ABF
,
LLN HHSYY[r   __main__)r   N)r7   collectionsr   osr   qtpy.QtCorer   r   r   r   r   r	   spyder.py3compatr
   namerR   r   r   r<   r   r   r   r   r4    r   r   <module>r      s     	 
! ! , 	ggo2/!7 /!dF!G F!Rf%G f%T!
. zL r   