
    BVh                        d Z ddlZddlZddlmZmZmZ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 ddlmZ ddlmZ da ej<                  dd      Z edg      d        Z  edg      d        Z! edddg      dede"df   dee"df   fd       Z# edddg      d&d       Z$ edg       G d de%             Z&d Z' ed        G d! d ejP                  ejR                               Z* ejV                  e*        G d" d#      Z, ejZ                   e,              d'd$Z.d(d'd%Z/y))z*Helper classes for tensor shape inference.    N)OptionalSequenceTypeUnion)tensor_shape_pb2)
trace_type)
struct_pb2)tf2)
monitoring)
tf_logging)nested_structure_coder)trace)	tf_export)doc_controlsz/tensorflow/api/v2_tensorshapez7Whether tensor_shape.enable_v2_tensorshape() is called.enable_v2_tensorshape)v1c                  z    da t        j                  dd       t        j	                         j                  d       y)a  In TensorFlow 2.0, iterating over a TensorShape instance returns values.

  This enables the new behavior.

  Concretely, `tensor_shape[i]` returned a Dimension instance in V1, but
  it V2 it returns either an integer, or None.

  Examples:

  ```
  #######################
  # If you had this in V1:
  value = tensor_shape[i].value

  # Do this in V2 instead:
  value = tensor_shape[i]

  #######################
  # If you had this in V1:
  for dim in tensor_shape:
    value = dim.value
    print(value)

  # Do this in V2 instead:
  for value in tensor_shape:
    print(value)

  #######################
  # If you had this in V1:
  dim = tensor_shape[i]
  dim.assert_is_compatible_with(other_shape)  # or using any other shape method

  # Do this in V2 instead:
  if tensor_shape.rank is None:
    dim = Dimension(None)
  else:
    dim = tensor_shape.dims[i]
  dim.assert_is_compatible_with(other_shape)  # or using any other shape method

  # The V2 suggestion above is more explicit, which will save you from
  # the following trap (present in V1):
  # you might do in-place modifications to `dim` and expect them to be reflected
  # in `tensor_shape[i]`, but they would not be.
  ```
  T   zEnabling v2 tensorshapeN_TENSORSHAPE_V2_OVERRIDEloggingvlog_api_usage_gaugeget_cellset     X/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/framework/tensor_shape.pyr   r   &   s1    ` "	,,q+,!!$'r   disable_v2_tensorshapec                  z    da t        j                  dd       t        j	                         j                  d       y)zDisables the V2 TensorShape behavior and reverts to V1 behavior.

  See docstring for `enable_v2_tensorshape` for details about the new behavior.
  Fr   zDisabling v2 tensorshapeNr   r   r   r   r   r   [   s0     #	,,q,-!!%(r   zcompat.dimension_valuedimension_value	dimension	Dimensionreturnc                 >    t        | t              r| j                  S | S )a  Compatibility utility required to allow for both V1 and V2 behavior in TF.

  Until the release of TF 2.0, we need the legacy behavior of `TensorShape` to
  coexist with the new behavior. This utility is a bridge between the two.

  When accessing the value of a TensorShape dimension,
  use this utility, like this:

  ```
  # If you had this in your V1 code:
  value = tensor_shape[i].value

  # Use `dimension_value` as direct replacement compatible with both V1 & V2:
  value = dimension_value(tensor_shape[i])

  # This would be the V2 equivalent:
  value = tensor_shape[i]  # Warning: this will return the dim value in V2!
  ```

  Args:
    dimension: Either a `Dimension` instance, an integer, or None.

  Returns:
    A plain value, i.e. an integer or None.
  )
isinstancer#   value)r"   s    r   r!   r!   g   s    > 	9%??	r   zcompat.dimension_at_indexdimension_at_indexc                 r    t        | t              sJ | j                  t        d      S | j                  |   S )a  Compatibility utility required to allow for both V1 and V2 behavior in TF.

  Until the release of TF 2.0, we need the legacy behavior of `TensorShape` to
  coexist with the new behavior. This utility is a bridge between the two.

  If you want to retrieve the Dimension instance corresponding to a certain
  index in a TensorShape instance, use this utility, like this:

  ```
  # If you had this in your V1 code:
  dim = tensor_shape[i]

  # Use `dimension_at_index` as direct replacement compatible with both V1 & V2:
  dim = dimension_at_index(tensor_shape, i)

  # Another possibility would be this, but WARNING: it only works if the
  # tensor_shape instance has a defined rank.
  dim = tensor_shape.dims[i]  # `dims` may be None if the rank is undefined!

  # In native V2 code, we recommend instead being more explicit:
  if tensor_shape.rank is None:
    dim = Dimension(None)
  else:
    dim = tensor_shape.dims[i]

  # Being more explicit will save you from the following trap (present in V1):
  # you might do in-place modifications to `dim` and expect them to be reflected
  # in `tensor_shape[i]`, but they would not be (as the Dimension object was
  # instantiated on the fly.
  ```

  Args:
    shape: A TensorShape instance.
    index: An integer index.

  Returns:
    A dimension object.
  N)r&   TensorShaperankr#   dims)shapeindexs     r   r(   r(      s8    T 
E;	''	'
ZZT?::er   c                       e Zd ZdZdgZd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Zed        Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Z d Z!d Z"d  Z#d! Z$d" Z%y#)$r#   a  Represents the value of one dimension in a TensorShape.

  @compatibility(TF2)
  In TF2, members of a `TensorShape` object are integers. The `Dimension` class
  is not part of TF2's data model.

  Please refer to the [TensorShape section of the migration guide]
  (https://www.tensorflow.org/guide/migrate/index#tensorshape) on common code
  patterns adapting Dimension objects to a TF2 syntax.
  @end_compatibility
  _valuec           	         t        |t              r|dk  rt        d|z        || _        y|d| _        yt        |t              r|j                  | _        y	 t        |j                               | _        | j                  dk  rt        d| j                  z        y# t        $ r& t        dj                  |t        |                  dw xY w)z-Creates a new Dimension with the given value.r   zDimension %d must be >= 0NzhDimension value must be integer or None or have an __index__ method, got value '{0!r}' with type '{1!r}')
r&   int
ValueErrorr0   r#   	__index__AttributeError	TypeErrorformattypeselfr'   s     r   __init__zDimension.__init__   s    %	4u<==dk	dk	E9	%LLdk/ %//+, 
q4t{{BCC 
  /GGMvtE{H$% +/	//s   B /Cc                 2    dt        | j                        z  S )NzDimension(%s))reprr0   r:   s    r   __repr__zDimension.__repr__   s    T$++...r   c                 8    | j                   }|dS t        |      S )N?)r0   strr9   s     r   __str__zDimension.__str__   s    KKE-3/SZ/r   c                     	 t        |      }| j                  |j
                  y| j                  |j
                  k(  S # t        t        f$ r	 t        cY S w xY w)zCReturns true if `other` has the same known value as this Dimension.Nas_dimensionr6   r3   NotImplementedr0   r'   r:   others     r   __eq__zDimension.__eq__   X    5!e {{ekk1;;%++%%	 z"    ? AAc                     	 t        |      }| j                  |j
                  y| j                  |j
                  k7  S # t        t        f$ r	 t        cY S w xY w)z@Returns true if `other` has a different known value from `self`.NrE   rH   s     r   __ne__zDimension.__ne__   rK   rL   c                 ,    t        | j                        S )z!Equivalent to `bool(self.value)`.)boolr0   r>   s    r   __bool__zDimension.__bool__   s    r   c                     | j                   S Nr0   r>   s    r   __int__zDimension.__int__      ;;r   c                     | j                   S rS   rT   r>   s    r   __long__zDimension.__long__  rV   r   c                     | j                   S rS   rT   r>   s    r   r4   zDimension.__index__
  s    ;;r   c                     | j                   S )z6The value of this dimension, or None if it is unknown.rT   r>   s    r   r'   zDimension.value  s     ;;r   c                     t        |      }| j                  du xs) |j                  du xs | j                  |j                  k(  S )a9  Returns true if `other` is compatible with this Dimension.

    Two known Dimensions are compatible if they have the same value.
    An unknown Dimension is compatible with all other Dimensions.

    Args:
      other: Another Dimension.

    Returns:
      True if this Dimension and `other` are compatible.
    NrF   r0   r'   rH   s     r   is_compatible_withzDimension.is_compatible_with  sD     EKK4 '5;;$#6 'KK5;;&(r   c                 J    | j                  |      st        d| d|d      y)zRaises an exception if `other` is not compatible with this Dimension.

    Args:
      other: Another Dimension.

    Raises:
      ValueError: If `self` and `other` are not compatible (see
        is_compatible_with).
    zDimensions  and  are not compatibleNr]   r3   rH   s     r   assert_is_compatible_withz#Dimension.assert_is_compatible_with$  s.     ""5)e% & & *r   c                     t        |      }| j                  |       | j                  t        |j                        S t        | j                        S )a  Returns a Dimension that combines the information in `self` and `other`.

    Dimensions are combined as follows:

    ```python
    tf.compat.v1.Dimension(n)   .merge_with(tf.compat.v1.Dimension(n))     ==
    tf.compat.v1.Dimension(n)
    tf.compat.v1.Dimension(n)   .merge_with(tf.compat.v1.Dimension(None))  ==
    tf.compat.v1.Dimension(n)
    tf.compat.v1.Dimension(None).merge_with(tf.compat.v1.Dimension(n))     ==
    tf.compat.v1.Dimension(n)
    # equivalent to tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None).merge_with(tf.compat.v1.Dimension(None))

    # raises ValueError for n != m
    tf.compat.v1.Dimension(n)   .merge_with(tf.compat.v1.Dimension(m))
    ```

    Args:
      other: Another Dimension.

    Returns:
      A Dimension containing the combined information of `self` and
      `other`.

    Raises:
      ValueError: If `self` and `other` are not compatible (see
        is_compatible_with).
    )rF   rb   r0   r#   r'   rH   s     r   
merge_withzDimension.merge_with2  sD    < E""5){{u{{##t{{##r   c                     	 t        |      }| j                  |j
                  t        d      S t        | j                  |j
                  z         S # t        t        f$ r	 t        cY S w xY w)a  Returns the sum of `self` and `other`.

    Dimensions are summed as follows:

    ```python
    tf.compat.v1.Dimension(m)    + tf.compat.v1.Dimension(n)     ==
    tf.compat.v1.Dimension(m + n)
    tf.compat.v1.Dimension(m)    + tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) + tf.compat.v1.Dimension(n)     # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) + tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    ```

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the sum of `self` and `other`.
    NrF   r6   r3   rG   r0   r'   r#   rH   s     r   __add__zDimension.__add__W  d    ,5!e {{ekk1t_t{{U[[011 z"    A A*)A*c                     | |z   S )zReturns the sum of `other` and `self`.

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the sum of `self` and `other`.
    r   rH   s     r   __radd__zDimension.__radd__v       %<r   c                     	 t        |      }| j                  |j
                  t        d      S t        | j                  |j
                  z
        S # t        t        f$ r	 t        cY S w xY w)a  Returns the subtraction of `other` from `self`.

    Dimensions are subtracted as follows:

    ```python
    tf.compat.v1.Dimension(m)    - tf.compat.v1.Dimension(n)     ==
    tf.compat.v1.Dimension(m - n)
    tf.compat.v1.Dimension(m)    - tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) - tf.compat.v1.Dimension(n)     # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) - tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    ```

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the subtraction of `other` from `self`.
    Nrf   rH   s     r   __sub__zDimension.__sub__  rh   ri   c                     t        |      }| j                  |j                  t        d      S t        |j                  | j                  z
        S )zReturns the subtraction of `self` from `other`.

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the subtraction of `self` from `other`.
    NrF   r0   r'   r#   rH   s     r   __rsub__zDimension.__rsub__  sC     E{{ekk1t_u{{T[[011r   c                     	 t        |      }| j                  |j
                  t        d      S t        | j                  |j
                  z        S # t        t        f$ r	 t        cY S w xY w)a  Returns the product of `self` and `other`.

    Dimensions are summed as follows:

    ```python
    tf.compat.v1.Dimension(m)    * tf.compat.v1.Dimension(n)     ==
    tf.compat.v1.Dimension(m * n)
    tf.compat.v1.Dimension(m)    * tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) * tf.compat.v1.Dimension(n)     # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) * tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    ```

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the product of `self` and `other`.
    Nrf   rH   s     r   __mul__zDimension.__mul__  sd    ,5!e {{ekk1t_t{{U[[011 z" ri   c                     | |z  S )zReturns the product of `self` and `other`.

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is the product of `self` and `other`.
    r   rH   s     r   __rmul__zDimension.__rmul__  rl   r   c                     	 t        |      }| j                  |j
                  t        d      S t        | j                  |j
                  z        S # t        t        f$ r	 t        cY S w xY w)a  Returns the quotient of `self` and `other` rounded down.

    Dimensions are divided as follows:

    ```python
    tf.compat.v1.Dimension(m)    // tf.compat.v1.Dimension(n)     ==
    tf.compat.v1.Dimension(m // n)
    tf.compat.v1.Dimension(m)    // tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) // tf.compat.v1.Dimension(n)     # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) // tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    ```

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A `Dimension` whose value is the integer quotient of `self` and `other`.
    Nrf   rH   s     r   __floordiv__zDimension.__floordiv__  sd    ,5!e {{ekk1t_t{{ekk122 z" ri   c                     t        |      }| j                  |j                  t        d      S t        |j                  | j                  z        S )zReturns the quotient of `other` and `self` rounded down.

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A `Dimension` whose value is the integer quotient of `self` and `other`.
    Nrp   rH   s     r   __rfloordiv__zDimension.__rfloordiv__  sC     E{{ekk1t_u{{dkk122r   c                     | |z  S )a  DEPRECATED: Use `__floordiv__` via `x // y` instead.

    This function exists only for backwards compatibility purposes; new code
    should use `__floordiv__` via the syntax `x // y`.  Using `x // y`
    communicates clearly that the result rounds down, and is forward compatible
    to Python 3.

    Args:
      other: Another `Dimension`.

    Returns:
      A `Dimension` whose value is the integer quotient of `self` and `other`.
    r   rH   s     r   __div__zDimension.__div__  s     5=r   c                 \    t        dj                  t        |      j                              aP  Use `__floordiv__` via `x // y` instead.

    This function exists only to have a better error message. Instead of:
    `TypeError: unsupported operand type(s) for /: 'int' and 'Dimension'`,
    this function will explicitly call for usage of `//` instead.

    Args:
      other: Another `Dimension`.

    Raises:
      TypeError.
    zNunsupported operand type(s) for /: '{}' and 'Dimension', please use // insteadr6   r7   r8   __name__rH   s     r   __rdiv__zDimension.__rdiv__  ,      ,,2F4;3G3G,HJ Jr   c                 \    t        dj                  t        |      j                              )aP  Use `__floordiv__` via `x // y` instead.

    This function exists only to have a better error message. Instead of:
    `TypeError: unsupported operand type(s) for /: 'Dimension' and 'int'`,
    this function will explicitly call for usage of `//` instead.

    Args:
      other: Another `Dimension`.

    Raises:
      TypeError.
    zNunsupported operand type(s) for /: 'Dimension' and '{}', please use // insteadr~   rH   s     r   __truediv__zDimension.__truediv__(  r   r   c                 \    t        dj                  t        |      j                              r}   r~   rH   s     r   __rtruediv__zDimension.__rtruediv__8  r   r   c                     t        |      }| j                  |j                  t        d      S t        | j                  |j                  z        S )a  Returns `self` modulo `other`.

    Dimension modulo are computed as follows:

    ```python
    tf.compat.v1.Dimension(m)    % tf.compat.v1.Dimension(n)     ==
    tf.compat.v1.Dimension(m % n)
    tf.compat.v1.Dimension(m)    % tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) % tf.compat.v1.Dimension(n)     # equiv. to
    tf.compat.v1.Dimension(None)
    tf.compat.v1.Dimension(None) % tf.compat.v1.Dimension(None)  # equiv. to
    tf.compat.v1.Dimension(None)
    ```

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is `self` modulo `other`.
    Nrp   rH   s     r   __mod__zDimension.__mod__H  sC    , E{{ekk1t_t{{U[[011r   c                 "    t        |      }|| z  S )zReturns `other` modulo `self`.

    Args:
      other: Another Dimension, or a value accepted by `as_dimension`.

    Returns:
      A Dimension whose value is `other` modulo `self`.
    )rF   rH   s     r   __rmod__zDimension.__rmod__d  s     E4<r   c                 |    t        |      }| j                  |j                  y| j                  |j                  k  S )a8  Returns True if `self` is known to be less than `other`.

    Dimensions are compared as follows:

    ```python
    (tf.compat.v1.Dimension(m)    < tf.compat.v1.Dimension(n))    == (m < n)
    (tf.compat.v1.Dimension(m)    < tf.compat.v1.Dimension(None)) == None
    (tf.compat.v1.Dimension(None) < tf.compat.v1.Dimension(n))    == None
    (tf.compat.v1.Dimension(None) < tf.compat.v1.Dimension(None)) == None
    ```

    Args:
      other: Another Dimension.

    Returns:
      The value of `self.value < other.value` if both are known, otherwise
      None.
    Nr\   rH   s     r   __lt__zDimension.__lt__p  7    & E{{ekk1[[5;;&&r   c                 |    t        |      }| j                  |j                  y| j                  |j                  k  S )aJ  Returns True if `self` is known to be less than or equal to `other`.

    Dimensions are compared as follows:

    ```python
    (tf.compat.v1.Dimension(m)    <= tf.compat.v1.Dimension(n))    == (m <= n)
    (tf.compat.v1.Dimension(m)    <= tf.compat.v1.Dimension(None)) == None
    (tf.compat.v1.Dimension(None) <= tf.compat.v1.Dimension(n))    == None
    (tf.compat.v1.Dimension(None) <= tf.compat.v1.Dimension(None)) == None
    ```

    Args:
      other: Another Dimension.

    Returns:
      The value of `self.value <= other.value` if both are known, otherwise
      None.
    Nr\   rH   s     r   __le__zDimension.__le__  7    & E{{ekk1[[EKK''r   c                 |    t        |      }| j                  |j                  y| j                  |j                  kD  S )a;  Returns True if `self` is known to be greater than `other`.

    Dimensions are compared as follows:

    ```python
    (tf.compat.v1.Dimension(m)    > tf.compat.v1.Dimension(n))    == (m > n)
    (tf.compat.v1.Dimension(m)    > tf.compat.v1.Dimension(None)) == None
    (tf.compat.v1.Dimension(None) > tf.compat.v1.Dimension(n))    == None
    (tf.compat.v1.Dimension(None) > tf.compat.v1.Dimension(None)) == None
    ```

    Args:
      other: Another Dimension.

    Returns:
      The value of `self.value > other.value` if both are known, otherwise
      None.
    Nr\   rH   s     r   __gt__zDimension.__gt__  r   r   c                 |    t        |      }| j                  |j                  y| j                  |j                  k\  S )aM  Returns True if `self` is known to be greater than or equal to `other`.

    Dimensions are compared as follows:

    ```python
    (tf.compat.v1.Dimension(m)    >= tf.compat.v1.Dimension(n))    == (m >= n)
    (tf.compat.v1.Dimension(m)    >= tf.compat.v1.Dimension(None)) == None
    (tf.compat.v1.Dimension(None) >= tf.compat.v1.Dimension(n))    == None
    (tf.compat.v1.Dimension(None) >= tf.compat.v1.Dimension(None)) == None
    ```

    Args:
      other: Another Dimension.

    Returns:
      The value of `self.value >= other.value` if both are known, otherwise
      None.
    Nr\   rH   s     r   __ge__zDimension.__ge__  r   r   c                 (    t         | j                  ffS rS   )r#   r0   r>   s    r   
__reduce__zDimension.__reduce__  s    t{{n$$r   N)&r   
__module____qualname____doc__	__slots__r;   r?   rC   rJ   rN   rQ   rU   rX   r4   propertyr'   r]   rb   rd   rg   rk   rn   rq   rs   ru   rw   ry   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r#   r#      s    
 j)D./0&&
  
( &#$J2>	2>22@	3>3 J J J 28
'2(2'2(2%r   c                 <    t        | t              r| S t        |       S )aO  Converts the given value to a Dimension.

  A Dimension input will be returned unmodified.
  An input of `None` will be converted to an unknown Dimension.
  An integer input will be converted to a Dimension with that value.

  Args:
    value: The value to be converted.

  Returns:
    A Dimension corresponding to the given value.
  )r&   r#   )r'   s    r   rF   rF     s     y!LUr   r*   c                       e Zd ZdZdgZd Zed        Zd Zd Z	ed        Z
ed        Zed	        Zd
 Zd ZeZd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zdej:                  defdZde ej:                     de!d    fdZ"e#jH                   fd       Z%e#jH                   fd       Z&e#jH                   fd       Z'e#jH                   fd        Z(e#jH                   fd!       Z)e*de+e,jZ                     fd"       Z.e*d#e,jZ                  dd fd$       Z/de,jZ                  fd%Z0d& Z1d' Z2d1d(Z3d) Z4d* Z5d+ Z6d, Z7d- Z8d. Z9d/ Z:d0 Z; xZ<S )2r*   aF  Represents the shape of a `Tensor`.

  >>> t = tf.constant([[1,2,3],[4,5,6]])
  >>> t.shape
  TensorShape([2, 3])

  `TensorShape` is the *static* shape representation of a Tensor.
  During eager execution a Tensor always has a fully specified shape but
  when tracing a `tf.function` it may be one of the following:

  * *Fully-known shape:* has a known number of dimensions and a known size
    for each dimension. e.g. `TensorShape([16, 256])`
  * *Partially-known shape:* has a known number of dimensions, and an unknown
    size for one or more dimension. e.g. `TensorShape([None, 256])`
  * *Unknown shape:* has an unknown number of dimensions, and an unknown
    size in all dimensions. e.g. `TensorShape(None)`

  During function tracing `t.shape` will return a `TensorShape` object
  representing the shape of Tensor as it is known during tracing.
  This static representation will be partially defined in cases where the
  exact shape depends on the values within the tensors. To get the
  *dynamic* representation, please use `tf.shape(t)`
  which will return Tensor representing the fully defined shape of `t`.
  This way, you can express logic that manipulates the shapes of tensors by
  building other tensors that depend on the dynamic shape of `t`.

  Note: `tf.RaggedTensor.shape` also returns a `tf.TensorShape`,
  the lengths of any ragged dimensions are unknown (`None`).

  For example, this function prints the `TensorShape' (`t.shape`), when you
  trace the function, and returns a tensor `tf.shape(t)` for given input `t`:

  >>> @tf.function
  ... def get_dynamic_shape(t):
  ...   print("tracing...")
  ...   print(f"static shape is {t.shape}")
  ...   return tf.shape(t)

  Just calling the function traces it with a fully-specified static shape:

  >>> result = get_dynamic_shape(tf.constant([[1, 1, 1], [0, 0, 0]]))
  tracing...
  static shape is (2, 3)
  >>> result.numpy()
  array([2, 3], dtype=int32)

  But `tf.function` can also trace the function with a partially specified
  (or even unspecified) shape:

  >>> cf1 = get_dynamic_shape.get_concrete_function(tf.TensorSpec(
  ...                                               shape=[None, 2]))
  tracing...
  static shape is (None, 2)
  >>> cf1(tf.constant([[1., 0],[1, 0],[1, 0]])).numpy()
  array([3, 2], dtype=int32)

  >>> cf2 = get_dynamic_shape.get_concrete_function(tf.TensorSpec(shape=None))
  tracing...
  static shape is <unknown>
  >>> cf2(tf.constant([[[[[1., 0]]]]])).numpy()
  array([1, 1, 1, 1, 2], dtype=int32)

  If a tensor is produced by an operation of type `"Foo"`, its shape
  may be inferred if there is a registered shape function for
  `"Foo"`. See [Shape
  functions](https://www.tensorflow.org/guide/create_op#shape_functions_in_c)
  for details of shape functions and how to register them. Alternatively,
  you may set the shape explicitly using `tf.Tensor.ensure_shape`.
  _dimsc                    t        |t        t        f      rt        d |D              | _        y|d| _        yt        |t        j
                        r6|j                  rd| _        yt        d |j                  D              | _        yt        |t              r|j                  | _        y	 t        |      }g | _        |D ]1  }	 | j                  j                  t        |      j                         3 t        | j                        | _        y# t        $ r!}t        dj                  ||            |d}~ww xY w# t        $ r t        |      j                  f| _        Y yw xY w)zCreates a new TensorShape with the given dimensions.

    Args:
      dims: A list of Dimensions, or None if the shape is unspecified.

    Raises:
      TypeError: If dims cannot be converted to a list of dimensions.
    c              3   F   K   | ]  }t        |      j                    y wrS   )rF   r'   .0ds     r   	<genexpr>z'TensorShape.__init__.<locals>.<genexpr>>  s     =1a..=s   !Nc              3   V   K   | ]!  }|j                   d k7  r|j                   nd # yw)Nsizer   dims     r   r   z'TensorShape.__init__.<locals>.<genexpr>E  s-        BCHHD0s   ')zFailed to convert '{0!r}' to a shape: '{1!r}'could not be converted to a dimension. A shape should either be single dimension (e.g. 10), or an iterable of dimensions (e.g. [1, 10, None]).)r&   tuplelistr   r   TensorShapeProtounknown_rankr   r*   iterappendrF   r'   r6   r7   )r:   r,   	dims_iterr   es        r   r;   zTensorShape.__init__4  sD    $&===dj	dj	D*;;	<			
  xx 

 
D+	&::dj'J	
 
 	KAKJJl1o334	K 4::&
  K3 4:6$?	D JK	KK  1"4(..0
1s*   ,D< .D	D9D44D9<$E#"E#c                 B    t         t        j                         S t         S rS   )r   r
   enabledr>   s    r   _v2_behaviorzTensorShape._v2_behavior_  s    '[[]##r   c                     | j                   r&| j                  dt        | j                         dS yd| j                   dS )NzTensorShape()zTensorShape(None))r   r   r   r,   r>   s    r   r?   zTensorShape.__repr__e  sD    		d4::./q11"DII;a((r   c                 F   | j                   y| j                   dk(  r0| j                  rd| j                  d   z  S d| j                  d   z  S | j                  r%ddj	                  d | j                  D              z  S ddj	                  d | j                  D              z  S )	Nz	<unknown>r   z(%s,)r   z(%s)z, c              3   2   K   | ]  }t        |        y wrS   rB   r   s     r   r   z&TensorShape.__str__.<locals>.<genexpr>x  s     !=Q#a&!=   c              3   2   K   | ]  }t        |        y wrS   r   r   s     r   r   z&TensorShape.__str__.<locals>.<genexpr>z  s     !<Q#a&!<r   )r+   r   r   r,   joinr>   s    r   rC   zTensorShape.__str__n  s    yy	a			A&&1%%					!=$**!====		!<$))!<<<<r   c                 F    | j                   t        | j                         S y)z=Returns the rank of this shape, or None if it is unspecified.N)r   lenr>   s    r   r+   zTensorShape.rank|  s     zz_r   c                 l    | j                   y| j                   D cg c]  }t        |       c}S c c}w )zDeprecated.  Returns list of dimensions for this shape.

    Suggest `TensorShape.as_list` instead.

    Returns:
      A list containing `tf.compat.v1.Dimension`s, or None if the shape is
      unspecified.
    N)r   rF   r:   r   s     r   r,   zTensorShape.dims  s-     zz%)ZZ0LO000s   1c                     | j                   S )zDeprecated accessor for `rank`.r+   r>   s    r   ndimszTensorShape.ndims  s     99r   c                 Z    | j                   t        d      t        | j                         S )zDReturns the rank of this shape, or raises ValueError if unspecified.z2Cannot take the length of shape with unknown rank.)r   r3   r   r>   s    r   __len__zTensorShape.__len__  s&    zzKLLtzz?r   c                     | j                   duS )z9Returns True if this shape contains non-zero information.Nr   r>   s    r   rQ   zTensorShape.__bool__  s    ::T!!r   c                     | j                   t        d      | j                  rt        d | j                   D              S t        d | j                  D              S )zFReturns `self.dims` if the rank is known, otherwise raises ValueError.z.Cannot iterate over a shape with unknown rank.c              3       K   | ]  }|  y wrS   r   r   s     r   r   z'TensorShape.__iter__.<locals>.<genexpr>  s     *!A*   c              3       K   | ]  }|  y wrS   r   r   s     r   r   z'TensorShape.__iter__.<locals>.<genexpr>  s     )!A)r   )r   r3   r   r   r,   r>   s    r   __iter__zTensorShape.__iter__  sK    zzGHH			*tzz***)tyy)))r   c                    | j                   Rt        |t              rt        | j                   |         S | j                  r| j                   |   S | j
                  |   S t        |t              rl|j                  |j                  nd}|j                  }|j                  t        d      |
t               S |dk  s|dk  r
t               S t        ||z
        S | j                  ryt        d      S )a  Returns the value of a dimension or a shape, depending on the key.

    Args:
      key: If `key` is an integer, returns the dimension at that index;
        otherwise if `key` is a slice, returns a TensorShape whose dimensions
        are those selected by the slice from `self`.

    Returns:
      An integer if `key` is an integer, or a `TensorShape` if `key` is a
      slice.

    Raises:
      ValueError: If `key` is a slice and `self` is completely unknown and
        the step is set.
    Nr   zSteps are not yet handledr   )r   r&   slicer*   r   r,   startstopstepr3   unknown_shaper#   )r:   keyr   r   s       r   __getitem__zTensorShape.__getitem__  s      zz	C	4::c?++C
 3
	C	 YY2		xx8867
7<
 
 QY$( 
 D5L1
14
 r   c                     | j                         r3t        j                  t        j                  | j                         d      S y)zDReturns the total number of elements, or none for incomplete shapes.r   N)is_fully_defined	functoolsreduceoperatormulas_listr>   s    r   num_elementszTensorShape.num_elements  s0    hllDLLNA>>r   c                 V   t        |      }| j                  |S |j                  | S 	 | j                  |       t        | j                  |j                        D cg c]  \  }}|j	                  |       }}}t        |      S c c}}w # t        $ r t        d| d|d      w xY w)a  Returns a `TensorShape` combining the information in `self` and `other`.

    The dimensions in `self` and `other` are merged element-wise,
    according to the rules below:

    ```python
    Dimension(n).merge_with(Dimension(None)) == Dimension(n)
    Dimension(None).merge_with(Dimension(n)) == Dimension(n)
    Dimension(None).merge_with(Dimension(None)) == Dimension(None)
    # raises ValueError for n != m
    Dimension(n).merge_with(Dimension(m))
    ```
    >> ts = tf.TensorShape([1,2])
    >> ot1 = tf.TensorShape([1,2])
    >> ts.merge_with(ot).as_list()
    [1,2]

    >> ot2 = tf.TensorShape([1,None])
    >> ts.merge_with(ot2).as_list()
    [1,2]

    >> ot3 = tf.TensorShape([None, None])
    >> ot3.merge_with(ot2).as_list()
    [1, None]

    Args:
      other: Another `TensorShape`.

    Returns:
      A `TensorShape` containing the combined information of `self` and
      `other`.

    Raises:
      ValueError: If `self` and `other` are not compatible.
    Shapes r_   r`   )as_shaper,   assert_same_rankziprd   r*   r3   )r:   rI   r   	other_dimnew_dimss        r   rd   zTensorShape.merge_with  s    H UOEyylzzkPe$ #&dii"<
Y NN9%
 
 8$$	

  P$NOOPs   4B B8B B B(c                 $    | j                  |      S rS   concatenaterH   s     r   rg   zTensorShape.__add__      E""r   c                 Z    t        |t              st        |      }|j                  |       S rS   )r&   r*   r   rH   s     r   rk   zTensorShape.__radd__  s'    e[)% eT""r   c                     t        |      }| j                  |j                  
t               S t        | j                  |j                  z         S )a  Returns the concatenation of the dimension in `self` and `other`.

    *N.B.* If either `self` or `other` is completely unknown,
    concatenation will discard information about the other shape. In
    future, we might support concatenation that preserves this
    information for use with slicing.

    Args:
      other: Another `TensorShape`.

    Returns:
      A `TensorShape` whose dimensions are the concatenation of the
      dimensions in `self` and `other`.
    )r   r,   r   r*   rH   s     r   r   zTensorShape.concatenate"  s@    " UOEyyEJJ._UZZ/00r   c                     t        |      }| j                  9|j                  ,| j                  |j                  k7  rt        d| d|d      yyy)zRaises an exception if `self` and `other` do not have compatible ranks.

    Args:
      other: Another `TensorShape`.

    Raises:
      ValueError: If `self` and `other` do not represent shapes with the
        same rank.
    Nr   r_   z must have the same rank)r   r+   r3   rH   s     r   r   zTensorShape.assert_same_rank9  sT     UOEyy!7	ejj	 ' ( 	( 
! "8r   c                 D    | j                   d|fvrt        d| |fz        y)zRaises an exception if `self` is not compatible with the given `rank`.

    Args:
      rank: An integer.

    Raises:
      ValueError: If `self` does not represent a shape with the given `rank`.
    NShape %s must have rank %dr+   r3   r:   r+   s     r   assert_has_rankzTensorShape.assert_has_rankI  s.     yyt$3tTlBCC %r   c                 t    	 | j                  t        |            S # t        $ r t        d| |fz        w xY w)ab  Returns a shape based on `self` with the given rank.

    This method promotes a completely unknown shape to one with a
    known rank.

    Args:
      rank: An integer.

    Returns:
      A shape that is at least as specific as `self` with the given rank.

    Raises:
      ValueError: If `self` does not represent a shape with the given `rank`.
    r   r   )rd   r   r3   r   s     r   	with_rankzTensorShape.with_rankU  sB    D__]566 D3tTlBCCDs    7c                 \    | j                   | j                   |k  rt        d| |fz        | S )a8  Returns a shape based on `self` with at least the given rank.

    Args:
      rank: An integer.

    Returns:
      A shape that is at least as specific as `self` with at least the given
      rank.

    Raises:
      ValueError: If `self` does not represent a shape with at least the given
        `rank`.
    z#Shape %s must have rank at least %dr   r   s     r   with_rank_at_leastzTensorShape.with_rank_at_leasti  s3     yyT!1<d|KLLkr   c                 \    | j                   | j                   |kD  rt        d| |fz        | S )a5  Returns a shape based on `self` with at most the given rank.

    Args:
      rank: An integer.

    Returns:
      A shape that is at least as specific as `self` with at most the given
      rank.

    Raises:
      ValueError: If `self` does not represent a shape with at most the given
        `rank`.
    z"Shape %s must have rank at most %dr   r   s     r   with_rank_at_mostzTensorShape.with_rank_at_most|  s3     yyT!1;tTlJKKkr   rI   r$   c                     t        |t              sy|j                  y| j                  |j                  k7  ryt        d t	        | j
                  |j
                        D              S )a  Returns True iff `self` is subtype of `other`.

    Shape A is a subtype of shape B if shape B can successfully represent it:

    * A `TensorShape` of any rank is a subtype of `TensorShape(None)`.

    *  TensorShapes of equal ranks are covariant, i.e.
      `TensorShape([A1, A2, ..])` is a subtype of
      `TensorShape([B1, B2, ..])` iff An is a subtype of Bn.

      An is subtype of Bn iff An == Bn or Bn is None.

    * TensorShapes of different defined ranks have no subtyping relation.

    The subtyping relation is reflexive and transitive, but not symmetric.

    Some examples:
    * `TensorShape([32, 784])` is a subtype of `TensorShape(None)`, and
      `TensorShape([4, 4])` is also a subtype of `TensorShape(None)` but
      `TensorShape([32, 784])` and `TensorShape([4, 4])` are not subtypes of
      each other.

    * All two-dimensional shapes are subtypes of `TensorShape([None, None])`,
      such as `TensorShape([32, 784])`. There is no subtype relationship with,
      for example, `TensorShape([None])` or `TensorShape([None, None, None])`.

    * `TensorShape([32, None])` is also a subtype of `TensorShape([None, None])`
      and `TensorShape(None)`. It is not a subtype of, for example,
      `TensorShape([32])`, `TensorShape([32, None, 1])`,
      `TensorShape([64, None])` or `TensorShape([None, 32])`.

    * `TensorShape([32, 784])` is a subtype of itself, and also
      `TensorShape([32, None])`, `TensorShape([None, 784])`,
      `TensorShape([None, None])` and `TensorShape(None)`.
      It has no subtype relation with, for example, `TensorShape([32, 1, 784])`
      or `TensorShape([None])`.

    Args:
      other: Another `TensorShape`.

    Returns:
      True iff `self` is subtype of `other`.

    FTc              3   8   K   | ]  \  }}|d u xs ||k(    y wrS   r   )r   sos      r   r   z,TensorShape.is_subtype_of.<locals>.<genexpr>  s$     Ltq!qDy"AF"Ls   )r&   r*   r+   allr   r   rH   s     r   is_subtype_ofzTensorShape.is_subtype_of  sX    Z e[) zz yyEJJ Ls4::u{{/KLLLr   othersc                 8    t        d |D              ry j                  
t               S t         fd|D              r
t               S t         j                        D cg c]  \  t        fd|D              rnd  }}}t        |      S c c}}w )a  Returns the most specific supertype `TensorShape` of self and others.

    * `TensorShape([None, 1])` is the most specific `TensorShape` supertyping
      both `TensorShape([2, 1])` and `TensorShape([5, 1])`. Note that
      `TensorShape(None)` is also a supertype but it is not "most specific".

    * `TensorShape([1, 2, 3])` is the most specific `TensorShape` supertyping
      both `TensorShape([1, 2, 3])` and `TensorShape([1, 2, 3]`). There are
      other less specific TensorShapes that supertype above mentioned
      TensorShapes, e.g. `TensorShape([1, 2, None])`, `TensorShape(None)`.

     * `TensorShape([None, None])` is the most specific `TensorShape`
       supertyping both `TensorShape([2, None])` and `TensorShape([None, 3])`.
       As always, `TensorShape(None)` is also a supertype but not the most
       specific one.

     * `TensorShape(None`) is the only `TensorShape` supertyping both
       `TensorShape([1, 2, 3])` and `TensorShape([1, 2])`. In general, any two
       shapes that have different ranks will only have `TensorShape(None)`
       as a common supertype.

     * `TensorShape(None)` is the only `TensorShape` supertyping both
       `TensorShape([1, 2, 3])` and `TensorShape(None)`. In general, the common
       supertype of any shape with `TensorShape(None)` is `TensorShape(None)`.

    Args:
      others: Sequence of `TensorShape`.

    Returns:
      A `TensorShape` which is the most specific supertype shape of `self`
      and `others`. None if it does not exist.
    c              3   >   K   | ]  }t        |t                 y wrS   r&   r*   )r   rI   s     r   r   z=TensorShape.most_specific_common_supertype.<locals>.<genexpr>  s     
B%z%--
Bs   Nc              3   p   K   | ]-  }|j                   d u xs j                  |j                  k7   / y wrS   )r,   r+   )r   rI   r:   s     r   r   z=TensorShape.most_specific_common_supertype.<locals>.<genexpr>  s/     
MU5::8ejj!88
Ms   36c              3   B   K   | ]  }|j                      k(    y wrS   r   )r   rI   r   is     r   r   z=TensorShape.most_specific_common_supertype.<locals>.<genexpr>  s&      ( %++a.( (s   )anyr+   r   	enumerater   r   r*   )r:   r   r  r   r,   s   ` `` r   most_specific_common_supertypez*TensorShape.most_specific_common_supertype  s    D 
B6
BB yy_ 
Mf
MM_  

+  As  ( &( (-1	2D 
 ts   %#Bc                 "    t         |   |      S z/See tf.types.experimental.TraceType base class.)superplaceholder_value)r:   placeholder_context	__class__s     r   r	  zTensorShape.placeholder_value  s     7$%899r   c                 "    t         |   |      S r  )r  from_tensors)r:   tensorsr  s     r   r  zTensorShape.from_tensors  s     7((r   c                 "    t         |   |      S r  )r  
to_tensors)r:   r'   r  s     r   r  zTensorShape.to_tensors  s     7e$$r   c                      t         |          S r  )r  flatten)r:   r  s    r   r  zTensorShape.flatten  s     7?r   c                 $    t         |   ||      S r  )r  cast)r:   r'   cast_contextr  s      r   r  zTensorShape.cast  s     7<|,,r   c                 "    t         j                  S )zDReturns the type of proto associated with TensorShape serialization.)r   r   )clss    r   experimental_type_protoz#TensorShape.experimental_type_proto  s     ,,,r   protoc                     t        |      S )z=Returns a TensorShape instance based on the serialized proto.)r*   )r  r  s     r   experimental_from_protoz#TensorShape.experimental_from_proto!  s     ur   c                 "    | j                         S )z;Returns a proto representation of the TensorShape instance.)as_protor>   s    r   experimental_as_protoz!TensorShape.experimental_as_proto'  s    ==?r   c                     t        |      }| j                  [|j                  O| j                  |j                  k7  ryt        | j                  |j                        D ]  \  }}|	|||k7  s y y)aB  Returns True iff `self` is compatible with `other`.

    Two possibly-partially-defined shapes are compatible if there
    exists a fully-defined shape that both shapes can represent. Thus,
    compatibility allows the shape inference code to reason about
    partially-defined shapes. For example:

    * TensorShape(None) is compatible with all shapes.

    * TensorShape([None, None]) is compatible with all two-dimensional
      shapes, such as TensorShape([32, 784]), and also TensorShape(None). It is
      not compatible with, for example, TensorShape([None]) or
      TensorShape([None, None, None]).

    * TensorShape([32, None]) is compatible with all two-dimensional shapes
      with size 32 in the 0th dimension, and also TensorShape([None, None])
      and TensorShape(None). It is not compatible with, for example,
      TensorShape([32]), TensorShape([32, None, 1]) or TensorShape([64, None]).

    * TensorShape([32, 784]) is compatible with itself, and also
      TensorShape([32, None]), TensorShape([None, 784]), TensorShape([None,
      None]) and TensorShape(None). It is not compatible with, for example,
      TensorShape([32, 1, 784]) or TensorShape([None]).

    The compatibility relation is reflexive and symmetric, but not
    transitive. For example, TensorShape([32, 784]) is compatible with
    TensorShape(None), and TensorShape(None) is compatible with
    TensorShape([4, 4]), but TensorShape([32, 784]) is not compatible with
    TensorShape([4, 4]).

    Args:
      other: Another TensorShape.

    Returns:
      True iff `self` is compatible with `other`.

    FT)r   r   r+   r   )r:   rI   x_dimy_dims       r   r]   zTensorShape.is_compatible_with,  so    L UOEzz%++"9	ejj	 djj%++6 ,%!2u~ r   c                 J    | j                  |      st        d| d|d      y)a<  Raises exception if `self` and `other` do not represent the same shape.

    This method can be used to assert that there exists a shape that both
    `self` and `other` represent.

    Args:
      other: Another TensorShape.

    Raises:
      ValueError: If `self` and `other` do not represent the same shape.
    r   r_   z are incompatibleNra   rH   s     r   rb   z%TensorShape.assert_is_compatible_with\  s'     ""5)dEJKK *r   c                 *   t        |      }| j                  %|j                  | j                  |j                  k7  r
t               S t	        | j                  |j                        D cg c]  \  }}|	|||k(  r|nd }}}t        |      S c c}}w )a  Returns the most specific TensorShape compatible with `self` and `other`.

    * TensorShape([None, 1]) is the most specific TensorShape compatible with
      both TensorShape([2, 1]) and TensorShape([5, 1]). Note that
      TensorShape(None) is also compatible with above mentioned TensorShapes.

    * TensorShape([1, 2, 3]) is the most specific TensorShape compatible with
      both TensorShape([1, 2, 3]) and TensorShape([1, 2, 3]). There are more
      less specific TensorShapes compatible with above mentioned TensorShapes,
      e.g. TensorShape([1, 2, None]), TensorShape(None).

    Args:
      other: Another `TensorShape`.

    Returns:
      A `TensorShape` which is the most specific compatible shape of `self`
      and `other`.
    N)r   r,   r+   r   r   r*   )r:   rI   d1d2r,   s        r   most_specific_compatible_shapez*TensorShape.most_specific_compatible_shapek  s    ( UOEyyEJJ.$))uzz2I_ $))UZZ0B nB"H$FD  t	s   *Bc                 Z    | j                   duxr t        d | j                   D              S )z<Returns True iff `self` is fully defined in every dimension.Nc              3   $   K   | ]  }|d u 
 y wrS   r   r   s     r   r   z/TensorShape.is_fully_defined.<locals>.<genexpr>  s     6C46s   )r   r   r>   s    r   r   zTensorShape.is_fully_defined  s*    JJd" 764::668r   c                 @    | j                         st        d| z        y)zRaises an exception if `self` is not fully defined in every dimension.

    Raises:
      ValueError: If `self` does not have a known value for every dimension.
    zShape %s is not fully definedN)r   r3   r>   s    r   assert_is_fully_definedz#TensorShape.assert_is_fully_defined  s&       "6=>> #r   c                 Z    | j                   t        d      t        | j                         S )zReturns a list of integers or `None` for each dimension.

    Returns:
      A list of integers or `None` for each dimension.

    Raises:
      ValueError: If `self` is an unknown shape with an unknown rank.
    z3as_list() is not defined on an unknown TensorShape.)r   r3   r   r>   s    r   r   zTensorShape.as_list  s)     zzLMM

r   c                     | j                   t        j                  d      S t        j                  | j                   D cg c]&  }t        j                  j                  |dn|      ( c}      S c c}w )z+Returns this shape as a `TensorShapeProto`.T)r   r   r   )r   )r   r   r   Dimr   s     r   r  zTensorShape.as_proto  sn    zz..DAA..48JJ4/0 
+
+
/
/2 0 +4 	 	 4s    +A3c                 v    	 t        |      }| j                  |j                  k(  S # t        $ r	 t        cY S w xY w)a  Returns True if `self` is equivalent to `other`.

    It first tries to convert `other` to `TensorShape`. `TypeError` is thrown
    when the conversion fails. Otherwise, it compares each element in the
    TensorShape dimensions.

    * Two *Fully known* shapes, return True iff each element is equal.
    >>> t_a = tf.TensorShape([1,2])
    >>> a = [1, 2]
    >>> t_b = tf.TensorShape([1,2])
    >>> t_c = tf.TensorShape([1,2,3])
    >>> t_a.__eq__(a)
    True
    >>> t_a.__eq__(t_b)
    True
    >>> t_a.__eq__(t_c)
    False

    * Two *Partially-known* shapes, return True iff each element is equal.
    >>> p_a = tf.TensorShape([1,None])
    >>> p_b = tf.TensorShape([1,None])
    >>> p_c = tf.TensorShape([2,None])
    >>> p_a.__eq__(p_b)
    True
    >>> t_a.__eq__(p_a)
    False
    >>> p_a.__eq__(p_c)
    False

    * Two *Unknown shape*, return True.
    >>> unk_a = tf.TensorShape(None)
    >>> unk_b = tf.TensorShape(None)
    >>> unk_a.__eq__(unk_b)
    True
    >>> unk_a.__eq__(t_a)
    False

    Args:
      other: A `TensorShape` or type that can be converted to `TensorShape`.

    Returns:
      True if the dimensions are all equal.

    Raises:
      TypeError if `other` can not be converted to `TensorShape`.
    )r   r6   rG   r   rH   s     r   rJ   zTensorShape.__eq__  s=    `uoe ::$$  s   & 88c                 ,    t        | j                        S rS   )hashr   r>   s    r   __hash__zTensorShape.__hash__  s    

r   c                 (    t         | j                  ffS rS   )r*   r,   r>   s    r   r   zTensorShape.__reduce__  s    $$r   c                 $    | j                  |      S rS   r   rH   s     r   
__concat__zTensorShape.__concat__  r   r   r$   r*   )=r   r   r   r   r   r;   r   r   r?   rC   r+   r,   r   r   rQ   __nonzero__r   r   r   rd   rg   rk   r   r   r   r   r   r   r   	TraceTyperP   r   r   r   r  r   do_not_doc_inheritabler	  r  r  r  r  classmethodr   r   r   r  r  r  r]   rb   r&  r   r*  r   r  rJ   r1  r   r4  __classcell__)r  s   @r   r*   r*     s$   DJ i))'V $ $
)=   1 1  "
 +*0!d2Ph##
1.( 
DD(&&:M :MT :Mx6U__-62:=2I6p &&: ': &&) ') &&% '% && ' &&- '- -d+;+L+L&M - - "338E 
%5%F%F 
.`L<8
?	5%n%#r   c                   (    e Zd ZdZd Zd Zd Zd Zy)_TensorShapeCodeczCodec for `TensorShape`.c                 "    t        |t              S rS   r   )r:   pyobjs     r   
can_encodez_TensorShapeCodec.can_encode  s    e[))r   c                     ~t        j                         }|j                  j                  |j	                                |S rS   )r	   StructuredValuetensor_shape_valueCopyFromr  )r:   rB  	encode_fnencoded_tensor_shapes       r   	do_encodez_TensorShapeCodec.do_encode  s:    %557++44##%'r   c                 $    |j                  d      S )NrB  )HasFieldr9   s     r   
can_decodez_TensorShapeCodec.can_decode  s    >>.//r   c                 .    ~t        |j                        S rS   )r*   rB  )r:   r'   	decode_fns      r   	do_decodez_TensorShapeCodec.do_decode  s    u//00r   N)r   r   r   r   r?  rF  rI  rL  r   r   r   r<  r<    s     * 01r   r<  c                 <    t        | t              r| S t        |       S )z+Converts the given object to a TensorShape.r   )r-   s    r   r   r   	  s    {#Lur   c                     | d|v r|j                  d      } |rt        d|z        | t        d      S t        t        d      g| z        S )a  Returns an unknown TensorShape, optionally with a known rank.

  Args:
    rank: (Optional) If specified, the number of dimensions in the shape.
    **kwargs: For backwards compatibility.

  Returns:
    An unknown TensorShape.

  Raises:
    TypeError: In case of invalid arguments.
  Nr   zUnknown argument: %s)popr6   r*   r#   )r+   kwargss     r   r   r     sY     
\g'::gD
*V3
44	\t	$(4/00r   )r$   r#   r5  rS   )0r   r   r   typingr   r   r   r   tensorflow.core.frameworkr   tensorflow.core.functionr   tensorflow.core.protobufr	   tensorflow.pythonr
   tensorflow.python.eagerr   tensorflow.python.platformr   r   tensorflow.python.saved_modelr   tensorflow.python.typesr    tensorflow.python.util.tf_exportr   tensorflow.tools.docsr   r   	BoolGauger   r   r   r2   r!   r(   objectr#   rF   r7  Serializabler*   register_serializabler<  register_codecr   r   r   r   r   <module>ra     s   1   2 2 6 / / ! . < @ ) 6 . ':''$=? 
 &'(1( )1(h '()) *) "35M!N[#t+,
39B 9:<+<+\ {mX% X% X%v& =@#%//:#:#: @# @#D !
     -1 1* &  % %&7&9 :1r   