B
    nb\                 @   sn   d Z ddlmZ ddlZddlZddlZddlmZ dd ZdddZ	d	d
 Z
dddZdd ZdddZdS )za
Debug utilities that are independent of Spyder code.

See spyder.config.base for other helpers.
    )print_functionN)PY2c             C   sV   dt t    }tdt| | d t|| d tdt| | d td| d d S )NzLogging time: %s=)file )timeZctimeprintlen)fdZtimestr r   1lib/python3.7/site-packages/spyder/utils/debug.pylog_time   s
    r   c             C   s   t | d}t| |rtd|d td|d td|d tr\td|d |d nt||d td|d td|d td	|d td|d tj|d td|d td|d d
S )zBLog last error in filename *fname* -- *context*: string (optional)aZContext)r   z-------r    zutf-8Z	Tracebackz	---------N)	openr   r   r   joinencodestrip	traceback	print_exc)fnamecontextr
   r   r   r   log_last_error   s     
r   c             C   sV   t | d}t| td|dtdt |   f |d td|d td|d d S )Nr   z	%s: %d ms
   g      Y@)r   r   )r   r   r   roundr   )r   r   Zt0r
   r   r   r   log_dt2   s
    
(r      c             C   s   t  }d|  }t||d k r$dS || d }g }t |}|rN||j d|jkrl||jd jj |jj	}|dkr|| ~d
|S )a   
    Get name of a caller in the format module.class.method

    `skip` specifies how many levels of call stack to skip for caller's name.
    skip=1 means "who calls me", skip=2 "who calls my caller" etc.
       
    An empty string is returned if skipped levels exceed stack height
    r      r   selfz<module>.)inspectstackr	   Z	getmoduleappend__name__f_locals	__class__f_codeco_namer   )skipr!   startZparentframenamemoduleZcodenamer   r   r   caller_name9   s     	


r,   c             C   s,   x&t | jD ]}| j|jkr|jS qW d S )N)r    ZgetmroZim_classr#   __dict__)methodclsr   r   r   get_class_that_definedZ   s    r0   c                s`   t | d  | | d|dkr&|ddi fddddlfd	d
}||_dS )a  
    Hack `some_class` to log all method calls into `fname` file.
    If `prefix` format is not set, each log entry is prefixed with:
      --[ asked / called / defined ] --
        asked   - name of `some_class`
        called  - name of class for which a method is called
        defined - name of class where method is defined
    
    Must be used carefully, because it monkeypatches __getattribute__ call.
    
    Example:  log_methods_calls('log.log', ShellBaseWidget)
    r   z,--[ %(asked)s / %(called)s / %(defined)s ]--No_Or   c                sD    j |jj t| d}| }tt|d d< |d dS )zK
        --[ ShellBase / Internal / BaseEdit ]------- get_position
        )ZaskedZcalledZdefinedr1   -)r#   r%   r0   maxr	   ljust)r.   Z	methodobjZ
classnamesline)CLASSMAXWIDTHPREFIXr   r   format_prefixv   s    z(log_methods_calls.<locals>.format_prefixr   c                s:   t  t jk	r S  fdd}|S d S )Nc                 s<   t  d}}|d|f  |  | |}|S )Nr   z%s %s
)r   writeclose)argskwargslogprefixresult)FILENAMEattrr9   r*   r   r   r   newfunc   s    


z<log_methods_calls.<locals>.__getattribute__.<locals>.newfunc)object__getattribute__type
MethodType)r   r*   rC   )rA   r9   types)rB   r*   r   r   rE      s
    z+log_methods_calls.<locals>.__getattribute__)r   r;   rH   rE   )r   Z
some_classr?   rE   r   )r6   rA   r7   r8   r9   rH   r   log_methods_calls_   s    rI   )N)r   )N)__doc__Z
__future__r   r    r   r   Zspyder.py3compatr   r   r   r   r,   r0   rI   r   r   r   r   <module>   s   

!