From 7aeb4b9ce85fa9d15c79bbb3c1ccf6cc31cd5e61 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Tue, 23 Aug 1994 13:32:20 +0000 Subject: [PATCH] * 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) --- Lib/linecache.py | 2 +- Lib/macpath.py | 2 +- Lib/macstat.py | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ Lib/stat.py | 2 +- Lib/traceback.py | 32 ++++++++++++++++--- Lib/urllib.py | 28 ++++++++++------ 6 files changed, 131 insertions(+), 18 deletions(-) create mode 100755 Lib/macstat.py diff --git a/Lib/linecache.py b/Lib/linecache.py index b9818698591..f5726e9eb8d 100644 --- a/Lib/linecache.py +++ b/Lib/linecache.py @@ -59,7 +59,7 @@ def checkcache(): 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 b5c17f0be71..0e32ab2168d 100644 --- a/Lib/macpath.py +++ b/Lib/macpath.py @@ -43,7 +43,7 @@ def split(s): 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 00000000000..4b53953634c --- /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 381e28a9bcf..5f6f522dc20 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 c78d9ad9c32..1eec209742c 100644 --- a/Lib/traceback.py +++ b/Lib/traceback.py @@ -42,11 +42,33 @@ def extract_tb(tb, limit = None): 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 = "" + 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 e8f56a72486..476570bf948 100644 --- a/Lib/urllib.py +++ b/Lib/urllib.py @@ -52,7 +52,13 @@ class URLopener: # 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 @@ class URLopener: 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 @@ class URLopener: # 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 @@ class URLopener: 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)