
    de                     4   d Z ddlZddl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mZ ddlmZ dd	lmZ dd
lmZ g dZdgZg dZddgZ ej        d          Z ej        d          ZdZd Z G d dej                  Z G d de          Z dS )z'Here is defined the AttributeSet class.    N   )hdf5extension)SizeType)class_name_dict)ClosedNodeErrorPerformanceWarning)check_attribute_name)attr_to_shadow)Filters)CLASSVERSIONTITLENROWSEXTDIMENCODINGPYTABLES_FORMAT_VERSIONFLAVORFILTERS
AUTO_INDEXDIRTY	NODE_TYPENODE_TYPE_VERSION
PSEUDOATOMFIELD_)r   r   r   r   r   r   r   r   r   r   z^FIELD_[0-9]+_FILL$s   \(([ic])tables\.Leaf\ns   (\1tables.filters\nc                 z     t           t          v p$t          j         fdt          D                                 S )z,Check if a name is a system attribute or notc                 :    g | ]}                     |          S  )
startswith).0prefixnames     3lib/python3.11/site-packages/tables/attributeset.py
<listcomp>z!issysattrname.<locals>.<listcomp>4   s%    BBBV	 	 BBB    )bool	SYS_ATTRSnpprodSYS_ATTRS_PREFIXES)r!   s   `r"   issysattrnamer*   0   sO     	! DRWBBBB/ABBB&D &D E E Er$   c                        e Zd ZdZd Zed             Zd Zd ZddZ	 f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dZd Zd Zd Zd Z xZS )AttributeSeta  Container for the HDF5 attributes of a Node.

    This class provides methods to create new HDF5 node attributes,
    and to get, rename or delete existing ones.

    Like in Group instances (see :ref:`GroupClassDescr`), AttributeSet
    instances make use of the *natural naming* convention, i.e. you can
    access the attributes on disk as if they were normal Python
    attributes of the AttributeSet instance.

    This offers the user a very convenient way to access HDF5 node
    attributes. However, for this reason and in order not to pollute the
    object namespace, one can not assign *normal* attributes to
    AttributeSet instances, and their members use names which start by
    special prefixes as happens with Group objects.

    .. rubric:: Notes on native and pickled attributes

    The values of most basic types are saved as HDF5 native data in the
    HDF5 file.  This includes Python bool, int, float, complex and str
    (but not long nor unicode) values, as well as their NumPy scalar
    versions and homogeneous or *structured* NumPy arrays of them.  When
    read, these values are always loaded as NumPy scalar or array
    objects, as needed.

    For that reason, attributes in native HDF5 files will be always
    mapped into NumPy objects.  Specifically, a multidimensional
    attribute will be mapped into a multidimensional ndarray and a
    scalar will be mapped into a NumPy scalar object (for example, a
    scalar H5T_NATIVE_LLONG will be read and returned as a numpy.int64
    scalar).

    However, other kinds of values are serialized using pickle, so you
    only will be able to correctly retrieve them using a Python-aware
    HDF5 library.  Thus, if you want to save Python scalar values and
    make sure you are able to read them with generic HDF5 tools, you
    should make use of *scalar or homogeneous/structured array NumPy
    objects* (for example, numpy.int64(1) or numpy.array([1, 2, 3],
    dtype='int16')).

    One more advice: because of the various potential difficulties in
    restoring a Python object stored in an attribute, you may end up
    getting a pickle string where a Python object is expected. If this
    is the case, you may wish to run pickle.loads() on that string to
    get an idea of where things went wrong, as shown in this example::

        >>> import os, tempfile
        >>> import tables as tb
        >>>
        >>> class MyClass:
        ...     foo = 'bar'
        ...
        >>> myObject = MyClass()  # save object of custom class in HDF5 attr
        >>> h5fname = tempfile.mktemp(suffix='.h5')
        >>> h5f = tb.open_file(h5fname, 'w')
        >>> h5f.root._v_attrs.obj = myObject  # store the object
        >>> print(h5f.root._v_attrs.obj.foo)  # retrieve it
        bar
        >>> h5f.close()
        >>>
        >>> del MyClass, myObject  # delete class of object and reopen file
        >>> h5f = tb.open_file(h5fname, 'r')
        >>> print(repr(h5f.root._v_attrs.obj))
        b'ccopy_reg\n_reconstructor...
        >>> import pickle  # let's unpickle that to see what went wrong
        >>> pickle.loads(h5f.root._v_attrs.obj)
        Traceback (most recent call last):
        ...
        AttributeError: Can't get attribute 'MyClass' ...
        >>> # So the problem was not in the stored object,
        ... # but in the *environment* where it was restored.
        ... h5f.close()
        >>> os.remove(h5fname)


    .. rubric:: Notes on AttributeSet methods

    Note that this class overrides the __getattr__(), __setattr__(),
    __delattr__() and __dir__() special methods.  This allows you to
    read, assign or delete attributes on disk by just using the next
    constructs::

        leaf.attrs.myattr = 'str attr'    # set a string (native support)
        leaf.attrs.myattr2 = 3            # set an integer (native support)
        leaf.attrs.myattr3 = [3, (1, 2)]  # a generic object (Pickled)
        attrib = leaf.attrs.myattr        # get the attribute ``myattr``
        del leaf.attrs.myattr             # delete the attribute ``myattr``

    In addition, the dictionary-like __getitem__(), __setitem__() and
    __delitem__() methods are available, so you may write things like
    this::

        for name in node._v_attrs._f_list():
            print("name: %s, value: %s" % (name, node._v_attrs[name]))

    Use whatever idiom you prefer to access the attributes.

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

    If an attribute is set on a target node that already has a large
    number of attributes, a PerformanceWarning will be issued.


    .. rubric:: AttributeSet attributes

    .. attribute:: _v_attrnames

        A list with all attribute names.

    .. attribute:: _v_attrnamessys

        A list with system attribute names.

    .. attribute:: _v_attrnamesuser

        A list with user attribute names.

    .. attribute:: _v_unimplemented

        A list of attribute names with unimplemented native HDF5 types.

    c                 @    | j                             | j                  S N)_v__nodefile	_get_node_v__nodepathselfs    r"   
_g_getnodezAttributeSet._g_getnode   s     **4+<===r$   c                 *    |                                  S )zAThe :class:`Node` instance this attribute set is associated with.)r4   r2   s    r"   _v_nodezAttributeSet._v_node   s        r$   c                    |j         st          d          | j        }|                     |           |j        |d<   |j        |d<   |                     |          |d<   g |d<   	 |j        j        }|dk    rd}nHt          t          t          |                    d                              }n# t          $ r d}Y nw xY w||d	<   g |d
<   g |d<   | j        D ][}|                     |           t          |          r| j                            |           A| j                            |           \| j                                         | j                                         | j                                         dS )zCreate the basic structures to keep the attribute information.

        Reads all the HDF5 attributes (if any) on disk for the node "node".

        Parameters
        ----------
        node
            The parent node

        z$the node for attribute set is closedr/   r1   _v_attrnames_v_unimplementedunknownN._v__format_version_v_attrnamessys_v_attrnamesuser)	_v_isopenr   __dict___g_new_v_file_v_pathname_g_list_attrformat_versiontuplemapintsplitAttributeErrorr8   __getattr__r*   r=   appendr>   sort)r3   nodedict_rE   parsed_versionattrs         r"   __init__zAttributeSet.__init__   s    ~ 	J!"HIIID $n $ 0n $ 1 1$ 7 7n$& !	L!\8N **!%!&s30D0DS0I0I'J'J!K!K  	" 	" 	"!NNN	" '5"##% $& !% 	3 	3D T"""T"" 3$++D1111%,,T2222 	   !!###""$$$$$s   %B0 0B?>B?c                 f    | j         }|j        |d<   |j        |d<   |                     |           dS )z=Updates the location information about the associated `node`.r/   r1   N)r@   rB   rC   rA   )r3   rN   rO   s      r"   _g_update_node_locationz$AttributeSet._g_update_node_location   s<      $n $ 0nDr$   userc                     |dk    r| j         dd         S |dk    r| j        dd         S |dk    r| j        dd         S dS )a-  Get a list of attribute names.

        The attrset string selects the attribute set to be used.  A
        'user' value returns only user attributes (this is the default).
        A 'sys' value returns only system attributes.  Finally, 'all'
        returns both system and user attributes.

        rU   Nsysall)r>   r=   r8   )r3   attrsets     r"   _f_listzAttributeSet._f_list   sc     f(++'**$QQQ'' r$   c                     t          d t                                                      | j        z   D                       S )zvAutocomplete only children named as valid python identifiers.

        Only PY3 supports this special method.
        c                 :    h | ]}|                                 |S r   )isidentifier)r   cs     r"   	<setcomp>z'AttributeSet.__dir__.<locals>.<setcomp>  s6     ) ) )1~~'')Q ) ) )r$   )listsuper__dir__r8   )r3   	__class__s    r"   rb   zAttributeSet.__dir__  sI    
  ) )GGOO%%(99) ) ) * * 	*r$   c                 p   || j         vrt          d|d| j                  | j        }|                     | j        |          }t          |t          j                  o9|j	        j
        t          j        k    o|j        dk    o|                    d          }|r|dv r|}n|r^t                              |          rD|dk    r>	 t!          j        |          }t          j        |          }n;# t&          $ r d}Y n,w xY w|rE|dk    r?|=|d	k     r7t(                              t,          |d
          }t!          j        |          }n|r	 t!          j        |          }n|# t.          $ rb 	 t!          j        |d          }nG# t0          $ r- 	 t!          j        |d          }n# t2          $ r |}Y nw xY wY nt2          $ r |}Y nw xY wY nt2          $ r |}Y nw xY wt          |t4                    r |dk    rt          j        |          d         }n|dk    rm|k|d	k    re	 t7          j        |          }n# t:          $ rB t<          j                             d           t<          j        !                                 d}Y nw xY w|dk    r+t          |t4                    s|"                    d          }nrtG          |          rat          |tH          t4          f          rEt          |t4                    s0t                              |          s|"                    d          }n|}|| j%        |<   |S )zGet the attribute named "name".z
Attribute z does not exist in node: r      .)   0s   0.)r      Nr      r   r   latin1)encodingbytes r   zFailed parsing FILTERS key
r   zutf-8)&r8   rJ   r1   r<   
_g_getattrr6   
isinstancer'   genericdtypetypebytes_itemsizeendswith_field_fill_rematchpickleloadsarrayImportError_old_filters_resub_new_filters_subUnicodeDecodeError	TypeError	Exceptionstrr   _unpack
ValueErrorrW   stderrwriteflushdecoder*   rl   r@   )r3   r!   rE   valuemaybe_pickledretvals         r"   rK   zAttributeSet.__getattr__  s    t(((  "Cd "C "C-1->"C "C D D D 0d33
 ubj)) 8K	)8NQ8#(>>$#7#7 	
  K	e}44 FF G	 4 4T : : G	 F**e,,&))    >	i(v%% $''(8%CCE\%((FF 6	 e,, & # # ###\%(CCCFF  ' ' ''!'eg!F!F!F$ ' ' '!&'  # # #"FFF# 
 
 
 
 &#&& .6R<<&))"-i(&& //   
  !?@@@
  """ W__Zs%;%;_\\'**FFD!! 	j&E&E 	UC((	1?1E1Ed1K1K	 \\'**FFF %ds   (C1 1D DE# #
G.FG
G	F'&G	'F63G	5F66G	9G;G	GG		GGG%H: :A	JJc                    |}t          |          r|dv r)t          j        |t          j                  }|d         }nV|dk    r$t          j        |t                    }|d         }n,|dk    r&| j        | j        dk    r|                                }||u rt          |          t          t          t          t          t          t          t          j        fv rYt          |t                    r(t!          |          dk    rt          j        d	          }nt          j        |          }|d         }|                     | j        ||           || j        |<   | j        }||vr|                    |           |                                 t          |          r2| j        }|                    |           |                                 dS | j        }|                    |           |                                 dS dS )
zSet a PyTables attribute.

        Sets a (maybe new) PyTables attribute with the specified `name`
        and `value`.  If the attribute already exists, it is simply
        replaced.

        It does not log the change.

        )r   r   r   r   )rq   r   r   r   Nrh   r   rm   )r*   r'   rz   int32r   r<   _packrr   r%   rl   rH   floatcomplexr   unicode_ro   len
_g_setattrr6   r@   r8   rL   rM   r=   r>   )r3   r!   r   stvalue	attrnamesattrnamessysattrnamesusers          r"   _g__setattrzAttributeSet._g__setattr}  s     
	(MMM(5999(5999)##)5)V33++--
 uUeS%# " - - - %%% *#e**//(2,,(5//BKEdG444 $d %	y  T"""NNT"" %#3##D)))!!##### $ 5$$T***""$$$$$ ! r$   c                    | j         }| j        }t          |           |                                 |j        d         }t          |          |k    r$t          j        d| j        |fz  t                     |
                                }|r||v r|                     |           |                     ||           |r|                     |           dS dS )a  Set a PyTables attribute.

        Sets a (maybe new) PyTables attribute with the specified `name`
        and `value`.  If the attribute already exists, it is simply
        replaced.

        A ``ValueError`` is raised when the name starts with a reserved
        prefix or contains a ``/``.  A `NaturalNameWarning` is issued if
        the name is not a valid Python identifier.  A
        `PerformanceWarning` is issued when the recommended maximum
        number of attributes in a node is going to be exceeded.

        MAX_NODE_ATTRSznode ``%s`` is exceeding the recommended maximum number of attributes (%d);be ready to see PyTables asking for *lots* of memory and possibly slow I/ON)r/   r8   r	   _check_writableparamsr   warningswarnr1   r   is_undo_enabled_g_del_and_logr   
_g_log_add)r3   r!   r   nodefiler   max_node_attrsundo_enableds          r"   __setattr__zAttributeSet.__setattr__  s    $%	 	T"""  """ ")9:y>>^++M N ".?@ -	. . .  //11 	&TY..%%% 	u%%%  	"OOD!!!!!	" 	"r$   c                 H    | j                             d| j        |           d S )NADDATTR)r/   _logr1   r3   r!   s     r"   r   zAttributeSet._g_log_add  s&    y$*;TBBBBBr$   c                 r    | j         }| j        }|                    d||           t          |||           d S )NDELATTR)r/   r1   r   r
   )r3   r!   r   node_pathnames       r"   r   zAttributeSet._g_del_and_log  s@    $)i555x55555r$   c                     |                      | j        |           | j                            |           || j        v r| j                            |           n| j                            |           | j        |= dS )zDelete a PyTables attribute.

        Deletes the specified existing PyTables attribute.

        It does not log the change.

        N)	_g_remover6   r8   remover=   r>   r@   r   s     r"   _g__delattrzAttributeSet._g__delattr  s     	t|T*** 	  &&&4''' ''----!((... M$r$   c                    | j         }|| j        vrt          d|d| j        d          |                                 |                                r|                     |           dS |                     |           dS )zDelete a PyTables attribute.

        Deletes the specified existing PyTables attribute from the
        attribute set.  If a nonexistent or system attribute is
        specified, an ``AttributeError`` is raised.

        Attribute ('') does not exist in node ''N)r/   r8   rJ   r1   r   r   r   r   )r3   r!   r   s      r"   __delattr__zAttributeSet.__delattr__  s     $ t((( .44***,- - - 	  """ ##%% 	#%%%%%T"""""r$   c                     	 |                      |          S # t          $ r t          d|d| j        d          w xY w)z0The dictionary like interface for __getattr__().r   r   r   )rK   rJ   KeyErrorr1   r   s     r"   __getitem__zAttributeSet.__getitem__  sa    	-##D))) 	- 	- 	-(44***,- - -	-s    &=c                 2    |                      ||           dS )z0The dictionary like interface for __setattr__().N)r   )r3   r!   r   s      r"   __setitem__zAttributeSet.__setitem__)  s      	u%%%%%r$   c                     	 |                      |           dS # t          $ r t          d|d| j        d          w xY w)z0The dictionary like interface for __delattr__().r   r   r   N)r   rJ   r   r1   r   s     r"   __delitem__zAttributeSet.__delitem__.  sg    	-T""""" 	- 	- 	-(44***,- - -	-s    &?c                     || j         v S )zIs there an attribute with that name?

        A true value is returned if the attribute set has an attribute
        with the given name, false otherwise.

        )r8   r   s     r"   __contains__zAttributeSet.__contains__9  s     t(((r$   c                 x    ||k    rdS t          | |          }t          | ||           t          | |           dS )z4Rename an attribute from oldattrname to newattrname.N)getattrsetattrdelattr)r3   oldattrnamenewattrname	attrvalues       r"   	_f_renamezAttributeSet._f_renameC  sQ     +%%F D+..	 	k9--- 	k"""""r$   NFc                    |j         j        d         }||j        }| j        D ]%}|| j        vr ||t          | |                     &|rq| j        D ]:}|t          vr/|                    d          s ||t          | |                     ;|r/t          D ])}|| j        v r ||t          | |                     &dS dS dS )a  Copy set attributes.

        Copies all user and allowed system PyTables attributes to the
        given attribute set, replacing the existing ones.

        You can specify a *bound* method of the destination set that
        will be used to set its attributes.  Else, its `_g__setattr`
        method will be used.

        Changes are logged depending on the chosen setting method.  The
        default setting method does not log anything.

        .. versionchanged:: 3.0
           The *newSet* parameter has been renamed into *newset*.

        .. versionchanged:: 3.0
           The *copyClass* parameter has been renamed into *copyclass*.

        PYTABLES_SYS_ATTRSNr   )
r/   r   r   r>   r9   r   r=   SYS_ATTRS_NOTTOBECOPIEDr   FORCE_COPY_CLASS)r3   newsetset_attr	copyclasscopysysattrsattrnames         r"   _g_copyzAttributeSet._g_copyS  s)   * *12FG)H- 	< 	<Ht44474#:#:;;; 	D 0 @ @%<<< %//99	 =
 HXwtX'>'>??? D 0 D DH4#777 74+B+BCCC	D 	DD DD Dr$   c                     t          |t          d                   st          d|          |                     |j        |j        j                   dS )zCopy attributes to the where node.

        Copies all user and certain system attributes to the given where
        node (a Node instance - see :ref:`NodeClassDescr`), replacing
        the existing ones.

        Nodez"destination object is not a node: N)ro   r   r   r   _v_attrsr   )r3   wheres     r"   _f_copyzAttributeSet._f_copy  sT     %!899 	LJJJKKKU^U^%?@@@@@r$   c                     d S r.   r   r2   s    r"   _g_closezAttributeSet._g_close  s	     	r$   c                 z    | j         }| j        j        }t          d | j        D                       }| d| d| dS )z*The string representation for this object.c              3      K   | ]}d V  dS )r   Nr   )r   _s     r"   	<genexpr>z'AttributeSet.__str__.<locals>.<genexpr>  s"      66q666666r$   z._v_attrs (z), z attributes)r1   rc   __name__sumr8   )r3   pathname	classname
attrnumbers       r"   __str__zAttributeSet.__str__  sT     $N+	66D$566666
LLyLLZLLLLr$   c                      t           j                  }|r, fd|D             } dd                    |          z   dz   S t                     S )z1A detailed string representation for this object.c                 :    g | ]}| d t          |          S )z := )r   )r   rQ   r3   s     r"   r#   z)AttributeSet.__repr__.<locals>.<listcomp>  s1    NNNDd77d 3 377NNNr$   z:
   [z,
    ])r`   r8   joinr   )r3   r   reps   `  r"   __repr__zAttributeSet.__repr__  sg     *++	 	NNNNINNNC%%%	s(;(;;cAAt99r$   )rU   )NF)r   
__module____qualname____doc__r4   propertyr6   rR   rT   rZ   rb   rK   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   __classcell__)rc   s   @r"   r,   r,   7   s       { {z> > > ! ! X!4% 4% 4%l  ( ( ( ("* * * * *e e eN9% 9% 9%v*" *" *"XC C C6 6 6     .# # #2	- 	- 	-& & &
	- 	- 	-) ) )# # # *D *D *D *DXA A A   
	M 	M 	M	 	 	 	 	 	 	r$   r,   c                       e Zd Zd Zd ZdS )NotLoggedAttributeSetc                     d S r.   r   r   s     r"   r   z NotLoggedAttributeSet._g_log_add  s    r$   c                 0    |                      |           d S r.   )r   r   s     r"   r   z$NotLoggedAttributeSet._g_del_and_log  s    r$   N)r   r   r   r   r   r   r$   r"   r   r     s2              r$   r   )!r   rerW   r   rx   numpyr'   rm   r   utilsr   registryr   
exceptionsr   r   pathr	   undoredor
   filtersr   r&   r)   r   r   compilerv   r|   r~   r*   r,   r   r   r$   r"   <module>r      s   - - 				 



                   % % % % % % ; ; ; ; ; ; ; ; & & & & & & $ $ $ $ $ $        	 Z M M M  Y' 122"*788* E E Eq	 q	 q	 q	 q	=- q	 q	 q	h    L     r$   