
    dӹ                        d Z ddlZddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
 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mZmZ ddlmZmZ ddlmZ ddlmZmZ ddlm Z m!Z!m"Z" dZ# G d de          Z$ G d dej%        e          Z% G d de%          Z& G d dee%          Z' G d dee%          Z( G d dee%          Z)dS )z Here is defined the Group class.    N   )	ProxyDict)hdf5extension)utilsextension)class_id_dict)	NodeErrorNoSuchNodeErrorNaturalNameWarningPerformanceWarning)Filters)get_class_by_name)check_name_validity	join_pathisvisiblename)NodeNotLoggedMixin)Leaf)UnImplementedUnknown)LinkSoftLinkExternalLinkz1.0c                       e Zd Zd ZdS )_ChildrenDictc                 ,    |                     |          S N)_f_get_child)self	containerkeys      ,lib/python3.11/site-packages/tables/group.py_get_value_from_containerz'_ChildrenDict._get_value_from_container   s    %%c***    N)__name__
__module____qualname__r"    r#   r!   r   r      s#        + + + + +r#   r   c                       e Zd ZdZdZdZd Z ee          Zd Z	d Z
d Z ee	e
ed          Z	 	 d0 fd	Zd Z fdZd Zd1dZd Zd Zd Zd Zd Zd2dZd Zd Zd1dZd Z fdZd1dZd Zd Zd2d Z d2d!Z!d" Z" fd#Z# fd$Z$d% Z% fd&Z&d' Z'd( Z( fd)Z)d* Z*d3 fd+	Z+	 	 d4 fd,	Z,	 	 d5d-Z-d. Z.d/ Z/ xZ0S )6Groupa2  Basic PyTables grouping structure.

    Instances of this class are grouping structures containing *child*
    instances of zero or more groups or leaves, together with
    supporting metadata. Each group has exactly one *parent* group.

    Working with groups and leaves is similar in many ways to working
    with directories and files, respectively, in a Unix filesystem.
    As with Unix directories and files, objects in the object tree are
    often described by giving their full (or absolute) path names.
    This full path can be specified either as a string (like in
    '/group1/group2') or as a complete object path written in *natural
    naming* schema (like in file.root.group1.group2).

    A collateral effect of the *natural naming* schema is that the
    names of members in the Group class and its instances must be
    carefully chosen to avoid colliding with existing children node
    names.  For this reason and to avoid polluting the children
    namespace all members in a Group start with some reserved prefix,
    like _f_ (for public methods), _g_ (for private ones), _v_ (for
    instance variables) or _c_ (for class variables). Any attempt to
    create a new child node whose name starts with one of these
    prefixes will raise a ValueError exception.

    Another effect of natural naming is that children named after
    Python keywords or having names not valid as Python identifiers
    (e.g.  class, $a or 44) can not be accessed using the node.child
    syntax. You will be forced to use node._f_get_child(child) to
    access them (which is recommended for programmatic accesses).

    You will also need to use _f_get_child() to access an existing
    child node if you set a Python attribute in the Group with the
    same name as that node (you will get a NaturalNameWarning when
    doing this).

    Parameters
    ----------
    parentnode
        The parent :class:`Group` object.
    name : str
        The name of this node in its parent group.
    title
        The title for this group
    new
        If this group is new or has to be read from disk
    filters : Filters
        A Filters instance


    .. versionchanged:: 3.0
       *parentNode* renamed into *parentnode*

    Notes
    -----
    The following documentation includes methods that are automatically
    called when a Group instance is accessed in a special way.

    For instance, this class defines the __setattr__, __getattr__,
    __delattr__ and __dir__ methods, and they set, get and delete
    *ordinary Python attributes* as normally intended. In addition to that,
    __getattr__ allows getting *child nodes* by their name for the sake of
    easy interaction on the command line, as long as there is no Python
    attribute with the same name. Groups also allow the interactive
    completion (when using readline) of the names of child nodes.
    For instance::

        # get a Python attribute
        nchild = group._v_nchildren

        # Add a Table child called 'table' under 'group'.
        h5file.create_table(group, 'table', myDescription)
        table = group.table          # get the table child instance
        group.table = 'foo'          # set a Python attribute

        # (PyTables warns you here about using the name of a child node.)
        foo = group.table            # get a Python attribute
        del group.table              # delete a Python attribute
        table = group.table          # get the table child instance again

    Additionally, on interactive python sessions you may get autocompletions
    of children named as *valid python identifiers* by pressing the  `[Tab]`
    key, or to use the dir() global function.

    .. rubric:: Group attributes

    The following instance variables are provided in addition to those
    in Node (see :ref:`NodeClassDescr`):

    .. attribute:: _v_children

        Dictionary with all nodes hanging from this group.

    .. attribute:: _v_groups

        Dictionary with all groups hanging from this group.

    .. attribute:: _v_hidden

        Dictionary with all hidden nodes hanging from this group.

    .. attribute:: _v_leaves

        Dictionary with all leaves hanging from this group.

    .. attribute:: _v_links

        Dictionary with all links hanging from this group.

    .. attribute:: _v_unknown

        Dictionary with all unknown nodes hanging from this group.

    GROUP)__members___v_children	_v_groups	_v_leaves_v_links
_v_unknown	_v_hiddenc                 *    t          | j                  S )z/The number of children hanging from this group.)lenr,   r   s    r!   _g_getnchildrenzGroup._g_getnchildren   s    4#$$$r#   c                 R    t          | j        dd           }|t                      }|S )NFILTERS)getattr_v_attrsr   )r   filterss     r!   _g_getfilterszGroup._g_getfilters   s(    $-D99?iiGr#   c                 l    t          |t                    st          d|          || j        _        d S )Nz'value is not an instance of `Filters`: )
isinstancer   	TypeErrorr9   r7   )r   values     r!   _g_setfilterszGroup._g_setfilters   sE    %)) 	EC%CCE E E %r#   c                     | j         `d S r   )r9   r7   r4   s    r!   _g_delfilterszGroup._g_delfilters   s    M!!!r#   aP  Default filter properties for child nodes.

        You can (and are encouraged to) use this property to get, set and
        delete the FILTERS HDF5 attribute of the group, which stores a Filters
        instance (see :ref:`FiltersClassDescr`). When the group has no such
        attribute, a default Filters instance is used.
         FNTc                     t           | _        	 || _        	 || _        	 || _        	 |j        j        d         | _        	 t                      	                    |||           d S )NMAX_GROUP_WIDTH)
	obversion
_v_version_v_new_v_new_title_v_new_filters_v_fileparams_v_max_group_widthsuper__init__)r   
parentnodenametitlenewr:   _log	__class__s          r!   rO   zGroup.__init__   sl     $/?!&%<","4";<M"N	 	T400000r#   c                 v   | j         r| j        j        d         rs| j        j        } |d| j                    |d| j                    |d| j                   | j        }|t          | j
        j        dd           }| |d|           d S d S d S d| j        j        v r| j        j        | _        d S d| _        d S )NPYTABLES_SYS_ATTRSTITLECLASSVERSIONr7   z0.0 (unknown))rH   rK   rL   r9   _g__setattrrI   
_c_classidrG   rJ   r8   	_v_parent_v_attrnamessysrZ   )r   set_attr
newfilterss      r!   _g_post_init_hookzGroup._g_post_init_hook   s    ; 	2|"#78 4=4$"3444$/222DO444 "0
% ")/D"B "BJ)HY
33333#4 4  *) DM999"&-"7"1r#   c                 P   | j         r}| j        | j        j        j        v red| j        v r\t          j        |           }|| j        _	        || j
        _	        || j        _	        || j        _	        || j        _	        || j        _	        t                                                       d S )Nr,   )	_v_isopen_v_pathnamerK   _node_managerregistry__dict__weakrefrefr,   containerrefr-   r.   r/   r0   r1   rN   __del__)r   selfrefrU   s     r!   rk   zGroup.__del__   s    N 	2 : CCC.. k$''G,3D)*1DN'*1DN')0DM&+2DO(*1DN'r#   c                     |                      |d          }|*t          |t                    s|                    d          }|t          v rt          |         S t
          S )zrGet the class of a not-yet-loaded group child.

        `childname` must be the name of a *group* child.

        rY   Nutf-8)_g_get_gchild_attrr=   strdecoder   r)   )r   	childnamechildCIDs      r!   _g_get_child_group_classzGroup._g_get_child_group_class  sZ     **9g>>
8S(A(Aw//H}$$ **Lr#   c                    | j         j        d         rC|                     |d          }|*t          |t                    s|                    d          }nd}|t          v rt          |         S t          j        | j	        |          }|dk    rd|r[|+t          j        d|                     |          z             n.t          j        d|                     |          d|d	           t          S |t          v sJ t          |         S )
a.  Get the class of a not-yet-loaded leaf child.

        `childname` must be the name of a *leaf* child.  If the child
        belongs to an unknown kind of leaf, or if its kind can not be
        guessed, `UnImplemented` will be returned and a warning will be
        issued if `warn` is true.

        rW   rY   Nrn   UNSUPPORTEDzOleaf ``%s`` is of an unsupported type; it will become an ``UnImplemented`` nodezleaf ``z`` has an unknown class ID ``z,``; it will become an ``UnImplemented`` node)rK   rL   _g_get_lchild_attrr=   rp   rq   r   r   which_class_v_objectidwarningswarn_g_joinr   )r   rr   r{   rs   	childCID2s        r!   _g_get_child_leaf_classzGroup._g_get_child_leaf_class  s4    <34 	..y'BBH#Jx,E,E##??733H}$$ ** '243CYOOIM)) 
C' G"ll95567 7 7 7
 !  $||I6666BC C C %$---- ++r#   c                    | j         }g x|d<   }	 t          |           x|d<   }	 t          |           x|d<   }	 t          |           x|d<   }	 t          |           x|d<   }	 t          |           x|d<   }	 t          |           x|d<   }	 |                     | j                  \  }	}
}}|	|f|
|f||f||ffD ]?\  }}|D ]7}t	          |          r!|                    d|           d	||<   d	||<   2d	||<   8@d	S )
zWAdd children names to this group taking into account their
        visibility and kind.r+   r,   r-   r.   r/   r0   r1   r   N)rg   r   _g_list_groupr]   r   insert)r   mydictmemberschildrengroupsleaveslinksunknownhiddengroup_names
leaf_names
link_namesunknown_names
childnames	childdictrr   s                   r!   _g_add_children_nameszGroup._g_add_children_namesC  s     +-,}	+8+>+>>}='4T':'::{fA'4T':'::{fA%24%8%88zU@)6t)<)<<|wH'4T':'::{fG t~.. 	=j*m
 *5f(=)3V(<)3U(;)6(@(B 	- 	-#Z
 ( 
- 
-	 !++ -NN1i000*.HY'+/Ii(( )-F9%%
-	- 	-r#   c                 r    |                      |          }|dk    rt          d| j        d|d          |S )zACheck whether 'name' is a children of 'self' and return its type.
NoSuchNodegroup ``z!`` does not have a child named ````)_g_get_objinfor	   rd   )r   rQ   	node_types      r!   _g_check_has_childzGroup._g_check_has_childq  sU     ''--	$$!/###TTT+, , , r#   c                 *    |                                  S )ag  Iterate over the child nodes hanging directly from the group.

        This iterator is *not* recursive.

        Examples
        --------

        ::

            # Non-recursively list all the nodes hanging from '/detector'
            print("Nodes in '/detector' group:")
            for node in h5file.root.detector:
                print(node)

        )_f_iter_nodesr4   s    r!   __iter__zGroup.__iter__|  s    " !!###r#   c                 ~    |                                   	 |                     |           n# t          $ r Y dS w xY wdS )zIs there a child with that `name`?

        Returns a true value if the group has a child node (visible or
        hidden) with the given `name` (a string), false otherwise.

        FT)_g_check_openr   r	   r   rQ   s     r!   __contains__zGroup.__contains__  sY     		##D)))) 	 	 	55	ts   , 
::c                 h    	 |                      |          S # t          $ r t          |          w xY w)zyReturn the (visible or hidden) child with that `name` ( a string).

        Raise IndexError if child not exist.
        )r   r	   
IndexError)r   rr   s     r!   __getitem__zGroup.__getitem__  sD    
	($$Y/// 	( 	( 	(Y'''	(s    1c              #      K   |                                   |dk    rd}|dk    r|                                 E d{V  dS |                                 D ]}|                    |          E d{V  dS )a  Iterate over descendant nodes.

        This method recursively walks *self* top to bottom (preorder),
        iterating over child groups in alphanumerical order, and yielding
        nodes.  If classname is supplied, only instances of the named class are
        yielded.

        If *classname* is Group, it behaves like :meth:`Group._f_walk_groups`,
        yielding only groups.  If you don't want a recursive behavior,
        use :meth:`Group._f_iter_nodes` instead.

        Examples
        --------

        ::

            # Recursively print all the arrays hanging from '/'
            print("Arrays in the object tree '/':")
            for array in h5file.root._f_walknodes('Array', recursive=True):
                print(array)

        rC   Nr)   )r   _f_walk_groupsr   )r   	classnamegroups      r!   _f_walknodeszGroup._f_walknodes  s      0 	 ??I**,,,,,,,,,,,,,.. : : ..y9999999999: :r#   c                 F    |dk    r| j         S t          | j         |          S )zcHelper method to correctly concatenate a name child object with the
        pathname of this group./)rd   r   r   s     r!   r|   zGroup._g_join  s)     3;;##)4000r#   c                 X    t          j        d| j        | j        fz  t                     dS )z7Issue a :exc:`PerformanceWarning` on too many children.zgroup ``%s`` is exceeding the recommended maximum number of children (%d); be ready to see PyTables asking for *lots* of memory and possibly slow I/O.Nrz   r{   rd   rM   r   r4   s    r!   _g_width_warningzGroup._g_width_warning  sC     	 O )4+BCD )		* 	* 	* 	* 	*r#   c                 ,   |r$t          |           |                    |           t          |t                    s|| v rt	          d| j        d|d          || j        v r&t          j        d| j        d|dt                     t          | j                  t          | j                  z   | j        k    r|                                  t          |          r| j                            d|           d| j        |<   t          |t$                    rd| j        |<   dS t          |t                    rd| j        |<   dS t          |t*                    rd| j        |<   dS t          |t.                    rd| j        |<   dS dS d| j        |<   dS )a|  Insert references to a `childnode` via a `childname`.

        Checks that the `childname` is valid and does not exist, then
        creates references to the given `childnode` by that `childname`.
        The validation of the name can be omitted by setting `validate`
        to a false value (this may be useful for adding already existing
        nodes to the tree).

        r   $`` already has a child node named ``r   z$`` already has an attribute named ``G``; you will not be able to use natural naming to access the child noder   N)r   _g_check_namer=   r   r   rd   rg   rz   r{   r
   r3   r,   r1   rM   r   r   r+   r   r   r0   r/   r   r.   r)   r-   )r   	childnoderr   validates       r!   
_g_refnodezGroup._g_refnode  s     	/	***##I... 9d++ 	1d1B1B)###YYY01 1 1
 %%MM ###YYY0 2D	E E E  !!C$7$77'( (!!###
 ## 	-##Ay111*.DY')W-- 1-1	***It,, 1+/i(((It,, 1,0y)))Iu-- 1,0y)))1 1 )-DN9%%%r#   c                    || v sJ d| j         d|d            d| j        v r|| j        v r| j        }|                    |          }||= | j        |= | j                            |d           | j                            |d           | j                            |d           | j	                            |d           dS | j
        |= dS dS )zYRemove references to a node.

        Removes all references to the named node.

        r   z&`` does not have a child node named ``r   r,   N)rd   rg   r,   r+   indexr0   popr/   r.   r-   r1   )r   rr   r   member_indexs       r!   _g_unrefnodezGroup._g_unrefnode  s     D    ###YYY0 !  
 DM))D,,,*&}}Y77L)$Y/##It444!!)T222""9d333""9d33333 N9--- *)r#   c                     | j         }t                                          ||           | j         }| j                            ||           d S r   )rd   rN   _g_moverK   _update_node_locations)r   	newparentnewnameoldpathnewpathrU   s        r!   r   zGroup._g_move6  sK    "	7+++" 	++GW=====r#   c                    |                     d| j                  }|                     dd           }|                     dd           }|| j        }|t          | j        dd           }t	          |||d||          }	|                     dd          r!| j                            |	j        d           ||d	xx         d
z  cc<   |r8|                                }|                    dd             | j        |	fi | |	S )NrR   r:   statsr7   T)rS   r:   rT   copyuserattrs)	copyclassr   r   )	get_v_titler8   r9   r)   _g_copycopyr   _g_copy_children)
r   r   r   	recursiverT   kwargsrR   r:   r   new_nodes
             r!   r   zGroup._g_copy@  s+   

7DM22**Y--

7D)) =ME ?dmY==G GD'F F F ::ot,, 	EM!!("3t!DDD (OOOq OOO 	6 [[]]FJJw%%%!D!(55f555r#   c                    |                     dd          }|r|                    di           }| |fg}|r|                                \  }}|r4|j                                        D ]}|                                \  }	}
|
dk    r|	|v r||	         d         \  }}t          j                            ||          }|j	        
                    ||j        |           ||	                             |j        |j        f           |                    dd          }||dxx         dz  cc<    |j        |fi |}t          |t                     r|                    ||f           |
dk    r|j        |j        fg||	<   nV|j                                        D ]<} |j        |fi |}t          |t                     r|                    ||f           =|dS dS )	aB  Copy child nodes.

        Copies all nodes descending from this one into the specified
        `newparent`.  If the new parent has a child node with the same
        name as one of the nodes in this group, the copy fails with a
        `NodeError`, maybe resulting in a partial copy.  Nothing is
        logged.

        use_hardlinksFaddress_mapr   r   r   N	hardlinks)r   
setdefaultr   r,   values_get_obj_infoospathjoinrK   create_hard_linkrQ   appendrd   _g_copy_as_childr=   r)   )r   r   r   r   r   parentstack	srcparent	dstparentsrcchildaddrrcwhererQ   localsrcr   dstchilds                   r!   r   zGroup._g_copy_childrenc  si     

?E:: 	? ++M2>>Ki() "	A%0__%6%6"Y	 A ) 5 < < > >  H'5577HD"Avv$+"5"5&1$&7&:t#%7<<t#<#<!)::9;C=;CE E E $D)00&2HMB  
 !'

7D 9 9 ,!+...!3...#<8#<Y $G $G?E$G $G%h66 E'..(/CDDD66!*!6 F1K-/6 !* 5 < < > > A AH8x8MMfMMH!(E22 A#**Hh+?@@@E  "	A "	A "	A "	A "	Ar#   c                     |                                   |                     |           t          | j        |          }| j                            |          S )at  Get the child called childname of this group.

        If the child exists (be it visible or not), it is returned.  Else, a
        NoSuchNodeError is raised.

        Using this method is recommended over getattr() when doing programmatic
        accesses to children if childname is unknown beforehand or when its
        name is not a valid Python identifier.

        )r   r   r   rd   rK   	_get_node)r   rr   	childpaths      r!   r   zGroup._f_get_child  sR     		***d.	::	|%%i000r#   c                 F    t          |                     |                    S )zzReturn a *list* with children nodes.

        This is a list-returning version of :meth:`Group._f_iter_nodes()`.

        )listr   )r   r   s     r!   _f_list_nodeszGroup._f_list_nodes  s      D&&y11222r#   c              #   b  K   |                                   |s(t          | j                  D ]}| j        |         V  dS |dk    r(t          | j                  D ]}| j        |         V  dS |dk    r(t          | j                  D ]}| j        |         V  dS |dk    r(t          | j                  D ]}| j        |         V  dS |dk    rt          d          t          |          }t          | j                                                  D ]\  }}t          ||          r|V  dS )a}  Iterate over children nodes.

        Child nodes are yielded alphanumerically sorted by node name.  If the
        name of a class derived from Node (see :ref:`NodeClassDescr`) is
        supplied in the classname parameter, only instances of that class (or
        subclasses of it) will be returned.

        This is an iterator version of :meth:`Group._f_list_nodes`.

        r)   r   r   
IndexArrayz+listing ``IndexArray`` nodes is not allowedN)
r   sortedr,   r-   r.   r/   r>   r   itemsr=   )r   r   rQ   class_rr   r   s         r!   r   zGroup._f_iter_nodes  s      	 	$t/00 - -&t,,,,,- -'!!t~.. + +nT*****+ +&  t~.. + +nT*****+ +&  t}-- * *mD)))))* *,&&=? ? ? 'y11F(.t/?/E/E/G/G(H(H $ $$	9i00 $#OOO$ $r#   c              #     K   |                                   | g}| V  |r`|                                }t          |j                  }|D ]1}|                    |j        |                    |j        |         V  2|^dS dS )a  Recursively iterate over descendent groups (not leaves).

        This method starts by yielding *self*, and then it goes on to
        recursively iterate over all child groups in alphanumerical order, top
        to bottom (preorder), following the same procedure.

        N)r   r   r   r-   r   )r   stackobjgroup
groupnames	groupnames        r!   r   zGroup._f_walk_groups  s       	


 	4yy{{H 233J ( 4 4	X/	:;;;(33333  	4 	4 	4 	4 	4r#   c                     	 t                                          |           dS # t          $ r,}d}|                    t	          |          |z             d}~ww xY w)a9  Delete a Python attribute called name.

        This method only provides a extra warning in case the user
        tries to delete a children node using __delattr__.

        To remove a children node from this group use
        :meth:`File.remove_node` or :meth:`Node._f_remove`. To delete
        a PyTables node attribute use :meth:`File.del_node_attr`,
        :meth:`Node._f_delattr` or :attr:`Node._v_attrs``.

        If there is an attribute and a child node with the same name,
        the child node will be made accessible again via natural naming.

        z8 (use ``node._f_remove()`` if you want to remove a node)N)rN   __delattr__AttributeErrorrU   rp   )r   rQ   aehintrU   s       r!   r   zGroup.__delattr__  sf     	/GG%%%%% 	/ 	/ 	/MD,,s2ww~...	/s   !& 
A'AAc                 l    d | j         D             }t                                                      |z   S )zvAutocomplete only children named as valid python identifiers.

        Only PY3 supports this special method.
        c                 :    g | ]}|                                 |S r'   )isidentifier).0cs     r!   
<listcomp>z!Group.__dir__.<locals>.<listcomp>  s'    CCC!..2B2BC1CCCr#   )r,   rN   __dir__)r   subnodsrU   s     r!   r   zGroup.__dir__  s5    
 DCd.CCCww  7**r#   c                     || j         v r!|                                  | j        |         S |                     |          S )zGet a Python attribute or child node called name.
        If the node has a child node called name it is returned,
        else an AttributeError is raised.
        )_c_lazy_children_attrsr   rg   r   r   s     r!   __getattr__zGroup.__getattr__  sE     4...&&(((=&&  &&&r#   c                     | j         }d|v r/|| j        v r&t          j        d| j        d|dt
                     t                                          ||           dS )a0  Set a Python attribute called name with the given value.

        This method stores an *ordinary Python attribute* in the object. It
        does *not* store new children nodes under this group; for that, use the
        File.create*() methods (see the File class
        in :ref:`FileClassDescr`). It does *neither* store a PyTables node
        attribute; for that,
        use :meth:`File.set_node_attr`, :meth`:Node._f_setattr`
        or :attr:`Node._v_attrs`.

        If there is already a child node with the same name, a
        NaturalNameWarning will be issued and the child node will not be
        accessible via natural naming nor getattr(). It will still be available
        via :meth:`File.get_node`, :meth:`Group._f_get_child` and children
        dictionaries in the group (if visible).

        r+   r   r   r   N)rg   r+   rz   r{   rd   r
   rN   __setattr__)r   rQ   r?   r   rU   s       r!   r  zGroup.__setattr__   s~    N F""tt/?'?'?MM ###TTT+ -?	@ @ @ 	D%(((((r#   c                 V    |                                   |                                  dS )zFlush this Group.N)r   _g_flush_groupr4   s    r!   _f_flushzGroup._f_flushQ  s.     	r#   c                 R    | j         j        }|                    | j                   dS )z6Close all the *loaded* descendent nodes of this group.N)rK   re   close_subtreerd   )r   node_managers     r!   _g_close_descendentszGroup._g_close_descendentsW  s+     |1""4#344444r#   c                 ~    | j         r|                                  t                                                       dS )zClose this (open) group.N)rc   _g_close_grouprN   _f_close)r   rU   s    r!   _g_closezGroup._g_close]  sA     > 	" !!! 	r#   c                     | j         sdS | j        s| j        |                                  |                                  dS )a  Close this group and all its descendents.

        This method has the behavior described in :meth:`Node._f_close`.
        It should be noted that this operation closes all the nodes
        descending from this group.

        You should not need to close nodes manually because they are
        automatically opened/closed when they are loaded/evicted from
        the integrated LRU cache.

        N)rc   _v__deletingry   r	  r  r4   s    r!   r  zGroup._f_closeh  sM     ~ 	F ! 	(T%5%=%%''' 	r#   c                     | j         dk    r0|s|st          d| j        d          |                                  t	                                          ||           dS )zzRemove (recursively if needed) the Group.

        This version correctly handles both visible and hidden nodes.

        r   r   zJ`` has child nodes; please set `recursive` or `force` to true to remove itN)_v_nchildrenr   rd   r	  rN   	_g_remove)r   r   forcerU   s      r!   r  zGroup._g_remove  s     q   7 7i $(#3#3#3!6 7 7 7 %%''' 	)U+++++r#   c                 @     t                      j        |||||fi |S )a  Copy this node and return the new one.

        This method has the behavior described in :meth:`Node._f_copy`.
        In addition, it recognizes the following keyword arguments:

        Parameters
        ----------
        title
            The new title for the destination. If omitted or None, the
            original title is used. This only applies to the topmost
            node in recursive copies.
        filters : Filters
            Specifying this parameter overrides the original filter
            properties in the source node. If specified, it must be an
            instance of the Filters class (see :ref:`FiltersClassDescr`).
            The default is to copy the filter properties from the source
            node.
        copyuserattrs
            You can prevent the user attributes from being copied by setting
            thisparameter to False. The default is to copy them.
        stats
            This argument may be used to collect statistics on the copy
            process. When used, it should be a dictionary with keys 'groups',
            'leaves', 'links' and 'bytes' having a numeric value. Their values
            willbe incremented to reflect the number of groups, leaves and
            bytes, respectively, that have been copied during the operation.

        )rN   _f_copy)r   r   r   	overwriter   createparentsr   rU   s          r!   r  zGroup._f_copy  s9    @ uwwwy-; ;39; ; 	;r#   c                    |                                   | j                            ||          }|                     |           |s)| j        D ]!}||v rt          d|j        d|d          "|                    dd          }|r |                    di           }	| j        	                                D ]}
|

                                \  }}|dk    r||	v r|	|         d         \  }}t          j                            ||          }|j                            ||
j        |           |	|                             |j        |
j        f           |                    d	d
          }||dxx         dz  cc<    |
j        |d
||fi | |dk    r|j        |
j        fg|	|<   d
S | j        	                                D ]}
 |
j        |d
||fi | d
S )a  Copy the children of this group into another group.

        Children hanging directly from this group are copied into dstgroup,
        which can be a Group (see :ref:`GroupClassDescr`) object or its
        pathname in string form. If createparents is true, the needed groups
        for the given destination group path to exist will be created.

        The operation will fail with a NodeError if there is a child node
        in the destination group with the same name as one of the copied
        children from this one, unless overwrite is true; in this case,
        the former child node is recursively removed before copying the
        later.

        By default, nodes descending from children groups of this node
        are not copied. If the recursive argument is true, all descendant
        nodes of this node are recursively copied.

        Additional keyword arguments may be passed to customize the
        copying process. For instance, title and filters may be changed,
        user attributes may be or may not be copied, data may be sub-sampled,
        stats may be collected, etc. Arguments unknown to nodes are simply
        ignored. Check the documentation for copying operations of nodes to
        see which options they support.

        zdestination group ``z`` already has a node named ``z2``; you may want to use the ``overwrite`` argumentr   Fr   r   r   r   Nr   )r   rK   _get_or_create_path_g_check_groupr,   r   rd   r   r   r   r   r   r   r   r   rQ   r   r   r  )r   dstgroupr  r   r  r   r   rr   r   r   childr   r   r   rQ   r   r   s                    r!   _f_copy_childrenzGroup._f_copy_children  so   8 	 L44X}MM	I&&& 		> "- > >		))#) %000)))=> > > * 

?E:: 	O ++M2>>K)0022   ..00b66dk11"-d"3A"6KE4!w||E488H%66y%*7?A A A%,,".
;  
 #JJw55E(k***a/***!EM)T9i , ,$*, , ,Avv&2EJ?-D)' . )0022 O Oiy)NNvNNNNO Or#   c                 >    | j          d| j        j         d| j        S )a,  Return a short string representation of the group.

        Examples
        --------

        ::

            >>> import tables
            >>> f = tables.open_file('tables/tests/Tables_lzo2.h5')
            >>> print(f.root.group0)
            /group0 (Group) ''
            >>> f.close()

         (z) )rd   rU   r$   r   r4   s    r!   __str__zGroup.__str__  s9      # % %t~'> % %=% % 	&r#   c                 ~    d | j                                         D             }| dd                    |           dS )ag  Return a detailed string representation of the group.

        Examples
        --------

        ::

            >>> import tables
            >>> f = tables.open_file('tables/tests/Tables_lzo2.h5')
            >>> f.root.group0
            /group0 (Group) ''
              children := ['group1' (Group), 'tuple1' (Table)]
            >>> f.close()

        c                 8    g | ]\  }}|d |j         j         dS )r  ))rU   r$   )r   rr   r  s      r!   r   z"Group.__repr__.<locals>.<listcomp>1  sB     
 
 
"E 99eo6999
 
 
r#   z
  children := [z, ])r,   r   r   )r   reps     r!   __repr__zGroup.__repr__   sR    "
 
&*&6&<&<&>&>
 
 
 <<499S>><<<<r#   )rC   FNT)Tr   )FF)NNFFF)FFF)1r$   r%   r&   __doc__r\   r   r5   propertyr  r;   r@   rB   
_v_filtersrO   ra   rk   rt   r~   r   r   r   r   r   r   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r	  r  r  r  r  r  r   r&  __classcell__)rU   s   @r!   r)   r)      sp       p pf J/% % % 8O,,L  & & &" " " }m	 J /31 1 1 1 1 1B2 2 2:    "   $, $, $, $,L,- ,- ,-\	 	 	$ $ $&  ( ( (#: #: #: #:J1 1 1* * *8- 8- 8- 8-t. . .:> > > > >! ! ! !F7A 7A 7Ar1 1 1&3 3 3 3%$ %$ %$ %$N4 4 40/ / / / /,+ + + + +	' 	' 	'/) /) /) /) /)b  5 5 5	 	 	 	 	  <, , , , , ,* /3@E"; "; "; "; "; ";H EJ',LO LO LO LO\& & &&= = = = = = =r#   r)   c                   0    e Zd Zd Zd Zd ZddZd	dZdS )
	RootGroupc                    | j         }t          | _        || _        |r|| _        || _        nd | _        d | _        || _        d| _        d| _        d| _	        d| _
        |j        d         | _        d| _        d | _        ||d<   |j                            | d           |                     ||d           |                                 | _        d S )NTr   r   rE   Fr]   )init)rg   rF   rG   rH   rI   rJ   rK   rc   rd   _v_name_v_depthrL   rM   r  ry   re   register_node_g_new_g_open)r   ptfilerQ   rR   rS   r:   r   s          r!   rO   zRootGroup.__init__;  s     $ 	' %D")D $D"&D "(-0A"B! %{**4555 	FDt,,,<<>>r#   c                    | j         j        dk    rt          | j         j        |          }|                     |          }|dk    rt	          | |          S |dk    r=| j         j        d         r|                     |          }nt          } || |d          S |dk    ry|                     |d	          }	  || |          S # t          $ rH}t          j        d
|                     |          d|d           t          | |          cY d}~S d}~ww xY w|dk    rt          | |          S |dk    rt          | |          S t          | |          S )zLoad a child node from disk.

        The child node `childname` is loaded from disk and an adequate
        `Node` object is created and returned.  If there is no such
        child, a `NoSuchNodeError` is raised.

        r   r   r)   rW   F)rS   r   T)r{   zproblems loading leaf ``z``::

  z1

The leaf will become an ``UnImplemented`` node.Nr   r   )rK   root_uepr   r   r   rL   rt   r)   r~   	Exceptionrz   r{   r|   r   r   r   )r   rr   r   
ChildClassexcs        r!   _g_load_childzRootGroup._g_load_childe  s    < C''!$,"7CCI++I66	 	!!4+++ |"#78 #!::9EE

 #
:dI59999&  55id5KKJ	6!z$	222 6 6 6 ||I....56 6 6 %T9555555556 *$$D),,,.((i000 y111s   7C 
D=D
DDc                      t          d          )Nz the root node can not be renamedr   )r   r   s     r!   	_f_renamezRootGroup._f_rename      :;;;r#   NFc                      t          d          )Nzthe root node can not be movedr<  )r   r   r   r  s       r!   _f_movezRootGroup._f_move  s    8999r#   c                      t          d          )Nz the root node can not be removedr<  )r   r   s     r!   	_f_removezRootGroup._f_remove  r>  r#   )NNF)F)r$   r%   r&   rO   r:  r=  r@  rB  r'   r#   r!   r,  r,  9  sk         *  *  *T/2 /2 /2b< < <: : : :< < < < < <r#   r,  c                       e Zd ZdZd ZdS )TransactionGroupG
TRANSGROUPc                 L    t          j        d| j        fz  t                     d S )Nzthe number of transactions is exceeding the recommended maximum (%d);be ready to see PyTables asking for *lots* of memory and possibly slow I/O)rz   r{   rM   r   r4   s    r!   r   z"TransactionGroupG._g_width_warning  sA     N 023 5G	H 	H 	H 	H 	Hr#   Nr$   r%   r&   r\   r   r'   r#   r!   rD  rD    s-        JH H H H Hr#   rD  c                       e Zd ZdZd ZdS )TransactionGTRANSGc                 X    t          j        d| j        | j        fz  t                     d S )Nztransaction ``%s`` is exceeding the recommended maximum number of marks (%d);be ready to see PyTables asking for *lots* of memory and possibly slow I/Or   r4   s    r!   r   zTransactionG._g_width_warning  A     N )4+BCD )		* 	* 	* 	* 	*r#   NrG  r'   r#   r!   rI  rI    s(        J* * * * *r#   rI  c                   P    e Zd ZdZddlZe                    d          Zd Zd ZdS )MarkGMARKGr   Nz	^a[0-9]+$c                 X    t          j        d| j        | j        fz  t                     d S )Nzmark ``%s`` is exceeding the recommended maximum action storage (%d nodes);be ready to see PyTables asking for *lots* of memory and possibly slow I/Or   r4   s    r!   r   zMarkG._g_width_warning  rL  r#   c                    t          | j                                                  D ]}|                    dd           | j        }| j        }|j        dd         D ],}|                    |          r|                    |           -dS )zEmpty action storage (nodes and attributes).

        This method empties all action storage kept in this node: nodes
        and attributes.

        TN)	r   r,   r   r  r9   _c_shadow_name_re_v_attrnamesusermatch_g__delattr)r   r  attrsshnameattrnames        r!   _g_resetzMarkG._g_reset  s     $*113344 	( 	(EOOD$'''' '.qqq1 	, 	,H||H%% ,!!(+++	, 	,r#   )	r$   r%   r&   r\   recompilerR  r   rY  r'   r#   r!   rN  rN    sR        JIII

<00* * *, , , , ,r#   rN  )*r'  r   rh   rz   misc.proxydictr   rC   r   r   rf   r   
exceptionsr   r	   r
   r   r:   r   r   r   r   r   r   noder   r   leafr   unimplementedr   r   linkr   r   r   rF   r   r)   r,  rD  rI  rN  r'   r#   r!   <module>rb     s~   & & 				   % % % % % %             # # # # # #- - - - - - - - - - - -       ' ' ' ' ' ' ? ? ? ? ? ? ? ? ? ? & & & & & & & &       1 1 1 1 1 1 1 1 . . . . . . . . . . 	+ + + + +I + + +
V= V= V= V= V=M V= V= V=t d< d< d< d< d< d< d< d<NH H H H H H H H* * * * *>5 * * *, , , , ,NE , , , , ,r#   