summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2000-09-26 17:32:27 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2000-09-26 17:32:27 (GMT)
commitd635b1d724e79a1d2dce416b29a95c389fdfab30 (patch)
tree91545a903b9628f4a592b6d911fd9bd23d7510b6
parent0872e0585196a894c8c2c2dbea1a0fdd68391c90 (diff)
downloadcpython-d635b1d724e79a1d2dce416b29a95c389fdfab30.zip
cpython-d635b1d724e79a1d2dce416b29a95c389fdfab30.tar.gz
cpython-d635b1d724e79a1d2dce416b29a95c389fdfab30.tar.bz2
The Usual
-rwxr-xr-xLib/dos-8x3/cgihttps.py254
-rw-r--r--Lib/dos-8x3/configpa.py2
-rwxr-xr-xLib/dos-8x3/posixfil.py3
-rwxr-xr-xLib/dos-8x3/py_compi.py5
-rw-r--r--Lib/dos-8x3/sre_pars.py2
-rwxr-xr-xLib/dos-8x3/stringio.py6
-rw-r--r--Lib/dos-8x3/test_arr.py14
-rw-r--r--Lib/dos-8x3/test_cpi.py106
-rwxr-xr-xLib/dos-8x3/test_exc.py49
-rw-r--r--Lib/dos-8x3/test_fcn.py2
-rwxr-xr-xLib/dos-8x3/test_gra.py7
-rw-r--r--Lib/dos-8x3/test_min.py125
-rw-r--r--Lib/dos-8x3/test_pic.py82
-rw-r--r--Lib/dos-8x3/test_pye.py74
-rw-r--r--Lib/dos-8x3/test_rfc.py4
-rw-r--r--Lib/dos-8x3/test_str.py143
-rw-r--r--Lib/dos-8x3/test_url.py32
-rw-r--r--Lib/dos-8x3/test_win.py150
-rwxr-xr-xLib/dos-8x3/userlist.py1
-rw-r--r--Lib/dos-8x3/webbrows.py2
20 files changed, 642 insertions, 421 deletions
diff --git a/Lib/dos-8x3/cgihttps.py b/Lib/dos-8x3/cgihttps.py
index 6a259a3..ba1e76b 100755
--- a/Lib/dos-8x3/cgihttps.py
+++ b/Lib/dos-8x3/cgihttps.py
@@ -3,28 +3,31 @@
This module builds on SimpleHTTPServer by implementing GET and POST
requests to cgi-bin scripts.
-If the os.fork() function is not present, this module will not work;
-SystemError will be raised instead.
+If the os.fork() function is not present (e.g. on Windows),
+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 sys
import string
import urllib
import BaseHTTPServer
import SimpleHTTPServer
-try:
- os.fork
-except AttributeError:
- raise SystemError, __name__ + " requires os.fork()"
-
-
class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""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
# the rest to a subprocess, so we can't use buffered input.
rbufsize = 0
@@ -59,9 +66,9 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(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
slash if it is not empty.
@@ -83,6 +90,15 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
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):
"""Execute a CGI script."""
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)" %
`scriptname`)
return
- if not executable(scriptfile):
- self.send_error(403, "CGI script is not executable (%s)" %
- `scriptname`)
- return
- nobody = nobody_uid()
+ ispy = self.is_python(scriptname)
+ if not ispy:
+ if not (self.have_fork or self.have_popen2):
+ self.send_error(403, "CGI script is not a Python script (%s)" %
+ `scriptname`)
+ return
+ if not self.is_executable(scriptfile):
+ self.send_error(403, "CGI script is not executable (%s)" %
+ `scriptname`)
+ return
+
+ # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
+ # XXX Much of the following could be prepared ahead of time!
+ env = {}
+ env['SERVER_SOFTWARE'] = self.version_string()
+ env['SERVER_NAME'] = self.server.server_name
+ env['GATEWAY_INTERFACE'] = 'CGI/1.1'
+ env['SERVER_PROTOCOL'] = self.protocol_version
+ env['SERVER_PORT'] = str(self.server.server_port)
+ env['REQUEST_METHOD'] = self.command
+ uqrest = urllib.unquote(rest)
+ env['PATH_INFO'] = uqrest
+ env['PATH_TRANSLATED'] = self.translate_path(uqrest)
+ env['SCRIPT_NAME'] = scriptname
+ if query:
+ env['QUERY_STRING'] = query
+ host = self.address_string()
+ if host != self.client_address[0]:
+ env['REMOTE_HOST'] = host
+ env['REMOTE_ADDR'] = self.client_address[0]
+ # XXX AUTH_TYPE
+ # XXX REMOTE_USER
+ # XXX REMOTE_IDENT
+ if self.headers.typeheader is None:
+ env['CONTENT_TYPE'] = self.headers.type
+ else:
+ env['CONTENT_TYPE'] = self.headers.typeheader
+ length = self.headers.getheader('content-length')
+ if length:
+ env['CONTENT_LENGTH'] = length
+ accept = []
+ for line in self.headers.getallmatchingheaders('accept'):
+ if line[:1] in string.whitespace:
+ accept.append(string.strip(line))
+ else:
+ accept = accept + string.split(line[7:], ',')
+ env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
+ ua = self.headers.getheader('user-agent')
+ if ua:
+ env['HTTP_USER_AGENT'] = ua
+ co = filter(None, self.headers.getheaders('cookie'))
+ if co:
+ env['HTTP_COOKIE'] = string.join(co, ', ')
+ # XXX Other HTTP_* headers
+ if not self.have_fork:
+ # Since we're setting the env in the parent, provide empty
+ # values to override previously set values
+ for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH',
+ 'HTTP_USER_AGENT', 'HTTP_COOKIE'):
+ env.setdefault(k, "")
+
self.send_response(200, "Script output follows")
- self.wfile.flush() # Always flush before forking
- pid = os.fork()
- if pid != 0:
- # Parent
- pid, sts = os.waitpid(pid, 0)
+
+ 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)
+ except os.error:
+ pass
+ os.dup2(self.rfile.fileno(), 0)
+ os.dup2(self.wfile.fileno(), 1)
+ os.execve(scriptfile, args, env)
+ except:
+ 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%x" % sts)
- return
- # Child
- try:
- # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
- # XXX Much of the following could be prepared ahead of time!
- env = {}
- env['SERVER_SOFTWARE'] = self.version_string()
- env['SERVER_NAME'] = self.server.server_name
- env['GATEWAY_INTERFACE'] = 'CGI/1.1'
- env['SERVER_PROTOCOL'] = self.protocol_version
- env['SERVER_PORT'] = str(self.server.server_port)
- env['REQUEST_METHOD'] = self.command
- uqrest = urllib.unquote(rest)
- env['PATH_INFO'] = uqrest
- env['PATH_TRANSLATED'] = self.translate_path(uqrest)
- env['SCRIPT_NAME'] = scriptname
- if query:
- env['QUERY_STRING'] = query
- host = self.address_string()
- if host != self.client_address[0]:
- env['REMOTE_HOST'] = host
- env['REMOTE_ADDR'] = self.client_address[0]
- # AUTH_TYPE
- # REMOTE_USER
- # REMOTE_IDENT
- if self.headers.typeheader is None:
- env['CONTENT_TYPE'] = self.headers.type
+ self.log_error("CGI script exit status %#x", sts)
else:
- env['CONTENT_TYPE'] = self.headers.typeheader
- length = self.headers.getheader('content-length')
- if length:
- env['CONTENT_LENGTH'] = length
- accept = []
- for line in self.headers.getallmatchingheaders('accept'):
- if line[:1] in string.whitespace:
- accept.append(string.strip(line))
- else:
- accept = accept + string.split(line[7:], ',')
- env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
- ua = self.headers.getheader('user-agent')
- if ua:
- env['HTTP_USER_AGENT'] = ua
- co = filter(None, self.headers.getheaders('cookie'))
- if co:
- env['HTTP_COOKIE'] = string.join(co, ', ')
- # XXX Other HTTP_* headers
- decoded_query = string.replace(query, '+', ' ')
+ 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:
- os.setuid(nobody)
- except os.error:
- pass
- os.dup2(self.rfile.fileno(), 0)
- os.dup2(self.wfile.fileno(), 1)
- print scriptfile, script, decoded_query
- os.execve(scriptfile,
- [script, decoded_query],
- env)
- except:
- self.server.handle_error(self.request, self.client_address)
- os._exit(127)
+ 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
@@ -187,7 +276,10 @@ def nobody_uid():
global nobody
if nobody:
return nobody
- import pwd
+ try:
+ import pwd
+ except ImportError:
+ return -1
try:
nobody = pwd.getpwnam('nobody')[2]
except KeyError:
diff --git a/Lib/dos-8x3/configpa.py b/Lib/dos-8x3/configpa.py
index e7636b9..16d18d2 100644
--- a/Lib/dos-8x3/configpa.py
+++ b/Lib/dos-8x3/configpa.py
@@ -440,7 +440,7 @@ class ConfigParser:
# allow empty values
if optval == '""':
optval = ''
- cursect[optname] = optval
+ cursect[self.optionxform(optname)] = optval
else:
# a non-fatal parsing error occurred. set up the
# exception but keep going. the exception will be
diff --git a/Lib/dos-8x3/posixfil.py b/Lib/dos-8x3/posixfil.py
index d358dc4..23f2c85 100755
--- a/Lib/dos-8x3/posixfil.py
+++ b/Lib/dos-8x3/posixfil.py
@@ -67,9 +67,6 @@ class _posixfile_:
(self.states[file.closed], file.name, file.mode, \
hex(id(self))[2:])
- def __del__(self):
- self._file_.close()
-
#
# Initialization routines
#
diff --git a/Lib/dos-8x3/py_compi.py b/Lib/dos-8x3/py_compi.py
index c54d61b..b453109 100755
--- a/Lib/dos-8x3/py_compi.py
+++ b/Lib/dos-8x3/py_compi.py
@@ -48,6 +48,11 @@ def compile(file, cfile=None, dfile=None):
except AttributeError:
timestamp = long(os.stat(file)[8])
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()
if codestring and codestring[-1] != '\n':
codestring = codestring + '\n'
diff --git a/Lib/dos-8x3/sre_pars.py b/Lib/dos-8x3/sre_pars.py
index 55de24c..f4741c9 100644
--- a/Lib/dos-8x3/sre_pars.py
+++ b/Lib/dos-8x3/sre_pars.py
@@ -634,7 +634,7 @@ def parse_template(source, pattern):
while 1:
group = _group(this, pattern.groups+1)
if group:
- if (not s.next or
+ if (s.next not in DIGITS or
not _group(this + s.next, pattern.groups+1)):
code = MARK, int(group)
break
diff --git a/Lib/dos-8x3/stringio.py b/Lib/dos-8x3/stringio.py
index 8efd7d8..02eb7c8 100755
--- a/Lib/dos-8x3/stringio.py
+++ b/Lib/dos-8x3/stringio.py
@@ -91,11 +91,15 @@ class StringIO:
r = self.buf[self.pos:newpos]
self.pos = newpos
return r
- def readlines(self):
+ def readlines(self, sizehint = 0):
+ total = 0
lines = []
line = self.readline()
while line:
lines.append(line)
+ total += len(line)
+ if 0 < sizehint <= total:
+ break
line = self.readline()
return lines
def write(self, s):
diff --git a/Lib/dos-8x3/test_arr.py b/Lib/dos-8x3/test_arr.py
index d3fe7e9..fb451a9 100644
--- a/Lib/dos-8x3/test_arr.py
+++ b/Lib/dos-8x3/test_arr.py
@@ -122,9 +122,14 @@ def testtype(type, example):
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"):
raise TestFailed, "array(%s) pop-test" % `type`
+ a.reverse()
+ if a != array.array(type, "dca"):
+ raise TestFailed, "array(%s) reverse-test" % `type`
else:
a = array.array(type, [1, 2, 3, 4, 5])
a[:-1] = a
@@ -155,9 +160,14 @@ def testtype(type, example):
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]):
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
# to array of specific integral types
diff --git a/Lib/dos-8x3/test_cpi.py b/Lib/dos-8x3/test_cpi.py
index f5e920f..f2aa0fe 100644
--- a/Lib/dos-8x3/test_cpi.py
+++ b/Lib/dos-8x3/test_cpi.py
@@ -1,107 +1,5 @@
# 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
-
-class C:
- 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()
+import test_pickle
+test_pickle.dotest(cPickle)
diff --git a/Lib/dos-8x3/test_exc.py b/Lib/dos-8x3/test_exc.py
index 7ee203c..076f470 100755
--- a/Lib/dos-8x3/test_exc.py
+++ b/Lib/dos-8x3/test_exc.py
@@ -86,6 +86,55 @@ r(SyntaxError)
try: exec '/\n'
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(TabError)
diff --git a/Lib/dos-8x3/test_fcn.py b/Lib/dos-8x3/test_fcn.py
index 3c1be88..e1ed88b 100644
--- a/Lib/dos-8x3/test_fcn.py
+++ b/Lib/dos-8x3/test_fcn.py
@@ -21,7 +21,7 @@ if sys.platform in ('netbsd1',
'bsdos2', 'bsdos3', 'bsdos4',
'openbsd', 'openbsd2'):
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)
else:
lockdata = struct.pack('hhllhh', FCNTL.F_WRLCK, 0, 0, 0, 0, 0)
diff --git a/Lib/dos-8x3/test_gra.py b/Lib/dos-8x3/test_gra.py
index ef7c09b..68cae81 100755
--- a/Lib/dos-8x3/test_gra.py
+++ b/Lib/dos-8x3/test_gra.py
@@ -355,6 +355,13 @@ def f():
del z
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()
g = {}
exec 'z = 1' in g
diff --git a/Lib/dos-8x3/test_min.py b/Lib/dos-8x3/test_min.py
index 73c8ac4..8a63535 100644
--- a/Lib/dos-8x3/test_min.py
+++ b/Lib/dos-8x3/test_min.py
@@ -5,6 +5,7 @@ from xml.dom.minidom import parse, Node, Document, parseString
import os.path
import sys
import traceback
+from test_support import verbose
if __name__ == "__main__":
base = sys.argv[0]
@@ -13,15 +14,28 @@ else:
tstfile = os.path.join(os.path.dirname(base), "test.xml")
del base
+def confirm( test, testname="Test" ):
+ if test:
+ print "Passed " + testname
+ else:
+ print "Failed " + testname
+ raise Exception
+
Node._debug=1
+def testParseFromFile():
+ from StringIO import StringIO
+ dom=parse( StringIO( open( tstfile ).read() ) )
+ dom.unlink()
+ confirm(isinstance(dom,Document))
+
def testGetElementsByTagName( ):
dom=parse( tstfile )
- assert dom.getElementsByTagName( "LI" )==\
- dom.documentElement.getElementsByTagName( "LI" )
+ confirm( dom.getElementsByTagName( "LI" )==\
+ dom.documentElement.getElementsByTagName( "LI" ) )
dom.unlink()
dom=None
- assert( len( Node.allnodes ))==0
+ confirm (len( Node.allnodes )==0)
def testInsertBefore( ):
dom=parse( tstfile )
@@ -32,44 +46,44 @@ def testInsertBefore( ):
#docel.insertBefore( dom.createProcessingInstruction("a", "b"),
# docel.childNodes[0])
- #assert docel.childNodes[0].target=="a"
- #assert docel.childNodes[2].target=="a"
+ #confirm( docel.childNodes[0].tet=="a" )
+ #confirm( docel.childNodes[2].tet=="a" )
dom.unlink()
del dom
del docel
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0)
def testAppendChild():
dom=parse( tstfile )
dom.documentElement.appendChild( dom.createComment( u"Hello" ))
- assert dom.documentElement.childNodes[-1].nodeName=="#comment"
- assert dom.documentElement.childNodes[-1].data=="Hello"
+ confirm( dom.documentElement.childNodes[-1].nodeName=="#comment" )
+ confirm( dom.documentElement.childNodes[-1].data=="Hello" )
dom.unlink()
dom=None
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0 )
def testNonZero():
dom=parse( tstfile )
- assert dom # should not be zero
+ confirm( dom )# should not be zero
dom.appendChild( dom.createComment( "foo" ) )
- assert not dom.childNodes[-1].childNodes
+ confirm( not dom.childNodes[-1].childNodes )
dom.unlink()
dom=None
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0 )
def testUnlink():
dom=parse( tstfile )
dom.unlink()
dom=None
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0 )
def testElement():
dom=Document()
dom.appendChild( dom.createElement( "abc" ) )
- assert dom.documentElement
+ confirm( dom.documentElement )
dom.unlink()
dom=None
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0 )
def testAAA():
dom=parseString( "<abc/>" )
@@ -91,20 +105,20 @@ def testAddAttr():
child=dom.appendChild( dom.createElement( "abc" ) )
child.setAttribute( "def", "ghi" )
- assert child.getAttribute( "def" )=="ghi"
- assert child.attributes["def"].value=="ghi"
+ confirm( child.getAttribute( "def" )=="ghi" )
+ confirm( child.attributes["def"].value=="ghi" )
child.setAttribute( "jkl", "mno" )
- assert child.getAttribute( "jkl" )=="mno"
- assert child.attributes["jkl"].value=="mno"
+ confirm( child.getAttribute( "jkl" )=="mno" )
+ confirm( child.attributes["jkl"].value=="mno" )
- assert len( child.attributes )==2
+ confirm( len( child.attributes )==2 )
child.setAttribute( "def", "newval" )
- assert child.getAttribute( "def" )=="newval"
- assert child.attributes["def"].value=="newval"
+ confirm( child.getAttribute( "def" )=="newval" )
+ confirm( child.attributes["def"].value=="newval" )
- assert len( child.attributes )==2
+ confirm( len( child.attributes )==2 )
dom.unlink()
dom=None
@@ -114,22 +128,22 @@ def testDeleteAttr():
dom=Document()
child=dom.appendChild( dom.createElement( "abc" ) )
- assert len( child.attributes)==0
+ confirm( len( child.attributes)==0 )
child.setAttribute( "def", "ghi" )
- assert len( child.attributes)==1
+ confirm( len( child.attributes)==1 )
del child.attributes["def"]
- assert len( child.attributes)==0
+ confirm( len( child.attributes)==0 )
dom.unlink()
- assert( len( Node.allnodes ))==0
+ confirm( len( Node.allnodes )==0 )
def testRemoveAttr():
dom=Document()
child=dom.appendChild( dom.createElement( "abc" ) )
child.setAttribute( "def", "ghi" )
- assert len( child.attributes)==1
+ confirm( len( child.attributes)==1 )
child.removeAttribute("def" )
- assert len( child.attributes)==0
+ confirm( len( child.attributes)==0 )
dom.unlink()
@@ -140,9 +154,9 @@ def testRemoveAttrNS():
child.setAttributeNS( "http://www.w3.org", "xmlns:python",
"http://www.python.org" )
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" )
- assert len( child.attributes )==1
+ confirm( len( child.attributes )==1 )
dom.unlink()
dom=None
@@ -151,31 +165,31 @@ def testRemoveAttributeNode():
dom=Document()
child=dom.appendChild( dom.createElement( "foo" ) )
child.setAttribute( "spam", "jam" )
- assert len( child.attributes )==1
+ confirm( len( child.attributes )==1 )
node=child.getAttributeNode( "spam" )
child.removeAttributeNode( node )
- assert len( child.attributes )==0
+ confirm( len( child.attributes )==0 )
dom.unlink()
dom=None
- assert len( Node.allnodes )==0
+ confirm( len( Node.allnodes )==0 )
def testChangeAttr():
dom=parseString( "<abc/>" )
el=dom.documentElement
el.setAttribute( "spam", "jam" )
- assert len( el.attributes )==1
+ confirm( len( el.attributes )==1 )
el.setAttribute( "spam", "bam" )
- assert len( el.attributes )==1
+ confirm( len( el.attributes )==1 )
el.attributes["spam"]="ham"
- assert len( el.attributes )==1
+ confirm( len( el.attributes )==1 )
el.setAttribute( "spam2", "bam" )
- assert len( el.attributes )==2
+ confirm( len( el.attributes )==2 )
el.attributes[ "spam2"]= "bam2"
- assert len( el.attributes )==2
+ confirm( len( el.attributes )==2 )
dom.unlink()
dom=None
- assert len( Node.allnodes )==0
+ confirm( len( Node.allnodes )==0 )
def testGetAttrList():
pass
@@ -199,7 +213,7 @@ def testElementReprAndStr():
el=dom.appendChild( dom.createElement( "abc" ) )
string1=repr( el )
string2=str( el )
- assert string1==string2
+ confirm( string1==string2 )
dom.unlink()
# commented out until Fredrick's fix is checked in
@@ -208,25 +222,25 @@ def _testElementReprAndStrUnicode():
el=dom.appendChild( dom.createElement( u"abc" ) )
string1=repr( el )
string2=str( el )
- assert string1==string2
+ confirm( string1==string2 )
dom.unlink()
# commented out until Fredrick's fix is checked in
def _testElementReprAndStrUnicodeNS():
dom=Document()
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 )
string2=str( el )
- assert string1==string2
- assert string1.find("slash:abc" )!=-1
+ confirm( string1==string2 )
+ confirm( string1.find("slash:abc" )!=-1 )
dom.unlink()
def testAttributeRepr():
dom=Document()
el=dom.appendChild( dom.createElement( u"abc" ) )
node=el.setAttribute( "abc", "def" )
- assert str( node ) == repr( node )
+ confirm( str( node ) == repr( node ) )
dom.unlink()
def testTextNodeRepr(): pass
@@ -312,6 +326,9 @@ def testClonePIDeep(): pass
names=globals().keys()
names.sort()
+
+works=1
+
for name in names:
if name.startswith( "test" ):
func=globals()[name]
@@ -320,12 +337,24 @@ for name in names:
print "Test Succeeded", name
if len( Node.allnodes ):
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={}
except Exception, e :
+ works=0
print "Test Failed: ", name
apply( traceback.print_exception, sys.exc_info() )
print `e`
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
diff --git a/Lib/dos-8x3/test_pic.py b/Lib/dos-8x3/test_pic.py
index 8fb534d..3c81fdd 100644
--- a/Lib/dos-8x3/test_pic.py
+++ b/Lib/dos-8x3/test_pic.py
@@ -1,5 +1,6 @@
# Test the pickle module
+# break into multiple strings to please font-lock-mode
DATA = """(lp0
I0
aL1L
@@ -7,17 +8,20 @@ aF2.0
ac__builtin__
complex
p1
-(F3.0
+""" \
+"""(F3.0
F0.0
tp2
Rp3
a(S'abc'
p4
g4
-(i__main__
+""" \
+"""(i__main__
C
p5
-(dp6
+""" \
+"""(dp6
S'foo'
p7
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.'
-import pickle
-
class C:
def __cmp__(self, other):
return cmp(self.__dict__, other.__dict__)
@@ -42,7 +44,7 @@ class C:
import __main__
__main__.C = C
-def dotest():
+def dotest(pickle):
c = C()
c.foo = 1
c.bar = 2
@@ -51,6 +53,8 @@ def dotest():
x.append(y)
x.append(y)
x.append(5)
+ r = []
+ r.append(r)
print "dumps()"
s = pickle.dumps(x)
print "loads()"
@@ -71,5 +75,69 @@ def dotest():
x2 = pickle.loads(BINDATA)
if x2 == x: print "ok"
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)
diff --git a/Lib/dos-8x3/test_pye.py b/Lib/dos-8x3/test_pye.py
index d6bd84b..a119987 100644
--- a/Lib/dos-8x3/test_pye.py
+++ b/Lib/dos-8x3/test_pye.py
@@ -3,10 +3,7 @@
# XXX TypeErrors on calling handlers, or on bad return values from a
# handler, are obscure and unhelpful.
-import sys, string
-import os
-
-import pyexpat
+from xml.parsers import expat
class Outputter:
def StartElementHandler(self, name, attrs):
@@ -16,7 +13,7 @@ class Outputter:
print 'End element:\n\t', repr(name)
def CharacterDataHandler(self, data):
- data = string.strip(data)
+ data = data.strip()
if data:
print 'Character data:'
print '\t', repr(data)
@@ -63,29 +60,37 @@ class Outputter:
pass
+def confirm(ok):
+ if ok:
+ print "OK."
+ else:
+ print "Not OK."
+
out = Outputter()
-parser = pyexpat.ParserCreate(namespace_separator='!')
+parser = expat.ParserCreate(namespace_separator='!')
# Test getting/setting returns_unicode
-parser.returns_unicode = 0 ; assert parser.returns_unicode == 0
-parser.returns_unicode = 1 ; assert parser.returns_unicode == 1
-parser.returns_unicode = 2 ; assert parser.returns_unicode == 1
-parser.returns_unicode = 0 ; assert parser.returns_unicode == 0
-
-HANDLER_NAMES = ['StartElementHandler', 'EndElementHandler',
- 'CharacterDataHandler', 'ProcessingInstructionHandler',
- 'UnparsedEntityDeclHandler', 'NotationDeclHandler',
- 'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
- 'CommentHandler', 'StartCdataSectionHandler',
- 'EndCdataSectionHandler',
- 'DefaultHandler', 'DefaultHandlerExpand',
- #'NotStandaloneHandler',
- 'ExternalEntityRefHandler'
- ]
+parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
+parser.returns_unicode = 1; confirm(parser.returns_unicode == 1)
+parser.returns_unicode = 2; confirm(parser.returns_unicode == 1)
+parser.returns_unicode = 0; confirm(parser.returns_unicode == 0)
+
+HANDLER_NAMES = [
+ 'StartElementHandler', 'EndElementHandler',
+ 'CharacterDataHandler', 'ProcessingInstructionHandler',
+ 'UnparsedEntityDeclHandler', 'NotationDeclHandler',
+ 'StartNamespaceDeclHandler', 'EndNamespaceDeclHandler',
+ 'CommentHandler', 'StartCdataSectionHandler',
+ 'EndCdataSectionHandler',
+ 'DefaultHandler', 'DefaultHandlerExpand',
+ #'NotStandaloneHandler',
+ 'ExternalEntityRefHandler'
+ ]
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"?>
<!-- comment data -->
<!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>
&external_entity;
</root>
-"""
+'''
# Produce UTF-8 output
parser.returns_unicode = 0
try:
parser.Parse(data, 1)
-except pyexpat.error:
- print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
+except expat.error:
+ print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
print '** Line', parser.ErrorLineNumber
print '** Column', parser.ErrorColumnNumber
print '** Byte', parser.ErrorByteIndex
# Try the parse again, this time producing Unicode output
-parser = pyexpat.ParserCreate(namespace_separator='!')
+parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
for name in HANDLER_NAMES:
- setattr(parser, name, getattr(out, name) )
+ setattr(parser, name, getattr(out, name))
try:
parser.Parse(data, 1)
-except pyexpat.error:
- print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
+except expat.error:
+ print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
print '** Line', parser.ErrorLineNumber
print '** Column', parser.ErrorColumnNumber
print '** Byte', parser.ErrorByteIndex
# Try parsing a file
-parser = pyexpat.ParserCreate(namespace_separator='!')
+parser = expat.ParserCreate(namespace_separator='!')
parser.returns_unicode = 1
for name in HANDLER_NAMES:
- setattr(parser, name, getattr(out, name) )
+ setattr(parser, name, getattr(out, name))
import StringIO
file = StringIO.StringIO(data)
try:
parser.ParseFile(file)
-except pyexpat.error:
- print '** Error', parser.ErrorCode, pyexpat.ErrorString( parser.ErrorCode)
+except expat.error:
+ print '** Error', parser.ErrorCode, expat.ErrorString(parser.ErrorCode)
print '** Line', parser.ErrorLineNumber
print '** Column', parser.ErrorColumnNumber
print '** Byte', parser.ErrorByteIndex
-
diff --git a/Lib/dos-8x3/test_rfc.py b/Lib/dos-8x3/test_rfc.py
index 0d4c66f..36e7a51 100644
--- a/Lib/dos-8x3/test_rfc.py
+++ b/Lib/dos-8x3/test_rfc.py
@@ -120,3 +120,7 @@ Date: Wed, 13 Jan 1999 23:57:35 -0500
test''', [('', 'goit@lip.com')])
+
+test('''To: guido@[132.151.1.21]
+
+foo''', [('', 'guido@[132.151.1.21]')])
diff --git a/Lib/dos-8x3/test_str.py b/Lib/dos-8x3/test_str.py
index c713d05..6e321e9 100644
--- a/Lib/dos-8x3/test_str.py
+++ b/Lib/dos-8x3/test_str.py
@@ -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
-from test_support import verbose
+def do_test(module):
+ s = (string.letters+'\n')*5
+ f = module.StringIO(s)
+ print f.read(10)
+ print f.readline()
+ print len(f.readlines(60))
-def main():
- global verbose
- now = time.time()
- strftest(now)
- 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()
+# Don't bother testing cStringIO without
+import StringIO, cStringIO
+do_test(StringIO)
+do_test(cStringIO)
diff --git a/Lib/dos-8x3/test_url.py b/Lib/dos-8x3/test_url.py
index e69de29..484acea 100644
--- a/Lib/dos-8x3/test_url.py
+++ b/Lib/dos-8x3/test_url.py
@@ -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"
+
+
diff --git a/Lib/dos-8x3/test_win.py b/Lib/dos-8x3/test_win.py
index 7b4fa15..18ce7a7 100644
--- a/Lib/dos-8x3/test_win.py
+++ b/Lib/dos-8x3/test_win.py
@@ -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
-for i in range(100, 2000, 100):
- winsound.Beep(i, 75)
-print "Hopefully you heard some sounds increasing in frequency!"
+from _winreg import *
+import os, sys
+
+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'"
diff --git a/Lib/dos-8x3/userlist.py b/Lib/dos-8x3/userlist.py
index 1146060..aab5119 100755
--- a/Lib/dos-8x3/userlist.py
+++ b/Lib/dos-8x3/userlist.py
@@ -17,6 +17,7 @@ class UserList:
return cmp(self.data, other.data)
else:
return cmp(self.data, other)
+ def __contains__(self, item): return item in self.data
def __len__(self): return len(self.data)
def __getitem__(self, i): return self.data[i]
def __setitem__(self, i, item): self.data[i] = item
diff --git a/Lib/dos-8x3/webbrows.py b/Lib/dos-8x3/webbrows.py
index 66cdbff..a8b0e8b 100644
--- a/Lib/dos-8x3/webbrows.py
+++ b/Lib/dos-8x3/webbrows.py
@@ -183,7 +183,7 @@ register("grail", Grail)
class WindowsDefault:
def open(self, url, new=0):
- self.junk = os.popen("start " + url)
+ os.startfile(url)
def open_new(self, url):
self.open(url)