σ
jϊ\c           @@  sσ   d  Z  d d l m 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 d d l Z d d l Z d	   Z d
 e f d     YZ e j d e j e f d     Y Z e j d e j e f d     Y Z d S(   s  Create links in the HDF5 file.

This module implements containers for soft and external links.  Hard
links doesn't need a container as such as they are the same as regular
nodes (groups or leaves).

Classes:

    SoftLink
    ExternalLink

Functions:

Misc variables:

i    (   t   absolute_importNi   (   t   linkextension(   t   Node(   t   lazyattr(   t   AttributeSetc         C@  s   t  j |  |  S(   s   Guess the link class.(   R   t   _get_link_class(   t	   parent_idt   name(    (    s*   lib/python2.7/site-packages/tables/link.pyt   _g_get_link_class)   s    t   Linkc           B@  st   e  Z d  Z e d    Z d e d  Z d d e e d  Z d d e d  Z	 d   Z
 d e d  Z d   Z RS(	   s  Abstract base class for all PyTables links.

    A link is a node that refers to another node.  The Link class inherits from
    Node class and the links that inherits from Link are SoftLink and
    ExternalLink.  There is not a HardLink subclass because hard links behave
    like a regular Group or Leaf.  Contrarily to other nodes, links cannot have
    HDF5 attributes.  This is an HDF5 library limitation that might be solved
    in future releases.

    See :ref:`LinksTutorial` for a small tutorial on how to work with links.

    .. rubric:: Link attributes

    .. attribute:: target

        The path string to the pointed node.

    c         C@  s    d t  f d     Y} | |   S(   sά   
        A *NoAttrs* instance replacing the typical *AttributeSet* instance of
        other node objects.  The purpose of *NoAttrs* is to make clear that
        HDF5 attributes are not supported in link nodes.
        t   NoAttrsc           B@  s#   e  Z d    Z d   Z d   Z RS(   c         S@  s   t  d |  j j   d  S(   Ns1   you cannot get attributes from this `%s` instance(   t   KeyErrort	   __class__t   __name__(   t   selfR   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   __getattr__M   s    c         S@  s   t  d |  j j   d  S(   Ns/   you cannot set attributes to this `%s` instance(   R   R   R   (   R   R   t   value(    (    s*   lib/python2.7/site-packages/tables/link.pyt   __setattr__Q   s    c         S@  s   d  S(   N(    (   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   _g_closeU   s    (   R   t
   __module__R   R   R   (    (    (    s*   lib/python2.7/site-packages/tables/link.pyR
   L   s   		(   R   (   R   R
   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   _v_attrsE   s    c         C@  s8   | d  k	 |  _ | |  _ t t |   j | | |  d  S(   N(   t   Nonet   _v_newt   targett   superR	   t   __init__(   R   t
   parentnodeR   R   t   _log(    (    s*   lib/python2.7/site-packages/tables/link.pyR   Y   s    	c      	   C@  s>   |  j  d | d | d | d |  } | j j | | t  | S(   sΰ   Copy this link and return the new one.

        See :meth:`Node._f_copy` for a complete explanation of the arguments.
        Please note that there is no recursive flag since links do not have
        child nodes.

        t	   newparentt   newnamet	   overwritet   createparents(   t   _f_copyt	   _v_parentt
   _g_refnodet   True(   R   R   R   R   R   t   newnode(    (    s*   lib/python2.7/site-packages/tables/link.pyt   copya   s
    
	c         C@  s   |  j  d | d | d |  S(   sr   Move or rename this link.

        See :meth:`Node._f_move` for a complete explanation of the arguments.

        R   R   R   (   t   _f_move(   R   R   R   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   mover   s    c         C@  s
   |  j    S(   s$   Remove this link from the hierarchy.(   t	   _f_remove(   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   remove|   s    c         C@  s   |  j  d | d |  S(   su   Rename this link in place.

        See :meth:`Node._f_rename` for a complete explanation of the arguments.

        R   R   (   t	   _f_rename(   R   R   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   rename   s    c         C@  s
   t  |   S(   N(   t   str(   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   __repr__   s    N(   R   R   t   __doc__R   R   R   t   FalseR   R%   R'   R)   R+   R-   (    (    (    s*   lib/python2.7/site-packages/tables/link.pyR	   0   s   
		t   SoftLinkc           B@  sh   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 RS(   s,  Represents a soft link (aka symbolic link).

    A soft link is a reference to another node in the *same* file hierarchy.
    Provided that the target node exists, its attributes and methods can be
    accessed directly from the softlink using the normal `.` syntax.

    Softlinks also have the following public methods/attributes:

        * `target`
        * `dereference()`
        * `copy()`
        * `move()`
        * `remove()`
        * `rename()`
        * `is_dangling()`

    Note that these will override any correspondingly named methods/attributes
    of the target node.

    For backwards compatibility, it is also possible to obtain the target node
    via the `__call__()` special method (this action is called *dereferencing*;
    see below)

    Examples
    --------

    ::

        >>> f = tables.open_file('/tmp/test_softlink.h5', 'w')
        >>> a = f.create_array('/', 'A', np.arange(10))
        >>> link_a = f.create_soft_link('/', 'link_A', target='/A')

        # transparent read/write access to a softlinked node
        >>> link_a[0] = -1
        >>> print(link_a[:], link_a.dtype)
        (array([-1,  1,  2,  3,  4,  5,  6,  7,  8,  9]), dtype('int64'))

        # dereferencing a softlink using the __call__() method
        >>> print(link_a() is a)
        True

        # SoftLink.remove() overrides Array.remove()
        >>> link_a.remove()
        >>> print(link_a)
        <closed tables.link.SoftLink at 0x7febe97186e0>
        >>> print(a[:], a.dtype)
        (array([-1,  1,  2,  3,  4,  5,  6,  7,  8,  9]), dtype('int64'))


    t   SOFTLINKR   t   dereferencet   is_danglingR%   R'   R)   R+   R   t   __str__R-   t   __unicode__R   t   __dict__t   _f_t   _c_t   _g_t   _v_c         C@  s
   |  j    S(   s;  Dereference `self.target` and return the object.

        Examples
        --------

        ::

            >>> f=tables.open_file('data/test.h5')
            >>> print(f.root.link0)
            /link0 (SoftLink) -> /another/path
            >>> print(f.root.link0())
            /another/path (Group) ''

        (   R2   (   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   __call__Ο   s    c         C@  sT   |  j  rL |  j } |  j j d  s< |  j j |  j  } n  |  j j |  Sd  Sd  S(   Nt   /(   t	   _v_isopenR   t
   startswithR!   t   _g_joint   _v_filet	   _get_nodeR   (   R   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyR2   ΰ   s    		c         C@  s   | t  j k s" | d  t  j k r2 t j |  |  S|  j sM t j d   nK |  j   r] d  S|  j
   } y | j |  SWn t k
 r | j |  SXd  S(   Ni   s   the node object is closed(   R0   t   _link_attrnamest   _link_attrprefixest   objectt   __getattribute__R=   t   tablest   ClosedNodeErrorR3   R   R2   t   AttributeErrorR   (   R   t   attrnamet   target_node(    (    s*   lib/python2.7/site-packages/tables/link.pyRE   λ   s    	c         C@  s   | t  j k s" | d  t  j k r8 t j |  | |  nL |  j sS t j d   n1 |  j   rn t	 d   n |  j
   j | |  d  S(   Ni   s   the node object is closeds   softlink target does not exist(   R0   RB   RC   RD   R   R=   RF   RG   R3   t
   ValueErrorR2   (   R   RI   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyR      s    	c         C@  sM   |  j  s t j d   n. |  j   r6 t d   n |  j   j |  Sd S(   sd   __getitem__ must be defined in the SoftLink class in order for array
        indexing syntax to works   the node object is closeds   softlink target does not existN(   R=   RF   RG   R3   RK   R2   t   __getitem__(   R   t   key(    (    s*   lib/python2.7/site-packages/tables/link.pyRL     s
    	c         C@  sP   |  j  s t j d   n1 |  j   r6 t d   n |  j   j | |  d S(   sd   __setitem__ must be defined in the SoftLink class in order for array
        indexing syntax to works   the node object is closeds   softlink target does not existN(   R=   RF   RG   R3   RK   R2   t   __setitem__(   R   RM   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyRN     s
    	c         C@  s   |  j    |  j k S(   N(   R2   R@   (   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyR3   %  s    c         C@  s   |  j  j } t |  j  } |  j j d  sE |  j j |  j  } n  |  j rW d } n d } | |  j k ru d } n d } d | |  j	 | |  j | f S(   sρ   Return a short string representation of the link.

        Examples
        --------

        ::

            >>> f=tables.open_file('data/test.h5')
            >>> print(f.root.link0)
            /link0 (SoftLink) -> /path/to/node

        R<   t    s   closed s    (dangling)s   %s%s (%s) -> %s%s(
   R   R   R,   R   R>   R!   R?   R=   R@   t   _v_pathname(   R   t	   classnameR   t   closedt   dangling(    (    s*   lib/python2.7/site-packages/tables/link.pyR4   )  s    			(   R   R2   R3   R%   R'   R)   R+   R   R4   R-   R5   R   R6   (   R7   R8   R9   R:   (   R   R   R.   t
   _c_classidRB   RC   R;   R2   RE   R   RL   RN   R3   R4   (    (    (    s*   lib/python2.7/site-packages/tables/link.pyR0      s   3  							t   ExternalLinkc           B@  sP   e  Z d  Z d Z d e d  Z d   Z d   Z d   Z	 d   Z
 d   Z RS(	   sΧ  Represents an external link.

    An external link is a reference to a node in *another* file.
    Getting access to the pointed node (this action is called
    *dereferencing*) is done via the :meth:`__call__` special method
    (see below).

    .. rubric:: ExternalLink attributes

    .. attribute:: extfile

        The external file handler, if the link has been dereferenced.
        In case the link has not been dereferenced yet, its value is
        None.

    t   EXTERNALLINKc         C@  s,   d  |  _ t t |   j | | | |  d  S(   N(   R   t   extfileR   RU   R   (   R   R   R   R   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyR   _  s    	c         C@  s&   |  j  j d  \ } } | d | f S(   s=   Return the external filename and nodepath from `self.target`.s   :/R<   (   R   t   split(   R   t   filenameR   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   _get_filename_nodef  s    c         K@  sΤ   |  j    \ } } t j j |  sT t j j |  j j  } t j j | |  } n  |  j d k sp |  j j
 r t j | |  |  _ n< |  j j | k s  t  |  j j | j d d  k sΔ t  |  j j |  S(   s’  Dereference self.target and return the object.

        You can pass all the arguments supported by the :func:`open_file`
        function (except filename, of course) so as to open the referenced
        external file.

        Examples
        --------

        ::

            >>> f=tables.open_file('data1/test1.h5')
            >>> print(f.root.link2)
            /link2 (ExternalLink) -> data2/test2.h5:/path/to/node
            >>> plink2 = f.root.link2('a')  # open in 'a'ppend mode
            >>> print(plink2)
            /path/to/node (Group) ''
            >>> print(plink2._v_filename)
            'data2/test2.h5'        # belongs to referenced file

        t   modet   rN(   RZ   t   ost   patht   isabst   dirnameR@   RY   t   joinRW   R   t   isopenRF   t	   open_filet   AssertionErrorR[   t   getRA   (   R   t   kwargsRY   R   t   base_directory(    (    s*   lib/python2.7/site-packages/tables/link.pyR;   m  s    $c         C@  s8   |  j  } | d k	 r4 | j r4 | j   d |  _  n  d S(   s'   Safely unmount self.extfile, if opened.N(   RW   R   Rb   t   close(   R   RW   (    (    s*   lib/python2.7/site-packages/tables/link.pyt   umount  s    	
c         C@  s!   |  j    t t |   j   d S(   s#   Especific close for external links.N(   Ri   R   RU   t   _f_close(   R   (    (    s*   lib/python2.7/site-packages/tables/link.pyRj     s    
c         C@  s#   |  j  j } d |  j | |  j f S(   s  Return a short string representation of the link.

        Examples
        --------

        ::

            >>> f=tables.open_file('data1/test1.h5')
            >>> print(f.root.link2)
            /link2 (ExternalLink) -> data2/test2.h5:/path/to/node

        s   %s (%s) -> %s(   R   R   RP   R   (   R   RQ   (    (    s*   lib/python2.7/site-packages/tables/link.pyR4   €  s    N(   R   R   R.   RT   R   R/   R   RZ   R;   Ri   Rj   R4   (    (    (    s*   lib/python2.7/site-packages/tables/link.pyRU   H  s   		(			(   R.   t
   __future__R    R]   RF   RO   R   t   nodeR   t   utilsR   t   attributesetR   t   sixt   tables.fileR   R	   t   python_2_unicode_compatibleR0   RU   (    (    (    s*   lib/python2.7/site-packages/tables/link.pyt   <module>   s   	^	Ή	