mirror of https://github.com/python/cpython
Another batch of updates...
This commit is contained in:
parent
52a42fe9e7
commit
a8763e54ff
|
@ -1,13 +1,13 @@
|
|||
"""Object-oriented interface to the parser module.
|
||||
|
||||
This module exports three classes which together provide an interface
|
||||
This module exports four classes which together provide an interface
|
||||
to the parser module. Together, the three classes represent two ways
|
||||
to create parsed representations of Python source and the two starting
|
||||
data types (source text and tuple representations). Each class
|
||||
provides interfaces which are identical other than the constructors.
|
||||
The constructors are described in detail in the documentation for each
|
||||
class and the remaining, shared portion of the interface is documented
|
||||
below. Briefly, the three classes provided are:
|
||||
below. Briefly, the classes provided are:
|
||||
|
||||
AST
|
||||
Defines the primary interface to the AST objects and supports creation
|
||||
|
@ -23,6 +23,9 @@ FileSuiteAST
|
|||
Convenience subclass of the `SuiteAST' class; loads source text of the
|
||||
suite from an external file.
|
||||
|
||||
Common Methods
|
||||
--------------
|
||||
|
||||
Aside from the constructors, several methods are provided to allow
|
||||
access to the various interpretations of the parse tree and to check
|
||||
conditions of the construct represented by the parse tree.
|
||||
|
@ -68,8 +71,8 @@ class AST:
|
|||
This base class provides all of the query methods for subclass
|
||||
objects defined in this module.
|
||||
"""
|
||||
_p = __import__('parser') # import internally to avoid
|
||||
# namespace pollution at the
|
||||
import parser # import internally to avoid
|
||||
_p = parser # namespace pollution at the
|
||||
# top level
|
||||
_text = None
|
||||
_code = None
|
||||
|
@ -84,7 +87,8 @@ class AST:
|
|||
The tuple tree to convert.
|
||||
|
||||
The tuple-tree may represent either an expression or a suite; the
|
||||
type will be determined automatically.
|
||||
type will be determined automatically. Line number information may
|
||||
optionally be present for any subset of the terminal tokens.
|
||||
"""
|
||||
if type(tuple) is not type(()):
|
||||
raise TypeError, 'Base AST class requires tuple parameter.'
|
||||
|
@ -93,11 +97,24 @@ class AST:
|
|||
self._ast = self._p.tuple2ast(tuple)
|
||||
self._type = (self._p.isexpr(self._ast) and 'expression') or 'suite'
|
||||
|
||||
def tuple(self):
|
||||
def list(self, line_info = 0):
|
||||
"""Returns a fresh list representing the parse tree.
|
||||
|
||||
line_info
|
||||
If true, includes line number information for terminal tokens in
|
||||
the output data structure,
|
||||
"""
|
||||
return self._p.ast2list(self._ast, line_info)
|
||||
|
||||
def tuple(self, line_info = 0):
|
||||
"""Returns the tuple representing the parse tree.
|
||||
|
||||
line_info
|
||||
If true, includes line number information for terminal tokens in
|
||||
the output data structure,
|
||||
"""
|
||||
if self._tupl is None:
|
||||
self._tupl = self._p.ast2tuple(self._ast)
|
||||
self._tupl = self._p.ast2tuple(self._ast, line_info)
|
||||
return self._tupl
|
||||
|
||||
def code(self):
|
||||
|
|
|
@ -141,6 +141,7 @@ def _test():
|
|||
return self.sum
|
||||
o = Original()
|
||||
b = Bastion(o)
|
||||
testcode = """if 1:
|
||||
b.add(81)
|
||||
b.add(18)
|
||||
print "b.total() =", b.total()
|
||||
|
@ -156,6 +157,20 @@ def _test():
|
|||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
try:
|
||||
print "b._get_.func_defaults =", b._get_.func_defaults,
|
||||
except:
|
||||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
\n"""
|
||||
exec testcode
|
||||
print '='*20, "Using rexec:", '='*20
|
||||
import rexec
|
||||
r = rexec.RExec()
|
||||
m = r.add_module('__main__')
|
||||
m.b = b
|
||||
r.r_exec(testcode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -43,7 +43,7 @@ def compile_dir(dir, maxlevels = 10):
|
|||
|
||||
def compile_path(skip_curdir = 1):
|
||||
for dir in sys.path:
|
||||
if dir == os.curdir and skip_curdir:
|
||||
if (not dir or dir == os.curdir) and skip_curdir:
|
||||
print 'Skipping current directory'
|
||||
else:
|
||||
compile_dir(dir, 0)
|
||||
|
|
|
@ -10,7 +10,7 @@ AS_IS = None
|
|||
|
||||
class NullFormatter:
|
||||
|
||||
def __init__(self): pass
|
||||
def __init__(self, writer): pass
|
||||
def end_paragraph(self, blankline): pass
|
||||
def add_line_break(self): pass
|
||||
def add_hor_rule(self, abswidth=None, percentwidth=1.0,
|
||||
|
@ -33,6 +33,11 @@ class NullFormatter:
|
|||
|
||||
class AbstractFormatter:
|
||||
|
||||
# Space handling policy: blank spaces at the boundary between elements
|
||||
# are handled by the outermost context. "Literal" data is not checked
|
||||
# to determine context, so spaces in literal data are handled directly
|
||||
# in all circumstances.
|
||||
|
||||
def __init__(self, writer):
|
||||
self.writer = writer # Output device
|
||||
self.align = None # Current alignment
|
||||
|
@ -162,7 +167,8 @@ class AbstractFormatter:
|
|||
|
||||
def add_literal_data(self, data):
|
||||
if not data: return
|
||||
# Caller is expected to cause flush_softspace() if needed.
|
||||
if self.softspace:
|
||||
self.writer.send_flowing_data(" ")
|
||||
self.hard_break = data[-1:] == '\n'
|
||||
self.nospace = self.para_end = self.softspace = \
|
||||
self.parskip = self.have_label = 0
|
||||
|
@ -170,8 +176,9 @@ class AbstractFormatter:
|
|||
|
||||
def flush_softspace(self):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.parskip = \
|
||||
self.hard_break = self.para_end = self.parskip = \
|
||||
self.have_label = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
|
||||
def push_alignment(self, align):
|
||||
|
@ -194,7 +201,8 @@ class AbstractFormatter:
|
|||
|
||||
def push_font(self, (size, i, b, tt)):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
csize, ci, cb, ctt = self.font_stack[-1]
|
||||
|
@ -207,9 +215,6 @@ class AbstractFormatter:
|
|||
self.writer.new_font(font)
|
||||
|
||||
def pop_font(self):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
del self.font_stack[-1]
|
||||
if self.font_stack:
|
||||
|
@ -241,22 +246,20 @@ class AbstractFormatter:
|
|||
|
||||
def push_style(self, *styles):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
for style in styles:
|
||||
self.style_stack.append(style)
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def pop_style(self, n=1):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.writer.send_flowing_data(' ')
|
||||
del self.style_stack[-n:]
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def assert_line_data(self, flag=1):
|
||||
self.nospace = self.hard_break = not flag
|
||||
self.para_end = self.have_label = 0
|
||||
self.para_end = self.parskip = self.have_label = 0
|
||||
|
||||
|
||||
class NullWriter:
|
||||
|
|
|
@ -106,8 +106,14 @@ def choose_boundary():
|
|||
import socket
|
||||
import os
|
||||
hostid = socket.gethostbyname(socket.gethostname())
|
||||
uid = `os.getuid()`
|
||||
pid = `os.getpid()`
|
||||
try:
|
||||
uid = `os.getuid()`
|
||||
except:
|
||||
uid = '1'
|
||||
try:
|
||||
pid = `os.getpid()`
|
||||
except:
|
||||
pid = '1'
|
||||
seed = `rand.rand()`
|
||||
_prefix = hostid + '.' + uid + '.' + pid
|
||||
timestamp = `int(time.time())`
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
"""Generic MIME writer.
|
||||
|
||||
Classes:
|
||||
|
||||
MimeWriter - the only thing here.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '$Revision$'
|
||||
# $Source$
|
||||
|
||||
|
||||
import string
|
||||
import mimetools
|
||||
|
||||
|
||||
class MimeWriter:
|
||||
|
||||
"""Generic MIME writer.
|
||||
|
||||
Methods:
|
||||
|
||||
__init__()
|
||||
addheader()
|
||||
flushheaders()
|
||||
startbody()
|
||||
startmultipartbody()
|
||||
nextpart()
|
||||
lastpart()
|
||||
|
||||
A MIME writer is much more primitive than a MIME parser. It
|
||||
doesn't seek around on the output file, and it doesn't use large
|
||||
amounts of buffer space, so you have to write the parts in the
|
||||
order they should occur on the output file. It does buffer the
|
||||
headers you add, allowing you to rearrange their order.
|
||||
|
||||
General usage is:
|
||||
|
||||
f = <open the output file>
|
||||
w = MimeWriter(f)
|
||||
...call w.addheader(key, value) 0 or more times...
|
||||
|
||||
followed by either:
|
||||
|
||||
f = w.startbody(content_type)
|
||||
...call f.write(data) for body data...
|
||||
|
||||
or:
|
||||
|
||||
w.startmultipartbody(subtype)
|
||||
for each part:
|
||||
subwriter = w.nextpart()
|
||||
...use the subwriter's methods to create the subpart...
|
||||
w.lastpart()
|
||||
|
||||
The subwriter is another MimeWriter instance, and should be
|
||||
treated in the same way as the toplevel MimeWriter. This way,
|
||||
writing recursive body parts is easy.
|
||||
|
||||
Warning: don't forget to call lastpart()!
|
||||
|
||||
XXX There should be more state so calls made in the wrong order
|
||||
are detected.
|
||||
|
||||
Some special cases:
|
||||
|
||||
- startbody() just returns the file passed to the constructor;
|
||||
but don't use this knowledge, as it may be changed.
|
||||
|
||||
- startmultipartbody() actually returns a file as well;
|
||||
this can be used to write the initial 'if you can read this your
|
||||
mailer is not MIME-aware' message.
|
||||
|
||||
- If you call flushheaders(), the headers accumulated so far are
|
||||
written out (and forgotten); this is useful if you don't need a
|
||||
body part at all, e.g. for a subpart of type message/rfc822
|
||||
that's (mis)used to store some header-like information.
|
||||
|
||||
- Passing a keyword argument 'prefix=<flag>' to addheader(),
|
||||
start*body() affects where the header is inserted; 0 means
|
||||
append at the end, 1 means insert at the start; default is
|
||||
append for addheader(), but insert for start*body(), which use
|
||||
it to determine where the Content-Type header goes.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, fp):
|
||||
self._fp = fp
|
||||
self._headers = []
|
||||
|
||||
def addheader(self, key, value, prefix=0):
|
||||
lines = string.splitfields(value, "\n")
|
||||
while lines and not lines[-1]: del lines[-1]
|
||||
while lines and not lines[0]: del lines[0]
|
||||
for i in range(1, len(lines)):
|
||||
lines[i] = " " + string.strip(lines[i])
|
||||
value = string.joinfields(lines, "\n") + "\n"
|
||||
line = key + ": " + value
|
||||
if prefix:
|
||||
self._headers.insert(0, line)
|
||||
else:
|
||||
self._headers.append(line)
|
||||
|
||||
def flushheaders(self):
|
||||
self._fp.writelines(self._headers)
|
||||
self._headers = []
|
||||
|
||||
def startbody(self, ctype, plist=[], prefix=1):
|
||||
for name, value in plist:
|
||||
ctype = ctype + ';\n %s=\"%s\"' % (name, value)
|
||||
self.addheader("Content-Type", ctype, prefix=prefix)
|
||||
self.flushheaders()
|
||||
self._fp.write("\n")
|
||||
return self._fp
|
||||
|
||||
def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
|
||||
self._boundary = boundary or mimetools.choose_boundary()
|
||||
return self.startbody("multipart/" + subtype,
|
||||
[("boundary", self._boundary)] + plist,
|
||||
prefix=prefix)
|
||||
|
||||
def nextpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "\n")
|
||||
return self.__class__(self._fp)
|
||||
|
||||
def lastpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "--\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "To test the MimeWriter module, run TestMimeWriter.py."
|
|
@ -174,11 +174,15 @@ class _posixfile_:
|
|||
elif len(args) > 3:
|
||||
raise TypeError, 'too many arguments'
|
||||
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd;
|
||||
# additions for AIX by Vladimir.Marangozov@imag.fr
|
||||
import sys, os
|
||||
if sys.platform == 'freebsd2':
|
||||
flock = struct.pack('lxxxxlxxxxlhh', \
|
||||
l_start, l_len, os.getpid(), l_type, l_whence)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
flock = struct.pack('hhlllii', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0, 0)
|
||||
else:
|
||||
flock = struct.pack('hhllhh', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0)
|
||||
|
@ -189,6 +193,9 @@ class _posixfile_:
|
|||
if sys.platform == 'freebsd2':
|
||||
l_start, l_len, l_pid, l_type, l_whence = \
|
||||
struct.unpack('lxxxxlxxxxlhh', flock)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
|
||||
struct.unpack('hhlllii', flock)
|
||||
else:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
|
|
|
@ -53,7 +53,7 @@ def split(p):
|
|||
|
||||
|
||||
# Split a path in root and extension.
|
||||
# The extension is everything starting at the first dot in the last
|
||||
# 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.
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
# Python test set -- math module
|
||||
# XXXX Should not do tests around zero only
|
||||
|
||||
from test_support import *
|
||||
|
||||
eps=1e-5
|
||||
print 'math module, testing with eps', eps
|
||||
import math
|
||||
|
||||
def testit(name, value, expected):
|
||||
if abs(value-expected) > eps:
|
||||
raise TestFailed, '%s returned %f, expected %f'%\
|
||||
(name, value, expected)
|
||||
|
||||
print 'constants'
|
||||
testit('pi', math.pi, 3.1415926)
|
||||
testit('e', math.e, 2.7182818)
|
||||
|
||||
print 'acos'
|
||||
testit('acos(-1)', math.acos(-1), math.pi)
|
||||
testit('acos(0)', math.acos(0), math.pi/2)
|
||||
testit('acos(1)', math.acos(1), 0)
|
||||
|
||||
print 'asin'
|
||||
testit('asin(-1)', math.asin(-1), -math.pi/2)
|
||||
testit('asin(0)', math.asin(0), 0)
|
||||
testit('asin(1)', math.asin(1), math.pi/2)
|
||||
|
||||
print 'atan'
|
||||
testit('atan(-1)', math.atan(-1), -math.pi/4)
|
||||
testit('atan(0)', math.atan(0), 0)
|
||||
testit('atan(1)', math.atan(1), math.pi/4)
|
||||
|
||||
print 'atan2'
|
||||
testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
|
||||
testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
|
||||
testit('atan2(0, 1)', math.atan2(0, 1), 0)
|
||||
testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
|
||||
testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
|
||||
|
||||
print 'ceil'
|
||||
testit('ceil(0.5)', math.ceil(0.5), 1)
|
||||
testit('ceil(1.0)', math.ceil(1.0), 1)
|
||||
testit('ceil(1.5)', math.ceil(1.5), 2)
|
||||
testit('ceil(-0.5)', math.ceil(-0.5), 0)
|
||||
testit('ceil(-1.0)', math.ceil(-1.0), -1)
|
||||
testit('ceil(-1.5)', math.ceil(-1.5), -1)
|
||||
|
||||
print 'cos'
|
||||
testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
|
||||
testit('cos(0)', math.cos(0), 1)
|
||||
testit('cos(pi/2)', math.cos(math.pi/2), 0)
|
||||
testit('cos(pi)', math.cos(math.pi), -1)
|
||||
|
||||
print 'cosh'
|
||||
testit('cosh(0)', math.cosh(0), 1)
|
||||
testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
|
||||
|
||||
print 'exp'
|
||||
testit('exp(-1)', math.exp(-1), 1/math.e)
|
||||
testit('exp(0)', math.exp(0), 1)
|
||||
testit('exp(1)', math.exp(1), math.e)
|
||||
|
||||
print 'fabs'
|
||||
testit('fabs(-1)', math.fabs(-1), 1)
|
||||
testit('fabs(0)', math.fabs(0), 0)
|
||||
testit('fabs(1)', math.fabs(1), 1)
|
||||
|
||||
print 'floor'
|
||||
testit('floor(0.5)', math.floor(0.5), 0)
|
||||
testit('floor(1.0)', math.floor(1.0), 1)
|
||||
testit('floor(1.5)', math.floor(1.5), 1)
|
||||
testit('floor(-0.5)', math.floor(-0.5), -1)
|
||||
testit('floor(-1.0)', math.floor(-1.0), -1)
|
||||
testit('floor(-1.5)', math.floor(-1.5), -2)
|
||||
|
||||
print 'fmod'
|
||||
testit('fmod(10,1)', math.fmod(10,1), 0)
|
||||
testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
|
||||
testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
|
||||
testit('fmod(-10,1)', math.fmod(-10,1), 0)
|
||||
testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
|
||||
testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
|
||||
|
||||
print 'frexp'
|
||||
def testfrexp(name, (mant, exp), (emant, eexp)):
|
||||
if abs(mant-emant) > eps or exp <> eexp:
|
||||
raise TestFailed, '%s returned %s, expected %s'%\
|
||||
(name, `mant, exp`, `emant,eexp`)
|
||||
|
||||
testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
|
||||
testfrexp('frexp(0)', math.frexp(0), (0, 0))
|
||||
testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
|
||||
testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
|
||||
|
||||
print 'hypot'
|
||||
testit('hypot(0,0)', math.hypot(0,0), 0)
|
||||
testit('hypot(3,4)', math.hypot(3,4), 5)
|
||||
|
||||
print 'ldexp'
|
||||
testit('ldexp(0,1)', math.ldexp(0,1), 0)
|
||||
testit('ldexp(1,1)', math.ldexp(1,1), 2)
|
||||
testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
|
||||
testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
|
||||
|
||||
print 'log'
|
||||
testit('log(1/e)', math.log(1/math.e), -1)
|
||||
testit('log(1)', math.log(1), 0)
|
||||
testit('log(e)', math.log(math.e), 1)
|
||||
|
||||
print 'log10'
|
||||
testit('log10(0.1)', math.log10(0.1), -1)
|
||||
testit('log10(1)', math.log10(1), 0)
|
||||
testit('log10(10)', math.log10(10), 1)
|
||||
|
||||
print 'modf'
|
||||
def testmodf(name, (v1, v2), (e1, e2)):
|
||||
if abs(v1-e1) > eps or abs(v2-e2):
|
||||
raise TestFailed, '%s returned %s, expected %s'%\
|
||||
(name, `v1,v2`, `e1,e2`)
|
||||
|
||||
testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
|
||||
testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
|
||||
|
||||
print 'pow'
|
||||
testit('pow(0,1)', math.pow(0,1), 0)
|
||||
testit('pow(1,0)', math.pow(1,0), 1)
|
||||
testit('pow(2,1)', math.pow(2,1), 2)
|
||||
testit('pow(2,-1)', math.pow(2,-1), 0.5)
|
||||
|
||||
print 'sin'
|
||||
testit('sin(0)', math.sin(0), 0)
|
||||
testit('sin(pi/2)', math.sin(math.pi/2), 1)
|
||||
testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
|
||||
|
||||
print 'sinh'
|
||||
testit('sinh(0)', math.sinh(0), 0)
|
||||
testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
|
||||
testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
|
||||
|
||||
print 'sqrt'
|
||||
testit('sqrt(0)', math.sqrt(0), 0)
|
||||
testit('sqrt(1)', math.sqrt(1), 1)
|
||||
testit('sqrt(4)', math.sqrt(4), 2)
|
||||
|
||||
print 'tan'
|
||||
testit('tan(0)', math.tan(0), 0)
|
||||
testit('tan(pi/4)', math.tan(math.pi/4), 1)
|
||||
testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
|
||||
|
||||
print 'tanh'
|
||||
testit('tanh(0)', math.tanh(0), 0)
|
||||
testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
|
|
@ -7,6 +7,25 @@ import types
|
|||
|
||||
def _print(file, str='', terminator='\n'):
|
||||
file.write(str+terminator)
|
||||
|
||||
|
||||
def print_list(extracted_list, file=None):
|
||||
if not file:
|
||||
file = sys.stderr
|
||||
for filename, lineno, name, line in extracted_list:
|
||||
_print(file,
|
||||
' File "%s", line %d, in %s' % (filename,lineno,name))
|
||||
if line:
|
||||
_print(file, ' %s' % string.strip(line))
|
||||
|
||||
def format_list(extracted_list):
|
||||
list = []
|
||||
for filename, lineno, name, line in extracted_list:
|
||||
item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
|
||||
if line:
|
||||
item = item + ' %s\n' % string.strip(line)
|
||||
list.append(item)
|
||||
return list
|
||||
|
||||
|
||||
def print_tb(tb, limit=None, file=None):
|
||||
|
@ -30,13 +49,7 @@ def print_tb(tb, limit=None, file=None):
|
|||
n = n+1
|
||||
|
||||
def format_tb(tb, limit = None):
|
||||
list = []
|
||||
for filename, lineno, name, line in extract_tb(tb, limit):
|
||||
item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
|
||||
if line:
|
||||
item = item + ' %s\n' % string.strip(line)
|
||||
list.append(item)
|
||||
return list
|
||||
return format_list(extract_tb(tb, limit))
|
||||
|
||||
def extract_tb(tb, limit = None):
|
||||
if limit is None:
|
||||
|
@ -123,3 +136,48 @@ def print_last(limit=None, file=None):
|
|||
file = sys.stderr
|
||||
print_exception(sys.last_type, sys.last_value, sys.last_traceback,
|
||||
limit, file)
|
||||
|
||||
|
||||
def print_stack(f=None, limit=None, file=None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
print_list(extract_stack(f, limit), file)
|
||||
|
||||
def format_stack(f=None, limit=None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
return format_list(extract_stack(t, limit))
|
||||
|
||||
def extract_stack(f=None, limit = None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
if limit is None:
|
||||
if hasattr(sys, 'tracebacklimit'):
|
||||
limit = sys.tracebacklimit
|
||||
list = []
|
||||
n = 0
|
||||
while f is not None and (limit is None or n < limit):
|
||||
lineno = f.f_lineno
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
line = linecache.getline(filename, lineno)
|
||||
if line: line = string.strip(line)
|
||||
else: line = None
|
||||
list.append(filename, lineno, name, line)
|
||||
f = f.f_back
|
||||
n = n+1
|
||||
list.reverse()
|
||||
return list
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
"""Object-oriented interface to the parser module.
|
||||
|
||||
This module exports three classes which together provide an interface
|
||||
This module exports four classes which together provide an interface
|
||||
to the parser module. Together, the three classes represent two ways
|
||||
to create parsed representations of Python source and the two starting
|
||||
data types (source text and tuple representations). Each class
|
||||
provides interfaces which are identical other than the constructors.
|
||||
The constructors are described in detail in the documentation for each
|
||||
class and the remaining, shared portion of the interface is documented
|
||||
below. Briefly, the three classes provided are:
|
||||
below. Briefly, the classes provided are:
|
||||
|
||||
AST
|
||||
Defines the primary interface to the AST objects and supports creation
|
||||
|
@ -23,6 +23,9 @@ FileSuiteAST
|
|||
Convenience subclass of the `SuiteAST' class; loads source text of the
|
||||
suite from an external file.
|
||||
|
||||
Common Methods
|
||||
--------------
|
||||
|
||||
Aside from the constructors, several methods are provided to allow
|
||||
access to the various interpretations of the parse tree and to check
|
||||
conditions of the construct represented by the parse tree.
|
||||
|
@ -68,8 +71,8 @@ class AST:
|
|||
This base class provides all of the query methods for subclass
|
||||
objects defined in this module.
|
||||
"""
|
||||
_p = __import__('parser') # import internally to avoid
|
||||
# namespace pollution at the
|
||||
import parser # import internally to avoid
|
||||
_p = parser # namespace pollution at the
|
||||
# top level
|
||||
_text = None
|
||||
_code = None
|
||||
|
@ -84,7 +87,8 @@ class AST:
|
|||
The tuple tree to convert.
|
||||
|
||||
The tuple-tree may represent either an expression or a suite; the
|
||||
type will be determined automatically.
|
||||
type will be determined automatically. Line number information may
|
||||
optionally be present for any subset of the terminal tokens.
|
||||
"""
|
||||
if type(tuple) is not type(()):
|
||||
raise TypeError, 'Base AST class requires tuple parameter.'
|
||||
|
@ -93,11 +97,24 @@ class AST:
|
|||
self._ast = self._p.tuple2ast(tuple)
|
||||
self._type = (self._p.isexpr(self._ast) and 'expression') or 'suite'
|
||||
|
||||
def tuple(self):
|
||||
def list(self, line_info = 0):
|
||||
"""Returns a fresh list representing the parse tree.
|
||||
|
||||
line_info
|
||||
If true, includes line number information for terminal tokens in
|
||||
the output data structure,
|
||||
"""
|
||||
return self._p.ast2list(self._ast, line_info)
|
||||
|
||||
def tuple(self, line_info = 0):
|
||||
"""Returns the tuple representing the parse tree.
|
||||
|
||||
line_info
|
||||
If true, includes line number information for terminal tokens in
|
||||
the output data structure,
|
||||
"""
|
||||
if self._tupl is None:
|
||||
self._tupl = self._p.ast2tuple(self._ast)
|
||||
self._tupl = self._p.ast2tuple(self._ast, line_info)
|
||||
return self._tupl
|
||||
|
||||
def code(self):
|
||||
|
|
|
@ -141,6 +141,7 @@ def _test():
|
|||
return self.sum
|
||||
o = Original()
|
||||
b = Bastion(o)
|
||||
testcode = """if 1:
|
||||
b.add(81)
|
||||
b.add(18)
|
||||
print "b.total() =", b.total()
|
||||
|
@ -156,6 +157,20 @@ def _test():
|
|||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
try:
|
||||
print "b._get_.func_defaults =", b._get_.func_defaults,
|
||||
except:
|
||||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
\n"""
|
||||
exec testcode
|
||||
print '='*20, "Using rexec:", '='*20
|
||||
import rexec
|
||||
r = rexec.RExec()
|
||||
m = r.add_module('__main__')
|
||||
m.b = b
|
||||
r.r_exec(testcode)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -43,7 +43,7 @@ def compile_dir(dir, maxlevels = 10):
|
|||
|
||||
def compile_path(skip_curdir = 1):
|
||||
for dir in sys.path:
|
||||
if dir == os.curdir and skip_curdir:
|
||||
if (not dir or dir == os.curdir) and skip_curdir:
|
||||
print 'Skipping current directory'
|
||||
else:
|
||||
compile_dir(dir, 0)
|
||||
|
|
|
@ -10,7 +10,7 @@ AS_IS = None
|
|||
|
||||
class NullFormatter:
|
||||
|
||||
def __init__(self): pass
|
||||
def __init__(self, writer): pass
|
||||
def end_paragraph(self, blankline): pass
|
||||
def add_line_break(self): pass
|
||||
def add_hor_rule(self, abswidth=None, percentwidth=1.0,
|
||||
|
@ -33,6 +33,11 @@ class NullFormatter:
|
|||
|
||||
class AbstractFormatter:
|
||||
|
||||
# Space handling policy: blank spaces at the boundary between elements
|
||||
# are handled by the outermost context. "Literal" data is not checked
|
||||
# to determine context, so spaces in literal data are handled directly
|
||||
# in all circumstances.
|
||||
|
||||
def __init__(self, writer):
|
||||
self.writer = writer # Output device
|
||||
self.align = None # Current alignment
|
||||
|
@ -162,7 +167,8 @@ class AbstractFormatter:
|
|||
|
||||
def add_literal_data(self, data):
|
||||
if not data: return
|
||||
# Caller is expected to cause flush_softspace() if needed.
|
||||
if self.softspace:
|
||||
self.writer.send_flowing_data(" ")
|
||||
self.hard_break = data[-1:] == '\n'
|
||||
self.nospace = self.para_end = self.softspace = \
|
||||
self.parskip = self.have_label = 0
|
||||
|
@ -170,8 +176,9 @@ class AbstractFormatter:
|
|||
|
||||
def flush_softspace(self):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.parskip = \
|
||||
self.hard_break = self.para_end = self.parskip = \
|
||||
self.have_label = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
|
||||
def push_alignment(self, align):
|
||||
|
@ -194,7 +201,8 @@ class AbstractFormatter:
|
|||
|
||||
def push_font(self, (size, i, b, tt)):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
csize, ci, cb, ctt = self.font_stack[-1]
|
||||
|
@ -207,9 +215,6 @@ class AbstractFormatter:
|
|||
self.writer.new_font(font)
|
||||
|
||||
def pop_font(self):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
del self.font_stack[-1]
|
||||
if self.font_stack:
|
||||
|
@ -241,22 +246,20 @@ class AbstractFormatter:
|
|||
|
||||
def push_style(self, *styles):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
for style in styles:
|
||||
self.style_stack.append(style)
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def pop_style(self, n=1):
|
||||
if self.softspace:
|
||||
self.hard_break = self.nospace = self.para_end = self.softspace = 0
|
||||
self.writer.send_flowing_data(' ')
|
||||
del self.style_stack[-n:]
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def assert_line_data(self, flag=1):
|
||||
self.nospace = self.hard_break = not flag
|
||||
self.para_end = self.have_label = 0
|
||||
self.para_end = self.parskip = self.have_label = 0
|
||||
|
||||
|
||||
class NullWriter:
|
||||
|
|
|
@ -106,8 +106,14 @@ def choose_boundary():
|
|||
import socket
|
||||
import os
|
||||
hostid = socket.gethostbyname(socket.gethostname())
|
||||
uid = `os.getuid()`
|
||||
pid = `os.getpid()`
|
||||
try:
|
||||
uid = `os.getuid()`
|
||||
except:
|
||||
uid = '1'
|
||||
try:
|
||||
pid = `os.getpid()`
|
||||
except:
|
||||
pid = '1'
|
||||
seed = `rand.rand()`
|
||||
_prefix = hostid + '.' + uid + '.' + pid
|
||||
timestamp = `int(time.time())`
|
||||
|
|
|
@ -0,0 +1,131 @@
|
|||
"""Generic MIME writer.
|
||||
|
||||
Classes:
|
||||
|
||||
MimeWriter - the only thing here.
|
||||
|
||||
"""
|
||||
|
||||
__version__ = '$Revision$'
|
||||
# $Source$
|
||||
|
||||
|
||||
import string
|
||||
import mimetools
|
||||
|
||||
|
||||
class MimeWriter:
|
||||
|
||||
"""Generic MIME writer.
|
||||
|
||||
Methods:
|
||||
|
||||
__init__()
|
||||
addheader()
|
||||
flushheaders()
|
||||
startbody()
|
||||
startmultipartbody()
|
||||
nextpart()
|
||||
lastpart()
|
||||
|
||||
A MIME writer is much more primitive than a MIME parser. It
|
||||
doesn't seek around on the output file, and it doesn't use large
|
||||
amounts of buffer space, so you have to write the parts in the
|
||||
order they should occur on the output file. It does buffer the
|
||||
headers you add, allowing you to rearrange their order.
|
||||
|
||||
General usage is:
|
||||
|
||||
f = <open the output file>
|
||||
w = MimeWriter(f)
|
||||
...call w.addheader(key, value) 0 or more times...
|
||||
|
||||
followed by either:
|
||||
|
||||
f = w.startbody(content_type)
|
||||
...call f.write(data) for body data...
|
||||
|
||||
or:
|
||||
|
||||
w.startmultipartbody(subtype)
|
||||
for each part:
|
||||
subwriter = w.nextpart()
|
||||
...use the subwriter's methods to create the subpart...
|
||||
w.lastpart()
|
||||
|
||||
The subwriter is another MimeWriter instance, and should be
|
||||
treated in the same way as the toplevel MimeWriter. This way,
|
||||
writing recursive body parts is easy.
|
||||
|
||||
Warning: don't forget to call lastpart()!
|
||||
|
||||
XXX There should be more state so calls made in the wrong order
|
||||
are detected.
|
||||
|
||||
Some special cases:
|
||||
|
||||
- startbody() just returns the file passed to the constructor;
|
||||
but don't use this knowledge, as it may be changed.
|
||||
|
||||
- startmultipartbody() actually returns a file as well;
|
||||
this can be used to write the initial 'if you can read this your
|
||||
mailer is not MIME-aware' message.
|
||||
|
||||
- If you call flushheaders(), the headers accumulated so far are
|
||||
written out (and forgotten); this is useful if you don't need a
|
||||
body part at all, e.g. for a subpart of type message/rfc822
|
||||
that's (mis)used to store some header-like information.
|
||||
|
||||
- Passing a keyword argument 'prefix=<flag>' to addheader(),
|
||||
start*body() affects where the header is inserted; 0 means
|
||||
append at the end, 1 means insert at the start; default is
|
||||
append for addheader(), but insert for start*body(), which use
|
||||
it to determine where the Content-Type header goes.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, fp):
|
||||
self._fp = fp
|
||||
self._headers = []
|
||||
|
||||
def addheader(self, key, value, prefix=0):
|
||||
lines = string.splitfields(value, "\n")
|
||||
while lines and not lines[-1]: del lines[-1]
|
||||
while lines and not lines[0]: del lines[0]
|
||||
for i in range(1, len(lines)):
|
||||
lines[i] = " " + string.strip(lines[i])
|
||||
value = string.joinfields(lines, "\n") + "\n"
|
||||
line = key + ": " + value
|
||||
if prefix:
|
||||
self._headers.insert(0, line)
|
||||
else:
|
||||
self._headers.append(line)
|
||||
|
||||
def flushheaders(self):
|
||||
self._fp.writelines(self._headers)
|
||||
self._headers = []
|
||||
|
||||
def startbody(self, ctype, plist=[], prefix=1):
|
||||
for name, value in plist:
|
||||
ctype = ctype + ';\n %s=\"%s\"' % (name, value)
|
||||
self.addheader("Content-Type", ctype, prefix=prefix)
|
||||
self.flushheaders()
|
||||
self._fp.write("\n")
|
||||
return self._fp
|
||||
|
||||
def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
|
||||
self._boundary = boundary or mimetools.choose_boundary()
|
||||
return self.startbody("multipart/" + subtype,
|
||||
[("boundary", self._boundary)] + plist,
|
||||
prefix=prefix)
|
||||
|
||||
def nextpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "\n")
|
||||
return self.__class__(self._fp)
|
||||
|
||||
def lastpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "--\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "To test the MimeWriter module, run TestMimeWriter.py."
|
|
@ -174,11 +174,15 @@ class _posixfile_:
|
|||
elif len(args) > 3:
|
||||
raise TypeError, 'too many arguments'
|
||||
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd;
|
||||
# additions for AIX by Vladimir.Marangozov@imag.fr
|
||||
import sys, os
|
||||
if sys.platform == 'freebsd2':
|
||||
flock = struct.pack('lxxxxlxxxxlhh', \
|
||||
l_start, l_len, os.getpid(), l_type, l_whence)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
flock = struct.pack('hhlllii', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0, 0)
|
||||
else:
|
||||
flock = struct.pack('hhllhh', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0)
|
||||
|
@ -189,6 +193,9 @@ class _posixfile_:
|
|||
if sys.platform == 'freebsd2':
|
||||
l_start, l_len, l_pid, l_type, l_whence = \
|
||||
struct.unpack('lxxxxlxxxxlhh', flock)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
|
||||
struct.unpack('hhlllii', flock)
|
||||
else:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
|
|
|
@ -53,7 +53,7 @@ def split(p):
|
|||
|
||||
|
||||
# Split a path in root and extension.
|
||||
# The extension is everything starting at the first dot in the last
|
||||
# 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.
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
# Python test set -- math module
|
||||
# XXXX Should not do tests around zero only
|
||||
|
||||
from test_support import *
|
||||
|
||||
eps=1e-5
|
||||
print 'math module, testing with eps', eps
|
||||
import math
|
||||
|
||||
def testit(name, value, expected):
|
||||
if abs(value-expected) > eps:
|
||||
raise TestFailed, '%s returned %f, expected %f'%\
|
||||
(name, value, expected)
|
||||
|
||||
print 'constants'
|
||||
testit('pi', math.pi, 3.1415926)
|
||||
testit('e', math.e, 2.7182818)
|
||||
|
||||
print 'acos'
|
||||
testit('acos(-1)', math.acos(-1), math.pi)
|
||||
testit('acos(0)', math.acos(0), math.pi/2)
|
||||
testit('acos(1)', math.acos(1), 0)
|
||||
|
||||
print 'asin'
|
||||
testit('asin(-1)', math.asin(-1), -math.pi/2)
|
||||
testit('asin(0)', math.asin(0), 0)
|
||||
testit('asin(1)', math.asin(1), math.pi/2)
|
||||
|
||||
print 'atan'
|
||||
testit('atan(-1)', math.atan(-1), -math.pi/4)
|
||||
testit('atan(0)', math.atan(0), 0)
|
||||
testit('atan(1)', math.atan(1), math.pi/4)
|
||||
|
||||
print 'atan2'
|
||||
testit('atan2(-1, 0)', math.atan2(-1, 0), -math.pi/2)
|
||||
testit('atan2(-1, 1)', math.atan2(-1, 1), -math.pi/4)
|
||||
testit('atan2(0, 1)', math.atan2(0, 1), 0)
|
||||
testit('atan2(1, 1)', math.atan2(1, 1), math.pi/4)
|
||||
testit('atan2(1, 0)', math.atan2(1, 0), math.pi/2)
|
||||
|
||||
print 'ceil'
|
||||
testit('ceil(0.5)', math.ceil(0.5), 1)
|
||||
testit('ceil(1.0)', math.ceil(1.0), 1)
|
||||
testit('ceil(1.5)', math.ceil(1.5), 2)
|
||||
testit('ceil(-0.5)', math.ceil(-0.5), 0)
|
||||
testit('ceil(-1.0)', math.ceil(-1.0), -1)
|
||||
testit('ceil(-1.5)', math.ceil(-1.5), -1)
|
||||
|
||||
print 'cos'
|
||||
testit('cos(-pi/2)', math.cos(-math.pi/2), 0)
|
||||
testit('cos(0)', math.cos(0), 1)
|
||||
testit('cos(pi/2)', math.cos(math.pi/2), 0)
|
||||
testit('cos(pi)', math.cos(math.pi), -1)
|
||||
|
||||
print 'cosh'
|
||||
testit('cosh(0)', math.cosh(0), 1)
|
||||
testit('cosh(2)-2*cosh(1)**2', math.cosh(2)-2*math.cosh(1)**2, -1) # Thanks to Lambert
|
||||
|
||||
print 'exp'
|
||||
testit('exp(-1)', math.exp(-1), 1/math.e)
|
||||
testit('exp(0)', math.exp(0), 1)
|
||||
testit('exp(1)', math.exp(1), math.e)
|
||||
|
||||
print 'fabs'
|
||||
testit('fabs(-1)', math.fabs(-1), 1)
|
||||
testit('fabs(0)', math.fabs(0), 0)
|
||||
testit('fabs(1)', math.fabs(1), 1)
|
||||
|
||||
print 'floor'
|
||||
testit('floor(0.5)', math.floor(0.5), 0)
|
||||
testit('floor(1.0)', math.floor(1.0), 1)
|
||||
testit('floor(1.5)', math.floor(1.5), 1)
|
||||
testit('floor(-0.5)', math.floor(-0.5), -1)
|
||||
testit('floor(-1.0)', math.floor(-1.0), -1)
|
||||
testit('floor(-1.5)', math.floor(-1.5), -2)
|
||||
|
||||
print 'fmod'
|
||||
testit('fmod(10,1)', math.fmod(10,1), 0)
|
||||
testit('fmod(10,0.5)', math.fmod(10,0.5), 0)
|
||||
testit('fmod(10,1.5)', math.fmod(10,1.5), 1)
|
||||
testit('fmod(-10,1)', math.fmod(-10,1), 0)
|
||||
testit('fmod(-10,0.5)', math.fmod(-10,0.5), 0)
|
||||
testit('fmod(-10,1.5)', math.fmod(-10,1.5), -1)
|
||||
|
||||
print 'frexp'
|
||||
def testfrexp(name, (mant, exp), (emant, eexp)):
|
||||
if abs(mant-emant) > eps or exp <> eexp:
|
||||
raise TestFailed, '%s returned %s, expected %s'%\
|
||||
(name, `mant, exp`, `emant,eexp`)
|
||||
|
||||
testfrexp('frexp(-1)', math.frexp(-1), (-0.5, 1))
|
||||
testfrexp('frexp(0)', math.frexp(0), (0, 0))
|
||||
testfrexp('frexp(1)', math.frexp(1), (0.5, 1))
|
||||
testfrexp('frexp(2)', math.frexp(2), (0.5, 2))
|
||||
|
||||
print 'hypot'
|
||||
testit('hypot(0,0)', math.hypot(0,0), 0)
|
||||
testit('hypot(3,4)', math.hypot(3,4), 5)
|
||||
|
||||
print 'ldexp'
|
||||
testit('ldexp(0,1)', math.ldexp(0,1), 0)
|
||||
testit('ldexp(1,1)', math.ldexp(1,1), 2)
|
||||
testit('ldexp(1,-1)', math.ldexp(1,-1), 0.5)
|
||||
testit('ldexp(-1,1)', math.ldexp(-1,1), -2)
|
||||
|
||||
print 'log'
|
||||
testit('log(1/e)', math.log(1/math.e), -1)
|
||||
testit('log(1)', math.log(1), 0)
|
||||
testit('log(e)', math.log(math.e), 1)
|
||||
|
||||
print 'log10'
|
||||
testit('log10(0.1)', math.log10(0.1), -1)
|
||||
testit('log10(1)', math.log10(1), 0)
|
||||
testit('log10(10)', math.log10(10), 1)
|
||||
|
||||
print 'modf'
|
||||
def testmodf(name, (v1, v2), (e1, e2)):
|
||||
if abs(v1-e1) > eps or abs(v2-e2):
|
||||
raise TestFailed, '%s returned %s, expected %s'%\
|
||||
(name, `v1,v2`, `e1,e2`)
|
||||
|
||||
testmodf('modf(1.5)', math.modf(1.5), (0.5, 1.0))
|
||||
testmodf('modf(-1.5)', math.modf(-1.5), (-0.5, -1.0))
|
||||
|
||||
print 'pow'
|
||||
testit('pow(0,1)', math.pow(0,1), 0)
|
||||
testit('pow(1,0)', math.pow(1,0), 1)
|
||||
testit('pow(2,1)', math.pow(2,1), 2)
|
||||
testit('pow(2,-1)', math.pow(2,-1), 0.5)
|
||||
|
||||
print 'sin'
|
||||
testit('sin(0)', math.sin(0), 0)
|
||||
testit('sin(pi/2)', math.sin(math.pi/2), 1)
|
||||
testit('sin(-pi/2)', math.sin(-math.pi/2), -1)
|
||||
|
||||
print 'sinh'
|
||||
testit('sinh(0)', math.sinh(0), 0)
|
||||
testit('sinh(1)**2-cosh(1)**2', math.sinh(1)**2-math.cosh(1)**2, -1)
|
||||
testit('sinh(1)+sinh(-1)', math.sinh(1)+math.sinh(-1), 0)
|
||||
|
||||
print 'sqrt'
|
||||
testit('sqrt(0)', math.sqrt(0), 0)
|
||||
testit('sqrt(1)', math.sqrt(1), 1)
|
||||
testit('sqrt(4)', math.sqrt(4), 2)
|
||||
|
||||
print 'tan'
|
||||
testit('tan(0)', math.tan(0), 0)
|
||||
testit('tan(pi/4)', math.tan(math.pi/4), 1)
|
||||
testit('tan(-pi/4)', math.tan(-math.pi/4), -1)
|
||||
|
||||
print 'tanh'
|
||||
testit('tanh(0)', math.tanh(0), 0)
|
||||
testit('tanh(1)+tanh(-1)', math.tanh(1)+math.tanh(-1), 0)
|
|
@ -7,6 +7,25 @@ import types
|
|||
|
||||
def _print(file, str='', terminator='\n'):
|
||||
file.write(str+terminator)
|
||||
|
||||
|
||||
def print_list(extracted_list, file=None):
|
||||
if not file:
|
||||
file = sys.stderr
|
||||
for filename, lineno, name, line in extracted_list:
|
||||
_print(file,
|
||||
' File "%s", line %d, in %s' % (filename,lineno,name))
|
||||
if line:
|
||||
_print(file, ' %s' % string.strip(line))
|
||||
|
||||
def format_list(extracted_list):
|
||||
list = []
|
||||
for filename, lineno, name, line in extracted_list:
|
||||
item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
|
||||
if line:
|
||||
item = item + ' %s\n' % string.strip(line)
|
||||
list.append(item)
|
||||
return list
|
||||
|
||||
|
||||
def print_tb(tb, limit=None, file=None):
|
||||
|
@ -30,13 +49,7 @@ def print_tb(tb, limit=None, file=None):
|
|||
n = n+1
|
||||
|
||||
def format_tb(tb, limit = None):
|
||||
list = []
|
||||
for filename, lineno, name, line in extract_tb(tb, limit):
|
||||
item = ' File "%s", line %d, in %s\n' % (filename,lineno,name)
|
||||
if line:
|
||||
item = item + ' %s\n' % string.strip(line)
|
||||
list.append(item)
|
||||
return list
|
||||
return format_list(extract_tb(tb, limit))
|
||||
|
||||
def extract_tb(tb, limit = None):
|
||||
if limit is None:
|
||||
|
@ -123,3 +136,48 @@ def print_last(limit=None, file=None):
|
|||
file = sys.stderr
|
||||
print_exception(sys.last_type, sys.last_value, sys.last_traceback,
|
||||
limit, file)
|
||||
|
||||
|
||||
def print_stack(f=None, limit=None, file=None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
print_list(extract_stack(f, limit), file)
|
||||
|
||||
def format_stack(f=None, limit=None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
return format_list(extract_stack(t, limit))
|
||||
|
||||
def extract_stack(f=None, limit = None):
|
||||
if f is None:
|
||||
try:
|
||||
raise ZeroDivisionError
|
||||
except ZeroDivisionError:
|
||||
tb = sys.exc_traceback
|
||||
f = tb.tb_frame.f_back
|
||||
if limit is None:
|
||||
if hasattr(sys, 'tracebacklimit'):
|
||||
limit = sys.tracebacklimit
|
||||
list = []
|
||||
n = 0
|
||||
while f is not None and (limit is None or n < limit):
|
||||
lineno = f.f_lineno
|
||||
co = f.f_code
|
||||
filename = co.co_filename
|
||||
name = co.co_name
|
||||
line = linecache.getline(filename, lineno)
|
||||
if line: line = string.strip(line)
|
||||
else: line = None
|
||||
list.append(filename, lineno, name, line)
|
||||
f = f.f_back
|
||||
n = n+1
|
||||
list.reverse()
|
||||
return list
|
||||
|
|
Loading…
Reference in New Issue