new files
This commit is contained in:
parent
8d2080d043
commit
9a22de101f
|
@ -0,0 +1,275 @@
|
||||||
|
# Complex numbers
|
||||||
|
# ---------------
|
||||||
|
|
||||||
|
# This module represents complex numbers as instances of the class Complex.
|
||||||
|
# A Complex instance z has two data attribues, z.re (the real part) and z.im
|
||||||
|
# (the imaginary part). In fact, z.re and z.im can have any value -- all
|
||||||
|
# arithmetic operators work regardless of the type of z.re and z.im (as long
|
||||||
|
# as they support numerical operations).
|
||||||
|
#
|
||||||
|
# The following functions exist (Complex is actually a class):
|
||||||
|
# Complex([re [,im]) -> creates a complex number from a real and an imaginary part
|
||||||
|
# IsComplex(z) -> true iff z is a complex number (== has .re and .im attributes)
|
||||||
|
# Polar([r [,phi [,fullcircle]]]) ->
|
||||||
|
# the complex number z for which r == z.radius() and phi == z.angle(fullcircle)
|
||||||
|
# (r and phi default to 0)
|
||||||
|
#
|
||||||
|
# Complex numbers have the following methods:
|
||||||
|
# z.abs() -> absolute value of z
|
||||||
|
# z.radius() == z.abs()
|
||||||
|
# z.angle([fullcircle]) -> angle from positive X axis; fullcircle gives units
|
||||||
|
# z.phi([fullcircle]) == z.angle(fullcircle)
|
||||||
|
#
|
||||||
|
# These standard functions and unary operators accept complex arguments:
|
||||||
|
# abs(z)
|
||||||
|
# -z
|
||||||
|
# +z
|
||||||
|
# not z
|
||||||
|
# repr(z) == `z`
|
||||||
|
# str(z)
|
||||||
|
# hash(z) -> a combination of hash(z.re) and hash(z.im) such that if z.im is zero
|
||||||
|
# the result equals hash(z.re)
|
||||||
|
# Note that hex(z) and oct(z) are not defined.
|
||||||
|
#
|
||||||
|
# These conversions accept complex arguments only if their imaginary part is zero:
|
||||||
|
# int(z)
|
||||||
|
# long(z)
|
||||||
|
# float(z)
|
||||||
|
#
|
||||||
|
# The following operators accept two complex numbers, or one complex number
|
||||||
|
# and one real number (int, long or float):
|
||||||
|
# z1 + z2
|
||||||
|
# z1 - z2
|
||||||
|
# z1 * z2
|
||||||
|
# z1 / z2
|
||||||
|
# pow(z1, z2)
|
||||||
|
# cmp(z1, z2)
|
||||||
|
# Note that z1 % z2 and divmod(z1, z2) are not defined,
|
||||||
|
# nor are shift and mask operations.
|
||||||
|
#
|
||||||
|
# The standard module math does not support complex numbers.
|
||||||
|
# (I suppose it would be easy to implement a cmath module.)
|
||||||
|
#
|
||||||
|
# Idea:
|
||||||
|
# add a class Polar(r, phi) and mixed-mode arithmetic which
|
||||||
|
# chooses the most appropriate type for the result:
|
||||||
|
# Complex for +,-,cmp
|
||||||
|
# Polar for *,/,pow
|
||||||
|
|
||||||
|
|
||||||
|
import types, math
|
||||||
|
|
||||||
|
if not hasattr(math, 'hypot'):
|
||||||
|
def hypot(x, y):
|
||||||
|
# XXX I know there's a way to compute this without possibly causing
|
||||||
|
# overflow, but I can't remember what it is right now...
|
||||||
|
return math.sqrt(x*x + y*y)
|
||||||
|
math.hypot = hypot
|
||||||
|
|
||||||
|
twopi = math.pi*2.0
|
||||||
|
halfpi = math.pi/2.0
|
||||||
|
|
||||||
|
def IsComplex(obj):
|
||||||
|
return hasattr(obj, 're') and hasattr(obj, 'im')
|
||||||
|
|
||||||
|
def Polar(r = 0, phi = 0, fullcircle = twopi):
|
||||||
|
phi = phi * (twopi / fullcircle)
|
||||||
|
return Complex(math.cos(phi)*r, math.sin(phi)*r)
|
||||||
|
|
||||||
|
class Complex:
|
||||||
|
|
||||||
|
def __init__(self, re=0, im=0):
|
||||||
|
if IsComplex(re):
|
||||||
|
im = im + re.im
|
||||||
|
re = re.re
|
||||||
|
if IsComplex(im):
|
||||||
|
re = re - im.im
|
||||||
|
im = im.re
|
||||||
|
self.re = re
|
||||||
|
self.im = im
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
if hasattr(self, name):
|
||||||
|
raise TypeError, "Complex numbers have set-once attributes"
|
||||||
|
self.__dict__[name] = value
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if not self.im:
|
||||||
|
return 'Complex(%s)' % `self.re`
|
||||||
|
else:
|
||||||
|
return 'Complex(%s, %s)' % (`self.re`, `self.im`)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if not self.im:
|
||||||
|
return `self.re`
|
||||||
|
else:
|
||||||
|
return 'Complex(%s, %s)' % (`self.re`, `self.im`)
|
||||||
|
|
||||||
|
def __coerce__(self, other):
|
||||||
|
if IsComplex(other):
|
||||||
|
return self, other
|
||||||
|
return self, Complex(other) # May fail
|
||||||
|
|
||||||
|
def __cmp__(self, other):
|
||||||
|
return cmp(self.re, other.re) or cmp(self.im, other.im)
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
if not self.im: return hash(self.re)
|
||||||
|
mod = sys.maxint + 1L
|
||||||
|
return int((hash(self.re) + 2L*hash(self.im) + mod) % (2L*mod) - mod)
|
||||||
|
|
||||||
|
def __neg__(self):
|
||||||
|
return Complex(-self.re, -self.im)
|
||||||
|
|
||||||
|
def __pos__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __abs__(self):
|
||||||
|
return math.hypot(self.re, self.im)
|
||||||
|
##return math.sqrt(self.re*self.re + self.im*self.im)
|
||||||
|
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
if self.im:
|
||||||
|
raise ValueError, "can't convert Complex with nonzero im to int"
|
||||||
|
return int(self.re)
|
||||||
|
|
||||||
|
def __long__(self):
|
||||||
|
if self.im:
|
||||||
|
raise ValueError, "can't convert Complex with nonzero im to long"
|
||||||
|
return long(self.re)
|
||||||
|
|
||||||
|
def __float__(self):
|
||||||
|
if self.im:
|
||||||
|
raise ValueError, "can't convert Complex with nonzero im to float"
|
||||||
|
return float(self.re)
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return not (self.re == self.im == 0)
|
||||||
|
|
||||||
|
abs = radius = __abs__
|
||||||
|
|
||||||
|
def angle(self, fullcircle = twopi):
|
||||||
|
return (fullcircle/twopi) * ((halfpi - math.atan2(self.re, self.im)) % twopi)
|
||||||
|
|
||||||
|
phi = angle
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return Complex(self.re + other.re, self.im + other.im)
|
||||||
|
|
||||||
|
__radd__ = __add__
|
||||||
|
|
||||||
|
def __sub__(self, other):
|
||||||
|
return Complex(self.re - other.re, self.im - other.im)
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return Complex(other.re - self.re, other.im - self.im)
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
return Complex(self.re*other.re - self.im*other.im,
|
||||||
|
self.re*other.im + self.im*other.re)
|
||||||
|
|
||||||
|
__rmul__ = __mul__
|
||||||
|
|
||||||
|
def __div__(self, other):
|
||||||
|
# Deviating from the general principle of not forcing re or im
|
||||||
|
# to be floats, we cast to float here, otherwise division
|
||||||
|
# of Complex numbers with integer re and im parts would use
|
||||||
|
# the (truncating) integer division
|
||||||
|
d = float(other.re*other.re + other.im*other.im)
|
||||||
|
if not d: raise ZeroDivisionError, 'Complex division'
|
||||||
|
return Complex((self.re*other.re + self.im*other.im) / d,
|
||||||
|
(self.im*other.re - self.re*other.im) / d)
|
||||||
|
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return other / self
|
||||||
|
|
||||||
|
def __pow__(self, n, z=None):
|
||||||
|
if z is not None:
|
||||||
|
raise TypeError, 'Complex does not support ternary pow()'
|
||||||
|
if IsComplex(n):
|
||||||
|
if n.im: raise TypeError, 'Complex to the Complex power'
|
||||||
|
n = n.re
|
||||||
|
r = pow(self.abs(), n)
|
||||||
|
phi = n*self.angle()
|
||||||
|
return Complex(math.cos(phi)*r, math.sin(phi)*r)
|
||||||
|
|
||||||
|
def __rpow__(self, base):
|
||||||
|
return pow(base, self)
|
||||||
|
|
||||||
|
|
||||||
|
# Everything below this point is part of the test suite
|
||||||
|
|
||||||
|
def checkop(expr, a, b, value, fuzz = 1e-6):
|
||||||
|
import sys
|
||||||
|
print ' ', a, 'and', b,
|
||||||
|
try:
|
||||||
|
result = eval(expr)
|
||||||
|
except:
|
||||||
|
result = sys.exc_type
|
||||||
|
print '->', result
|
||||||
|
if (type(result) == type('') or type(value) == type('')):
|
||||||
|
ok = result == value
|
||||||
|
else:
|
||||||
|
ok = abs(result - value) <= fuzz
|
||||||
|
if not ok:
|
||||||
|
print '!!\t!!\t!! should be', value, 'diff', abs(result - value)
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
testsuite = {
|
||||||
|
'a+b': [
|
||||||
|
(1, 10, 11),
|
||||||
|
(1, Complex(0,10), Complex(1,10)),
|
||||||
|
(Complex(0,10), 1, Complex(1,10)),
|
||||||
|
(Complex(0,10), Complex(1), Complex(1,10)),
|
||||||
|
(Complex(1), Complex(0,10), Complex(1,10)),
|
||||||
|
],
|
||||||
|
'a-b': [
|
||||||
|
(1, 10, -9),
|
||||||
|
(1, Complex(0,10), Complex(1,-10)),
|
||||||
|
(Complex(0,10), 1, Complex(-1,10)),
|
||||||
|
(Complex(0,10), Complex(1), Complex(-1,10)),
|
||||||
|
(Complex(1), Complex(0,10), Complex(1,-10)),
|
||||||
|
],
|
||||||
|
'a*b': [
|
||||||
|
(1, 10, 10),
|
||||||
|
(1, Complex(0,10), Complex(0, 10)),
|
||||||
|
(Complex(0,10), 1, Complex(0,10)),
|
||||||
|
(Complex(0,10), Complex(1), Complex(0,10)),
|
||||||
|
(Complex(1), Complex(0,10), Complex(0,10)),
|
||||||
|
],
|
||||||
|
'a/b': [
|
||||||
|
(1., 10, 0.1),
|
||||||
|
(1, Complex(0,10), Complex(0, -0.1)),
|
||||||
|
(Complex(0, 10), 1, Complex(0, 10)),
|
||||||
|
(Complex(0, 10), Complex(1), Complex(0, 10)),
|
||||||
|
(Complex(1), Complex(0,10), Complex(0, -0.1)),
|
||||||
|
],
|
||||||
|
'pow(a,b)': [
|
||||||
|
(1, 10, 1),
|
||||||
|
(1, Complex(0,10), 'TypeError'),
|
||||||
|
(Complex(0,10), 1, Complex(0,10)),
|
||||||
|
(Complex(0,10), Complex(1), Complex(0,10)),
|
||||||
|
(Complex(1), Complex(0,10), 'TypeError'),
|
||||||
|
(2, Complex(4,0), 16),
|
||||||
|
],
|
||||||
|
'cmp(a,b)': [
|
||||||
|
(1, 10, -1),
|
||||||
|
(1, Complex(0,10), 1),
|
||||||
|
(Complex(0,10), 1, -1),
|
||||||
|
(Complex(0,10), Complex(1), -1),
|
||||||
|
(Complex(1), Complex(0,10), 1),
|
||||||
|
],
|
||||||
|
}
|
||||||
|
exprs = testsuite.keys()
|
||||||
|
exprs.sort()
|
||||||
|
for expr in exprs:
|
||||||
|
print expr + ':'
|
||||||
|
t = (expr,)
|
||||||
|
for item in testsuite[expr]:
|
||||||
|
apply(checkop, t+item)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
|
@ -0,0 +1,278 @@
|
||||||
|
#!/usr/local/bin/python
|
||||||
|
#
|
||||||
|
# A class for wrapping the WWW Forms Common Gateway Interface (CGI)
|
||||||
|
# Michael McLay, NIST mclay@eeel.nist.gov 6/14/94
|
||||||
|
#
|
||||||
|
# modified by Steve Majewski <sdm7g@Virginia.EDU> 12/5/94
|
||||||
|
#
|
||||||
|
|
||||||
|
# Several classes to parse the name/value pairs that are passed to
|
||||||
|
# a server's CGI by GET, POST or PUT methods by a WWW FORM. This
|
||||||
|
# module is based on Mike McLay's original cgi.py after discussing
|
||||||
|
# changes with him and others on the comp.lang.python newsgroup, and
|
||||||
|
# at the NIST Python workshop.
|
||||||
|
#
|
||||||
|
# The rationale for changes was:
|
||||||
|
# The original FormContent class was almost, but not quite like
|
||||||
|
# a dictionary object. Besides adding some extra access methods,
|
||||||
|
# it had a values() method with different arguments and semantics
|
||||||
|
# from the standard values() method of a mapping object. Also,
|
||||||
|
# it provided several different access methods that may be necessary
|
||||||
|
# or useful, but made it a little more confusing to figure out how
|
||||||
|
# to use. Also, we wanted to make the most typical cases the simplest
|
||||||
|
# and most convenient access methods. ( Most form fields just return
|
||||||
|
# a single value, and in practice, a lot of code was just assuming
|
||||||
|
# a single value and ignoring all others. On the other hand, the
|
||||||
|
# protocol allows multiple values to be returned.
|
||||||
|
#
|
||||||
|
# The new base class (FormContentDict) is just like a dictionary.
|
||||||
|
# In fact, if you just want a dictionary, all of the stuff that was
|
||||||
|
# in __init__ has been extracted into a cgi.parse() function that will
|
||||||
|
# return the "raw" dictionary, but having a class allows you to customize
|
||||||
|
# it further.
|
||||||
|
# Mike McLay's original FormContent class is reimplemented as a
|
||||||
|
# subclass of FormContentDict.
|
||||||
|
# There are two additional sub-classes, but I'm not yet too sure
|
||||||
|
# whether they are what I want.
|
||||||
|
#
|
||||||
|
|
||||||
|
import string,regsub,sys,os,urllib
|
||||||
|
# since os.environ may often be used in cgi code, we name it in this module.
|
||||||
|
from os import environ
|
||||||
|
|
||||||
|
|
||||||
|
def parse():
|
||||||
|
if environ['REQUEST_METHOD'] == 'POST':
|
||||||
|
qs = sys.stdin.read(string.atoi(environ['CONTENT_LENGTH']))
|
||||||
|
environ['QUERY_STRING'] = qs
|
||||||
|
else:
|
||||||
|
qs = environ['QUERY_STRING']
|
||||||
|
name_value_pairs = string.splitfields(qs, '&')
|
||||||
|
dict = {}
|
||||||
|
for name_value in name_value_pairs:
|
||||||
|
nv = string.splitfields(name_value, '=')
|
||||||
|
if len(nv) != 2:
|
||||||
|
continue
|
||||||
|
name = nv[0]
|
||||||
|
value = urllib.unquote(regsub.gsub('+',' ',nv[1]))
|
||||||
|
if len(value):
|
||||||
|
if dict.has_key (name):
|
||||||
|
dict[name].append(value)
|
||||||
|
else:
|
||||||
|
dict[name] = [value]
|
||||||
|
return dict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# The FormContent constructor creates a dictionary from the name/value pairs
|
||||||
|
# passed through the CGI interface.
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# form['key']
|
||||||
|
# form.__getitem__('key')
|
||||||
|
# form.has_key('key')
|
||||||
|
# form.keys()
|
||||||
|
# form.values()
|
||||||
|
# form.items()
|
||||||
|
# form.dict
|
||||||
|
|
||||||
|
class FormContentDict:
|
||||||
|
def __init__( self ):
|
||||||
|
self.dict = parse()
|
||||||
|
self.query_string = environ['QUERY_STRING']
|
||||||
|
def __getitem__(self,key):
|
||||||
|
return self.dict[key]
|
||||||
|
def keys(self):
|
||||||
|
return self.dict.keys()
|
||||||
|
def has_key(self, key):
|
||||||
|
return self.dict.has_key(key)
|
||||||
|
def values(self):
|
||||||
|
return self.dict.values()
|
||||||
|
def items(self):
|
||||||
|
return self.dict.items()
|
||||||
|
def __len__( self ):
|
||||||
|
return len(self.dict)
|
||||||
|
|
||||||
|
|
||||||
|
# This is the "strict" single-value expecting version.
|
||||||
|
# IF you only expect a single value for each field, then form[key]
|
||||||
|
# will return that single value ( the [0]-th ), and raise an
|
||||||
|
# IndexError if that expectation is not true.
|
||||||
|
# IF you expect a field to have possible multiple values, than you
|
||||||
|
# can use form.getlist( key ) to get all of the values.
|
||||||
|
# values() and items() are a compromise: they return single strings
|
||||||
|
# where there is a single value, and lists of strings otherwise.
|
||||||
|
|
||||||
|
class SvFormContentDict(FormContentDict):
|
||||||
|
def __getitem__( self, key ):
|
||||||
|
if len( self.dict[key] ) > 1 :
|
||||||
|
raise IndexError, 'expecting a single value'
|
||||||
|
return self.dict[key][0]
|
||||||
|
def getlist( self, key ):
|
||||||
|
return self.dict[key]
|
||||||
|
def values( self ):
|
||||||
|
lis = []
|
||||||
|
for each in self.dict.values() :
|
||||||
|
if len( each ) == 1 :
|
||||||
|
lis.append( each[0] )
|
||||||
|
else: lis.append( each )
|
||||||
|
return lis
|
||||||
|
def items( self ):
|
||||||
|
lis = []
|
||||||
|
for key,value in self.dict.items():
|
||||||
|
if len(value) == 1 :
|
||||||
|
lis.append( (key,value[0]) )
|
||||||
|
else: lis.append( (key,value) )
|
||||||
|
return lis
|
||||||
|
|
||||||
|
|
||||||
|
# And this sub-class is similar to the above, but it will attempt to
|
||||||
|
# interpret numerical values. This is here as mostly as an example,
|
||||||
|
# but I think the real way to handle typed-data from a form may be
|
||||||
|
# to make an additional table driver parsing stage that has a table
|
||||||
|
# of allowed input patterns and the output conversion types - it
|
||||||
|
# would signal type-errors on parse, not on access.
|
||||||
|
class InterpFormContentDict(SvFormContentDict):
|
||||||
|
def __getitem__( self, key ):
|
||||||
|
v = SvFormContentDict.__getitem__( self, key )
|
||||||
|
if v[0] in string.digits+'+-.' :
|
||||||
|
try: return string.atoi( v )
|
||||||
|
except ValueError:
|
||||||
|
try: return string.atof( v )
|
||||||
|
except ValueError: pass
|
||||||
|
return string.strip(v)
|
||||||
|
def values( self ):
|
||||||
|
lis = []
|
||||||
|
for key in self.keys():
|
||||||
|
try:
|
||||||
|
lis.append( self[key] )
|
||||||
|
except IndexError:
|
||||||
|
lis.append( self.dict[key] )
|
||||||
|
return lis
|
||||||
|
def items( self ):
|
||||||
|
lis = []
|
||||||
|
for key in self.keys():
|
||||||
|
try:
|
||||||
|
lis.append( (key, self[key]) )
|
||||||
|
except IndexError:
|
||||||
|
lis.append( (key, self.dict[key]) )
|
||||||
|
return lis
|
||||||
|
|
||||||
|
|
||||||
|
# class FormContent parses the name/value pairs that are passed to a
|
||||||
|
# server's CGI by GET, POST, or PUT methods by a WWW FORM. several
|
||||||
|
# specialized FormContent dictionary access methods have been added
|
||||||
|
# for convenience.
|
||||||
|
|
||||||
|
# function return value
|
||||||
|
#
|
||||||
|
# form.keys() all keys in dictionary
|
||||||
|
# form.has_key('key') test keys existance
|
||||||
|
# form[key] returns list associated with key
|
||||||
|
# form.values('key') key's list (same as form.[key])
|
||||||
|
# form.indexed_value('key' index) nth element in key's value list
|
||||||
|
# form.value(key) key's unstripped value
|
||||||
|
# form.length(key) number of elements in key's list
|
||||||
|
# form.stripped(key) key's value with whitespace stripped
|
||||||
|
# form.pars() full dictionary
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FormContent(FormContentDict):
|
||||||
|
# This is the original FormContent semantics of values,
|
||||||
|
# not the dictionary like semantics.
|
||||||
|
def values(self,key):
|
||||||
|
if self.dict.has_key(key):return self.dict[key]
|
||||||
|
else: return None
|
||||||
|
def indexed_value(self,key, location):
|
||||||
|
if self.dict.has_key(key):
|
||||||
|
if len (self.dict[key]) > location:
|
||||||
|
return self.dict[key][location]
|
||||||
|
else: return None
|
||||||
|
else: return None
|
||||||
|
def value(self,key):
|
||||||
|
if self.dict.has_key(key):return self.dict[key][0]
|
||||||
|
else: return None
|
||||||
|
def length(self,key):
|
||||||
|
return len (self.dict[key])
|
||||||
|
def stripped(self,key):
|
||||||
|
if self.dict.has_key(key):return string.strip(self.dict[key][0])
|
||||||
|
else: return None
|
||||||
|
def pars(self):
|
||||||
|
return self.dict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def print_environ_usage():
|
||||||
|
print """
|
||||||
|
<H3>These operating system environment variables could have been
|
||||||
|
set:</H3> <UL>
|
||||||
|
<LI>AUTH_TYPE
|
||||||
|
<LI>CONTENT_LENGTH
|
||||||
|
<LI>CONTENT_TYPE
|
||||||
|
<LI>DATE_GMT
|
||||||
|
<LI>DATE_LOCAL
|
||||||
|
<LI>DOCUMENT_NAME
|
||||||
|
<LI>DOCUMENT_ROOT
|
||||||
|
<LI>DOCUMENT_URI
|
||||||
|
<LI>GATEWAY_INTERFACE
|
||||||
|
<LI>LAST_MODIFIED
|
||||||
|
<LI>PATH
|
||||||
|
<LI>PATH_INFO
|
||||||
|
<LI>PATH_TRANSLATED
|
||||||
|
<LI>QUERY_STRING
|
||||||
|
<LI>REMOTE_ADDR
|
||||||
|
<LI>REMOTE_HOST
|
||||||
|
<LI>REMOTE_IDENT
|
||||||
|
<LI>REMOTE_USER
|
||||||
|
<LI>REQUEST_METHOD
|
||||||
|
<LI>SCRIPT_NAME
|
||||||
|
<LI>SERVER_NAME
|
||||||
|
<LI>SERVER_PORT
|
||||||
|
<LI>SERVER_PROTOCOL
|
||||||
|
<LI>SERVER_ROOT
|
||||||
|
<LI>SERVER_SOFTWARE
|
||||||
|
</UL>
|
||||||
|
"""
|
||||||
|
|
||||||
|
def print_environ():
|
||||||
|
skeys = environ.keys()
|
||||||
|
skeys.sort()
|
||||||
|
print '<h3> The following environment variables were set by the CGI script: </H3>'
|
||||||
|
print '<dl>'
|
||||||
|
for key in skeys:
|
||||||
|
print '<dt>',key, '<dd>', environ[key]
|
||||||
|
print '</dl>'
|
||||||
|
|
||||||
|
def print_form( form ):
|
||||||
|
print '<h3> The following name/value pairs were entered in the form:</h3>'
|
||||||
|
print '<dl>'
|
||||||
|
skeys = form.keys()
|
||||||
|
skeys.sort()
|
||||||
|
for key in skeys:
|
||||||
|
print '<dt>',key, ' : <i> ',escape(`type(form[key])`),' </i>','<dd>', form[key]
|
||||||
|
print '</dl>'
|
||||||
|
|
||||||
|
def escape( s ):
|
||||||
|
return regsub.gsub( '<', '<', regsub.gsub( '>' , '>', s ))
|
||||||
|
|
||||||
|
def test( what ):
|
||||||
|
label = escape(str(what))
|
||||||
|
print 'Content-type: text/html\n\n'
|
||||||
|
print '<HEADER>\n<TITLE>' + label + '</TITLE>\n</HEADER>\n'
|
||||||
|
print '<BODY>\n'
|
||||||
|
print "<H1>" + label +"</H1>\n"
|
||||||
|
form = what()
|
||||||
|
print_form( form )
|
||||||
|
print_environ()
|
||||||
|
print_environ_usage()
|
||||||
|
print '</body>'
|
||||||
|
|
||||||
|
if __name__ == '__main__' :
|
||||||
|
test_classes = ( FormContent, FormContentDict, SvFormContentDict, InterpFormContentDict )
|
||||||
|
test( test_classes[0] ) # by default, test compatibility with
|
||||||
|
# old version, change index to test others.
|
|
@ -0,0 +1,35 @@
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import string
|
||||||
|
|
||||||
|
MAXFD = 100 # Max number of file descriptors (os.getdtablesize()???)
|
||||||
|
|
||||||
|
def popen2(cmd):
|
||||||
|
cmd = string.split(cmd)
|
||||||
|
p2cread, p2cwrite = os.pipe()
|
||||||
|
c2pread, c2pwrite = os.pipe()
|
||||||
|
pid = os.fork()
|
||||||
|
if pid == 0:
|
||||||
|
# Child
|
||||||
|
os.close(0)
|
||||||
|
os.close(1)
|
||||||
|
if os.dup(p2cread) <> 0:
|
||||||
|
sys.stderr.write('popen2: bad read dup\n')
|
||||||
|
if os.dup(c2pwrite) <> 1:
|
||||||
|
sys.stderr.write('popen2: bad write dup\n')
|
||||||
|
for i in range(3, MAXFD):
|
||||||
|
try:
|
||||||
|
os.close(i)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
os.execv(cmd[0], cmd)
|
||||||
|
finally:
|
||||||
|
os._exit(1)
|
||||||
|
# Shouldn't come here, I guess
|
||||||
|
os._exit(1)
|
||||||
|
os.close(p2cread)
|
||||||
|
tochild = os.fdopen(p2cwrite, 'w')
|
||||||
|
os.close(c2pwrite)
|
||||||
|
fromchild = os.fdopen(c2pread, 'r')
|
||||||
|
return fromchild, tochild
|
|
@ -0,0 +1,184 @@
|
||||||
|
# Implement restricted execution of Python code
|
||||||
|
|
||||||
|
import __builtin__
|
||||||
|
import new
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import types
|
||||||
|
|
||||||
|
def trace(fmt, *args):
|
||||||
|
if 0:
|
||||||
|
sys.stderr.write(fmt % args + '\n')
|
||||||
|
|
||||||
|
def copydict(src, dst, exceptions = [], only = None):
|
||||||
|
if only is None:
|
||||||
|
for key in src.keys():
|
||||||
|
if key not in exceptions:
|
||||||
|
dst[key] = src[key]
|
||||||
|
else:
|
||||||
|
for key in only:
|
||||||
|
dst[key] = src[key]
|
||||||
|
|
||||||
|
def copymodule(src, dst, exceptions = [], only = None):
|
||||||
|
copydict(src.__dict__, dst.__dict__, exceptions, only)
|
||||||
|
|
||||||
|
safe_path = ['/ufs/guido/lib/python']
|
||||||
|
safe_modules = ['array', 'math', 'regex', 'strop', 'time']
|
||||||
|
unsafe_builtin_names = ['open', 'reload', '__import__',
|
||||||
|
'eval', 'execfile', 'dir', 'vars',
|
||||||
|
'raw_input', 'input']
|
||||||
|
safe_posix_names = ['error', 'fstat', 'listdir', 'lstat', 'readlink', 'stat',
|
||||||
|
'times', 'uname', 'getpid', 'getppid', 'getcwd',
|
||||||
|
'getuid', 'getgid', 'geteuid', 'getegid']
|
||||||
|
|
||||||
|
safe_sys = new.module('sys')
|
||||||
|
safe_sys.modules = {}
|
||||||
|
safe_sys.modules['sys'] = safe_sys
|
||||||
|
safe_sys.path = safe_path[:]
|
||||||
|
safe_sys.argv = ['-']
|
||||||
|
safe_sys.builtin_module_names = safe_modules[:] + ['posix']
|
||||||
|
safe_sys.builtin_module_names.sort()
|
||||||
|
safe_sys.copyright = sys.copyright
|
||||||
|
safe_sys.version = sys.version + ' [restricted mode]'
|
||||||
|
safe_sys.exit = sys.exit
|
||||||
|
|
||||||
|
def new_module(name):
|
||||||
|
safe_sys.modules[name] = m = new.module(name)
|
||||||
|
return m
|
||||||
|
|
||||||
|
safe_builtin = new_module('__builtin__')
|
||||||
|
copymodule(__builtin__, safe_builtin, unsafe_builtin_names)
|
||||||
|
|
||||||
|
safe_main = new_module('__main__')
|
||||||
|
|
||||||
|
safe_posix = new_module('posix')
|
||||||
|
import posix
|
||||||
|
copymodule(posix, safe_posix, None, safe_posix_names)
|
||||||
|
safe_posix.environ = {}
|
||||||
|
copydict(posix.environ, safe_posix.environ)
|
||||||
|
|
||||||
|
safe_types = new_module('types')
|
||||||
|
copymodule(types, safe_types)
|
||||||
|
|
||||||
|
def safe_import(name):
|
||||||
|
if safe_sys.modules.has_key(name):
|
||||||
|
return safe_sys.modules[name]
|
||||||
|
if name in safe_modules:
|
||||||
|
temp = {}
|
||||||
|
exec "import "+name in temp
|
||||||
|
m = new_module(name)
|
||||||
|
copymodule(temp[name], m)
|
||||||
|
return m
|
||||||
|
for dirname in safe_path:
|
||||||
|
filename = os.path.join(dirname, name + '.py')
|
||||||
|
try:
|
||||||
|
f = open(filename, 'r')
|
||||||
|
f.close()
|
||||||
|
except IOError:
|
||||||
|
continue
|
||||||
|
m = new_module(name)
|
||||||
|
rexecfile(filename, m.__dict__)
|
||||||
|
return m
|
||||||
|
raise ImportError, name
|
||||||
|
safe_builtin.__import__ = safe_import
|
||||||
|
|
||||||
|
def safe_open(file, mode = 'r'):
|
||||||
|
if type(file) != types.StringType or type(mode) != types.StringType:
|
||||||
|
raise TypeError, 'open argument(s) must be string(s)'
|
||||||
|
if mode not in ('r', 'rb'):
|
||||||
|
raise IOError, 'open for writing not allowed'
|
||||||
|
if '/' in file:
|
||||||
|
raise IOError, 'open pathname not allowed'
|
||||||
|
return open(file, mode)
|
||||||
|
safe_builtin.open = safe_open
|
||||||
|
|
||||||
|
def safe_dir(object = safe_main):
|
||||||
|
keys = object.__dict__.keys()
|
||||||
|
keys.sort()
|
||||||
|
return keys
|
||||||
|
safe_builtin.dir = safe_dir
|
||||||
|
|
||||||
|
def safe_vars(object = safe_main):
|
||||||
|
keys = safe_dir(object)
|
||||||
|
dict = {}
|
||||||
|
copydict(object.__dict__, dict, None, keys)
|
||||||
|
return dict
|
||||||
|
safe_builtin.vars = safe_vars
|
||||||
|
|
||||||
|
|
||||||
|
def exterior():
|
||||||
|
"""Return env of caller's caller, as triple: (name, locals, globals).
|
||||||
|
|
||||||
|
Name will be None if env is __main__, and locals will be None if same
|
||||||
|
as globals, ie local env is global env."""
|
||||||
|
|
||||||
|
import sys, __main__
|
||||||
|
|
||||||
|
bogus = 'bogus' # A locally usable exception
|
||||||
|
try: raise bogus # Force an exception
|
||||||
|
except bogus:
|
||||||
|
at = sys.exc_traceback.tb_frame.f_back # The external frame.
|
||||||
|
if at.f_back: at = at.f_back # And further, if any.
|
||||||
|
where, globals, locals = at.f_code, at.f_globals, at.f_locals
|
||||||
|
if locals == globals: # Exterior is global?
|
||||||
|
locals = None
|
||||||
|
if where:
|
||||||
|
where = where.co_name
|
||||||
|
return (where, locals, globals)
|
||||||
|
|
||||||
|
|
||||||
|
def rexec(str, globals = None, locals = None):
|
||||||
|
trace('rexec(%s, ...)', `str`)
|
||||||
|
if globals is None:
|
||||||
|
globals = locals = exterior()[2]
|
||||||
|
elif locals is None:
|
||||||
|
locals = globals
|
||||||
|
globals['__builtins__'] = safe_builtin.__dict__
|
||||||
|
safe_sys.stdout = sys.stdout
|
||||||
|
safe_sys.stderr = sys.stderr
|
||||||
|
exec str in globals, locals
|
||||||
|
|
||||||
|
def rexecfile(file, globals = None, locals = None):
|
||||||
|
trace('rexecfile(%s, ...)', `file`)
|
||||||
|
if globals is None:
|
||||||
|
globals = locals = exterior()[2]
|
||||||
|
elif locals is None:
|
||||||
|
locals = globals
|
||||||
|
globals['__builtins__'] = safe_builtin.__dict__
|
||||||
|
safe_sys.stdout = sys.stdout
|
||||||
|
safe_sys.stderr = sys.stderr
|
||||||
|
return execfile(file, globals, locals)
|
||||||
|
|
||||||
|
def reval(str, globals = None, locals = None):
|
||||||
|
trace('reval(%s, ...)', `str`)
|
||||||
|
if globals is None:
|
||||||
|
globals = locals = exterior()[2]
|
||||||
|
elif locals is None:
|
||||||
|
locals = globals
|
||||||
|
globals['__builtins__'] = safe_builtin.__dict__
|
||||||
|
safe_sys.stdout = sys.stdout
|
||||||
|
safe_sys.stderr = sys.stderr
|
||||||
|
return eval(str, globals, locals)
|
||||||
|
safe_builtin.eval = reval
|
||||||
|
|
||||||
|
|
||||||
|
def test():
|
||||||
|
import traceback
|
||||||
|
g = {}
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
s = raw_input('--> ')
|
||||||
|
except EOFError:
|
||||||
|
break
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
c = compile(s, '', 'eval')
|
||||||
|
except:
|
||||||
|
rexec(s, g)
|
||||||
|
else:
|
||||||
|
print reval(c, g)
|
||||||
|
except:
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
test()
|
Loading…
Reference in New Issue