a
    ù!f65  ã                   @   s<   d Z ddlZddlZddlmZ G dd„ deƒZdd„ ZdS )z-Create / interact with gcloud datastore keys.é    N)Ú
entity_pb2c                   @   sä   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ Zed
d„ ƒZ	dd„ Z
dd„ Zdd„ Zdd„ Zedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZed d!„ ƒZed"d#„ ƒZed$d%„ ƒZd&d'„ Zed(d)„ ƒZd*d+„ Zd,S )-ÚKeyaÄ  An immutable representation of a datastore Key.

    To create a basic key:

      >>> Key('EntityKind', 1234)
      <Key[{'kind': 'EntityKind', 'id': 1234}]>
      >>> Key('EntityKind', 'foo')
      <Key[{'kind': 'EntityKind', 'name': 'foo'}]>

    To create a key with a parent:

      >>> Key('Parent', 'foo', 'Child', 1234)
      <Key[{'kind': 'Parent', 'name': 'foo'}, {'kind': 'Child', 'id': 1234}]>
      >>> Key('Child', 1234, parent=parent_key)
      <Key[{'kind': 'Parent', 'name': 'foo'}, {'kind': 'Child', 'id': 1234}]>

    To create a partial key:

      >>> Key('Parent', 'foo', 'Child')
      <Key[{'kind': 'Parent', 'name': 'foo'}, {'kind': 'Child'}]>

    :type path_args: tuple of string and integer
    :param path_args: May represent a partial (odd length) or full (even
                      length) key path.

    :type kwargs: dict
    :param kwargs: Keyword arguments to be passed in.

    Accepted keyword arguments are

    * namespace (string): A namespace identifier for the key.
    * project (string): The project associated with the key.
    * parent (:class:`gcloud.datastore.key.Key`): The parent of the key.

    The project argument is required unless it has been set implicitly.
    c                 O   sF   || _ | d¡ }| _| d¡| _| d¡}t||ƒ| _|  ¡ | _d S )NÚparentÚ	namespaceÚproject)Ú
_flat_pathÚgetÚ_parentÚ
_namespaceÚ_validate_projectÚ_projectÚ_combine_argsÚ_path)ÚselfÚ	path_argsÚkwargsr   r   © r   úU/var/www/html/python-backend/venv/lib/python3.9/site-packages/gcloud/datastore/key.pyÚ__init__=   s    
zKey.__init__c                 C   sB   t |tƒsdS | js|jrdS | j|jko@| j|jko@| j|jkS )a  Compare two keys for equality.

        Incomplete keys never compare equal to any other key.

        Completed keys compare equal if they have the same path, project,
        and namespace.

        :rtype: bool
        :returns: True if the keys compare equal, else False.
        F)Ú
isinstancer   Ú
is_partialÚ	flat_pathr   r   ©r   Úotherr   r   r   Ú__eq__G   s    

ÿ
þz
Key.__eq__c                 C   s   |   |¡ S )a  Compare two keys for inequality.

        Incomplete keys never compare equal to any other key.

        Completed keys compare equal if they have the same path, project,
        and namespace.

        :rtype: bool
        :returns: False if the keys compare equal, else True.
        )r   r   r   r   r   Ú__ne__\   s    z
Key.__ne__c                 C   s   t | jƒt | jƒ t | jƒ S )zyHash a keys for use in a dictionary lookp.

        :rtype: integer
        :returns: a hash of the key's state.
        )Úhashr   r   r   ©r   r   r   r   Ú__hash__i   s
    ÿþzKey.__hash__c                 C   sØ   t | ƒdkrtdƒ‚| ddd… }| ddd… }tƒ }t | ƒd dkrP||f7 }g }t||ƒD ]t\}}i }t|tjƒr€||d< n
t|dƒ‚t|tjƒr ||d< n(t|tjƒr¶||d	< n||urÈt|d
ƒ‚| |¡ q^|S )a_  Parses positional arguments into key path with kinds and IDs.

        :type path_args: tuple
        :param path_args: A tuple from positional arguments. Should be
                          alternating list of kinds (string) and ID/name
                          parts (int or string).

        :rtype: :class:`list` of :class:`dict`
        :returns: A list of key parts with kind and ID or name set.
        :raises: :class:`ValueError` if there are no ``path_args``, if one of
                 the kinds is not a string or if one of the IDs/names is not
                 a string or an integer.
        r   zKey path must not be empty.Né   é   ÚkindzKind was not a string.ÚnameÚidú$ID/name was not a string or integer.)	ÚlenÚ
ValueErrorÚobjectÚzipr   ÚsixÚstring_typesÚinteger_typesÚappend)r   Z	kind_listZid_or_name_listZpartial_endingÚresultr!   Ú
id_or_nameZcurr_key_partr   r   r   Ú_parse_paths   s.    




ÿzKey._parse_pathc                 C   sš   |   | j¡}| jdur–| jjr&tdƒ‚| jj| }| jj| j | _| jdurb| j| jjkrbtdƒ‚| jj| _| j	durŒ| j	| jj
krŒtdƒ‚| jj
| _	|S )aŽ  Sets protected data by combining raw data set from the constructor.

        If a ``_parent`` is set, updates the ``_flat_path`` and sets the
        ``_namespace`` and ``_project`` if not already set.

        :rtype: :class:`list` of :class:`dict`
        :returns: A list of key parts with kind and ID or name set.
        :raises: :class:`ValueError` if the parent key is not complete.
        NzParent key must be complete.z)Child namespace must agree with parent's.z'Child project must agree with parent's.)r/   r   r	   r   r&   Úpathr   r
   r   r   r   )r   Z
child_pathr   r   r   r       s"    


ÿ

ÿ
zKey._combine_argsc                 C   s$   | j | j| j| jdœŽ}| j|_|S )a3  Duplicates the Key.

        Most attributes are simple types, so don't require copying. Other
        attributes like ``parent`` are long-lived and so we re-use them.

        :rtype: :class:`gcloud.datastore.key.Key`
        :returns: A new ``Key`` instance with the same data as the current one.
        ©r   r   )Ú	__class__r   r   r   r	   )r   Zcloned_selfr   r   r   Ú_clone¾   s    	þz
Key._clonec                 C   sj   | j stdƒ‚d}t|tjƒr$d}nt|tjƒr6d}n
t|dƒ‚|  ¡ }||jd |< | j|f7  _|S )aò  Creates new key from existing partial key by adding final ID/name.

        :type id_or_name: string or integer
        :param id_or_name: ID or name to be added to the key.

        :rtype: :class:`gcloud.datastore.key.Key`
        :returns: A new ``Key`` instance with the same data as the current one
                  and an extra ID or name added.
        :raises: :class:`ValueError` if the current key is not partial or if
                 ``id_or_name`` is not a string or integer.
        z$Only a partial key can be completed.Nr"   r#   r$   éÿÿÿÿ)	r   r&   r   r)   r*   r+   r3   r   r   )r   r.   Zid_or_name_keyZnew_keyr   r   r   Úcompleted_keyÏ   s    ÿzKey.completed_keyc                 C   sr   t  ¡ }| j|j_| jr"| j|j_| jD ]D}|j ¡ }d|v rH|d |_	d|v rZ|d |_
d|v r(|d |_q(|S )z®Return a protobuf corresponding to the key.

        :rtype: :class:`gcloud.datastore._generated.entity_pb2.Key`
        :returns: The protobuf representing the key.
        r!   r#   r"   )Ú_entity_pb2r   r   Zpartition_idZ
project_idr   Znamespace_idr0   Úaddr!   r#   r"   )r   ÚkeyÚitemÚelementr   r   r   Úto_protobufì   s    





zKey.to_protobufc                 C   s
   | j du S )zËBoolean indicating if the key has an ID (or name).

        :rtype: bool
        :returns: ``True`` if the last element of the key's path does not have
                  an ``id`` or a ``name``.
        N)r.   r   r   r   r   r     s    zKey.is_partialc                 C   s   | j S )zfNamespace getter.

        :rtype: string
        :returns: The namespace of the current key.
        )r
   r   r   r   r   r     s    zKey.namespacec                 C   s   t  | j¡S )zµPath getter.

        Returns a copy so that the key remains immutable.

        :rtype: :class:`list` of :class:`dict`
        :returns: The (key) path of the current key.
        )ÚcopyÚdeepcopyr   r   r   r   r   r0     s    	zKey.pathc                 C   s   | j S )zŽGetter for the key path as a tuple.

        :rtype: tuple of string and integer
        :returns: The tuple of elements in the path.
        )r   r   r   r   r   r   !  s    zKey.flat_pathc                 C   s   | j d d S )zKind getter. Based on the last element of path.

        :rtype: string
        :returns: The kind of the current key.
        r4   r!   )r0   r   r   r   r   r!   *  s    zKey.kindc                 C   s   | j d  d¡S )z~ID getter. Based on the last element of path.

        :rtype: integer
        :returns: The (integer) ID of the key.
        r4   r#   ©r0   r   r   r   r   r   r#   3  s    zKey.idc                 C   s   | j d  d¡S )z€Name getter. Based on the last element of path.

        :rtype: string
        :returns: The (string) name of the key.
        r4   r"   r>   r   r   r   r   r"   <  s    zKey.namec                 C   s   | j p
| jS )zàGetter. Based on the last element of path.

        :rtype: integer (if ``id``) or string (if ``name``)
        :returns: The last element of the key's path if it is either an ``id``
                  or a ``name``.
        )r#   r"   r   r   r   r   r.   E  s    zKey.id_or_namec                 C   s   | j S )zUProject getter.

        :rtype: string
        :returns: The key's project.
        )r   r   r   r   r   r   O  s    zKey.projectc                 C   sB   | j r| jdd… }n| jdd… }|r>| j|| j| jdœŽS dS )aØ  Creates a parent key for the current path.

        Extracts all but the last element in the key path and creates a new
        key, while still matching the namespace and the project.

        :rtype: :class:`gcloud.datastore.key.Key` or :class:`NoneType`
        :returns: A new ``Key`` instance, whose path consists of all but the
                  last element of current path. If the current key has only
                  one path element, returns ``None``.
        Nr4   éþÿÿÿr1   )r   r   r2   r   r   )r   Zparent_argsr   r   r   Ú_make_parentX  s    
ÿzKey._make_parentc                 C   s   | j du r|  ¡ | _ | j S )a>  The parent of the current key.

        :rtype: :class:`gcloud.datastore.key.Key` or :class:`NoneType`
        :returns: A new ``Key`` instance, whose path consists of all but the
                  last element of current path. If the current key has only
                  one path element, returns ``None``.
        N)r	   r@   r   r   r   r   r   k  s    	

z
Key.parentc                 C   s   d| j | jf S )Nz<Key%s, project=%s>)r0   r   r   r   r   r   Ú__repr__y  s    zKey.__repr__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   Ústaticmethodr/   r   r3   r5   r;   Úpropertyr   r   r0   r   r!   r#   r"   r.   r   r@   r   rA   r   r   r   r   r      sB   %


,
	







	

r   c                 C   s   |du r| du rt dƒ‚| S )aa  Ensure the project is set appropriately.

    If ``parent`` is passed, skip the test (it will be checked / fixed up
    later).

    If ``project`` is unset, attempt to infer the project from the environment.

    :type project: string
    :param project: A project.

    :type parent: :class:`gcloud.datastore.key.Key` or ``NoneType``
    :param parent: The parent of the key or ``None``.

    :rtype: string
    :returns: The ``project`` passed in, or implied from the environment.
    :raises: :class:`ValueError` if ``project`` is ``None`` and no project
             can be inferred from the parent.
    NzA Key must have a project set.)r&   )r   r   r   r   r   r   }  s    r   )	rE   r<   r)   Zgcloud.datastore._generatedr   r6   r'   r   r   r   r   r   r   Ú<module>   s     h