a
    a                     @   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 )timectimeprintlen)fdZtimestr r   1lib/python3.9/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Contextr   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v 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,   t | jD ]}| j|jv r|j  S qd S )N)r"   ZgetmroZim_classr%   __dict__)methodclsr   r   r   get_class_that_definedZ   s    r2   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definedr3   -)r%   r'   r2   maxr   ljust)r0   Z	methodobjZ
classnamesline)CLASSMAXWIDTHPREFIXr   r   format_prefixv   s    z(log_methods_calls.<locals>.format_prefixr   c                    s:   t  t jur S  fdd}|S d S )Nc                     s@   t  d}}|d|f  |  | i |}|S )Nr   z%s %s
)r   writeclose)argskwargslogprefixresult)FILENAMEattrr;   r,   r    r   r   newfunc   s    

z<log_methods_calls.<locals>.__getattribute__.<locals>.newfunc)object__getattribute__type
MethodType)r    r,   rE   )rC   r;   types)rD   r,   r    r   rG      s
    z+log_methods_calls.<locals>.__getattribute__)r   r=   rJ   rG   )r   Z
some_classrA   rG   r   )r8   rC   r9   r:   r;   rJ   r   log_methods_calls_   s    rK   )N)r   )N)__doc__Z
__future__r   r"   r   r   Zspyder.py3compatr   r   r   r   r.   r2   rK   r   r   r   r   <module>   s   

!