B
    ٻd"                 @   s   d 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 ddlmZ ddlm	Z	 dd	l
mZ dd
lmZ ddlmZ eddedG dd dejejdZG dd deZedddgdG dd de	jZdS )z9A type for representing values that may or may not exist.    N)	structure)composite_tensor)dtypes)ops)tensor_spec)	type_spec)gen_dataset_ops)deprecation)	tf_exportzexperimental.Optionalzdata.experimental.Optionalc               @   sV   e Zd ZdZejdddZejdddZejdd Z	e
d	d
 Ze
dd ZdS )OptionalaX  Represents a value that may or may not be present.

  A `tf.experimental.Optional` can represent the result of an operation that may
  fail as a value, rather than raising an exception and halting execution. For
  example, `tf.data.Iterator.get_next_as_optional()` returns a
  `tf.experimental.Optional` that either contains the next element of an
  iterator if one exists, or an "empty" value that indicates the end of the
  sequence has been reached.

  `tf.experimental.Optional` can only be used with values that are convertible
  to `tf.Tensor` or `tf.CompositeTensor`.

  One can create a `tf.experimental.Optional` from a value using the
  `from_value()` method:

  >>> optional = tf.experimental.Optional.from_value(42)
  >>> print(optional.has_value())
  tf.Tensor(True, shape=(), dtype=bool)
  >>> print(optional.get_value())
  tf.Tensor(42, shape=(), dtype=int32)

  or without a value using the `empty()` method:

  >>> optional = tf.experimental.Optional.empty(
  ...   tf.TensorSpec(shape=(), dtype=tf.int32, name=None))
  >>> print(optional.has_value())
  tf.Tensor(False, shape=(), dtype=bool)
  Nc             C   s   t ddS )aW  Returns a tensor that evaluates to `True` if this optional has a value.

    >>> optional = tf.experimental.Optional.from_value(42)
    >>> print(optional.has_value())
    tf.Tensor(True, shape=(), dtype=bool)

    Args:
      name: (Optional.) A name for the created operation.

    Returns:
      A scalar `tf.Tensor` of type `tf.bool`.
    zOptional.has_value()N)NotImplementedError)selfname r   Y/var/www/html/venv/lib/python3.7/site-packages/tensorflow/python/data/ops/optional_ops.py	has_value=   s    zOptional.has_valuec             C   s   t ddS )a  Returns the value wrapped by this optional.

    If this optional does not have a value (i.e. `self.has_value()` evaluates to
    `False`), this operation will raise `tf.errors.InvalidArgumentError` at
    runtime.

    >>> optional = tf.experimental.Optional.from_value(42)
    >>> print(optional.get_value())
    tf.Tensor(42, shape=(), dtype=int32)

    Args:
      name: (Optional.) A name for the created operation.

    Returns:
      The wrapped value.
    zOptional.get_value()N)r   )r   r   r   r   r   	get_valueM   s    zOptional.get_valuec             C   s   t ddS )a  The type specification of an element of this optional.

    >>> optional = tf.experimental.Optional.from_value(42)
    >>> print(optional.element_spec)
    tf.TensorSpec(shape=(), dtype=tf.int32, name=None)

    Returns:
      A (nested) structure of `tf.TypeSpec` objects matching the structure of an
      element of this optional, specifying the type of individual components.
    zOptional.element_specN)r   )r   r   r   r   element_speca   s    zOptional.element_specc             C   s   t t | S )aU  Returns an `Optional` that has no value.

    NOTE: This method takes an argument that defines the structure of the value
    that would be contained in the returned `Optional` if it had a value.

    >>> optional = tf.experimental.Optional.empty(
    ...   tf.TensorSpec(shape=(), dtype=tf.int32, name=None))
    >>> print(optional.has_value())
    tf.Tensor(False, shape=(), dtype=bool)

    Args:
      element_spec: A (nested) structure of `tf.TypeSpec` objects matching the
        structure of an element of this optional.

    Returns:
      A `tf.experimental.Optional` with no value.
    )_OptionalImplr   Zoptional_none)r   r   r   r   emptyo   s    zOptional.emptyc          
   C   sV   t d2}t d t| }t|| }W dQ R X W dQ R X ttj||d|S )a  Returns a `tf.experimental.Optional` that wraps the given value.

    >>> optional = tf.experimental.Optional.from_value(42)
    >>> print(optional.has_value())
    tf.Tensor(True, shape=(), dtype=bool)
    >>> print(optional.get_value())
    tf.Tensor(42, shape=(), dtype=int32)

    Args:
      value: A value to wrap. The value must be convertible to `tf.Tensor` or
        `tf.CompositeTensor`.

    Returns:
      A `tf.experimental.Optional` that wraps `value`.
    optionalvalueN)r   )r   
name_scoper   Ztype_spec_from_valueZto_tensor_listr   r   Zoptional_from_value)r   scoper   Zencoded_valuer   r   r   
from_value   s    
 zOptional.from_value)N)N)__name__
__module____qualname____doc__abcabstractmethodr   r   abstractpropertyr   staticmethodr   r   r   r   r   r   r      s   r   )	metaclassc                   sL   e Zd ZdZ fddZdddZdddZed	d
 Zedd Z	  Z
S )r   zConcrete implementation of `tf.experimental.Optional`.

  NOTE(mrry): This implementation is kept private, to avoid defining
  `Optional.__init__()` in the public API.
  c                s   t    || _|| _d S )N)super__init___variant_tensor_element_spec)r   Zvariant_tensorr   )	__class__r   r   r%      s    
z_OptionalImpl.__init__Nc          	   C   s(   t | j tj| j|dS Q R X d S )N)r   )r   colocate_withr&   r   Zoptional_has_value)r   r   r   r   r   r      s    z_OptionalImpl.has_valuec          
   C   sh   t |d| jgL}t | j* tj| j|t| jt	| jd}W d Q R X t
| j|S Q R X d S )NZOptionalGetValue)r   Zoutput_typesZoutput_shapes)r   r   r&   r)   r   Zoptional_get_valuer   Zget_flat_tensor_typesr'   Zget_flat_tensor_shapesZfrom_tensor_list)r   r   r   resultr   r   r   r      s    
z_OptionalImpl.get_valuec             C   s   | j S )N)r'   )r   r   r   r   r      s    z_OptionalImpl.element_specc             C   s
   t | S )N)OptionalSpecr   )r   r   r   r   
_type_spec   s    z_OptionalImpl._type_spec)N)N)r   r   r   r   r%   r   r   propertyr   r,   __classcell__r   r   )r(   r   r      s   

r   r+   z#data.experimental.OptionalStructure)Zv1c                   sz   e Zd ZdZdgZ fddZedd Zdd Zed	d
 Z	dd Z
dd Zedd Zdd Zdd Zdd Z  ZS )r+   a  Type specification for `tf.experimental.Optional`.

  For instance, `tf.OptionalSpec` can be used to define a tf.function that takes
  `tf.experimental.Optional` as an input argument:

  >>> @tf.function(input_signature=[tf.OptionalSpec(
  ...   tf.TensorSpec(shape=(), dtype=tf.int32, name=None))])
  ... def maybe_square(optional):
  ...   if optional.has_value():
  ...     x = optional.get_value()
  ...     return x * x
  ...   return -1
  >>> optional = tf.experimental.Optional.from_value(5)
  >>> print(maybe_square(optional))
  tf.Tensor(25, shape=(), dtype=int32)

  Attributes:
    element_spec: A (nested) structure of `TypeSpec` objects that represents the
      type specification of the optional element.
  r'   c                s   t    || _d S )N)r$   r%   r'   )r   r   )r(   r   r   r%      s    
zOptionalSpec.__init__c             C   s   t S )N)r   )r   r   r   r   
value_type   s    zOptionalSpec.value_typec             C   s   | j fS )N)r'   )r   r   r   r   
_serialize   s    zOptionalSpec._serializec             C   s   t dtjgS )Nr   )r   Z
TensorSpecr   variant)r   r   r   r   _component_specs   s    zOptionalSpec._component_specsc             C   s   |j gS )N)r&   )r   r   r   r   r   _to_components   s    zOptionalSpec._to_componentsc             C   s   t |d | jS )Nr   )r   r'   )r   Z
flat_valuer   r   r   _from_components   s    zOptionalSpec._from_componentsc             C   s
   t | jS )N)r+   r   )r   r   r   r   r      s    zOptionalSpec.from_valuec             C   s   | S )Nr   )r   r   r   r   _to_legacy_output_types   s    z$OptionalSpec._to_legacy_output_typesc             C   s   | S )Nr   )r   r   r   r   _to_legacy_output_shapes   s    z%OptionalSpec._to_legacy_output_shapesc             C   s   | S )Nr   )r   r   r   r   _to_legacy_output_classes  s    z&OptionalSpec._to_legacy_output_classes)r   r   r   r   	__slots__r%   r-   r/   r0   r2   r3   r4   r"   r   r5   r6   r7   r.   r   r   )r(   r   r+      s   )r   r   Ztensorflow.python.data.utilr   Ztensorflow.python.frameworkr   r   r   r   r   Ztensorflow.python.opsr   Ztensorflow.python.utilr	   Z tensorflow.python.util.tf_exportr
   Zdeprecated_endpointsZCompositeTensorABCMetar   r   ZTypeSpecr+   r   r   r   r   <module>   s$    (