B
    ѻd4#                 @   s   d Z ddlZ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eZd	d
 Zdd Zdd Zdd Zi Zdd ZdddZdddZdS )zFDecorator that provides a warning if the wrapped object is never used.    N)context)ops)
tf_logging)tf_decoratorc               @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_TFShouldUseHelpera5  Object stored in TFShouldUse-wrapped objects.

  When it is deleted it will emit a warning or error if its `sate` method
  has not been called by time of deletion, and Tensorflow is not executing
  eagerly or inside a tf.function (which use autodeps and resolve the
  main issues this wrapper warns about).
  c                sb   | _ | _| _| _t r*|  _n4t rX|rPd _t	 fdd q^d _nd _d S )NFc                  s    j ddS )NT)raise_error)_check_sated )selfr	   V/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/util/tf_should_use.py<lambda>2       z-_TFShouldUseHelper.__init__.<locals>.<lambda>T)
_type_repr_stack_frameZ_error_in_functionr   executing_eagerly_satedr   inside_function'add_exit_callback_to_default_func_graph)r
   type_repr_stack_frameerror_in_functionwarn_in_eagerr	   )r
   r   __init__%   s    
z_TFShouldUseHelper.__init__c             C   s"   d| _ d | _d | _d | _d | _d S )NT)r   r   r   r   Z_logging_module)r
   r	   r	   r   sate9   s
    z_TFShouldUseHelper.satec             C   sr   | j r
dS ddd tj| jddD }|rVztd| j| j|W d| 	  X nt
d| j| j| dS )	z#Check if the object has been sated.N c             S   s   g | ]}|  qS r	   )rstrip).0liner	   r	   r   
<listcomp>E   s   z3_TFShouldUseHelper._check_sated.<locals>.<listcomp>   )limitzObject was never used (type {}): {}.  If you want to mark it as used call its "mark_used()" method.  It was originally created here:
{}z==================================
Object was never used (type {}):
{}
If you want to mark it as used call its "mark_used()" method.
It was originally created here:
{}
==================================)r   join	tracebackformat_stackr   RuntimeErrorformatr   r   r   r   error)r
   r   Zcreation_stackr	   r	   r   r   @   s    z_TFShouldUseHelper._check_satedc             C   s   | j dd d S )NF)r   )r   )r
   r	   r	   r   __del__X   s    z_TFShouldUseHelper.__del__N)__name__
__module____qualname____doc__r   r   r   r)   r	   r	   r	   r   r      s
   r   c             C   s   || _ || _d S )N)_tf_should_use_helper_tf_should_use_wrapped_value)r
   wrapped_valuetf_should_use_helperr	   r	   r   _new__init__\   s    r2   c             C   s*   |dkrt | ||S tt | d||S )N)r.   r/   r/   )object__setattr__setattr__getattribute__)r
   keyvaluer	   r	   r   _new__setattr__b   s
    
r9   c             C   s>   |dkrt | d  |dkr,t | |S tt | d|S )N)r.   r/   r.   )r.   	mark_usedZ
__setatt__r/   )r3   r6   r   getattr)r
   r7   r	   r	   r   _new__getattribute__j   s    r<   c             O   sH   t | d  yt t | dd}|||S  tk
rB   Y nX d S )Nr.   r/   r:   )r3   r6   r   AttributeError)r
   argskwargsmur	   r	   r   _new_mark_useds   s    

rA   c                s   t | }t|d}|r"|| |S t| t d j}tjdkrd fdd}t	j
 j||d}nt  j|t j}t|_t|_t|_t|_|t|< || |S )aV  Create a wrapper for object x, whose class subclasses type(x).

  The wrapper will emit a warning if it is deleted without any of its
  properties being accessed or methods being called.

  Args:
    x: The instance to wrap.
    tf_should_use_helper: The object that tracks usage.

  Returns:
    An object wrapping `x`, of type `type(x)`.
  N__orig_bases__)   r!   c                s   |   j | S )N)update__dict__)ns)txr	   r   set_body   s    z_get_wrapper.<locals>.set_body)	exec_body)type	_WRAPPERSgetcopydeepcopyr;   	__bases__sysversion_infotypes	new_classr*   dictrE   r2   r   r<   r6   rA   r:   r9   r4   )xr1   Ztype_xZmemoizedbasesrH   Zcopy_txr	   )rG   r   _get_wrapper   s     


rW   Fc             C   s   | dkst | tr| s| S t r*|s*| S t r:|s:| S y
t W n$ tk
rh   t d j	j
}Y nX tt| t| |||d}t| |S )a
  Wraps object x so that if it is never used, a warning is logged.

  Args:
    x: Python object.
    error_in_function: Python bool.  If `True`, a `RuntimeError` is raised
      if the returned value is never used when created during `tf.function`
      tracing.
    warn_in_eager: Python bool. If `True` raise warning if in Eager mode as well
      as graph mode.

  Returns:
    An instance of `TFShouldUseWarningWrapper` which subclasses `type(x)`
    and is a very shallow wrapper for `x` which logs access into `x`.
  N   )r   r   r   r   r   )
isinstancelistr   r   r   r   
ValueErrorrP   exc_infotb_framef_backr   rJ   reprrW   )rU   r   r   r   r1   r	   r	   r   _add_should_use_warning   s"    
r`   c                s&    fdd}| dk	r|| S |S dS )a  Function wrapper that ensures the function's output is used.

  If the output is not used, a `logging.error` is logged.  If
  `error_in_function` is set, then a `RuntimeError` will be raised at the
  end of function tracing if the output is not used by that point.

  An output is marked as used if any of its attributes are read, modified, or
  updated.  Examples when the output is a `Tensor` include:

  - Using it in any capacity (e.g. `y = t + 0`, `sess.run(t)`)
  - Accessing a property (e.g. getting `t.name` or `t.op`).
  - Calling `t.mark_used()`.

  Note, certain behaviors cannot be tracked - for these the object may not
  be marked as used.  Examples include:

  - `t != 0`.  In this case, comparison is done on types / ids.
  - `isinstance(t, tf.Tensor)`.  Similar to above.

  Args:
    fn: The function to wrap.
    warn_in_eager: Whether to create warnings in Eager as well.
    error_in_function: Whether to raise an error when creating a tf.function.

  Returns:
    The wrapped function.
  c                sn    fdd} j pd}|dd}t|dkr8|}n|\}}d|t|g}d}tj |d|| dS )	zDecorates the input function.c                 s   t | | dS )N)r   r   )r`   )r>   r?   )r   fnr   r	   r   wrapped   s    
z5should_use_result.<locals>.decorated.<locals>.wrappedr   
   z

Note: The output of this function should be used. If it is not, a warning will be logged or an error may be raised. To mark the output as used, call its .mark_used() method.should_use_result)targetdecorator_funcdecorator_namedecorator_doc)r-   splitlenr#   textwrapdedentr   make_decorator)ra   rb   Zfn_docZ	split_docZupdated_docZbriefrestnote)r   r   )ra   r   	decorated   s    
z$should_use_result.<locals>.decoratedNr	   )ra   r   r   rq   r	   )r   r   r   re      s    re   )FF)NFF)r-   rM   rP   rl   r$   rR   tensorflow.python.eagerr   tensorflow.python.frameworkr   tensorflow.python.platformr   tensorflow.python.utilr   r3   r   r2   r9   r<   rA   rK   rW   r`   re   r	   r	   r	   r   <module>   s$   @	*
)