| """Common pathname manipulations, JDK version. |
| |
| Instead of importing this module directly, import os and refer to this |
| module as os.path. |
| |
| """ |
| |
| # Incompletely implemented: |
| # ismount -- How? |
| # normcase -- How? |
| |
| # Missing: |
| # sameopenfile -- Java doesn't have fstat nor file descriptors? |
| # samestat -- How? |
| |
| import stat |
| import sys |
| from java.io import File |
| import java.io.IOException |
| from java.lang import System |
| import os |
| |
| from org.python.core.Py import newString as asPyString |
| |
| |
| def _tostr(s, method): |
| if isinstance(s, basestring): |
| return s |
| raise TypeError, "%s() argument must be a str or unicode object, not %s" % ( |
| method, _type_name(s)) |
| |
| def _type_name(obj): |
| TPFLAGS_HEAPTYPE = 1 << 9 |
| type_name = '' |
| obj_type = type(obj) |
| is_heap = obj_type.__flags__ & TPFLAGS_HEAPTYPE == TPFLAGS_HEAPTYPE |
| if not is_heap and obj_type.__module__ != '__builtin__': |
| type_name = '%s.' % obj_type.__module__ |
| type_name += obj_type.__name__ |
| return type_name |
| |
| def dirname(path): |
| """Return the directory component of a pathname""" |
| path = _tostr(path, "dirname") |
| result = asPyString(File(path).getParent()) |
| if not result: |
| if isabs(path): |
| result = path # Must be root |
| else: |
| result = "" |
| return result |
| |
| def basename(path): |
| """Return the final component of a pathname""" |
| path = _tostr(path, "basename") |
| return asPyString(File(path).getName()) |
| |
| def split(path): |
| """Split a pathname. |
| |
| Return tuple "(head, tail)" where "tail" is everything after the |
| final slash. Either part may be empty. |
| |
| """ |
| path = _tostr(path, "split") |
| return (dirname(path), basename(path)) |
| |
| def splitext(path): |
| """Split the extension from a pathname. |
| |
| Extension is everything from the last dot to the end. Return |
| "(root, ext)", either part may be empty. |
| |
| """ |
| i = 0 |
| n = -1 |
| for c in path: |
| if c == '.': n = i |
| i = i+1 |
| if n < 0: |
| return (path, "") |
| else: |
| return (path[:n], path[n:]) |
| |
| def splitdrive(path): |
| """Split a pathname into drive and path specifiers. |
| |
| Returns a 2-tuple "(drive,path)"; either part may be empty. |
| """ |
| # Algorithm based on CPython's ntpath.splitdrive and ntpath.isabs. |
| if path[1:2] == ':' and path[0].lower() in 'abcdefghijklmnopqrstuvwxyz' \ |
| and (path[2:] == '' or path[2] in '/\\'): |
| return path[:2], path[2:] |
| return '', path |
| |
| def exists(path): |
| """Test whether a path exists. |
| |
| Returns false for broken symbolic links. |
| |
| """ |
| path = _tostr(path, "exists") |
| return File(sys.getPath(path)).exists() |
| |
| def isabs(path): |
| """Test whether a path is absolute""" |
| path = _tostr(path, "isabs") |
| return File(path).isAbsolute() |
| |
| def isfile(path): |
| """Test whether a path is a regular file""" |
| path = _tostr(path, "isfile") |
| return File(sys.getPath(path)).isFile() |
| |
| def isdir(path): |
| """Test whether a path is a directory""" |
| path = _tostr(path, "isdir") |
| return File(sys.getPath(path)).isDirectory() |
| |
| def join(path, *args): |
| """Join two or more pathname components, inserting os.sep as needed""" |
| path = _tostr(path, "join") |
| f = File(path) |
| for a in args: |
| a = _tostr(a, "join") |
| g = File(a) |
| if g.isAbsolute() or len(f.getPath()) == 0: |
| f = g |
| else: |
| if a == "": |
| a = os.sep |
| f = File(f, a) |
| return asPyString(f.getPath()) |
| |
| def normcase(path): |
| """Normalize case of pathname. |
| |
| XXX Not done right under JDK. |
| |
| """ |
| path = _tostr(path, "normcase") |
| return asPyString(File(path).getPath()) |
| |
| def commonprefix(m): |
| "Given a list of pathnames, return the longest common leading component" |
| if not m: return '' |
| prefix = m[0] |
| for item in m: |
| for i in range(len(prefix)): |
| if prefix[:i+1] <> item[:i+1]: |
| prefix = prefix[:i] |
| if i == 0: return '' |
| break |
| return prefix |
| |
| def islink(path): |
| """Test whether a path is a symbolic link""" |
| try: |
| st = os.lstat(path) |
| except (os.error, AttributeError): |
| return False |
| return stat.S_ISLNK(st.st_mode) |
| |
| def samefile(path, path2): |
| """Test whether two pathnames reference the same actual file""" |
| path = _tostr(path, "samefile") |
| path2 = _tostr(path2, "samefile") |
| return _realpath(path) == _realpath(path2) |
| |
| def ismount(path): |
| """Test whether a path is a mount point. |
| |
| XXX This incorrectly always returns false under JDK. |
| |
| """ |
| return 0 |
| |
| def walk(top, func, arg): |
| """Walk a directory tree. |
| |
| walk(top,func,args) calls func(arg, d, files) for each directory |
| "d" in the tree rooted at "top" (including "top" itself). "files" |
| is a list of all the files and subdirs in directory "d". |
| |
| """ |
| try: |
| names = os.listdir(top) |
| except os.error: |
| return |
| func(arg, top, names) |
| for name in names: |
| name = join(top, name) |
| if isdir(name) and not islink(name): |
| walk(name, func, arg) |
| |
| def expanduser(path): |
| if path[:1] == "~": |
| c = path[1:2] |
| if not c: |
| return gethome() |
| if c == os.sep: |
| return asPyString(File(gethome(), path[2:]).getPath()) |
| return path |
| |
| def getuser(): |
| return System.getProperty("user.name") |
| |
| def gethome(): |
| return System.getProperty("user.home") |
| |
| |
| # normpath() from Python 1.5.2, with Java appropriate generalizations |
| |
| # Normalize a path, e.g. A//B, A/./B and A/foo/../B all become A/B. |
| # It should be understood that this may change the meaning of the path |
| # if it contains symbolic links! |
| def normpath(path): |
| """Normalize path, eliminating double slashes, etc.""" |
| sep = os.sep |
| if sep == '\\': |
| path = path.replace("/", sep) |
| curdir = os.curdir |
| pardir = os.pardir |
| import string |
| # Treat initial slashes specially |
| slashes = '' |
| while path[:1] == sep: |
| slashes = slashes + sep |
| path = path[1:] |
| comps = string.splitfields(path, sep) |
| i = 0 |
| while i < len(comps): |
| if comps[i] == curdir: |
| del comps[i] |
| while i < len(comps) and comps[i] == '': |
| del comps[i] |
| elif comps[i] == pardir and i > 0 and comps[i-1] not in ('', pardir): |
| del comps[i-1:i+1] |
| i = i-1 |
| elif comps[i] == '' and i > 0 and comps[i-1] <> '': |
| del comps[i] |
| else: |
| i = i+1 |
| # If the path is now empty, substitute '.' |
| if not comps and not slashes: |
| comps.append(curdir) |
| return slashes + string.joinfields(comps, sep) |
| |
| def abspath(path): |
| """Return an absolute path normalized but symbolic links not eliminated""" |
| path = _tostr(path, "abspath") |
| return _abspath(path) |
| |
| def _abspath(path): |
| # Must use normpath separately because getAbsolutePath doesn't normalize |
| # and getCanonicalPath would eliminate symlinks. |
| return normpath(asPyString(File(sys.getPath(path)).getAbsolutePath())) |
| |
| def realpath(path): |
| """Return an absolute path normalized and symbolic links eliminated""" |
| path = _tostr(path, "realpath") |
| return _realpath(path) |
| |
| def _realpath(path): |
| try: |
| return asPyString(File(sys.getPath(path)).getCanonicalPath()) |
| except java.io.IOException: |
| return _abspath(path) |
| |
| def getsize(path): |
| path = _tostr(path, "getsize") |
| f = File(sys.getPath(path)) |
| size = f.length() |
| # Sadly, if the returned length is zero, we don't really know if the file |
| # is zero sized or does not exist. |
| if size == 0 and not f.exists(): |
| raise OSError(0, 'No such file or directory', path) |
| return size |
| |
| def getmtime(path): |
| path = _tostr(path, "getmtime") |
| f = File(sys.getPath(path)) |
| if not f.exists(): |
| raise OSError(0, 'No such file or directory', path) |
| return f.lastModified() / 1000.0 |
| |
| def getatime(path): |
| # We can't detect access time so we return modification time. This |
| # matches the behaviour in os.stat(). |
| path = _tostr(path, "getatime") |
| f = File(sys.getPath(path)) |
| if not f.exists(): |
| raise OSError(0, 'No such file or directory', path) |
| return f.lastModified() / 1000.0 |
| |
| |
| # expandvars is stolen from CPython-2.1.1's Lib/ntpath.py: |
| |
| # Expand paths containing shell variable substitutions. |
| # The following rules apply: |
| # - no expansion within single quotes |
| # - no escape character, except for '$$' which is translated into '$' |
| # - ${varname} is accepted. |
| # - varnames can be made out of letters, digits and the character '_' |
| # XXX With COMMAND.COM you can use any characters in a variable name, |
| # XXX except '^|<>='. |
| |
| def expandvars(path): |
| """Expand shell variables of form $var and ${var}. |
| |
| Unknown variables are left unchanged.""" |
| if '$' not in path: |
| return path |
| import string |
| varchars = string.letters + string.digits + '_-' |
| res = '' |
| index = 0 |
| pathlen = len(path) |
| while index < pathlen: |
| c = path[index] |
| if c == '\'': # no expansion within single quotes |
| path = path[index + 1:] |
| pathlen = len(path) |
| try: |
| index = path.index('\'') |
| res = res + '\'' + path[:index + 1] |
| except ValueError: |
| res = res + path |
| index = pathlen - 1 |
| elif c == '$': # variable or '$$' |
| if path[index + 1:index + 2] == '$': |
| res = res + c |
| index = index + 1 |
| elif path[index + 1:index + 2] == '{': |
| path = path[index+2:] |
| pathlen = len(path) |
| try: |
| index = path.index('}') |
| var = path[:index] |
| if os.environ.has_key(var): |
| res = res + os.environ[var] |
| except ValueError: |
| res = res + path |
| index = pathlen - 1 |
| else: |
| var = '' |
| index = index + 1 |
| c = path[index:index + 1] |
| while c != '' and c in varchars: |
| var = var + c |
| index = index + 1 |
| c = path[index:index + 1] |
| if os.environ.has_key(var): |
| res = res + os.environ[var] |
| if c != '': |
| res = res + c |
| else: |
| res = res + c |
| index = index + 1 |
| return res |