macpath.py 4.95 KB
Newer Older
1
# module 'macpath' -- pathname (or -related) operations for the Macintosh
Guido van Rossum's avatar
Guido van Rossum committed
2

3
import string
4
import os
Guido van Rossum's avatar
Guido van Rossum committed
5 6
from stat import *

7

8 9 10 11 12
# Normalize the case of a pathname.  Dummy in Posix, but string.lower here.

normcase = string.lower


13 14 15 16 17 18
# Return true if a path is absolute.
# On the Mac, relative paths begin with a colon,
# but as a special case, paths with no colons at all are also relative.
# Anything else is absolute (the string up to the first colon is the
# volume name).

Guido van Rossum's avatar
Guido van Rossum committed
19 20 21
def isabs(s):
	return ':' in s and s[0] <> ':'

22

23 24 25 26 27 28 29 30 31 32 33 34 35 36
def join(s, *p):
	path = s
	for t in p:
		if (not s) or isabs(t):
			path = t
			continue
		if t[:1] == ':':
			t = t[1:]
		if ':' not in path:
			path = ':' + path
		if path[-1:] <> ':':
			path = path + ':'
		path = path + t
	return path
Guido van Rossum's avatar
Guido van Rossum committed
37

38 39 40

# Split a pathname in two parts: the directory leading up to the final bit,
# and the basename (the filename, without colons, in that directory).
Guido van Rossum's avatar
Guido van Rossum committed
41
# The result (s, t) is such that join(s, t) yields the original argument.
42 43 44 45 46

def split(s):
	if ':' not in s: return '', s
	colon = 0
	for i in range(len(s)):
Guido van Rossum's avatar
Guido van Rossum committed
47
		if s[i] == ':': colon = i+1
48 49 50 51
	path, file = s[:colon-1], s[colon:]
	if path and not ':' in path:
		path = path + ':'
	return path, file
52 53


Guido van Rossum's avatar
Guido van Rossum committed
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
# Split a path in root and extension.
# The extension is everything starting at the last dot in the last
# pathname component; the root is everything before that.
# It is always true that root + ext == p.

def splitext(p):
	root, ext = '', ''
	for c in p:
		if c == ':':
			root, ext = root + ext + c, ''
		elif c == '.':
			if ext:
				root, ext = root + ext, c
			else:
				ext = c
		elif ext:
			ext = ext + c
		else:
			root = root + c
	return root, ext


76 77 78 79 80
# Split a pathname into a drive specification and the rest of the
# path.  Useful on DOS/Windows/NT; on the Mac, the drive is always
# empty (don't use the volume name -- it doesn't have the same
# syntactic and semantic oddities as DOS drive letters, such as there
# being a separate current directory per drive).
81

82 83
def splitdrive(p):
	return '', p
84 85


86
# Short interfaces to split()
Guido van Rossum's avatar
Guido van Rossum committed
87

88 89
def dirname(s): return split(s)[0]
def basename(s): return split(s)[1]
Guido van Rossum's avatar
Guido van Rossum committed
90

91 92 93

# Return true if the pathname refers to an existing directory.

Guido van Rossum's avatar
Guido van Rossum committed
94 95
def isdir(s):
	try:
96 97
		st = os.stat(s)
	except os.error:
Guido van Rossum's avatar
Guido van Rossum committed
98 99 100
		return 0
	return S_ISDIR(st[ST_MODE])

101

102 103 104 105 106
# Get size, mtime, atime of files.

def getsize(filename):
    """Return the size of a file, reported by os.stat()."""
    st = os.stat(filename)
107
    return st[ST_SIZE]
108 109 110 111

def getmtime(filename):
    """Return the last modification time of a file, reported by os.stat()."""
    st = os.stat(filename)
112
    return st[ST_MTIME]
113 114 115 116

def getatime(filename):
    """Return the last access time of a file, reported by os.stat()."""
    st = os.stat(filename)
117
    return st[ST_MTIME]
118 119


Guido van Rossum's avatar
Guido van Rossum committed
120 121 122 123 124 125 126
# Return true if the pathname refers to a symbolic link.
# (Always false on the Mac, until we understand Aliases.)

def islink(s):
	return 0


127 128
# Return true if the pathname refers to an existing regular file.

Guido van Rossum's avatar
Guido van Rossum committed
129 130
def isfile(s):
	try:
131 132
		st = os.stat(s)
	except os.error:
Guido van Rossum's avatar
Guido van Rossum committed
133 134 135
		return 0
	return S_ISREG(st[ST_MODE])

136 137 138

# Return true if the pathname refers to an existing file or directory.

Guido van Rossum's avatar
Guido van Rossum committed
139 140
def exists(s):
	try:
141 142
		st = os.stat(s)
	except os.error:
Guido van Rossum's avatar
Guido van Rossum committed
143 144
		return 0
	return 1
145

146 147 148 149 150 151 152 153 154 155 156
#
# dummy expandvars to retain interface-compatability with other
# operating systems.
def expandvars(path):
	return path

#
# dummy expanduser to retain interface-compatability with other
# operating systems.
def expanduser(path):
	return path
157

158 159 160 161 162 163 164 165
# Normalize a pathname: get rid of '::' sequences by backing up,
# e.g., 'foo:bar::bletch' becomes 'foo:bletch'.
# Raise the exception norm_error below if backing up is impossible,
# e.g., for '::foo'.
# XXX The Unix version doesn't raise an exception but simply
# returns an unnormalized path.  Should do so here too.

norm_error = 'macpath.norm_error: path cannot be normalized'
166 167

def normpath(s):
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
	import string
	if ':' not in s:
		return ':' + s
	f = string.splitfields(s, ':')
	pre = []
	post = []
	if not f[0]:
		pre = f[:1]
		f = f[1:]
	if not f[len(f)-1]:
		post = f[-1:]
		f = f[:-1]
	res = []
	for seg in f:
		if seg:
			res.append(seg)
		else:
			if not res: raise norm_error, 'path starts with ::'
			del res[len(res)-1]
			if not (pre or res):
				raise norm_error, 'path starts with volume::'
	if pre: res = pre + res
	if post: res = res + post
	s = res[0]
	for seg in res[1:]:
		s = s + ':' + seg
194
	return s
195

196

197 198 199 200 201 202 203 204 205 206
# Directory tree walk.
# For each directory under top (including top itself),
# func(arg, dirname, filenames) is called, where
# dirname is the name of the directory and filenames is the list
# of files (and subdirectories etc.) in the directory.
# The func may modify the filenames list, to implement a filter,
# or to impose a different order of visiting.

def walk(top, func, arg):
	try:
207 208
		names = os.listdir(top)
	except os.error:
209 210 211 212 213 214
		return
	func(arg, top, names)
	for name in names:
		name = join(top, name)
		if isdir(name):
			walk(name, func, arg)
Guido van Rossum's avatar
Guido van Rossum committed
215 216 217 218 219 220 221


# Return an absolute path.
def abspath(path):
    if not isabs(path):
        path = join(os.getcwd(), path)
    return normpath(path)