mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
* 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)
This commit is contained in:
parent
9e1e149a5f
commit
7aeb4b9ce8
6 changed files with 131 additions and 18 deletions
|
@ -59,7 +59,7 @@ def checkcache():
|
||||||
def updatecache(filename):
|
def updatecache(filename):
|
||||||
if cache.has_key(filename):
|
if cache.has_key(filename):
|
||||||
del cache[filename]
|
del cache[filename]
|
||||||
if filename[0] + filename[-1] == '<>':
|
if not filename or filename[0] + filename[-1] == '<>':
|
||||||
return []
|
return []
|
||||||
fullname = filename
|
fullname = filename
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -43,7 +43,7 @@ def split(s):
|
||||||
colon = 0
|
colon = 0
|
||||||
for i in range(len(s)):
|
for i in range(len(s)):
|
||||||
if s[i] == ':': colon = i+1
|
if s[i] == ':': colon = i+1
|
||||||
return s[:colon], s[colon:]
|
return s[:colon-1], s[colon:]
|
||||||
|
|
||||||
|
|
||||||
# Short interfaces to split()
|
# Short interfaces to split()
|
||||||
|
|
83
Lib/macstat.py
Executable file
83
Lib/macstat.py
Executable file
|
@ -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
|
|
@ -8,7 +8,7 @@
|
||||||
# XXX Strictly spoken, this module may have to be adapted for each POSIX
|
# XXX Strictly spoken, this module may have to be adapted for each POSIX
|
||||||
# implementation; in practice, however, the numeric constants used by
|
# implementation; in practice, however, the numeric constants used by
|
||||||
# stat() are almost universal (even for stat() emulations on non-UNIX
|
# 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()
|
# Indices for stat struct members in tuple returned by os.stat()
|
||||||
|
|
||||||
|
|
|
@ -42,11 +42,33 @@ def extract_tb(tb, limit = None):
|
||||||
return list
|
return list
|
||||||
|
|
||||||
def print_exception(type, value, tb, limit = None):
|
def print_exception(type, value, tb, limit = None):
|
||||||
print 'Traceback (innermost last):'
|
if tb:
|
||||||
print_tb(tb, limit)
|
print 'Traceback (innermost last):'
|
||||||
print type,
|
print_tb(tb, limit)
|
||||||
if value is not None: print ':', value,
|
if value is None:
|
||||||
print
|
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):
|
def print_exc(limit = None):
|
||||||
print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback,
|
print_exception(sys.exc_type, sys.exc_value, sys.exc_traceback,
|
||||||
|
|
|
@ -52,7 +52,13 @@ class URLopener:
|
||||||
# Constructor
|
# Constructor
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.addheaders = []
|
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
|
self.ftpcache = ftpcache
|
||||||
# Undocumented feature: you can use a different
|
# Undocumented feature: you can use a different
|
||||||
# ftp cache by assigning to the .ftpcache member;
|
# ftp cache by assigning to the .ftpcache member;
|
||||||
|
@ -66,12 +72,13 @@ class URLopener:
|
||||||
|
|
||||||
def cleanup(self):
|
def cleanup(self):
|
||||||
import os
|
import os
|
||||||
for url in self.tempcache.keys():
|
if self.tempcache:
|
||||||
try:
|
for url in self.tempcache.keys():
|
||||||
os.unlink(self.tempcache[url][0])
|
try:
|
||||||
except os.error:
|
os.unlink(self.tempcache[url][0])
|
||||||
pass
|
except os.error:
|
||||||
del self.tempcache[url]
|
pass
|
||||||
|
del self.tempcache[url]
|
||||||
|
|
||||||
# Add a header to be used by the HTTP interface only
|
# Add a header to be used by the HTTP interface only
|
||||||
# e.g. u.addheader('Accept', 'sound/basic')
|
# e.g. u.addheader('Accept', 'sound/basic')
|
||||||
|
@ -98,10 +105,10 @@ class URLopener:
|
||||||
# retrieve(url) returns (filename, None) for a local object
|
# retrieve(url) returns (filename, None) for a local object
|
||||||
# or (tempfilename, headers) for a remote object
|
# or (tempfilename, headers) for a remote object
|
||||||
def retrieve(self, url):
|
def retrieve(self, url):
|
||||||
if self.tempcache.has_key(url):
|
if self.tempcache and self.tempcache.has_key(url):
|
||||||
return self.tempcache[url]
|
return self.tempcache[url]
|
||||||
url1 = unwrap(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]
|
self.tempcache[url] = self.tempcache[url1]
|
||||||
return self.tempcache[url1]
|
return self.tempcache[url1]
|
||||||
type, url1 = splittype(url1)
|
type, url1 = splittype(url1)
|
||||||
|
@ -116,7 +123,8 @@ class URLopener:
|
||||||
headers = fp.info()
|
headers = fp.info()
|
||||||
import tempfile
|
import tempfile
|
||||||
tfn = tempfile.mktemp()
|
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')
|
tfp = open(tfn, 'w')
|
||||||
bs = 1024*8
|
bs = 1024*8
|
||||||
block = fp.read(bs)
|
block = fp.read(bs)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue