def _g_refnode(self, childnode, childname, validate=True): """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). """ # Check for name validity. if validate: check_name_validity(childname) childnode._g_check_name(childname) # Check if there is already a child with the same name. # This can be triggered because of the user # (via node construction or renaming/movement). # Links are not checked here because they are copied and referenced # using ``File.get_node`` so they already exist in `self`. if (not isinstance(childnode, Link)) and childname in self: raise NodeError( "group ``%s`` already has a child node named ``%s``" % (self._v_pathname, childname)) # Show a warning if there is an object attribute with that name. if childname in self.__dict__: warnings.warn( "group ``%s`` already has an attribute named ``%s``; " "you will not be able to use natural naming " "to access the child node" % (self._v_pathname, childname), NaturalNameWarning) # Check group width limits. if (len(self._v_children) + len(self._v_hidden) >= self._v_max_group_width): self._g_width_warning() # Update members information. # Insert references to the new child. # (Assigned values are entirely irrelevant.) if isvisiblename(childname): # Visible node. self.__members__.insert(0, childname) # enable completion self._v_children[childname] = None # insert node if isinstance(childnode, Unknown): self._v_unknown[childname] = None elif isinstance(childnode, Link): self._v_links[childname] = None elif isinstance(childnode, Leaf): self._v_leaves[childname] = None elif isinstance(childnode, Group): self._v_groups[childname] = None else: # Hidden node. self._v_hidden[childname] = None # insert node
def __setattr__(self, name, value): """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. """ nodefile = self._v__nodefile attrnames = self._v_attrnames # Check for name validity check_name_validity(name) nodefile._check_writable() # Check if there are too many attributes. max_node_attrs = nodefile.params["MAX_NODE_ATTRS"] if len(attrnames) >= max_node_attrs: warnings.warn( """\ node ``%s`` is exceeding the recommended maximum number of attributes (%d);\ be ready to see PyTables asking for *lots* of memory and possibly slow I/O""" % (self._v__nodepath, max_node_attrs), PerformanceWarning, ) undo_enabled = nodefile.is_undo_enabled() # Log old attribute removal (if any). if undo_enabled and (name in attrnames): self._g_del_and_log(name) # Set the attribute. self._g__setattr(name, value) # Log new attribute addition. if undo_enabled: self._g_log_add(name)
def __setattr__(self, name, value): """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. """ nodeFile = self._v__nodefile attrnames = self._v_attrnames # Check for name validity check_name_validity(name) nodeFile._check_writable() # Check if there are too many attributes. maxNodeAttrs = nodeFile.params['MAX_NODE_ATTRS'] if len(attrnames) >= maxNodeAttrs: warnings.warn("""\ node ``%s`` is exceeding the recommended maximum number of attributes (%d);\ be ready to see PyTables asking for *lots* of memory and possibly slow I/O""" % (self._v__nodepath, maxNodeAttrs), PerformanceWarning) undoEnabled = nodeFile.is_undo_enabled() # Log old attribute removal (if any). if undoEnabled and (name in attrnames): self._g_del_and_log(name) # Set the attribute. self._g__setattr(name, value) # Log new attribute addition. if undoEnabled: self._g_log_add(name)
def __init__(self, classdict, nestedlvl=-1, validate=True): if not classdict: raise ValueError("cannot create an empty data type") # Do a shallow copy of classdict just in case this is going to # be shared by other instances newdict = self.__dict__ newdict["_v_name"] = "/" # The name for root descriptor newdict["_v_names"] = [] newdict["_v_dtypes"] = {} newdict["_v_types"] = {} newdict["_v_dflts"] = {} newdict["_v_colobjects"] = {} newdict["_v_is_nested"] = False nestedFormats = [] nestedDType = [] if not hasattr(newdict, "_v_nestedlvl"): newdict["_v_nestedlvl"] = nestedlvl + 1 cols_with_pos = [] # colum (position, name) pairs cols_no_pos = [] # just column names # Check for special variables and convert column descriptions for (name, descr) in classdict.iteritems(): if name.startswith('_v_'): if name in newdict: # print("Warning!") # special methods &c: copy to newdict, warn about conflicts warnings.warn("Can't set attr %r in description class %r" % (name, self)) else: # print("Special variable!-->", name, classdict[name]) newdict[name] = descr continue # This variable is not needed anymore columns = None if (type(descr) == type(IsDescription) and issubclass(descr, IsDescription)): # print("Nested object (type I)-->", name) columns = descr().columns elif (type(descr.__class__) == type(IsDescription) and issubclass(descr.__class__, IsDescription)): # print("Nested object (type II)-->", name) columns = descr.columns elif isinstance(descr, dict): # print("Nested object (type III)-->", name) columns = descr else: # print("Nested object (type IV)-->", name) descr = copy.copy(descr) # The copies above and below ensure that the structures # provided by the user will remain unchanged even if we # tamper with the values of ``_v_pos`` here. if columns is not None: descr = Description(copy.copy(columns), self._v_nestedlvl) classdict[name] = descr pos = getattr(descr, '_v_pos', None) if pos is None: cols_no_pos.append(name) else: cols_with_pos.append((pos, name)) # Sort field names: # # 1. Fields with explicit positions, according to their # positions (and their names if coincident). # 2. Fields with no position, in alfabetical order. cols_with_pos.sort() cols_no_pos.sort() keys = [name for (pos, name) in cols_with_pos] + cols_no_pos pos = 0 # Get properties for compound types for k in keys: if validate: # Check for key name validity check_name_validity(k) # Class variables object = classdict[k] newdict[k] = object # To allow natural naming if not (isinstance(object, Col) or isinstance(object, Description)): raise TypeError('Passing an incorrect value to a table column.' ' Expected a Col (or subclass) instance and ' 'got: "%s". Please make use of the Col(), or ' 'descendant, constructor to properly ' 'initialize columns.' % object) object._v_pos = pos # Set the position of this object object._v_parent = self # The parent description pos += 1 newdict['_v_colobjects'][k] = object newdict['_v_names'].append(k) object.__dict__['_v_name'] = k if not isinstance(k, str): # numpy only accepts "str" for field names if sys.version_info[0] < 3: # Python 2.x: unicode --> str kk = k.encode() # use the default encoding else: # Python 3.x: bytes --> str (unicode) kk = k.decode() else: kk = k if isinstance(object, Col): dtype = object.dtype newdict['_v_dtypes'][k] = dtype newdict['_v_types'][k] = object.type newdict['_v_dflts'][k] = object.dflt nestedFormats.append(object.recarrtype) baserecarrtype = dtype.base.str[1:] nestedDType.append((kk, baserecarrtype, dtype.shape)) else: # A description nestedFormats.append(object._v_nested_formats) nestedDType.append((kk, object._v_dtype)) # Assign the format list to _v_nested_formats newdict['_v_nested_formats'] = nestedFormats newdict['_v_dtype'] = numpy.dtype(nestedDType) # _v_itemsize is derived from the _v_dtype that already computes this newdict['_v_itemsize'] = newdict['_v_dtype'].itemsize if self._v_nestedlvl == 0: # Get recursively nested _v_nested_names and _v_nested_descr attrs self._g_set_nested_names_descr() # Get pathnames for nested groups self._g_set_path_names() # Check the _v_byteorder has been used an issue an Error if hasattr(self, "_v_byteorder"): raise ValueError( "Using a ``_v_byteorder`` in the description is obsolete. " "Use the byteorder parameter in the constructor instead.")
def __init__(self, classdict, nestedlvl=-1, validate=True): if not classdict: raise ValueError("cannot create an empty data type") # Do a shallow copy of classdict just in case this is going to # be shared by other instances newdict = self.__dict__ newdict["_v_name"] = "/" # The name for root descriptor newdict["_v_names"] = [] newdict["_v_dtypes"] = {} newdict["_v_types"] = {} newdict["_v_dflts"] = {} newdict["_v_colobjects"] = {} newdict["_v_is_nested"] = False nestedFormats = [] nestedDType = [] if not hasattr(newdict, "_v_nestedlvl"): newdict["_v_nestedlvl"] = nestedlvl + 1 cols_with_pos = [] # colum (position, name) pairs cols_no_pos = [] # just column names # Check for special variables and convert column descriptions for (name, descr) in classdict.items(): if name.startswith('_v_'): if name in newdict: # print("Warning!") # special methods &c: copy to newdict, warn about conflicts warnings.warn("Can't set attr %r in description class %r" % (name, self)) else: # print("Special variable!-->", name, classdict[name]) newdict[name] = descr continue # This variable is not needed anymore columns = None if (type(descr) == type(IsDescription) and issubclass(descr, IsDescription)): # print("Nested object (type I)-->", name) columns = descr().columns elif (type(descr.__class__) == type(IsDescription) and issubclass(descr.__class__, IsDescription)): # print("Nested object (type II)-->", name) columns = descr.columns elif isinstance(descr, dict): # print("Nested object (type III)-->", name) columns = descr else: # print("Nested object (type IV)-->", name) descr = copy.copy(descr) # The copies above and below ensure that the structures # provided by the user will remain unchanged even if we # tamper with the values of ``_v_pos`` here. if columns is not None: descr = Description(copy.copy(columns), self._v_nestedlvl) classdict[name] = descr pos = getattr(descr, '_v_pos', None) if pos is None: cols_no_pos.append(name) else: cols_with_pos.append((pos, name)) # Sort field names: # # 1. Fields with explicit positions, according to their # positions (and their names if coincident). # 2. Fields with no position, in alfabetical order. cols_with_pos.sort() cols_no_pos.sort() keys = [name for (pos, name) in cols_with_pos] + cols_no_pos pos = 0 # Get properties for compound types for k in keys: if validate: # Check for key name validity check_name_validity(k) # Class variables object = classdict[k] newdict[k] = object # To allow natural naming if not (isinstance(object, Col) or isinstance(object, Description)): raise TypeError('Passing an incorrect value to a table column.' ' Expected a Col (or subclass) instance and ' 'got: "%s". Please make use of the Col(), or ' 'descendant, constructor to properly ' 'initialize columns.' % object) object._v_pos = pos # Set the position of this object object._v_parent = self # The parent description pos += 1 newdict['_v_colobjects'][k] = object newdict['_v_names'].append(k) object.__dict__['_v_name'] = k if not isinstance(k, str): # numpy only accepts "str" for field names if sys.version_info[0] < 3: # Python 2.x: unicode --> str kk = k.encode() # use the default encoding else: # Python 3.x: bytes --> str (unicode) kk = k.decode() else: kk = k if isinstance(object, Col): dtype = object.dtype newdict['_v_dtypes'][k] = dtype newdict['_v_types'][k] = object.type newdict['_v_dflts'][k] = object.dflt nestedFormats.append(object.recarrtype) baserecarrtype = dtype.base.str[1:] nestedDType.append((kk, baserecarrtype, dtype.shape)) else: # A description nestedFormats.append(object._v_nested_formats) nestedDType.append((kk, object._v_dtype)) # Assign the format list to _v_nested_formats newdict['_v_nested_formats'] = nestedFormats newdict['_v_dtype'] = numpy.dtype(nestedDType) # _v_itemsize is derived from the _v_dtype that already computes this newdict['_v_itemsize'] = newdict['_v_dtype'].itemsize if self._v_nestedlvl == 0: # Get recursively nested _v_nested_names and _v_nested_descr attrs self._g_set_nested_names_descr() # Get pathnames for nested groups self._g_set_path_names() # Check the _v_byteorder has been used an issue an Error if hasattr(self, "_v_byteorder"): raise ValueError( "Using a ``_v_byteorder`` in the description is obsolete. " "Use the byteorder parameter in the constructor instead.")