Whitespace normalization.

This commit is contained in:
Tim Peters 2001-01-15 03:26:36 +00:00
parent 495ad3c8cc
commit b90f89a496
9 changed files with 493 additions and 496 deletions

View File

@ -248,125 +248,124 @@ def format_witnesses(w):
# in use. # in use.
if hasattr(tokenize, 'NL'): if hasattr(tokenize, 'NL'):
# take advantage of Guido's patch! # take advantage of Guido's patch!
indents = [] indents = []
check_equal = 0 check_equal = 0
def reset_globals(): def reset_globals():
global indents, check_equal global indents, check_equal
check_equal = 0 check_equal = 0
indents = [Whitespace("")] indents = [Whitespace("")]
def tokeneater(type, token, start, end, line, def tokeneater(type, token, start, end, line,
INDENT=tokenize.INDENT, INDENT=tokenize.INDENT,
DEDENT=tokenize.DEDENT, DEDENT=tokenize.DEDENT,
NEWLINE=tokenize.NEWLINE, NEWLINE=tokenize.NEWLINE,
JUNK=(tokenize.COMMENT, tokenize.NL) ): JUNK=(tokenize.COMMENT, tokenize.NL) ):
global indents, check_equal global indents, check_equal
if type == NEWLINE: if type == NEWLINE:
# a program statement, or ENDMARKER, will eventually follow, # a program statement, or ENDMARKER, will eventually follow,
# after some (possibly empty) run of tokens of the form # after some (possibly empty) run of tokens of the form
# (NL | COMMENT)* (INDENT | DEDENT+)? # (NL | COMMENT)* (INDENT | DEDENT+)?
# If an INDENT appears, setting check_equal is wrong, and will # If an INDENT appears, setting check_equal is wrong, and will
# be undone when we see the INDENT. # be undone when we see the INDENT.
check_equal = 1 check_equal = 1
elif type == INDENT: elif type == INDENT:
check_equal = 0 check_equal = 0
thisguy = Whitespace(token) thisguy = Whitespace(token)
if not indents[-1].less(thisguy): if not indents[-1].less(thisguy):
witness = indents[-1].not_less_witness(thisguy) witness = indents[-1].not_less_witness(thisguy)
msg = "indent not greater e.g. " + format_witnesses(witness) msg = "indent not greater e.g. " + format_witnesses(witness)
raise NannyNag(start[0], msg, line) raise NannyNag(start[0], msg, line)
indents.append(thisguy) indents.append(thisguy)
elif type == DEDENT: elif type == DEDENT:
# there's nothing we need to check here! what's important is # there's nothing we need to check here! what's important is
# that when the run of DEDENTs ends, the indentation of the # that when the run of DEDENTs ends, the indentation of the
# program statement (or ENDMARKER) that triggered the run is # program statement (or ENDMARKER) that triggered the run is
# equal to what's left at the top of the indents stack # equal to what's left at the top of the indents stack
# Ouch! This assert triggers if the last line of the source # Ouch! This assert triggers if the last line of the source
# is indented *and* lacks a newline -- then DEDENTs pop out # is indented *and* lacks a newline -- then DEDENTs pop out
# of thin air. # of thin air.
# assert check_equal # else no earlier NEWLINE, or an earlier INDENT # assert check_equal # else no earlier NEWLINE, or an earlier INDENT
check_equal = 1 check_equal = 1
del indents[-1] del indents[-1]
elif check_equal and type not in JUNK: elif check_equal and type not in JUNK:
# this is the first "real token" following a NEWLINE, so it # this is the first "real token" following a NEWLINE, so it
# must be the first token of the next program statement, or an # must be the first token of the next program statement, or an
# ENDMARKER; the "line" argument exposes the leading whitespace # ENDMARKER; the "line" argument exposes the leading whitespace
# for this statement; in the case of ENDMARKER, line is an empty # for this statement; in the case of ENDMARKER, line is an empty
# string, so will properly match the empty string with which the # string, so will properly match the empty string with which the
# "indents" stack was seeded # "indents" stack was seeded
check_equal = 0 check_equal = 0
thisguy = Whitespace(line) thisguy = Whitespace(line)
if not indents[-1].equal(thisguy): if not indents[-1].equal(thisguy):
witness = indents[-1].not_equal_witness(thisguy) witness = indents[-1].not_equal_witness(thisguy)
msg = "indent not equal e.g. " + format_witnesses(witness) msg = "indent not equal e.g. " + format_witnesses(witness)
raise NannyNag(start[0], msg, line) raise NannyNag(start[0], msg, line)
else: else:
# unpatched version of tokenize # unpatched version of tokenize
nesting_level = 0 nesting_level = 0
indents = [] indents = []
check_equal = 0 check_equal = 0
def reset_globals(): def reset_globals():
global nesting_level, indents, check_equal global nesting_level, indents, check_equal
nesting_level = check_equal = 0 nesting_level = check_equal = 0
indents = [Whitespace("")] indents = [Whitespace("")]
def tokeneater(type, token, start, end, line, def tokeneater(type, token, start, end, line,
INDENT=tokenize.INDENT, INDENT=tokenize.INDENT,
DEDENT=tokenize.DEDENT, DEDENT=tokenize.DEDENT,
NEWLINE=tokenize.NEWLINE, NEWLINE=tokenize.NEWLINE,
COMMENT=tokenize.COMMENT, COMMENT=tokenize.COMMENT,
OP=tokenize.OP): OP=tokenize.OP):
global nesting_level, indents, check_equal global nesting_level, indents, check_equal
if type == INDENT: if type == INDENT:
check_equal = 0 check_equal = 0
thisguy = Whitespace(token) thisguy = Whitespace(token)
if not indents[-1].less(thisguy): if not indents[-1].less(thisguy):
witness = indents[-1].not_less_witness(thisguy) witness = indents[-1].not_less_witness(thisguy)
msg = "indent not greater e.g. " + format_witnesses(witness) msg = "indent not greater e.g. " + format_witnesses(witness)
raise NannyNag(start[0], msg, line) raise NannyNag(start[0], msg, line)
indents.append(thisguy) indents.append(thisguy)
elif type == DEDENT: elif type == DEDENT:
del indents[-1] del indents[-1]
elif type == NEWLINE: elif type == NEWLINE:
if nesting_level == 0: if nesting_level == 0:
check_equal = 1 check_equal = 1
elif type == COMMENT: elif type == COMMENT:
pass pass
elif check_equal: elif check_equal:
check_equal = 0 check_equal = 0
thisguy = Whitespace(line) thisguy = Whitespace(line)
if not indents[-1].equal(thisguy): if not indents[-1].equal(thisguy):
witness = indents[-1].not_equal_witness(thisguy) witness = indents[-1].not_equal_witness(thisguy)
msg = "indent not equal e.g. " + format_witnesses(witness) msg = "indent not equal e.g. " + format_witnesses(witness)
raise NannyNag(start[0], msg, line) raise NannyNag(start[0], msg, line)
if type == OP and token in ('{', '[', '('): if type == OP and token in ('{', '[', '('):
nesting_level = nesting_level + 1 nesting_level = nesting_level + 1
elif type == OP and token in ('}', ']', ')'): elif type == OP and token in ('}', ']', ')'):
if nesting_level == 0: if nesting_level == 0:
raise NannyNag(start[0], raise NannyNag(start[0],
"unbalanced bracket '" + token + "'", "unbalanced bracket '" + token + "'",
line) line)
nesting_level = nesting_level - 1 nesting_level = nesting_level - 1
if __name__ == '__main__': if __name__ == '__main__':
main() main()

View File

@ -26,10 +26,10 @@ def gettempdir():
elif os.name == 'mac': elif os.name == 'mac':
import macfs, MACFS import macfs, MACFS
try: try:
refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk, refnum, dirid = macfs.FindFolder(MACFS.kOnSystemDisk,
MACFS.kTemporaryFolderType, 1) MACFS.kTemporaryFolderType, 1)
dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname() dirname = macfs.FSSpec((refnum, dirid, '')).as_pathname()
attempdirs.insert(0, dirname) attempdirs.insert(0, dirname)
except macfs.error: except macfs.error:
pass pass
for envname in 'TMPDIR', 'TEMP', 'TMP': for envname in 'TMPDIR', 'TEMP', 'TMP':
@ -38,27 +38,27 @@ def gettempdir():
testfile = gettempprefix() + 'test' testfile = gettempprefix() + 'test'
for dir in attempdirs: for dir in attempdirs:
try: try:
filename = os.path.join(dir, testfile) filename = os.path.join(dir, testfile)
if os.name == 'posix': if os.name == 'posix':
try: try:
fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700) fd = os.open(filename, os.O_RDWR|os.O_CREAT|os.O_EXCL, 0700)
except OSError: except OSError:
pass pass
else: else:
fp = os.fdopen(fd, 'w') fp = os.fdopen(fd, 'w')
fp.write('blat') fp.write('blat')
fp.close() fp.close()
os.unlink(filename) os.unlink(filename)
del fp, fd del fp, fd
tempdir = dir tempdir = dir
break break
else: else:
fp = open(filename, 'w') fp = open(filename, 'w')
fp.write('blat') fp.write('blat')
fp.close() fp.close()
os.unlink(filename) os.unlink(filename)
tempdir = dir tempdir = dir
break break
except IOError: except IOError:
pass pass
if tempdir is None: if tempdir is None:

View File

@ -54,51 +54,51 @@ uncompress.append('uncompress', '--')
class error(Exception): class error(Exception):
pass pass
def toaiff(filename): def toaiff(filename):
temps = [] temps = []
ret = None ret = None
try: try:
ret = _toaiff(filename, temps) ret = _toaiff(filename, temps)
finally: finally:
for temp in temps[:]: for temp in temps[:]:
if temp != ret: if temp != ret:
try: try:
os.unlink(temp) os.unlink(temp)
except os.error: except os.error:
pass pass
temps.remove(temp) temps.remove(temp)
return ret return ret
def _toaiff(filename, temps): def _toaiff(filename, temps):
if filename[-2:] == '.Z': if filename[-2:] == '.Z':
fname = tempfile.mktemp() fname = tempfile.mktemp()
temps.append(fname) temps.append(fname)
sts = uncompress.copy(filename, fname) sts = uncompress.copy(filename, fname)
if sts: if sts:
raise error, filename + ': uncompress failed' raise error, filename + ': uncompress failed'
else: else:
fname = filename fname = filename
try: try:
ftype = sndhdr.whathdr(fname) ftype = sndhdr.whathdr(fname)
if ftype: if ftype:
ftype = ftype[0] # All we're interested in ftype = ftype[0] # All we're interested in
except IOError: except IOError:
if type(msg) == type(()) and len(msg) == 2 and \ if type(msg) == type(()) and len(msg) == 2 and \
type(msg[0]) == type(0) and type(msg[1]) == type(''): type(msg[0]) == type(0) and type(msg[1]) == type(''):
msg = msg[1] msg = msg[1]
if type(msg) != type(''): if type(msg) != type(''):
msg = `msg` msg = `msg`
raise error, filename + ': ' + msg raise error, filename + ': ' + msg
if ftype == 'aiff': if ftype == 'aiff':
return fname return fname
if ftype is None or not table.has_key(ftype): if ftype is None or not table.has_key(ftype):
raise error, \ raise error, \
filename + ': unsupported audio file type ' + `ftype` filename + ': unsupported audio file type ' + `ftype`
temp = tempfile.mktemp() temp = tempfile.mktemp()
temps.append(temp) temps.append(temp)
sts = table[ftype].copy(fname, temp) sts = table[ftype].copy(fname, temp)
if sts: if sts:
raise error, filename + ': conversion to aiff failed' raise error, filename + ': conversion to aiff failed'
return temp return temp

View File

@ -215,4 +215,3 @@ if __name__ == '__main__': # testing
import sys import sys
if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline) if len(sys.argv) > 1: tokenize(open(sys.argv[1]).readline)
else: tokenize(sys.stdin.readline) else: tokenize(sys.stdin.readline)

View File

@ -6,273 +6,273 @@ import sys
import types import types
def _print(file, str='', terminator='\n'): def _print(file, str='', terminator='\n'):
file.write(str+terminator) file.write(str+terminator)
def print_list(extracted_list, file=None): def print_list(extracted_list, file=None):
"""Print the list of tuples as returned by extract_tb() or """Print the list of tuples as returned by extract_tb() or
extract_stack() as a formatted stack trace to the given file.""" extract_stack() as a formatted stack trace to the given file."""
if not file: if not file:
file = sys.stderr file = sys.stderr
for filename, lineno, name, line in extracted_list: for filename, lineno, name, line in extracted_list:
_print(file, _print(file,
' File "%s", line %d, in %s' % (filename,lineno,name)) ' File "%s", line %d, in %s' % (filename,lineno,name))
if line: if line:
_print(file, ' %s' % string.strip(line)) _print(file, ' %s' % string.strip(line))
def format_list(extracted_list): def format_list(extracted_list):
"""Given a list of tuples as returned by extract_tb() or """Given a list of tuples as returned by extract_tb() or
extract_stack(), return a list of strings ready for printing. extract_stack(), return a list of strings ready for printing.
Each string in the resulting list corresponds to the item with Each string in the resulting list corresponds to the item with
the same index in the argument list. Each string ends in a the same index in the argument list. Each string ends in a
newline; the strings may contain internal newlines as well, for newline; the strings may contain internal newlines as well, for
those items whose source text line is not None.""" those items whose source text line is not None."""
list = [] list = []
for filename, lineno, name, line in extracted_list: for filename, lineno, name, line in extracted_list:
item = ' File "%s", line %d, in %s\n' % (filename,lineno,name) item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
if line: if line:
item = item + ' %s\n' % string.strip(line) item = item + ' %s\n' % string.strip(line)
list.append(item) list.append(item)
return list return list
def print_tb(tb, limit=None, file=None): def print_tb(tb, limit=None, file=None):
"""Print up to 'limit' stack trace entries from the traceback 'tb'. """Print up to 'limit' stack trace entries from the traceback 'tb'.
If 'limit' is omitted or None, all entries are printed. If 'file' is If 'limit' is omitted or None, all entries are printed. If 'file' is
omitted or None, the output goes to sys.stderr; otherwise 'file' omitted or None, the output goes to sys.stderr; otherwise 'file'
should be an open file or file-like object with a write() method.""" should be an open file or file-like object with a write() method."""
if not file: if not file:
file = sys.stderr file = sys.stderr
if limit is None: if limit is None:
if hasattr(sys, 'tracebacklimit'): if hasattr(sys, 'tracebacklimit'):
limit = sys.tracebacklimit limit = sys.tracebacklimit
n = 0 n = 0
while tb is not None and (limit is None or n < limit): while tb is not None and (limit is None or n < limit):
f = tb.tb_frame f = tb.tb_frame
lineno = tb_lineno(tb) lineno = tb_lineno(tb)
co = f.f_code co = f.f_code
filename = co.co_filename filename = co.co_filename
name = co.co_name name = co.co_name
_print(file, _print(file,
' File "%s", line %d, in %s' % (filename,lineno,name)) ' File "%s", line %d, in %s' % (filename,lineno,name))
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: _print(file, ' ' + string.strip(line)) if line: _print(file, ' ' + string.strip(line))
tb = tb.tb_next tb = tb.tb_next
n = n+1 n = n+1
def format_tb(tb, limit = None): def format_tb(tb, limit = None):
"""A shorthand for 'format_list(extract_stack(f, limit)).""" """A shorthand for 'format_list(extract_stack(f, limit))."""
return format_list(extract_tb(tb, limit)) return format_list(extract_tb(tb, limit))
def extract_tb(tb, limit = None): def extract_tb(tb, limit = None):
"""Return a list of up to 'limit' pre-processed stack trace entries """Return a list of up to 'limit' pre-processed stack trace entries
extracted from the traceback object 'traceback'. This is useful for extracted from the traceback object 'traceback'. This is useful for
alternate formatting of stack traces. If 'limit' is omitted or None, alternate formatting of stack traces. If 'limit' is omitted or None,
all entries are extracted. A pre-processed stack trace entry is a all entries are extracted. A pre-processed stack trace entry is a
quadruple (filename, line number, function name, text) representing quadruple (filename, line number, function name, text) representing
the information that is usually printed for a stack trace. The text the information that is usually printed for a stack trace. The text
is a string with leading and trailing whitespace stripped; if the is a string with leading and trailing whitespace stripped; if the
source is not available it is None.""" source is not available it is None."""
if limit is None: if limit is None:
if hasattr(sys, 'tracebacklimit'): if hasattr(sys, 'tracebacklimit'):
limit = sys.tracebacklimit limit = sys.tracebacklimit
list = [] list = []
n = 0 n = 0
while tb is not None and (limit is None or n < limit): while tb is not None and (limit is None or n < limit):
f = tb.tb_frame f = tb.tb_frame
lineno = tb_lineno(tb) lineno = tb_lineno(tb)
co = f.f_code co = f.f_code
filename = co.co_filename filename = co.co_filename
name = co.co_name name = co.co_name
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: line = string.strip(line) if line: line = string.strip(line)
else: line = None else: line = None
list.append((filename, lineno, name, line)) list.append((filename, lineno, name, line))
tb = tb.tb_next tb = tb.tb_next
n = n+1 n = n+1
return list return list
def print_exception(etype, value, tb, limit=None, file=None): def print_exception(etype, value, tb, limit=None, file=None):
"""Print exception information and up to 'limit' stack trace entries """Print exception information and up to 'limit' stack trace entries
from the traceback 'tb' to 'file'. This differs from print_tb() in from the traceback 'tb' to 'file'. This differs from print_tb() in
the following ways: (1) if traceback is not None, it prints a header the following ways: (1) if traceback is not None, it prints a header
"Traceback (most recent call last):"; (2) it prints the exception type and "Traceback (most recent call last):"; (2) it prints the exception type and
value after the stack trace; (3) if type is SyntaxError and value has value after the stack trace; (3) if type is SyntaxError and value has
the appropriate format, it prints the line where the syntax error the appropriate format, it prints the line where the syntax error
occurred with a caret on the next line indicating the approximate occurred with a caret on the next line indicating the approximate
position of the error.""" position of the error."""
if not file: if not file:
file = sys.stderr file = sys.stderr
if tb: if tb:
_print(file, 'Traceback (most recent call last):') _print(file, 'Traceback (most recent call last):')
print_tb(tb, limit, file) print_tb(tb, limit, file)
lines = format_exception_only(etype, value) lines = format_exception_only(etype, value)
for line in lines[:-1]: for line in lines[:-1]:
_print(file, line, ' ') _print(file, line, ' ')
_print(file, lines[-1], '') _print(file, lines[-1], '')
def format_exception(etype, value, tb, limit = None): def format_exception(etype, value, tb, limit = None):
"""Format a stack trace and the exception information. The arguments """Format a stack trace and the exception information. The arguments
have the same meaning as the corresponding arguments to have the same meaning as the corresponding arguments to
print_exception(). The return value is a list of strings, each print_exception(). The return value is a list of strings, each
ending in a newline and some containing internal newlines. When ending in a newline and some containing internal newlines. When
these lines are concatenated and printed, exactly the same text is these lines are concatenated and printed, exactly the same text is
printed as does print_exception().""" printed as does print_exception()."""
if tb: if tb:
list = ['Traceback (most recent call last):\n'] list = ['Traceback (most recent call last):\n']
list = list + format_tb(tb, limit) list = list + format_tb(tb, limit)
else: else:
list = [] list = []
list = list + format_exception_only(etype, value) list = list + format_exception_only(etype, value)
return list return list
def format_exception_only(etype, value): def format_exception_only(etype, value):
"""Format the exception part of a traceback. The arguments are the """Format the exception part of a traceback. The arguments are the
exception type and value such as given by sys.last_type and exception type and value such as given by sys.last_type and
sys.last_value. The return value is a list of strings, each ending sys.last_value. The return value is a list of strings, each ending
in a newline. Normally, the list contains a single string; in a newline. Normally, the list contains a single string;
however, for SyntaxError exceptions, it contains several lines that however, for SyntaxError exceptions, it contains several lines that
(when printed) display detailed information about where the syntax (when printed) display detailed information about where the syntax
error occurred. The message indicating which exception occurred is error occurred. The message indicating which exception occurred is
the always last string in the list.""" the always last string in the list."""
list = [] list = []
if type(etype) == types.ClassType: if type(etype) == types.ClassType:
stype = etype.__name__ stype = etype.__name__
else: else:
stype = etype stype = etype
if value is None: if value is None:
list.append(str(stype) + '\n') list.append(str(stype) + '\n')
else: else:
if etype is SyntaxError: if etype is SyntaxError:
try: try:
msg, (filename, lineno, offset, line) = value msg, (filename, lineno, offset, line) = value
except: except:
pass pass
else: else:
if not filename: filename = "<string>" if not filename: filename = "<string>"
list.append(' File "%s", line %d\n' % list.append(' File "%s", line %d\n' %
(filename, lineno)) (filename, lineno))
i = 0 i = 0
while i < len(line) and \ while i < len(line) and \
line[i] in string.whitespace: line[i] in string.whitespace:
i = i+1 i = i+1
list.append(' %s\n' % string.strip(line)) list.append(' %s\n' % string.strip(line))
s = ' ' s = ' '
for c in line[i:offset-1]: for c in line[i:offset-1]:
if c in string.whitespace: if c in string.whitespace:
s = s + c s = s + c
else: else:
s = s + ' ' s = s + ' '
list.append('%s^\n' % s) list.append('%s^\n' % s)
value = msg value = msg
s = _some_str(value) s = _some_str(value)
if s: if s:
list.append('%s: %s\n' % (str(stype), s)) list.append('%s: %s\n' % (str(stype), s))
else: else:
list.append('%s\n' % str(stype)) list.append('%s\n' % str(stype))
return list return list
def _some_str(value): def _some_str(value):
try: try:
return str(value) return str(value)
except: except:
return '<unprintable %s object>' % type(value).__name__ return '<unprintable %s object>' % type(value).__name__
def print_exc(limit=None, file=None): def print_exc(limit=None, file=None):
"""This is a shorthand for 'print_exception(sys.exc_type, """This is a shorthand for 'print_exception(sys.exc_type,
sys.exc_value, sys.exc_traceback, limit, file)'. sys.exc_value, sys.exc_traceback, limit, file)'.
(In fact, it uses sys.exc_info() to retrieve the same information (In fact, it uses sys.exc_info() to retrieve the same information
in a thread-safe way.)""" in a thread-safe way.)"""
if not file: if not file:
file = sys.stderr file = sys.stderr
try: try:
etype, value, tb = sys.exc_info() etype, value, tb = sys.exc_info()
print_exception(etype, value, tb, limit, file) print_exception(etype, value, tb, limit, file)
finally: finally:
etype = value = tb = None etype = value = tb = None
def print_last(limit=None, file=None): def print_last(limit=None, file=None):
"""This is a shorthand for 'print_exception(sys.last_type, """This is a shorthand for 'print_exception(sys.last_type,
sys.last_value, sys.last_traceback, limit, file)'.""" sys.last_value, sys.last_traceback, limit, file)'."""
if not file: if not file:
file = sys.stderr file = sys.stderr
print_exception(sys.last_type, sys.last_value, sys.last_traceback, print_exception(sys.last_type, sys.last_value, sys.last_traceback,
limit, file) limit, file)
def print_stack(f=None, limit=None, file=None): def print_stack(f=None, limit=None, file=None):
"""This function prints a stack trace from its invocation point. """This function prints a stack trace from its invocation point.
The optional 'f' argument can be used to specify an alternate stack The optional 'f' argument can be used to specify an alternate stack
frame at which to start. The optional 'limit' and 'file' arguments frame at which to start. The optional 'limit' and 'file' arguments
have the same meaning as for print_exception().""" have the same meaning as for print_exception()."""
if f is None: if f is None:
try: try:
raise ZeroDivisionError raise ZeroDivisionError
except ZeroDivisionError: except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back f = sys.exc_info()[2].tb_frame.f_back
print_list(extract_stack(f, limit), file) print_list(extract_stack(f, limit), file)
def format_stack(f=None, limit=None): def format_stack(f=None, limit=None):
"""A shorthand for 'format_list(extract_stack(f, limit))'.""" """A shorthand for 'format_list(extract_stack(f, limit))'."""
if f is None: if f is None:
try: try:
raise ZeroDivisionError raise ZeroDivisionError
except ZeroDivisionError: except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back f = sys.exc_info()[2].tb_frame.f_back
return format_list(extract_stack(f, limit)) return format_list(extract_stack(f, limit))
def extract_stack(f=None, limit = None): def extract_stack(f=None, limit = None):
"""Extract the raw traceback from the current stack frame. The """Extract the raw traceback from the current stack frame. The
return value has the same format as for extract_tb(). The optional return value has the same format as for extract_tb(). The optional
'f' and 'limit' arguments have the same meaning as for print_stack(). 'f' and 'limit' arguments have the same meaning as for print_stack().
Each item in the list is a quadruple (filename, line number, Each item in the list is a quadruple (filename, line number,
function name, text), and the entries are in order from oldest function name, text), and the entries are in order from oldest
to newest stack frame.""" to newest stack frame."""
if f is None: if f is None:
try: try:
raise ZeroDivisionError raise ZeroDivisionError
except ZeroDivisionError: except ZeroDivisionError:
f = sys.exc_info()[2].tb_frame.f_back f = sys.exc_info()[2].tb_frame.f_back
if limit is None: if limit is None:
if hasattr(sys, 'tracebacklimit'): if hasattr(sys, 'tracebacklimit'):
limit = sys.tracebacklimit limit = sys.tracebacklimit
list = [] list = []
n = 0 n = 0
while f is not None and (limit is None or n < limit): while f is not None and (limit is None or n < limit):
lineno = f.f_lineno # XXX Too bad if -O is used lineno = f.f_lineno # XXX Too bad if -O is used
co = f.f_code co = f.f_code
filename = co.co_filename filename = co.co_filename
name = co.co_name name = co.co_name
line = linecache.getline(filename, lineno) line = linecache.getline(filename, lineno)
if line: line = string.strip(line) if line: line = string.strip(line)
else: line = None else: line = None
list.append((filename, lineno, name, line)) list.append((filename, lineno, name, line))
f = f.f_back f = f.f_back
n = n+1 n = n+1
list.reverse() list.reverse()
return list return list
def tb_lineno(tb): def tb_lineno(tb):
"""Calculate the correct line number of the traceback given in tb """Calculate the correct line number of the traceback given in tb
(even with -O on).""" (even with -O on)."""
# Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line() # Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
# in compile.c. # in compile.c.
# Revised version by Jim Hugunin to work with JPython too. # Revised version by Jim Hugunin to work with JPython too.
c = tb.tb_frame.f_code c = tb.tb_frame.f_code
if not hasattr(c, 'co_lnotab'): if not hasattr(c, 'co_lnotab'):
return tb.tb_lineno return tb.tb_lineno
tab = c.co_lnotab tab = c.co_lnotab
line = c.co_firstlineno line = c.co_firstlineno
stopat = tb.tb_lasti stopat = tb.tb_lasti
addr = 0 addr = 0
for i in range(0, len(tab), 2): for i in range(0, len(tab), 2):
addr = addr + ord(tab[i]) addr = addr + ord(tab[i])
if addr > stopat: if addr > stopat:
break break
line = line + ord(tab[i+1]) line = line + ord(tab[i+1])
return line return line

View File

@ -15,22 +15,21 @@ OSPEED = 5
CC = 6 CC = 6
def setraw(fd, when=TCSAFLUSH): def setraw(fd, when=TCSAFLUSH):
"""Put terminal into a raw mode.""" """Put terminal into a raw mode."""
mode = tcgetattr(fd) mode = tcgetattr(fd)
mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON) mode[IFLAG] = mode[IFLAG] & ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON)
mode[OFLAG] = mode[OFLAG] & ~(OPOST) mode[OFLAG] = mode[OFLAG] & ~(OPOST)
mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB) mode[CFLAG] = mode[CFLAG] & ~(CSIZE | PARENB)
mode[CFLAG] = mode[CFLAG] | CS8 mode[CFLAG] = mode[CFLAG] | CS8
mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG) mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON | IEXTEN | ISIG)
mode[CC][VMIN] = 1 mode[CC][VMIN] = 1
mode[CC][VTIME] = 0 mode[CC][VTIME] = 0
tcsetattr(fd, when, mode) tcsetattr(fd, when, mode)
def setcbreak(fd, when=TCSAFLUSH): def setcbreak(fd, when=TCSAFLUSH):
"""Put terminal into a cbreak mode.""" """Put terminal into a cbreak mode."""
mode = tcgetattr(fd) mode = tcgetattr(fd)
mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON) mode[LFLAG] = mode[LFLAG] & ~(ECHO | ICANON)
mode[CC][VMIN] = 1 mode[CC][VMIN] = 1
mode[CC][VTIME] = 0 mode[CC][VTIME] = 0
tcsetattr(fd, when, mode) tcsetattr(fd, when, mode)

View File

@ -4,90 +4,90 @@
# XXX Only the typical form "XXXhhYYY;ddd/hh,ddd/hh" is currently supported. # XXX Only the typical form "XXXhhYYY;ddd/hh,ddd/hh" is currently supported.
tzpat = ('^([A-Z][A-Z][A-Z])([-+]?[0-9]+)([A-Z][A-Z][A-Z]);' tzpat = ('^([A-Z][A-Z][A-Z])([-+]?[0-9]+)([A-Z][A-Z][A-Z]);'
'([0-9]+)/([0-9]+),([0-9]+)/([0-9]+)$') '([0-9]+)/([0-9]+),([0-9]+)/([0-9]+)$')
tzprog = None tzprog = None
def tzparse(tzstr): def tzparse(tzstr):
"""Given a timezone spec, return a tuple of information """Given a timezone spec, return a tuple of information
(tzname, delta, dstname, daystart, hourstart, dayend, hourend), (tzname, delta, dstname, daystart, hourstart, dayend, hourend),
where 'tzname' is the name of the timezone, 'delta' is the offset where 'tzname' is the name of the timezone, 'delta' is the offset
in hours from GMT, 'dstname' is the name of the daylight-saving in hours from GMT, 'dstname' is the name of the daylight-saving
timezone, and 'daystart'/'hourstart' and 'dayend'/'hourend' timezone, and 'daystart'/'hourstart' and 'dayend'/'hourend'
specify the starting and ending points for daylight saving time.""" specify the starting and ending points for daylight saving time."""
global tzprog global tzprog
if tzprog is None: if tzprog is None:
import re import re
tzprog = re.compile(tzpat) tzprog = re.compile(tzpat)
match = tzprog.match(tzstr) match = tzprog.match(tzstr)
if not match: if not match:
raise ValueError, 'not the TZ syntax I understand' raise ValueError, 'not the TZ syntax I understand'
subs = [] subs = []
for i in range(1, 8): for i in range(1, 8):
subs.append(match.group(i)) subs.append(match.group(i))
for i in (1, 3, 4, 5, 6): for i in (1, 3, 4, 5, 6):
subs[i] = eval(subs[i]) subs[i] = eval(subs[i])
[tzname, delta, dstname, daystart, hourstart, dayend, hourend] = subs [tzname, delta, dstname, daystart, hourstart, dayend, hourend] = subs
return (tzname, delta, dstname, daystart, hourstart, dayend, hourend) return (tzname, delta, dstname, daystart, hourstart, dayend, hourend)
def tzlocaltime(secs, params): def tzlocaltime(secs, params):
"""Given a Unix time in seconds and a tuple of information about """Given a Unix time in seconds and a tuple of information about
a timezone as returned by tzparse(), return the local time in the a timezone as returned by tzparse(), return the local time in the
form (year, month, day, hour, min, sec, yday, wday, tzname).""" form (year, month, day, hour, min, sec, yday, wday, tzname)."""
import time import time
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = params (tzname, delta, dstname, daystart, hourstart, dayend, hourend) = params
year, month, days, hours, mins, secs, yday, wday, isdst = \ year, month, days, hours, mins, secs, yday, wday, isdst = \
time.gmtime(secs - delta*3600) time.gmtime(secs - delta*3600)
if (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend): if (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend):
tzname = dstname tzname = dstname
hours = hours + 1 hours = hours + 1
return year, month, days, hours, mins, secs, yday, wday, tzname return year, month, days, hours, mins, secs, yday, wday, tzname
def tzset(): def tzset():
"""Determine the current timezone from the "TZ" environment variable.""" """Determine the current timezone from the "TZ" environment variable."""
global tzparams, timezone, altzone, daylight, tzname global tzparams, timezone, altzone, daylight, tzname
import os import os
tzstr = os.environ['TZ'] tzstr = os.environ['TZ']
tzparams = tzparse(tzstr) tzparams = tzparse(tzstr)
timezone = tzparams[1] * 3600 timezone = tzparams[1] * 3600
altzone = timezone - 3600 altzone = timezone - 3600
daylight = 1 daylight = 1
tzname = tzparams[0], tzparams[2] tzname = tzparams[0], tzparams[2]
def isdst(secs): def isdst(secs):
"""Return true if daylight-saving time is in effect for the given """Return true if daylight-saving time is in effect for the given
Unix time in the current timezone.""" Unix time in the current timezone."""
import time import time
(tzname, delta, dstname, daystart, hourstart, dayend, hourend) = \ (tzname, delta, dstname, daystart, hourstart, dayend, hourend) = \
tzparams tzparams
year, month, days, hours, mins, secs, yday, wday, isdst = \ year, month, days, hours, mins, secs, yday, wday, isdst = \
time.gmtime(secs - delta*3600) time.gmtime(secs - delta*3600)
return (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend) return (daystart, hourstart) <= (yday+1, hours) < (dayend, hourend)
tzset() tzset()
def localtime(secs): def localtime(secs):
"""Get the local time in the current timezone.""" """Get the local time in the current timezone."""
return tzlocaltime(secs, tzparams) return tzlocaltime(secs, tzparams)
def test(): def test():
from time import asctime, gmtime from time import asctime, gmtime
import time, sys import time, sys
now = time.time() now = time.time()
x = localtime(now) x = localtime(now)
tm = x[:-1] + (0,) tm = x[:-1] + (0,)
print 'now =', now, '=', asctime(tm), x[-1] print 'now =', now, '=', asctime(tm), x[-1]
now = now - now % (24*3600) now = now - now % (24*3600)
if sys.argv[1:]: now = now + eval(sys.argv[1]) if sys.argv[1:]: now = now + eval(sys.argv[1])
x = gmtime(now) x = gmtime(now)
tm = x[:-1] + (0,) tm = x[:-1] + (0,)
print 'gmtime =', now, '=', asctime(tm), 'yday =', x[-2] print 'gmtime =', now, '=', asctime(tm), 'yday =', x[-2]
jan1 = now - x[-2]*24*3600 jan1 = now - x[-2]*24*3600
x = localtime(jan1) x = localtime(jan1)
tm = x[:-1] + (0,) tm = x[:-1] + (0,)
print 'jan1 =', jan1, '=', asctime(tm), x[-1] print 'jan1 =', jan1, '=', asctime(tm), x[-1]
for d in range(85, 95) + range(265, 275): for d in range(85, 95) + range(265, 275):
t = jan1 + d*24*3600 t = jan1 + d*24*3600
x = localtime(t) x = localtime(t)
tm = x[:-1] + (0,) tm = x[:-1] + (0,)
print 'd =', d, 't =', t, '=', asctime(tm), x[-1] print 'd =', d, 't =', t, '=', asctime(tm), x[-1]