* Lib/linecache.py: don't crash on empty filename
* Lib/macpath.py: don't return trailing colon for dirname()
(XXX won't do for volume names -- but otherwise glob(':*:*.py')
loops forever)
* Lib/traceback.py: print SyntaxError correctly
* Lib/stat.py: moved to posixstat.py; added macstat.py which has
the constants for the Mac; and created new stat.py which includes
the right one
* Lib/urllib.py: fix caching bug (by disabling the cache)
diff --git a/Lib/linecache.py b/Lib/linecache.py
index b981869..f5726e9 100644
--- a/Lib/linecache.py
+++ b/Lib/linecache.py
@@ -59,7 +59,7 @@
def updatecache(filename):
if cache.has_key(filename):
del cache[filename]
- if filename[0] + filename[-1] == '<>':
+ if not filename or filename[0] + filename[-1] == '<>':
return []
fullname = filename
try:
diff --git a/Lib/macpath.py b/Lib/macpath.py
index b5c17f0..0e32ab2 100644
--- a/Lib/macpath.py
+++ b/Lib/macpath.py
@@ -43,7 +43,7 @@
colon = 0
for i in range(len(s)):
if s[i] == ':': colon = i+1
- return s[:colon], s[colon:]
+ return s[:colon-1], s[colon:]
# Short interfaces to split()
diff --git a/Lib/macstat.py b/Lib/macstat.py
new file mode 100755
index 0000000..4b53953
--- /dev/null
+++ b/Lib/macstat.py
@@ -0,0 +1,83 @@
+# Module 'stat'
+#
+# Defines constants and functions for interpreting stat/lstat struct
+# as returned by os.stat() and os.lstat() (if it exists).
+#
+# Suggested usage: from stat import *
+#
+# XXX Strictly spoken, this module may have to be adapted for each POSIX
+# implementation; in practice, however, the numeric constants used by
+# stat() are almost universal (even for stat() emulations on non-UNIX
+# systems like MS-DOS).
+
+# Indices for stat struct members in tuple returned by os.stat()
+
+ST_MODE = 0
+ST_INO = 1
+ST_DEV = 2
+ST_NLINK = 3
+ST_UID = 4
+ST_GID = 5
+ST_SIZE = 6
+ST_ATIME = 7
+ST_MTIME = 8
+ST_CTIME = 9
+
+# Extract bits from the mode
+
+def S_IMODE(mode):
+ return 0
+
+def S_IFMT(mode):
+ return mode & 0xFFFF
+
+# Constants used as S_IFMT() for various file types
+# (not all are implemented on all systems)
+
+S_IFDIR = 0x0000
+S_IFREG = 0x0003
+
+# Functions to test for each file type
+
+def S_ISDIR(mode):
+ return S_IFMT(mode) == S_IFDIR
+
+def S_ISCHR(mode):
+ return 0
+
+def S_ISBLK(mode):
+ return 0
+
+def S_ISREG(mode):
+ return S_IFMT(mode) == S_IFREG
+
+def S_ISFIFO(mode):
+ return 0
+
+def S_ISLNK(mode):
+ return 0
+
+def S_ISSOCK(mode):
+ return 0
+
+# Names for permission bits
+
+S_ISUID = 04000
+S_ISGID = 02000
+S_ENFMT = S_ISGID
+S_ISVTX = 01000
+S_IREAD = 00400
+S_IWRITE = 00200
+S_IEXEC = 00100
+S_IRWXU = 00700
+S_IRUSR = 00400
+S_IWUSR = 00200
+S_IXUSR = 00100
+S_IRWXG = 00070
+S_IRGRP = 00040
+S_IWGRP = 00020
+S_IXGRP = 00010
+S_IRWXO = 00007
+S_IROTH = 00004
+S_IWOTH = 00002
+S_IXOTH = 00001
diff --git a/Lib/stat.py b/Lib/stat.py
index 381e28a..5f6f522 100644
--- a/Lib/stat.py
+++ b/Lib/stat.py
@@ -8,7 +8,7 @@
# XXX Strictly spoken, this module may have to be adapted for each POSIX
# implementation; in practice, however, the numeric constants used by
# stat() are almost universal (even for stat() emulations on non-UNIX
-# systems like Macintosh or MS-DOS).
+# systems like MS-DOS).
# Indices for stat struct members in tuple returned by os.stat()
diff --git a/Lib/traceback.py b/Lib/traceback.py
index c78d9ad..1eec209 100644
--- a/Lib/traceback.py
+++ b/Lib/traceback.py
@@ -42,11 +42,33 @@
return list
def print_exception(type, value, tb, limit = None):
- print 'Traceback (innermost last):'
- print_tb(tb, limit)
- print type,
- if value is not None: print ':', value,
- print
+ if tb:
+ print 'Traceback (innermost last):'
+ print_tb(tb, limit)
+ if value is None:
+ print type
+ else:
+ if type is SyntaxError:
+ try:
+ msg, (filename, lineno, offset, line) = value
+ except:
+ pass
+ else:
+ if not filename: filename = "<string>"
+ print ' File "%s", line %d' % (filename, lineno)
+ i = 0
+ while i < len(line) and line[i] in string.whitespace:
+ i = i+1
+ s = ' '
+ print s + string.strip(line)
+ for c in line[i:offset-1]:
+ if c in string.whitespace:
+ s = s + c
+ else:
+ s = s + ' '
+ print s + '^'
+ value = msg
+ print '%s: %s' % (type, value)
def print_exc(limit = None):
print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback,
diff --git a/Lib/urllib.py b/Lib/urllib.py
index e8f56a7..476570b 100644
--- a/Lib/urllib.py
+++ b/Lib/urllib.py
@@ -52,7 +52,13 @@
# Constructor
def __init__(self):
self.addheaders = []
- self.tempcache = {}
+ self.tempcache = None
+ # Undocumented feature: if you assign {} to tempcache,
+ # it is used to cache files retrieved with
+ # self.retrieve(). This is not enabled by default
+ # since it does not work for changing documents (and I
+ # haven't got the logic to check expiration headers
+ # yet).
self.ftpcache = ftpcache
# Undocumented feature: you can use a different
# ftp cache by assigning to the .ftpcache member;
@@ -66,12 +72,13 @@
def cleanup(self):
import os
- for url in self.tempcache.keys():
- try:
- os.unlink(self.tempcache[url][0])
- except os.error:
- pass
- del self.tempcache[url]
+ if self.tempcache:
+ for url in self.tempcache.keys():
+ try:
+ os.unlink(self.tempcache[url][0])
+ except os.error:
+ pass
+ del self.tempcache[url]
# Add a header to be used by the HTTP interface only
# e.g. u.addheader('Accept', 'sound/basic')
@@ -98,10 +105,10 @@
# retrieve(url) returns (filename, None) for a local object
# or (tempfilename, headers) for a remote object
def retrieve(self, url):
- if self.tempcache.has_key(url):
+ if self.tempcache and self.tempcache.has_key(url):
return self.tempcache[url]
url1 = unwrap(url)
- if self.tempcache.has_key(url1):
+ if self.tempcache and self.tempcache.has_key(url1):
self.tempcache[url] = self.tempcache[url1]
return self.tempcache[url1]
type, url1 = splittype(url1)
@@ -116,7 +123,8 @@
headers = fp.info()
import tempfile
tfn = tempfile.mktemp()
- self.tempcache[url] = result = tfn, headers
+ if self.tempcache is not None:
+ self.tempcache[url] = result = tfn, headers
tfp = open(tfn, 'w')
bs = 1024*8
block = fp.read(bs)