""" Functionality related with node paths in a PyTables file. :Author: Ivan Vilata i Balaguer :Contact: ivilata at carabos dot com :License: BSD :Created: January 15, 2007 :Revision: $Id: path.py 2804 2007-04-29 09:22:37Z ivilata $ Variables ========= `__docformat`__ The format of documentation strings in this module. `__version__` Repository version of this file. """ # Imports # ======= import re import warnings import keyword from tables.exceptions import NaturalNameWarning # Public variables # ================ __docformat__ = 'reStructuredText' """The format of documentation strings in this module.""" __version__ = '$Revision: 2804 $' """Repository version of this file.""" # Private variables # ================= _pythonIdRE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') """Python identifier regular expression.""" _reservedIdRE = re.compile('^_[cfgv]_') """ PyTables reserved identifier regular expression. - c: class variables - f: class public methods - g: class private methods - v: instance variables """ _hiddenNameRE = re.compile('^_[pi]_') """ Nodes with a name *matching* this expression are considered hidden. For instance, ``name`` whould be visible while ``_i_name`` would not. """ _hiddenPathRE = re.compile('/_[pi]_') """ Nodes with a path *containing* this expression are considered hidden. For instance, a node with a pathname like ``/a/b/c`` would be visible while nodes with pathnames like ``/a/c/_i_x`` or ``/a/_p_x/y`` would not. """ # Public functions # ================ def checkNameValidity(name): """ Check the validity of the `name` of an object. If the name is not valid, a ``ValueError`` is raised. If it is valid but it can not be used with natural naming, a `NaturalNameWarning` is issued. """ warnInfo = ( "you will not be able to use natural naming to access this object; " "using ``getattr()`` will still work, though" ) if not isinstance(name, basestring): # Python >= 2.3 raise TypeError("object name is not a string: %r" % (name,)) # Check whether `name` is a valid HDF5 name. # http://hdfgroup.org/HDF5/doc/UG/03_Model.html#Structure if name == '': raise ValueError("the empty string is not allowed as an object name") if name == '.': raise ValueError("``.`` is not allowed as an object name") if '/' in name: raise ValueError( "the ``/`` character is not allowed " "in object names: %r" % name ) # Check whether `name` is a valid Python identifier. if not _pythonIdRE.match(name): warnings.warn( "object name is not a valid Python identifier: %r; " "it does not match the pattern ``%s``; %s" % (name, _pythonIdRE.pattern, warnInfo), NaturalNameWarning ) return # However, Python identifiers and keywords have the same form. if keyword.iskeyword(name): warnings.warn( "object name is a Python keyword: %r; %s" % (name, warnInfo), NaturalNameWarning ) return # Still, names starting with reserved prefixes are not allowed. if _reservedIdRE.match(name): raise ValueError( "object name starts with a reserved prefix: %r; " "it matches the pattern ``%s``" % (name, _reservedIdRE.pattern) ) # ``__members__`` is the only exception to that rule. if name == '__members__': raise ValueError("``__members__`` is not allowed as an object name") def joinPath(parentPath, name): """ Join a *canonical* `parentPath` with a *non-empty* `name`. >>> joinPath('/', 'foo') '/foo' >>> joinPath('/foo', 'bar') '/foo/bar' >>> joinPath('/foo', '/foo2/bar') '/foo/foo2/bar' """ if parentPath == '/' and name.startswith('/'): pstr = '%s' % name elif parentPath == '/' or name.startswith('/'): pstr = '%s%s' % (parentPath, name) else: pstr = '%s/%s' % (parentPath, name) return pstr def splitPath(path): """ Split a *canonical* `path` into a parent path and a node name. The result is returned as a tuple. The parent path does not include a trailing slash. >>> splitPath('/') ('/', '') >>> splitPath('/foo/bar') ('/foo', 'bar') """ lastSlash = path.rfind('/') ppath = path[:lastSlash] name = path[lastSlash+1:] if ppath == '': ppath = '/' return (ppath, name) def isVisibleName(name): """Does this `name` make the named node a visible one?""" return _hiddenNameRE.match(name) is None def isVisiblePath(path): """Does this `path` make the named node a visible one?""" return _hiddenPathRE.search(path) is None # Main part # ========= def _test(): """Run ``doctest`` on this module.""" import doctest doctest.testmod() if __name__ == '__main__': _test()