The Usual
This commit is contained in:
parent
0872e05851
commit
d635b1d724
|
@ -3,28 +3,31 @@
|
||||||
This module builds on SimpleHTTPServer by implementing GET and POST
|
This module builds on SimpleHTTPServer by implementing GET and POST
|
||||||
requests to cgi-bin scripts.
|
requests to cgi-bin scripts.
|
||||||
|
|
||||||
If the os.fork() function is not present, this module will not work;
|
If the os.fork() function is not present (e.g. on Windows),
|
||||||
SystemError will be raised instead.
|
os.popen2() is used as a fallback, with slightly altered semantics; if
|
||||||
|
that function is not present either (e.g. on Macintosh), only Python
|
||||||
|
scripts are supported, and they are executed by the current process.
|
||||||
|
|
||||||
|
In all cases, the implementation is intentionally naive -- all
|
||||||
|
requests are executed sychronously.
|
||||||
|
|
||||||
|
SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL
|
||||||
|
-- it may execute arbitrary Python code or external programs.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
__version__ = "0.3"
|
__version__ = "0.4"
|
||||||
|
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
import string
|
import string
|
||||||
import urllib
|
import urllib
|
||||||
import BaseHTTPServer
|
import BaseHTTPServer
|
||||||
import SimpleHTTPServer
|
import SimpleHTTPServer
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
os.fork
|
|
||||||
except AttributeError:
|
|
||||||
raise SystemError, __name__ + " requires os.fork()"
|
|
||||||
|
|
||||||
|
|
||||||
class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
"""Complete HTTP server with GET, HEAD and POST commands.
|
"""Complete HTTP server with GET, HEAD and POST commands.
|
||||||
|
@ -35,6 +38,10 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
# Determine platform specifics
|
||||||
|
have_fork = hasattr(os, 'fork')
|
||||||
|
have_popen2 = hasattr(os, 'popen2')
|
||||||
|
|
||||||
# Make rfile unbuffered -- we need to read one line and then pass
|
# Make rfile unbuffered -- we need to read one line and then pass
|
||||||
# the rest to a subprocess, so we can't use buffered input.
|
# the rest to a subprocess, so we can't use buffered input.
|
||||||
rbufsize = 0
|
rbufsize = 0
|
||||||
|
@ -59,9 +66,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
|
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
|
||||||
|
|
||||||
def is_cgi(self):
|
def is_cgi(self):
|
||||||
"""test whether PATH corresponds to a CGI script.
|
"""Test whether self.path corresponds to a CGI script.
|
||||||
|
|
||||||
Return a tuple (dir, rest) if PATH requires running a
|
Return a tuple (dir, rest) if self.path requires running a
|
||||||
CGI script, None if not. Note that rest begins with a
|
CGI script, None if not. Note that rest begins with a
|
||||||
slash if it is not empty.
|
slash if it is not empty.
|
||||||
|
|
||||||
|
@ -83,6 +90,15 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
|
|
||||||
cgi_directories = ['/cgi-bin', '/htbin']
|
cgi_directories = ['/cgi-bin', '/htbin']
|
||||||
|
|
||||||
|
def is_executable(self, path):
|
||||||
|
"""Test whether argument path is an executable file."""
|
||||||
|
return executable(path)
|
||||||
|
|
||||||
|
def is_python(self, path):
|
||||||
|
"""Test whether argument path is a Python script."""
|
||||||
|
head, tail = os.path.splitext(path)
|
||||||
|
return tail.lower() in (".py", ".pyw")
|
||||||
|
|
||||||
def run_cgi(self):
|
def run_cgi(self):
|
||||||
"""Execute a CGI script."""
|
"""Execute a CGI script."""
|
||||||
dir, rest = self.cgi_info
|
dir, rest = self.cgi_info
|
||||||
|
@ -105,79 +121,152 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
||||||
self.send_error(403, "CGI script is not a plain file (%s)" %
|
self.send_error(403, "CGI script is not a plain file (%s)" %
|
||||||
`scriptname`)
|
`scriptname`)
|
||||||
return
|
return
|
||||||
if not executable(scriptfile):
|
ispy = self.is_python(scriptname)
|
||||||
self.send_error(403, "CGI script is not executable (%s)" %
|
if not ispy:
|
||||||
`scriptname`)
|
if not (self.have_fork or self.have_popen2):
|
||||||
return
|
self.send_error(403, "CGI script is not a Python script (%s)" %
|
||||||
nobody = nobody_uid()
|
`scriptname`)
|
||||||
self.send_response(200, "Script output follows")
|
return
|
||||||
self.wfile.flush() # Always flush before forking
|
if not self.is_executable(scriptfile):
|
||||||
pid = os.fork()
|
self.send_error(403, "CGI script is not executable (%s)" %
|
||||||
if pid != 0:
|
`scriptname`)
|
||||||
# Parent
|
return
|
||||||
pid, sts = os.waitpid(pid, 0)
|
|
||||||
if sts:
|
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
|
||||||
self.log_error("CGI script exit status x%x" % sts)
|
# XXX Much of the following could be prepared ahead of time!
|
||||||
return
|
env = {}
|
||||||
# Child
|
env['SERVER_SOFTWARE'] = self.version_string()
|
||||||
try:
|
env['SERVER_NAME'] = self.server.server_name
|
||||||
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
|
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
|
||||||
# XXX Much of the following could be prepared ahead of time!
|
env['SERVER_PROTOCOL'] = self.protocol_version
|
||||||
env = {}
|
env['SERVER_PORT'] = str(self.server.server_port)
|
||||||
env['SERVER_SOFTWARE'] = self.version_string()
|
env['REQUEST_METHOD'] = self.command
|
||||||
env['SERVER_NAME'] = self.server.server_name
|
uqrest = urllib.unquote(rest)
|
||||||
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
|
env['PATH_INFO'] = uqrest
|
||||||
env['SERVER_PROTOCOL'] = self.protocol_version
|
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
|
||||||
env['SERVER_PORT'] = str(self.server.server_port)
|
env['SCRIPT_NAME'] = scriptname
|
||||||
env['REQUEST_METHOD'] = self.command
|
if query:
|
||||||
uqrest = urllib.unquote(rest)
|
env['QUERY_STRING'] = query
|
||||||
env['PATH_INFO'] = uqrest
|
host = self.address_string()
|
||||||
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
|
if host != self.client_address[0]:
|
||||||
env['SCRIPT_NAME'] = scriptname
|
env['REMOTE_HOST'] = host
|
||||||
if query:
|
env['REMOTE_ADDR'] = self.client_address[0]
|
||||||
env['QUERY_STRING'] = query
|
# XXX AUTH_TYPE
|
||||||
host = self.address_string()
|
# XXX REMOTE_USER
|
||||||
if host != self.client_address[0]:
|
# XXX REMOTE_IDENT
|
||||||
env['REMOTE_HOST'] = host
|
if self.headers.typeheader is None:
|
||||||
env['REMOTE_ADDR'] = self.client_address[0]
|
env['CONTENT_TYPE'] = self.headers.type
|
||||||
# AUTH_TYPE
|
else:
|
||||||
# REMOTE_USER
|
env['CONTENT_TYPE'] = self.headers.typeheader
|
||||||
# REMOTE_IDENT
|
length = self.headers.getheader('content-length')
|
||||||
if self.headers.typeheader is None:
|
if length:
|
||||||
env['CONTENT_TYPE'] = self.headers.type
|
env['CONTENT_LENGTH'] = length
|
||||||
|
accept = []
|
||||||
|
for line in self.headers.getallmatchingheaders('accept'):
|
||||||
|
if line[:1] in string.whitespace:
|
||||||
|
accept.append(string.strip(line))
|
||||||
else:
|
else:
|
||||||
env['CONTENT_TYPE'] = self.headers.typeheader
|
accept = accept + string.split(line[7:], ',')
|
||||||
length = self.headers.getheader('content-length')
|
env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
|
||||||
if length:
|
ua = self.headers.getheader('user-agent')
|
||||||
env['CONTENT_LENGTH'] = length
|
if ua:
|
||||||
accept = []
|
env['HTTP_USER_AGENT'] = ua
|
||||||
for line in self.headers.getallmatchingheaders('accept'):
|
co = filter(None, self.headers.getheaders('cookie'))
|
||||||
if line[:1] in string.whitespace:
|
if co:
|
||||||
accept.append(string.strip(line))
|
env['HTTP_COOKIE'] = string.join(co, ', ')
|
||||||
else:
|
# XXX Other HTTP_* headers
|
||||||
accept = accept + string.split(line[7:], ',')
|
if not self.have_fork:
|
||||||
env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
|
# Since we're setting the env in the parent, provide empty
|
||||||
ua = self.headers.getheader('user-agent')
|
# values to override previously set values
|
||||||
if ua:
|
for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
|
||||||
env['HTTP_USER_AGENT'] = ua
|
'HTTP_USER_AGENT', 'HTTP_COOKIE'):
|
||||||
co = filter(None, self.headers.getheaders('cookie'))
|
env.setdefault(k, "")
|
||||||
if co:
|
|
||||||
env['HTTP_COOKIE'] = string.join(co, ', ')
|
self.send_response(200, "Script output follows")
|
||||||
# XXX Other HTTP_* headers
|
|
||||||
decoded_query = string.replace(query, '+', ' ')
|
decoded_query = string.replace(query, '+', ' ')
|
||||||
|
|
||||||
|
if self.have_fork:
|
||||||
|
# Unix -- fork as we should
|
||||||
|
args = [script]
|
||||||
|
if '=' not in decoded_query:
|
||||||
|
args.append(decoded_query)
|
||||||
|
nobody = nobody_uid()
|
||||||
|
self.wfile.flush() # Always flush before forking
|
||||||
|
pid = os.fork()
|
||||||
|
if pid != 0:
|
||||||
|
# Parent
|
||||||
|
pid, sts = os.waitpid(pid, 0)
|
||||||
|
if sts:
|
||||||
|
self.log_error("CGI script exit status %#x", sts)
|
||||||
|
return
|
||||||
|
# Child
|
||||||
try:
|
try:
|
||||||
os.setuid(nobody)
|
try:
|
||||||
except os.error:
|
os.setuid(nobody)
|
||||||
pass
|
except os.error:
|
||||||
os.dup2(self.rfile.fileno(), 0)
|
pass
|
||||||
os.dup2(self.wfile.fileno(), 1)
|
os.dup2(self.rfile.fileno(), 0)
|
||||||
print scriptfile, script, decoded_query
|
os.dup2(self.wfile.fileno(), 1)
|
||||||
os.execve(scriptfile,
|
os.execve(scriptfile, args, env)
|
||||||
[script, decoded_query],
|
except:
|
||||||
env)
|
self.server.handle_error(self.request, self.client_address)
|
||||||
except:
|
os._exit(127)
|
||||||
self.server.handle_error(self.request, self.client_address)
|
|
||||||
os._exit(127)
|
elif self.have_popen2:
|
||||||
|
# Windows -- use popen2 to create a subprocess
|
||||||
|
import shutil
|
||||||
|
os.environ.update(env)
|
||||||
|
cmdline = scriptfile
|
||||||
|
if self.is_python(scriptfile):
|
||||||
|
interp = sys.executable
|
||||||
|
if interp.lower().endswith("w.exe"):
|
||||||
|
# On Windows, use python.exe, not python.exe
|
||||||
|
interp = interp[:-5] = interp[-4:]
|
||||||
|
cmdline = "%s %s" % (interp, cmdline)
|
||||||
|
if '=' not in query and '"' not in query:
|
||||||
|
cmdline = '%s "%s"' % (cmdline, query)
|
||||||
|
self.log_error("command: %s", cmdline)
|
||||||
|
try:
|
||||||
|
nbytes = int(length)
|
||||||
|
except:
|
||||||
|
nbytes = 0
|
||||||
|
fi, fo = os.popen2(cmdline)
|
||||||
|
if self.command.lower() == "post" and nbytes > 0:
|
||||||
|
data = self.rfile.read(nbytes)
|
||||||
|
fi.write(data)
|
||||||
|
fi.close()
|
||||||
|
shutil.copyfileobj(fo, self.wfile)
|
||||||
|
sts = fo.close()
|
||||||
|
if sts:
|
||||||
|
self.log_error("CGI script exit status %#x", sts)
|
||||||
|
else:
|
||||||
|
self.log_error("CGI script exited OK")
|
||||||
|
|
||||||
|
else:
|
||||||
|
# Other O.S. -- execute script in this process
|
||||||
|
os.environ.update(env)
|
||||||
|
save_argv = sys.argv
|
||||||
|
save_stdin = sys.stdin
|
||||||
|
save_stdout = sys.stdout
|
||||||
|
save_stderr = sys.stderr
|
||||||
|
try:
|
||||||
|
try:
|
||||||
|
sys.argv = [scriptfile]
|
||||||
|
if '=' not in decoded_query:
|
||||||
|
sys.argv.append(decoded_query)
|
||||||
|
sys.stdout = self.wfile
|
||||||
|
sys.stdin = self.rfile
|
||||||
|
execfile(scriptfile, {"__name__": "__main__"})
|
||||||
|
finally:
|
||||||
|
sys.argv = save_argv
|
||||||
|
sys.stdin = save_stdin
|
||||||
|
sys.stdout = save_stdout
|
||||||
|
sys.stderr = save_stderr
|
||||||
|
except SystemExit, sts:
|
||||||
|
self.log_error("CGI script exit status %s", str(sts))
|
||||||
|
else:
|
||||||
|
self.log_error("CGI script exited OK")
|
||||||
|
|
||||||
|
|
||||||
nobody = None
|
nobody = None
|
||||||
|
@ -187,7 +276,10 @@ def nobody_uid():
|
||||||
global nobody
|
global nobody
|
||||||
if nobody:
|
if nobody:
|
||||||
return nobody
|
return nobody
|
||||||
import pwd
|
try:
|
||||||
|
import pwd
|
||||||
|
except ImportError:
|
||||||
|
return -1
|
||||||
try:
|
try:
|
||||||
nobody = pwd.getpwnam('nobody')[2]
|
nobody = pwd.getpwnam('nobody')[2]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
|
|
@ -440,7 +440,7 @@ class ConfigParser:
|
||||||
# allow empty values
|
# allow empty values
|
||||||
if optval == '""':
|
if optval == '""':
|
||||||
optval = ''
|
optval = ''
|
||||||
cursect[optname] = optval
|
cursect[self.optionxform(optname)] = optval
|
||||||
else:
|
else:
|
||||||
# a non-fatal parsing error occurred. set up the
|
# a non-fatal parsing error occurred. set up the
|
||||||
# exception but keep going. the exception will be
|
# exception but keep going. the exception will be
|
||||||
|
|
|
@ -67,9 +67,6 @@ class _posixfile_:
|
||||||
(self.states[file.closed], file.name, file.mode, \
|
(self.states[file.closed], file.name, file.mode, \
|
||||||
hex(id(self))[2:])
|
hex(id(self))[2:])
|
||||||
|
|
||||||
def __del__(self):
|
|
||||||
self._file_.close()
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Initialization routines
|
# Initialization routines
|
||||||
#
|
#
|
||||||
|
|
|
@ -48,6 +48,11 @@ def compile(file, cfile=None, dfile=None):
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
timestamp = long(os.stat(file)[8])
|
timestamp = long(os.stat(file)[8])
|
||||||
codestring = f.read()
|
codestring = f.read()
|
||||||
|
# If parsing from a string, line breaks are \n (see parsetok.c:tok_nextc)
|
||||||
|
# Replace will return original string if pattern is not found, so
|
||||||
|
# we don't need to check whether it is found first.
|
||||||
|
codestring = codestring.replace("\r\n","\n")
|
||||||
|
codestring = codestring.replace("\r","\n")
|
||||||
f.close()
|
f.close()
|
||||||
if codestring and codestring[-1] != '\n':
|
if codestring and codestring[-1] != '\n':
|
||||||
codestring = codestring + '\n'
|
codestring = codestring + '\n'
|
||||||
|
|
|
@ -634,7 +634,7 @@ def parse_template(source, pattern):
|
||||||
while 1:
|
while 1:
|
||||||
group = _group(this, pattern.groups+1)
|
group = _group(this, pattern.groups+1)
|
||||||
if group:
|
if group:
|
||||||
if (not s.next or
|
if (s.next not in DIGITS or
|
||||||
not _group(this + s.next, pattern.groups+1)):
|
not _group(this + s.next, pattern.groups+1)):
|
||||||
code = MARK, int(group)
|
code = MARK, int(group)
|
||||||
break
|
break
|
||||||
|
|
|
@ -91,11 +91,15 @@ class StringIO:
|
||||||
r = self.buf[self.pos:newpos]
|
r = self.buf[self.pos:newpos]
|
||||||
self.pos = newpos
|
self.pos = newpos
|
||||||
return r
|
return r
|
||||||
def readlines(self):
|
def readlines(self, sizehint = 0):
|
||||||
|
total = 0
|
||||||
lines = []
|
lines = []
|
||||||
line = self.readline()
|
line = self.readline()
|
||||||
while line:
|
while line:
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
|
total += len(line)
|
||||||
|
if 0 < sizehint <= total:
|
||||||
|
break
|
||||||
line = self.readline()
|
line = self.readline()
|
||||||
return lines
|
return lines
|
||||||
def write(self, s):
|
def write(self, s):
|
||||||
|
|
|
@ -122,9 +122,14 @@ def testtype(type, example):
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
x = a.pop()
|
||||||
|
if x != 'e':
|
||||||
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
if a != array.array(type, "acd"):
|
if a != array.array(type, "acd"):
|
||||||
raise TestFailed, "array(%s) pop-test" % `type`
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
|
a.reverse()
|
||||||
|
if a != array.array(type, "dca"):
|
||||||
|
raise TestFailed, "array(%s) reverse-test" % `type`
|
||||||
else:
|
else:
|
||||||
a = array.array(type, [1, 2, 3, 4, 5])
|
a = array.array(type, [1, 2, 3, 4, 5])
|
||||||
a[:-1] = a
|
a[:-1] = a
|
||||||
|
@ -155,9 +160,14 @@ def testtype(type, example):
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
a.pop()
|
||||||
a.pop()
|
x = a.pop()
|
||||||
|
if x != 5:
|
||||||
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
if a != array.array(type, [1, 3, 4]):
|
if a != array.array(type, [1, 3, 4]):
|
||||||
raise TestFailed, "array(%s) pop-test" % `type`
|
raise TestFailed, "array(%s) pop-test" % `type`
|
||||||
|
a.reverse()
|
||||||
|
if a != array.array(type, [4, 3, 1]):
|
||||||
|
raise TestFailed, "array(%s) reverse-test" % `type`
|
||||||
|
|
||||||
# test that overflow exceptions are raised as expected for assignment
|
# test that overflow exceptions are raised as expected for assignment
|
||||||
# to array of specific integral types
|
# to array of specific integral types
|
||||||
|
|
|
@ -1,107 +1,5 @@
|
||||||
# Test the cPickle module
|
# Test the cPickle module
|
||||||
|
|
||||||
DATA = """(lp0
|
|
||||||
I0
|
|
||||||
aL1L
|
|
||||||
aF2.0
|
|
||||||
ac__builtin__
|
|
||||||
complex
|
|
||||||
p1
|
|
||||||
(F3.0
|
|
||||||
F0.0
|
|
||||||
tp2
|
|
||||||
Rp3
|
|
||||||
a(S'abc'
|
|
||||||
p4
|
|
||||||
g4
|
|
||||||
(i__main__
|
|
||||||
C
|
|
||||||
p5
|
|
||||||
(dp6
|
|
||||||
S'foo'
|
|
||||||
p7
|
|
||||||
I1
|
|
||||||
sS'bar'
|
|
||||||
p8
|
|
||||||
I2
|
|
||||||
sbg5
|
|
||||||
tp9
|
|
||||||
ag9
|
|
||||||
aI5
|
|
||||||
a.
|
|
||||||
"""
|
|
||||||
|
|
||||||
BINDATA = ']q\000(K\000L1L\012G@\000\000\000\000\000\000\000c__builtin__\012complex\012q\001(G@\010\000\000\000\000\000\000G\000\000\000\000\000\000\000\000tq\002Rq\003(U\003abcq\004h\004(c__main__\012C\012q\005oq\006}q\007(U\003fooq\010K\001U\003barq\011K\002ubh\006tq\012h\012K\005e.'
|
|
||||||
|
|
||||||
import cPickle
|
import cPickle
|
||||||
|
import test_pickle
|
||||||
class C:
|
test_pickle.dotest(cPickle)
|
||||||
def __cmp__(self, other):
|
|
||||||
return cmp(self.__dict__, other.__dict__)
|
|
||||||
|
|
||||||
import __main__
|
|
||||||
__main__.C = C
|
|
||||||
|
|
||||||
def dotest():
|
|
||||||
c = C()
|
|
||||||
c.foo = 1
|
|
||||||
c.bar = 2
|
|
||||||
x = [0, 1L, 2.0, 3.0+0j]
|
|
||||||
y = ('abc', 'abc', c, c)
|
|
||||||
x.append(y)
|
|
||||||
x.append(y)
|
|
||||||
x.append(5)
|
|
||||||
print "dumps()"
|
|
||||||
s = cPickle.dumps(x)
|
|
||||||
print "loads()"
|
|
||||||
x2 = cPickle.loads(s)
|
|
||||||
if x2 == x: print "ok"
|
|
||||||
else: print "bad"
|
|
||||||
print "loads() DATA"
|
|
||||||
x2 = cPickle.loads(DATA)
|
|
||||||
if x2 == x: print "ok"
|
|
||||||
else: print "bad"
|
|
||||||
print "dumps() binary"
|
|
||||||
s = cPickle.dumps(x, 1)
|
|
||||||
print "loads() binary"
|
|
||||||
x2 = cPickle.loads(s)
|
|
||||||
if x2 == x: print "ok"
|
|
||||||
else: print "bad"
|
|
||||||
print "loads() BINDATA"
|
|
||||||
x2 = cPickle.loads(BINDATA)
|
|
||||||
if x2 == x: print "ok"
|
|
||||||
else: print "bad"
|
|
||||||
|
|
||||||
# Test protection against closed files
|
|
||||||
import tempfile, os
|
|
||||||
fn = tempfile.mktemp()
|
|
||||||
f = open(fn, "w")
|
|
||||||
f.close()
|
|
||||||
try:
|
|
||||||
cPickle.dump(123, f)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print "dump to closed file should raise ValueError"
|
|
||||||
f = open(fn, "r")
|
|
||||||
f.close()
|
|
||||||
try:
|
|
||||||
cPickle.load(f)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
print "load from closed file should raise ValueError"
|
|
||||||
os.remove(fn)
|
|
||||||
|
|
||||||
# Test specific bad cases
|
|
||||||
for i in range(10):
|
|
||||||
try:
|
|
||||||
x = cPickle.loads('garyp')
|
|
||||||
except cPickle.BadPickleGet, y:
|
|
||||||
del y
|
|
||||||
else:
|
|
||||||
print "unexpected success!"
|
|
||||||
break
|
|
||||||
|
|
||||||
|
|
||||||
dotest()
|
|
||||||
|
|
|
@ -86,6 +86,55 @@ r(SyntaxError)
|
||||||
try: exec '/\n'
|
try: exec '/\n'
|
||||||
except SyntaxError: pass
|
except SyntaxError: pass
|
||||||
|
|
||||||
|
# make sure the right exception message is raised for each of these
|
||||||
|
# code fragments:
|
||||||
|
|
||||||
|
def ckmsg(src, msg):
|
||||||
|
try:
|
||||||
|
compile(src, '<fragment>', 'exec')
|
||||||
|
except SyntaxError, e:
|
||||||
|
print e.msg
|
||||||
|
if e.msg == msg:
|
||||||
|
print "ok"
|
||||||
|
else:
|
||||||
|
print "expected:", msg
|
||||||
|
else:
|
||||||
|
print "failed to get expected SyntaxError"
|
||||||
|
|
||||||
|
s = '''\
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
'''
|
||||||
|
ckmsg(s, "'continue' not supported inside 'try' clause")
|
||||||
|
s = '''\
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
continue
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
'''
|
||||||
|
ckmsg(s, "'continue' not supported inside 'try' clause")
|
||||||
|
s = '''\
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
if 1:
|
||||||
|
continue
|
||||||
|
finally:
|
||||||
|
pass
|
||||||
|
'''
|
||||||
|
ckmsg(s, "'continue' not supported inside 'try' clause")
|
||||||
|
s = '''\
|
||||||
|
try:
|
||||||
|
continue
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
'''
|
||||||
|
ckmsg(s, "'continue' not properly in loop")
|
||||||
|
ckmsg("continue\n", "'continue' not properly in loop")
|
||||||
|
|
||||||
r(IndentationError)
|
r(IndentationError)
|
||||||
|
|
||||||
r(TabError)
|
r(TabError)
|
||||||
|
|
|
@ -21,7 +21,7 @@ if sys.platform in ('netbsd1',
|
||||||
'bsdos2', 'bsdos3', 'bsdos4',
|
'bsdos2', 'bsdos3', 'bsdos4',
|
||||||
'openbsd', 'openbsd2'):
|
'openbsd', 'openbsd2'):
|
||||||
lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
|
lockdata = struct.pack('lxxxxlxxxxlhh', 0, 0, 0, FCNTL.F_WRLCK, 0)
|
||||||
elif sys.platform in ['aix3', 'aix4']:
|
elif sys.platform in ['aix3', 'aix4', 'hp-uxB']:
|
||||||
lockdata = struct.pack('hhlllii', FCNTL.F_WRLCK, 0, 0, 0, 0, 0, 0)
|
lockdata = struct.pack('hhlllii', FCNTL.F_WRLCK, 0, 0, 0, 0, 0, 0)
|
||||||
else:
|
else:
|
||||||
lockdata = struct.pack('hhllhh', FCNTL.F_WRLCK, 0, 0, 0, 0, 0)
|
lockdata = struct.pack('hhllhh', FCNTL.F_WRLCK, 0, 0, 0, 0, 0)
|
||||||
|
|
|
@ -355,6 +355,13 @@ def f():
|
||||||
del z
|
del z
|
||||||
exec 'z=1+1'
|
exec 'z=1+1'
|
||||||
if z <> 2: raise TestFailed, 'exec \'z=1+1\''
|
if z <> 2: raise TestFailed, 'exec \'z=1+1\''
|
||||||
|
z = None
|
||||||
|
del z
|
||||||
|
exec u'z=1+1\n'
|
||||||
|
if z <> 2: raise TestFailed, 'exec u\'z=1+1\'\\n'
|
||||||
|
del z
|
||||||
|
exec u'z=1+1'
|
||||||
|
if z <> 2: raise TestFailed, 'exec u\'z=1+1\''
|
||||||
f()
|
f()
|
||||||
g = {}
|
g = {}
|
||||||
exec 'z = 1' in g
|
exec 'z = 1' in g
|
||||||
|
|
|
@ -5,6 +5,7 @@ from xml.dom.minidom import parse, Node, Document, parseString
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
|
from test_support import verbose
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
base = sys.argv[0]
|
base = sys.argv[0]
|
||||||
|
@ -13,15 +14,28 @@ else:
|
||||||
tstfile = os.path.join(os.path.dirname(base), "test.xml")
|
tstfile = os.path.join(os.path.dirname(base), "test.xml")
|
||||||
del base
|
del base
|
||||||
|
|
||||||
|
def confirm( test, testname="Test" ):
|
||||||
|
if test:
|
||||||
|
print "Passed " + testname
|
||||||
|
else:
|
||||||
|
print "Failed " + testname
|
||||||
|
raise Exception
|
||||||
|
|
||||||
Node._debug=1
|
Node._debug=1
|
||||||
|
|
||||||
|
def testParseFromFile():
|
||||||
|
from StringIO import StringIO
|
||||||
|
dom=parse( StringIO( open( tstfile ).read() ) )
|
||||||
|
dom.unlink()
|
||||||
|
confirm(isinstance(dom,Document))
|
||||||
|
|
||||||
def testGetElementsByTagName( ):
|
def testGetElementsByTagName( ):
|
||||||
dom=parse( tstfile )
|
dom=parse( tstfile )
|
||||||
assert dom.getElementsByTagName( "LI" )==\
|
confirm( dom.getElementsByTagName( "LI" )==\
|
||||||
dom.documentElement.getElementsByTagName( "LI" )
|
dom.documentElement.getElementsByTagName( "LI" ) )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert( len( Node.allnodes ))==0
|
confirm (len( Node.allnodes )==0)
|
||||||
|
|
||||||
def testInsertBefore( ):
|
def testInsertBefore( ):
|
||||||
dom=parse( tstfile )
|
dom=parse( tstfile )
|
||||||
|
@ -32,44 +46,44 @@ def testInsertBefore( ):
|
||||||
#docel.insertBefore( dom.createProcessingInstruction("a", "b"),
|
#docel.insertBefore( dom.createProcessingInstruction("a", "b"),
|
||||||
# docel.childNodes[0])
|
# docel.childNodes[0])
|
||||||
|
|
||||||
#assert docel.childNodes[0].target=="a"
|
#confirm( docel.childNodes[0].tet=="a" )
|
||||||
#assert docel.childNodes[2].target=="a"
|
#confirm( docel.childNodes[2].tet=="a" )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
del dom
|
del dom
|
||||||
del docel
|
del docel
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0)
|
||||||
|
|
||||||
def testAppendChild():
|
def testAppendChild():
|
||||||
dom=parse( tstfile )
|
dom=parse( tstfile )
|
||||||
dom.documentElement.appendChild( dom.createComment( u"Hello" ))
|
dom.documentElement.appendChild( dom.createComment( u"Hello" ))
|
||||||
assert dom.documentElement.childNodes[-1].nodeName=="#comment"
|
confirm( dom.documentElement.childNodes[-1].nodeName=="#comment" )
|
||||||
assert dom.documentElement.childNodes[-1].data=="Hello"
|
confirm( dom.documentElement.childNodes[-1].data=="Hello" )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testNonZero():
|
def testNonZero():
|
||||||
dom=parse( tstfile )
|
dom=parse( tstfile )
|
||||||
assert dom # should not be zero
|
confirm( dom )# should not be zero
|
||||||
dom.appendChild( dom.createComment( "foo" ) )
|
dom.appendChild( dom.createComment( "foo" ) )
|
||||||
assert not dom.childNodes[-1].childNodes
|
confirm( not dom.childNodes[-1].childNodes )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testUnlink():
|
def testUnlink():
|
||||||
dom=parse( tstfile )
|
dom=parse( tstfile )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testElement():
|
def testElement():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
dom.appendChild( dom.createElement( "abc" ) )
|
dom.appendChild( dom.createElement( "abc" ) )
|
||||||
assert dom.documentElement
|
confirm( dom.documentElement )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testAAA():
|
def testAAA():
|
||||||
dom=parseString( "<abc/>" )
|
dom=parseString( "<abc/>" )
|
||||||
|
@ -91,20 +105,20 @@ def testAddAttr():
|
||||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||||
|
|
||||||
child.setAttribute( "def", "ghi" )
|
child.setAttribute( "def", "ghi" )
|
||||||
assert child.getAttribute( "def" )=="ghi"
|
confirm( child.getAttribute( "def" )=="ghi" )
|
||||||
assert child.attributes["def"].value=="ghi"
|
confirm( child.attributes["def"].value=="ghi" )
|
||||||
|
|
||||||
child.setAttribute( "jkl", "mno" )
|
child.setAttribute( "jkl", "mno" )
|
||||||
assert child.getAttribute( "jkl" )=="mno"
|
confirm( child.getAttribute( "jkl" )=="mno" )
|
||||||
assert child.attributes["jkl"].value=="mno"
|
confirm( child.attributes["jkl"].value=="mno" )
|
||||||
|
|
||||||
assert len( child.attributes )==2
|
confirm( len( child.attributes )==2 )
|
||||||
|
|
||||||
child.setAttribute( "def", "newval" )
|
child.setAttribute( "def", "newval" )
|
||||||
assert child.getAttribute( "def" )=="newval"
|
confirm( child.getAttribute( "def" )=="newval" )
|
||||||
assert child.attributes["def"].value=="newval"
|
confirm( child.attributes["def"].value=="newval" )
|
||||||
|
|
||||||
assert len( child.attributes )==2
|
confirm( len( child.attributes )==2 )
|
||||||
|
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
|
@ -114,22 +128,22 @@ def testDeleteAttr():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||||
|
|
||||||
assert len( child.attributes)==0
|
confirm( len( child.attributes)==0 )
|
||||||
child.setAttribute( "def", "ghi" )
|
child.setAttribute( "def", "ghi" )
|
||||||
assert len( child.attributes)==1
|
confirm( len( child.attributes)==1 )
|
||||||
del child.attributes["def"]
|
del child.attributes["def"]
|
||||||
assert len( child.attributes)==0
|
confirm( len( child.attributes)==0 )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
assert( len( Node.allnodes ))==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testRemoveAttr():
|
def testRemoveAttr():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
child=dom.appendChild( dom.createElement( "abc" ) )
|
child=dom.appendChild( dom.createElement( "abc" ) )
|
||||||
|
|
||||||
child.setAttribute( "def", "ghi" )
|
child.setAttribute( "def", "ghi" )
|
||||||
assert len( child.attributes)==1
|
confirm( len( child.attributes)==1 )
|
||||||
child.removeAttribute("def" )
|
child.removeAttribute("def" )
|
||||||
assert len( child.attributes)==0
|
confirm( len( child.attributes)==0 )
|
||||||
|
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
|
|
||||||
|
@ -140,9 +154,9 @@ def testRemoveAttrNS():
|
||||||
child.setAttributeNS( "http://www.w3.org", "xmlns:python",
|
child.setAttributeNS( "http://www.w3.org", "xmlns:python",
|
||||||
"http://www.python.org" )
|
"http://www.python.org" )
|
||||||
child.setAttributeNS( "http://www.python.org", "python:abcattr", "foo" )
|
child.setAttributeNS( "http://www.python.org", "python:abcattr", "foo" )
|
||||||
assert len( child.attributes )==2
|
confirm( len( child.attributes )==2 )
|
||||||
child.removeAttributeNS( "http://www.python.org", "abcattr" )
|
child.removeAttributeNS( "http://www.python.org", "abcattr" )
|
||||||
assert len( child.attributes )==1
|
confirm( len( child.attributes )==1 )
|
||||||
|
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
|
@ -151,31 +165,31 @@ def testRemoveAttributeNode():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
child=dom.appendChild( dom.createElement( "foo" ) )
|
child=dom.appendChild( dom.createElement( "foo" ) )
|
||||||
child.setAttribute( "spam", "jam" )
|
child.setAttribute( "spam", "jam" )
|
||||||
assert len( child.attributes )==1
|
confirm( len( child.attributes )==1 )
|
||||||
node=child.getAttributeNode( "spam" )
|
node=child.getAttributeNode( "spam" )
|
||||||
child.removeAttributeNode( node )
|
child.removeAttributeNode( node )
|
||||||
assert len( child.attributes )==0
|
confirm( len( child.attributes )==0 )
|
||||||
|
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert len( Node.allnodes )==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testChangeAttr():
|
def testChangeAttr():
|
||||||
dom=parseString( "<abc/>" )
|
dom=parseString( "<abc/>" )
|
||||||
el=dom.documentElement
|
el=dom.documentElement
|
||||||
el.setAttribute( "spam", "jam" )
|
el.setAttribute( "spam", "jam" )
|
||||||
assert len( el.attributes )==1
|
confirm( len( el.attributes )==1 )
|
||||||
el.setAttribute( "spam", "bam" )
|
el.setAttribute( "spam", "bam" )
|
||||||
assert len( el.attributes )==1
|
confirm( len( el.attributes )==1 )
|
||||||
el.attributes["spam"]="ham"
|
el.attributes["spam"]="ham"
|
||||||
assert len( el.attributes )==1
|
confirm( len( el.attributes )==1 )
|
||||||
el.setAttribute( "spam2", "bam" )
|
el.setAttribute( "spam2", "bam" )
|
||||||
assert len( el.attributes )==2
|
confirm( len( el.attributes )==2 )
|
||||||
el.attributes[ "spam2"]= "bam2"
|
el.attributes[ "spam2"]= "bam2"
|
||||||
assert len( el.attributes )==2
|
confirm( len( el.attributes )==2 )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
dom=None
|
dom=None
|
||||||
assert len( Node.allnodes )==0
|
confirm( len( Node.allnodes )==0 )
|
||||||
|
|
||||||
def testGetAttrList():
|
def testGetAttrList():
|
||||||
pass
|
pass
|
||||||
|
@ -199,7 +213,7 @@ def testElementReprAndStr():
|
||||||
el=dom.appendChild( dom.createElement( "abc" ) )
|
el=dom.appendChild( dom.createElement( "abc" ) )
|
||||||
string1=repr( el )
|
string1=repr( el )
|
||||||
string2=str( el )
|
string2=str( el )
|
||||||
assert string1==string2
|
confirm( string1==string2 )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
|
|
||||||
# commented out until Fredrick's fix is checked in
|
# commented out until Fredrick's fix is checked in
|
||||||
|
@ -208,25 +222,25 @@ def _testElementReprAndStrUnicode():
|
||||||
el=dom.appendChild( dom.createElement( u"abc" ) )
|
el=dom.appendChild( dom.createElement( u"abc" ) )
|
||||||
string1=repr( el )
|
string1=repr( el )
|
||||||
string2=str( el )
|
string2=str( el )
|
||||||
assert string1==string2
|
confirm( string1==string2 )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
|
|
||||||
# commented out until Fredrick's fix is checked in
|
# commented out until Fredrick's fix is checked in
|
||||||
def _testElementReprAndStrUnicodeNS():
|
def _testElementReprAndStrUnicodeNS():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
el=dom.appendChild(
|
el=dom.appendChild(
|
||||||
dom.createElementNS( u"http://www.slashdot.org", u"slash:abc" ))
|
dom.createElementNS( u"http://www.slashdot.org", u"slash:abc" ))
|
||||||
string1=repr( el )
|
string1=repr( el )
|
||||||
string2=str( el )
|
string2=str( el )
|
||||||
assert string1==string2
|
confirm( string1==string2 )
|
||||||
assert string1.find("slash:abc" )!=-1
|
confirm( string1.find("slash:abc" )!=-1 )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
|
|
||||||
def testAttributeRepr():
|
def testAttributeRepr():
|
||||||
dom=Document()
|
dom=Document()
|
||||||
el=dom.appendChild( dom.createElement( u"abc" ) )
|
el=dom.appendChild( dom.createElement( u"abc" ) )
|
||||||
node=el.setAttribute( "abc", "def" )
|
node=el.setAttribute( "abc", "def" )
|
||||||
assert str( node ) == repr( node )
|
confirm( str( node ) == repr( node ) )
|
||||||
dom.unlink()
|
dom.unlink()
|
||||||
|
|
||||||
def testTextNodeRepr(): pass
|
def testTextNodeRepr(): pass
|
||||||
|
@ -312,6 +326,9 @@ def testClonePIDeep(): pass
|
||||||
|
|
||||||
names=globals().keys()
|
names=globals().keys()
|
||||||
names.sort()
|
names.sort()
|
||||||
|
|
||||||
|
works=1
|
||||||
|
|
||||||
for name in names:
|
for name in names:
|
||||||
if name.startswith( "test" ):
|
if name.startswith( "test" ):
|
||||||
func=globals()[name]
|
func=globals()[name]
|
||||||
|
@ -320,12 +337,24 @@ for name in names:
|
||||||
print "Test Succeeded", name
|
print "Test Succeeded", name
|
||||||
if len( Node.allnodes ):
|
if len( Node.allnodes ):
|
||||||
print "Garbage left over:"
|
print "Garbage left over:"
|
||||||
print Node.allnodes.items()[0:10]
|
if verbose:
|
||||||
|
print Node.allnodes.items()[0:10]
|
||||||
|
else:
|
||||||
|
# Don't print specific nodes if repeatable results
|
||||||
|
# are needed
|
||||||
|
print len(Node.allnodes)
|
||||||
Node.allnodes={}
|
Node.allnodes={}
|
||||||
except Exception, e :
|
except Exception, e :
|
||||||
|
works=0
|
||||||
print "Test Failed: ", name
|
print "Test Failed: ", name
|
||||||
apply( traceback.print_exception, sys.exc_info() )
|
apply( traceback.print_exception, sys.exc_info() )
|
||||||
print `e`
|
print `e`
|
||||||
Node.allnodes={}
|
Node.allnodes={}
|
||||||
raise
|
|
||||||
|
|
||||||
|
if works:
|
||||||
|
print "All tests succeeded"
|
||||||
|
else:
|
||||||
|
print "\n\n\n\n************ Check for failures!"
|
||||||
|
|
||||||
|
Node.debug = None # Delete debug output collected in a StringIO object
|
||||||
|
Node._debug = 0 # And reset debug mode
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# Test the pickle module
|
# Test the pickle module
|
||||||
|
|
||||||
|
# break into multiple strings to please font-lock-mode
|
||||||
DATA = """(lp0
|
DATA = """(lp0
|
||||||
I0
|
I0
|
||||||
aL1L
|
aL1L
|
||||||
|
@ -7,17 +8,20 @@ aF2.0
|
||||||
ac__builtin__
|
ac__builtin__
|
||||||
complex
|
complex
|
||||||
p1
|
p1
|
||||||
(F3.0
|
""" \
|
||||||
|
"""(F3.0
|
||||||
F0.0
|
F0.0
|
||||||
tp2
|
tp2
|
||||||
Rp3
|
Rp3
|
||||||
a(S'abc'
|
a(S'abc'
|
||||||
p4
|
p4
|
||||||
g4
|
g4
|
||||||
(i__main__
|
""" \
|
||||||
|
"""(i__main__
|
||||||
C
|
C
|
||||||
p5
|
p5
|
||||||
(dp6
|
""" \
|
||||||
|
"""(dp6
|
||||||
S'foo'
|
S'foo'
|
||||||
p7
|
p7
|
||||||
I1
|
I1
|
||||||
|
@ -33,8 +37,6 @@ a.
|
||||||
|
|
||||||
BINDATA = ']q\000(K\000L1L\012G@\000\000\000\000\000\000\000c__builtin__\012complex\012q\001(G@\010\000\000\000\000\000\000G\000\000\000\000\000\000\000\000tq\002Rq\003(U\003abcq\004h\004(c__main__\012C\012q\005oq\006}q\007(U\003fooq\010K\001U\003barq\011K\002ubh\006tq\012h\012K\005e.'
|
BINDATA = ']q\000(K\000L1L\012G@\000\000\000\000\000\000\000c__builtin__\012complex\012q\001(G@\010\000\000\000\000\000\000G\000\000\000\000\000\000\000\000tq\002Rq\003(U\003abcq\004h\004(c__main__\012C\012q\005oq\006}q\007(U\003fooq\010K\001U\003barq\011K\002ubh\006tq\012h\012K\005e.'
|
||||||
|
|
||||||
import pickle
|
|
||||||
|
|
||||||
class C:
|
class C:
|
||||||
def __cmp__(self, other):
|
def __cmp__(self, other):
|
||||||
return cmp(self.__dict__, other.__dict__)
|
return cmp(self.__dict__, other.__dict__)
|
||||||
|
@ -42,7 +44,7 @@ class C:
|
||||||
import __main__
|
import __main__
|
||||||
__main__.C = C
|
__main__.C = C
|
||||||
|
|
||||||
def dotest():
|
def dotest(pickle):
|
||||||
c = C()
|
c = C()
|
||||||
c.foo = 1
|
c.foo = 1
|
||||||
c.bar = 2
|
c.bar = 2
|
||||||
|
@ -51,6 +53,8 @@ def dotest():
|
||||||
x.append(y)
|
x.append(y)
|
||||||
x.append(y)
|
x.append(y)
|
||||||
x.append(5)
|
x.append(5)
|
||||||
|
r = []
|
||||||
|
r.append(r)
|
||||||
print "dumps()"
|
print "dumps()"
|
||||||
s = pickle.dumps(x)
|
s = pickle.dumps(x)
|
||||||
print "loads()"
|
print "loads()"
|
||||||
|
@ -71,5 +75,69 @@ def dotest():
|
||||||
x2 = pickle.loads(BINDATA)
|
x2 = pickle.loads(BINDATA)
|
||||||
if x2 == x: print "ok"
|
if x2 == x: print "ok"
|
||||||
else: print "bad"
|
else: print "bad"
|
||||||
|
s = pickle.dumps(r)
|
||||||
|
print "dumps() RECURSIVE"
|
||||||
|
x2 = pickle.loads(s)
|
||||||
|
if x2 == r: print "ok"
|
||||||
|
else: print "bad"
|
||||||
|
# don't create cyclic garbage
|
||||||
|
del x2[0]
|
||||||
|
del r[0]
|
||||||
|
|
||||||
dotest()
|
# Test protection against closed files
|
||||||
|
import tempfile, os
|
||||||
|
fn = tempfile.mktemp()
|
||||||
|
f = open(fn, "w")
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
pickle.dump(123, f)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "dump to closed file should raise ValueError"
|
||||||
|
f = open(fn, "r")
|
||||||
|
f.close()
|
||||||
|
try:
|
||||||
|
pickle.load(f)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "load from closed file should raise ValueError"
|
||||||
|
os.remove(fn)
|
||||||
|
|
||||||
|
# Test specific bad cases
|
||||||
|
for i in range(10):
|
||||||
|
try:
|
||||||
|
x = pickle.loads('garyp')
|
||||||
|
except KeyError, y:
|
||||||
|
# pickle
|
||||||
|
del y
|
||||||
|
except pickle.BadPickleGet, y:
|
||||||
|
# cPickle
|
||||||
|
del y
|
||||||
|
else:
|
||||||
|
print "unexpected success!"
|
||||||
|
break
|
||||||
|
|
||||||
|
# Test insecure strings
|
||||||
|
insecure = ["abc", "2 + 2", # not quoted
|
||||||
|
"'abc' + 'def'", # not a single quoted string
|
||||||
|
"'abc", # quote is not closed
|
||||||
|
"'abc\"", # open quote and close quote don't match
|
||||||
|
"'abc' ?", # junk after close quote
|
||||||
|
# some tests of the quoting rules
|
||||||
|
"'abc\"\''",
|
||||||
|
"'\\\\a\'\'\'\\\'\\\\\''",
|
||||||
|
]
|
||||||
|
for s in insecure:
|
||||||
|
buf = "S" + s + "\012p0\012."
|
||||||
|
try:
|
||||||
|
x = pickle.loads(buf)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
print "accepted insecure string: %s" % repr(buf)
|
||||||
|
|
||||||
|
|
||||||
|
import pickle
|
||||||
|
dotest(pickle)
|
||||||
|
|
|
@ -3,10 +3,7 @@
|
||||||
# XXX TypeErrors on calling handlers, or on bad return values from a
|
# XXX TypeErrors on calling handlers, or on bad return values from a
|
||||||
# handler, are obscure and unhelpful.
|
# handler, are obscure and unhelpful.
|
||||||
|
|
||||||
import sys, string
|
from xml.parsers import expat
|
||||||
import os
|
|
||||||
|
|
||||||
import pyexpat
|
|
||||||
|
|
||||||
class Outputter:
|
class Outputter:
|
||||||
def StartElementHandler(self, name, attrs):
|
def StartElementHandler(self, name, attrs):
|
||||||
|
@ -16,7 +13,7 @@ class Outputter:
|
||||||
print 'End element:\n\t', repr(name)
|
print 'End element:\n\t', repr(name)
|
||||||
|
|
||||||
def CharacterDataHandler(self, data):
|
def CharacterDataHandler(self, data):
|
||||||
data = string.strip(data)
|
data = data.strip()
|
||||||
if data:
|
if data:
|
||||||
print 'Character data:'
|
print 'Character data:'
|
||||||
print '\t', repr(data)
|
print '\t', repr(data)
|
||||||
|
@ -63,29 +60,37 @@ class Outputter:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def confirm(ok):
|
||||||
|
if ok:
|
||||||
|
print "OK."
|
||||||
|
else:
|
||||||
|
print "Not OK."
|
||||||
|
|
||||||
out = Outputter()
|
out = Outputter()
|
||||||
parser = pyexpat.ParserCreate(namespace_separator='!')
|
parser = expat.ParserCreate(namespace_separator='!')
|
||||||
|
|
||||||
# Test getting/setting returns_unicode
|
# Test getting/setting returns_unicode
|
||||||
parser.returns_unicode = 0 ; assert parser.returns_unicode == 0
|
parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
|
||||||
parser.returns_unicode = 1 ; assert parser.returns_unicode == 1
|
parser.returns_unicode = 1; confirm(parser.returns_unicode == 1)
|
||||||
parser.returns_unicode = 2 ; assert parser.returns_unicode == 1
|
parser.returns_unicode = 2; confirm(parser.returns_unicode == 1)
|
||||||
parser.returns_unicode = 0 ; assert parser.returns_unicode == 0
|
parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
|
||||||
|
|
||||||
HANDLER_NAMES = ['StartElementHandler', 'EndElementHandler',
|
HANDLER_NAMES = [
|
||||||
'CharacterDataHandler', 'ProcessingInstructionHandler',
|
'StartElementHandler', 'EndElementHandler',
|
||||||
'UnparsedEntityDeclHandler', 'NotationDeclHandler',
|
'CharacterDataHandler', 'ProcessingInstructionHandler',
|
||||||
'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
|
'UnparsedEntityDeclHandler', 'NotationDeclHandler',
|
||||||
'CommentHandler', 'StartCdataSectionHandler',
|
'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
|
||||||
'EndCdataSectionHandler',
|
'CommentHandler', 'StartCdataSectionHandler',
|
||||||
'DefaultHandler', 'DefaultHandlerExpand',
|
'EndCdataSectionHandler',
|
||||||
#'NotStandaloneHandler',
|
'DefaultHandler', 'DefaultHandlerExpand',
|
||||||
'ExternalEntityRefHandler'
|
#'NotStandaloneHandler',
|
||||||
]
|
'ExternalEntityRefHandler'
|
||||||
|
]
|
||||||
for name in HANDLER_NAMES:
|
for name in HANDLER_NAMES:
|
||||||
setattr(parser, name, getattr(out, name) )
|
setattr(parser, name, getattr(out, name))
|
||||||
|
|
||||||
data = """<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
|
data = '''\
|
||||||
|
<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
|
||||||
<?xml-stylesheet href="stylesheet.css"?>
|
<?xml-stylesheet href="stylesheet.css"?>
|
||||||
<!-- comment data -->
|
<!-- comment data -->
|
||||||
<!DOCTYPE quotations SYSTEM "quotations.dtd" [
|
<!DOCTYPE quotations SYSTEM "quotations.dtd" [
|
||||||
|
@ -104,45 +109,44 @@ data = """<?xml version="1.0" encoding="iso-8859-1" standalone="no"?>
|
||||||
<sub2><![CDATA[contents of CDATA section]]></sub2>
|
<sub2><![CDATA[contents of CDATA section]]></sub2>
|
||||||
&external_entity;
|
&external_entity;
|
||||||
</root>
|
</root>
|
||||||
"""
|
'''
|
||||||
|
|
||||||
# Produce UTF-8 output
|
# Produce UTF-8 output
|
||||||
parser.returns_unicode = 0
|
parser.returns_unicode = 0
|
||||||
try:
|
try:
|
||||||
parser.Parse(data, 1)
|
parser.Parse(data, 1)
|
||||||
except pyexpat.error:
|
except expat.error:
|
||||||
print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
|
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
|
||||||
print '** Line', parser.ErrorLineNumber
|
print '** Line', parser.ErrorLineNumber
|
||||||
print '** Column', parser.ErrorColumnNumber
|
print '** Column', parser.ErrorColumnNumber
|
||||||
print '** Byte', parser.ErrorByteIndex
|
print '** Byte', parser.ErrorByteIndex
|
||||||
|
|
||||||
# Try the parse again, this time producing Unicode output
|
# Try the parse again, this time producing Unicode output
|
||||||
parser = pyexpat.ParserCreate(namespace_separator='!')
|
parser = expat.ParserCreate(namespace_separator='!')
|
||||||
parser.returns_unicode = 1
|
parser.returns_unicode = 1
|
||||||
|
|
||||||
for name in HANDLER_NAMES:
|
for name in HANDLER_NAMES:
|
||||||
setattr(parser, name, getattr(out, name) )
|
setattr(parser, name, getattr(out, name))
|
||||||
try:
|
try:
|
||||||
parser.Parse(data, 1)
|
parser.Parse(data, 1)
|
||||||
except pyexpat.error:
|
except expat.error:
|
||||||
print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
|
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
|
||||||
print '** Line', parser.ErrorLineNumber
|
print '** Line', parser.ErrorLineNumber
|
||||||
print '** Column', parser.ErrorColumnNumber
|
print '** Column', parser.ErrorColumnNumber
|
||||||
print '** Byte', parser.ErrorByteIndex
|
print '** Byte', parser.ErrorByteIndex
|
||||||
|
|
||||||
# Try parsing a file
|
# Try parsing a file
|
||||||
parser = pyexpat.ParserCreate(namespace_separator='!')
|
parser = expat.ParserCreate(namespace_separator='!')
|
||||||
parser.returns_unicode = 1
|
parser.returns_unicode = 1
|
||||||
|
|
||||||
for name in HANDLER_NAMES:
|
for name in HANDLER_NAMES:
|
||||||
setattr(parser, name, getattr(out, name) )
|
setattr(parser, name, getattr(out, name))
|
||||||
import StringIO
|
import StringIO
|
||||||
file = StringIO.StringIO(data)
|
file = StringIO.StringIO(data)
|
||||||
try:
|
try:
|
||||||
parser.ParseFile(file)
|
parser.ParseFile(file)
|
||||||
except pyexpat.error:
|
except expat.error:
|
||||||
print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
|
print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
|
||||||
print '** Line', parser.ErrorLineNumber
|
print '** Line', parser.ErrorLineNumber
|
||||||
print '** Column', parser.ErrorColumnNumber
|
print '** Column', parser.ErrorColumnNumber
|
||||||
print '** Byte', parser.ErrorByteIndex
|
print '** Byte', parser.ErrorByteIndex
|
||||||
|
|
||||||
|
|
|
@ -120,3 +120,7 @@ Date: Wed, 13 Jan 1999 23:57:35 -0500
|
||||||
|
|
||||||
test''', [('', 'goit@lip.com')])
|
test''', [('', 'goit@lip.com')])
|
||||||
|
|
||||||
|
|
||||||
|
test('''To: guido@[132.151.1.21]
|
||||||
|
|
||||||
|
foo''', [('', 'guido@[132.151.1.21]')])
|
||||||
|
|
|
@ -1,134 +1,15 @@
|
||||||
#! /usr/bin/env python
|
# Tests StringIO and cStringIO
|
||||||
|
|
||||||
# Sanity checker for time.strftime
|
import string
|
||||||
|
|
||||||
import time, calendar, sys, string, os, re
|
def do_test(module):
|
||||||
from test_support import verbose
|
s = (string.letters+'\n')*5
|
||||||
|
f = module.StringIO(s)
|
||||||
|
print f.read(10)
|
||||||
|
print f.readline()
|
||||||
|
print len(f.readlines(60))
|
||||||
|
|
||||||
def main():
|
# Don't bother testing cStringIO without
|
||||||
global verbose
|
import StringIO, cStringIO
|
||||||
now = time.time()
|
do_test(StringIO)
|
||||||
strftest(now)
|
do_test(cStringIO)
|
||||||
verbose = 0
|
|
||||||
# Try a bunch of dates and times, chosen to vary through time of
|
|
||||||
# day and daylight saving time
|
|
||||||
for j in range(-5, 5):
|
|
||||||
for i in range(25):
|
|
||||||
strftest(now + (i + j*100)*23*3603)
|
|
||||||
|
|
||||||
def strftest(now):
|
|
||||||
if verbose:
|
|
||||||
print "strftime test for", time.ctime(now)
|
|
||||||
nowsecs = str(long(now))[:-1]
|
|
||||||
gmt = time.gmtime(now)
|
|
||||||
now = time.localtime(now)
|
|
||||||
|
|
||||||
if now[3] < 12: ampm='AM'
|
|
||||||
else: ampm='PM'
|
|
||||||
|
|
||||||
jan1 = time.localtime(time.mktime((now[0], 1, 1) + (0,)*6))
|
|
||||||
|
|
||||||
try:
|
|
||||||
if now[8]: tz = time.tzname[1]
|
|
||||||
else: tz = time.tzname[0]
|
|
||||||
except AttributeError:
|
|
||||||
tz = ''
|
|
||||||
|
|
||||||
if now[3] > 12: clock12 = now[3] - 12
|
|
||||||
elif now[3] > 0: clock12 = now[3]
|
|
||||||
else: clock12 = 12
|
|
||||||
|
|
||||||
expectations = (
|
|
||||||
('%a', calendar.day_abbr[now[6]], 'abbreviated weekday name'),
|
|
||||||
('%A', calendar.day_name[now[6]], 'full weekday name'),
|
|
||||||
('%b', calendar.month_abbr[now[1]], 'abbreviated month name'),
|
|
||||||
('%B', calendar.month_name[now[1]], 'full month name'),
|
|
||||||
# %c see below
|
|
||||||
('%d', '%02d' % now[2], 'day of month as number (00-31)'),
|
|
||||||
('%H', '%02d' % now[3], 'hour (00-23)'),
|
|
||||||
('%I', '%02d' % clock12, 'hour (01-12)'),
|
|
||||||
('%j', '%03d' % now[7], 'julian day (001-366)'),
|
|
||||||
('%m', '%02d' % now[1], 'month as number (01-12)'),
|
|
||||||
('%M', '%02d' % now[4], 'minute, (00-59)'),
|
|
||||||
('%p', ampm, 'AM or PM as appropriate'),
|
|
||||||
('%S', '%02d' % now[5], 'seconds of current time (00-60)'),
|
|
||||||
('%U', '%02d' % ((now[7] + jan1[6])/7),
|
|
||||||
'week number of the year (Sun 1st)'),
|
|
||||||
('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'),
|
|
||||||
('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)/7),
|
|
||||||
'week number of the year (Mon 1st)'),
|
|
||||||
# %x see below
|
|
||||||
('%X', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
|
|
||||||
('%y', '%02d' % (now[0]%100), 'year without century'),
|
|
||||||
('%Y', '%d' % now[0], 'year with century'),
|
|
||||||
# %Z see below
|
|
||||||
('%%', '%', 'single percent sign'),
|
|
||||||
)
|
|
||||||
|
|
||||||
nonstandard_expectations = (
|
|
||||||
# These are standard but don't have predictable output
|
|
||||||
('%c', fixasctime(time.asctime(now)), 'near-asctime() format'),
|
|
||||||
('%x', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)),
|
|
||||||
'%m/%d/%y %H:%M:%S'),
|
|
||||||
('%Z', '%s' % tz, 'time zone name'),
|
|
||||||
|
|
||||||
# These are some platform specific extensions
|
|
||||||
('%D', '%02d/%02d/%02d' % (now[1], now[2], (now[0]%100)), 'mm/dd/yy'),
|
|
||||||
('%e', '%2d' % now[2], 'day of month as number, blank padded ( 0-31)'),
|
|
||||||
('%h', calendar.month_abbr[now[1]], 'abbreviated month name'),
|
|
||||||
('%k', '%2d' % now[3], 'hour, blank padded ( 0-23)'),
|
|
||||||
('%n', '\n', 'newline character'),
|
|
||||||
('%r', '%02d:%02d:%02d %s' % (clock12, now[4], now[5], ampm),
|
|
||||||
'%I:%M:%S %p'),
|
|
||||||
('%R', '%02d:%02d' % (now[3], now[4]), '%H:%M'),
|
|
||||||
('%s', nowsecs, 'seconds since the Epoch in UCT'),
|
|
||||||
('%t', '\t', 'tab character'),
|
|
||||||
('%T', '%02d:%02d:%02d' % (now[3], now[4], now[5]), '%H:%M:%S'),
|
|
||||||
('%3y', '%03d' % (now[0]%100),
|
|
||||||
'year without century rendered using fieldwidth'),
|
|
||||||
)
|
|
||||||
|
|
||||||
if verbose:
|
|
||||||
print "Strftime test, platform: %s, Python version: %s" % \
|
|
||||||
(sys.platform, string.split(sys.version)[0])
|
|
||||||
|
|
||||||
for e in expectations:
|
|
||||||
try:
|
|
||||||
result = time.strftime(e[0], now)
|
|
||||||
except ValueError, error:
|
|
||||||
print "Standard '%s' format gave error:" % e[0], error
|
|
||||||
continue
|
|
||||||
if re.match(e[1], result): continue
|
|
||||||
if not result or result[0] == '%':
|
|
||||||
print "Does not support standard '%s' format (%s)" % (e[0], e[2])
|
|
||||||
else:
|
|
||||||
print "Conflict for %s (%s):" % (e[0], e[2])
|
|
||||||
print " Expected %s, but got %s" % (e[1], result)
|
|
||||||
|
|
||||||
for e in nonstandard_expectations:
|
|
||||||
try:
|
|
||||||
result = time.strftime(e[0], now)
|
|
||||||
except ValueError, result:
|
|
||||||
if verbose:
|
|
||||||
print "Error for nonstandard '%s' format (%s): %s" % \
|
|
||||||
(e[0], e[2], str(result))
|
|
||||||
continue
|
|
||||||
if re.match(e[1], result):
|
|
||||||
if verbose:
|
|
||||||
print "Supports nonstandard '%s' format (%s)" % (e[0], e[2])
|
|
||||||
elif not result or result[0] == '%':
|
|
||||||
if verbose:
|
|
||||||
print "Does not appear to support '%s' format (%s)" % (e[0],
|
|
||||||
e[2])
|
|
||||||
else:
|
|
||||||
if verbose:
|
|
||||||
print "Conflict for nonstandard '%s' format (%s):" % (e[0],
|
|
||||||
e[2])
|
|
||||||
print " Expected %s, but got %s" % (e[1], result)
|
|
||||||
|
|
||||||
def fixasctime(s):
|
|
||||||
if s[8] == ' ':
|
|
||||||
s = s[:8] + '0' + s[9:]
|
|
||||||
return s
|
|
||||||
|
|
||||||
main()
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Minimal test of the quote function
|
||||||
|
import urllib
|
||||||
|
|
||||||
|
chars = 'abcdefghijklmnopqrstuvwxyz'\
|
||||||
|
'\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356' \
|
||||||
|
'\357\360\361\362\363\364\365\366\370\371\372\373\374\375\376\377' \
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' \
|
||||||
|
'\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317' \
|
||||||
|
'\320\321\322\323\324\325\326\330\331\332\333\334\335\336'
|
||||||
|
|
||||||
|
expected = 'abcdefghijklmnopqrstuvwxyz%df%e0%e1%e2%e3%e4%e5%e6%e7%e8%e9%ea%eb%ec%ed%ee%ef%f0%f1%f2%f3%f4%f5%f6%f8%f9%fa%fb%fc%fd%fe%ffABCDEFGHIJKLMNOPQRSTUVWXYZ%c0%c1%c2%c3%c4%c5%c6%c7%c8%c9%ca%cb%cc%cd%ce%cf%d0%d1%d2%d3%d4%d5%d6%d8%d9%da%db%dc%dd%de'
|
||||||
|
|
||||||
|
test = urllib.quote(chars)
|
||||||
|
assert test == expected, "urllib.quote problem"
|
||||||
|
test2 = urllib.unquote(expected)
|
||||||
|
assert test2 == chars
|
||||||
|
|
||||||
|
in1 = "abc/def"
|
||||||
|
out1_1 = "abc/def"
|
||||||
|
out1_2 = "abc%2fdef"
|
||||||
|
|
||||||
|
assert urllib.quote(in1) == out1_1, "urllib.quote problem"
|
||||||
|
assert urllib.quote(in1, '') == out1_2, "urllib.quote problem"
|
||||||
|
|
||||||
|
in2 = "abc?def"
|
||||||
|
out2_1 = "abc%3fdef"
|
||||||
|
out2_2 = "abc?def"
|
||||||
|
|
||||||
|
assert urllib.quote(in2) == out2_1, "urllib.quote problem"
|
||||||
|
assert urllib.quote(in2, '?') == out2_2, "urllib.quote problem"
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,147 @@
|
||||||
# Ridiculously simple test of the winsound module for Windows.
|
# Test the windows specific win32reg module.
|
||||||
|
# Only win32reg functions not hit here: FlushKey, LoadKey and SaveKey
|
||||||
|
|
||||||
import winsound
|
from _winreg import *
|
||||||
for i in range(100, 2000, 100):
|
import os, sys
|
||||||
winsound.Beep(i, 75)
|
|
||||||
print "Hopefully you heard some sounds increasing in frequency!"
|
test_key_name = "SOFTWARE\\Python Registry Test Key - Delete Me"
|
||||||
|
|
||||||
|
test_data = [
|
||||||
|
("Int Value", 45, REG_DWORD),
|
||||||
|
("String Val", "A string value", REG_SZ,),
|
||||||
|
(u"Unicode Val", u"A Unicode value", REG_SZ,),
|
||||||
|
("StringExpand", "The path is %path%", REG_EXPAND_SZ),
|
||||||
|
("UnicodeExpand", u"The path is %path%", REG_EXPAND_SZ),
|
||||||
|
("Multi-string", ["Lots", "of", "string", "values"], REG_MULTI_SZ),
|
||||||
|
("Multi-unicode", [u"Lots", u"of", u"unicode", u"values"], REG_MULTI_SZ),
|
||||||
|
("Multi-mixed", [u"Unicode", u"and", "string", "values"],REG_MULTI_SZ),
|
||||||
|
("Raw Data", ("binary"+chr(0)+"data"), REG_BINARY),
|
||||||
|
]
|
||||||
|
|
||||||
|
def WriteTestData(root_key):
|
||||||
|
# Set the default value for this key.
|
||||||
|
SetValue(root_key, test_key_name, REG_SZ, "Default value")
|
||||||
|
key = CreateKey(root_key, test_key_name)
|
||||||
|
# Create a sub-key
|
||||||
|
sub_key = CreateKey(key, "sub_key")
|
||||||
|
# Give the sub-key some named values
|
||||||
|
|
||||||
|
for value_name, value_data, value_type in test_data:
|
||||||
|
SetValueEx(sub_key, value_name, 0, value_type, value_data)
|
||||||
|
|
||||||
|
# Check we wrote as many items as we thought.
|
||||||
|
nkeys, nvalues, since_mod = QueryInfoKey(key)
|
||||||
|
assert nkeys==1, "Not the correct number of sub keys"
|
||||||
|
assert nvalues==1, "Not the correct number of values"
|
||||||
|
nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
|
||||||
|
assert nkeys==0, "Not the correct number of sub keys"
|
||||||
|
assert nvalues==len(test_data), "Not the correct number of values"
|
||||||
|
# Close this key this way...
|
||||||
|
# (but before we do, copy the key as an integer - this allows
|
||||||
|
# us to test that the key really gets closed).
|
||||||
|
int_sub_key = int(sub_key)
|
||||||
|
CloseKey(sub_key)
|
||||||
|
try:
|
||||||
|
QueryInfoKey(int_sub_key)
|
||||||
|
raise RuntimeError, "It appears the CloseKey() function does not close the actual key!"
|
||||||
|
except EnvironmentError:
|
||||||
|
pass
|
||||||
|
# ... and close that key that way :-)
|
||||||
|
int_key = int(key)
|
||||||
|
key.Close()
|
||||||
|
try:
|
||||||
|
QueryInfoKey(int_key)
|
||||||
|
raise RuntimeError, "It appears the key.Close() function does not close the actual key!"
|
||||||
|
except EnvironmentError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def ReadTestData(root_key):
|
||||||
|
# Check we can get default value for this key.
|
||||||
|
val = QueryValue(root_key, test_key_name)
|
||||||
|
assert val=="Default value", "Registry didn't give back the correct value"
|
||||||
|
|
||||||
|
key = OpenKey(root_key, test_key_name)
|
||||||
|
# Read the sub-keys
|
||||||
|
sub_key = OpenKey(key, "sub_key")
|
||||||
|
# Check I can enumerate over the values.
|
||||||
|
index = 0
|
||||||
|
while 1:
|
||||||
|
try:
|
||||||
|
data = EnumValue(sub_key, index)
|
||||||
|
except EnvironmentError:
|
||||||
|
break
|
||||||
|
assert data in test_data, "Didn't read back the correct test data"
|
||||||
|
index = index + 1
|
||||||
|
assert index==len(test_data), "Didn't read the correct number of items"
|
||||||
|
# Check I can directly access each item
|
||||||
|
for value_name, value_data, value_type in test_data:
|
||||||
|
read_val, read_typ = QueryValueEx(sub_key, value_name)
|
||||||
|
assert read_val==value_data and read_typ == value_type, \
|
||||||
|
"Could not directly read the value"
|
||||||
|
sub_key.Close()
|
||||||
|
# Enumerate our main key.
|
||||||
|
read_val = EnumKey(key, 0)
|
||||||
|
assert read_val == "sub_key", "Read subkey value wrong"
|
||||||
|
try:
|
||||||
|
EnumKey(key, 1)
|
||||||
|
assert 0, "Was able to get a second key when I only have one!"
|
||||||
|
except EnvironmentError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
key.Close()
|
||||||
|
|
||||||
|
def DeleteTestData(root_key):
|
||||||
|
key = OpenKey(root_key, test_key_name, 0, KEY_ALL_ACCESS)
|
||||||
|
sub_key = OpenKey(key, "sub_key", 0, KEY_ALL_ACCESS)
|
||||||
|
# It is not necessary to delete the values before deleting
|
||||||
|
# the key (although subkeys must not exist). We delete them
|
||||||
|
# manually just to prove we can :-)
|
||||||
|
for value_name, value_data, value_type in test_data:
|
||||||
|
DeleteValue(sub_key, value_name)
|
||||||
|
|
||||||
|
nkeys, nvalues, since_mod = QueryInfoKey(sub_key)
|
||||||
|
assert nkeys==0 and nvalues==0, "subkey not empty before delete"
|
||||||
|
sub_key.Close()
|
||||||
|
DeleteKey(key, "sub_key")
|
||||||
|
|
||||||
|
try:
|
||||||
|
# Shouldnt be able to delete it twice!
|
||||||
|
DeleteKey(key, "sub_key")
|
||||||
|
assert 0, "Deleting the key twice succeeded"
|
||||||
|
except EnvironmentError:
|
||||||
|
pass
|
||||||
|
key.Close()
|
||||||
|
DeleteKey(root_key, test_key_name)
|
||||||
|
# Opening should now fail!
|
||||||
|
try:
|
||||||
|
key = OpenKey(root_key, test_key_name)
|
||||||
|
assert 0, "Could open the non-existent key"
|
||||||
|
except WindowsError: # Use this error name this time
|
||||||
|
pass
|
||||||
|
|
||||||
|
def TestAll(root_key):
|
||||||
|
WriteTestData(root_key)
|
||||||
|
ReadTestData(root_key)
|
||||||
|
DeleteTestData(root_key)
|
||||||
|
|
||||||
|
# Test on my local machine.
|
||||||
|
TestAll(HKEY_CURRENT_USER)
|
||||||
|
print "Local registry tests worked"
|
||||||
|
try:
|
||||||
|
remote_name = sys.argv[sys.argv.index("--remote")+1]
|
||||||
|
except (IndexError, ValueError):
|
||||||
|
remote_name = None
|
||||||
|
|
||||||
|
if remote_name is not None:
|
||||||
|
try:
|
||||||
|
remote_key = ConnectRegistry(remote_name, HKEY_CURRENT_USER)
|
||||||
|
except EnvironmentError, exc:
|
||||||
|
print "Could not connect to the remote machine -", exc.strerror
|
||||||
|
remote_key = None
|
||||||
|
if remote_key is not None:
|
||||||
|
TestAll(remote_key)
|
||||||
|
print "Remote registry tests worked"
|
||||||
|
else:
|
||||||
|
print "Remote registry calls can be tested using",
|
||||||
|
print "'test_winreg.py --remote \\\\machine_name'"
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ class UserList:
|
||||||
return cmp(self.data, other.data)
|
return cmp(self.data, other.data)
|
||||||
else:
|
else:
|
||||||
return cmp(self.data, other)
|
return cmp(self.data, other)
|
||||||
|
def __contains__(self, item): return item in self.data
|
||||||
def __len__(self): return len(self.data)
|
def __len__(self): return len(self.data)
|
||||||
def __getitem__(self, i): return self.data[i]
|
def __getitem__(self, i): return self.data[i]
|
||||||
def __setitem__(self, i, item): self.data[i] = item
|
def __setitem__(self, i, item): self.data[i] = item
|
||||||
|
|
|
@ -183,7 +183,7 @@ register("grail", Grail)
|
||||||
|
|
||||||
class WindowsDefault:
|
class WindowsDefault:
|
||||||
def open(self, url, new=0):
|
def open(self, url, new=0):
|
||||||
self.junk = os.popen("start " + url)
|
os.startfile(url)
|
||||||
|
|
||||||
def open_new(self, url):
|
def open_new(self, url):
|
||||||
self.open(url)
|
self.open(url)
|
||||||
|
|
Loading…
Reference in New Issue