[Python-checkins] CVS: python/dist/src/Lib/test test_fileinput.py,NONE,1.1.2.1 test_socketserver.py,NONE,1.3.2.1 test_uu.py,NONE,1.1.2.1 test_cfgparser.py,1.7,1.7.6.1 test_gc.py,1.7,1.7.6.1 test_generators.py,1.17.2.3,1.17.2.4 test_pow.py,1.7,1.7.6.1 test_scope.py,1.14.4.1,1.14.4.2 test_sundry.py,1.4,1.4.4.1
Tim Peters
tim_one@users.sourceforge.net
Sat, 14 Jul 2001 00:47:37 -0700
- Previous message: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,NONE,1.1.2.1 ConfigParser.py,1.32,1.32.6.1 SocketServer.py,1.24,1.24.4.1 __future__.py,1.5,1.5.4.1 site.py,1.26.4.1,1.26.4.2 sre.py,1.31,1.31.4.1 symbol.py,1.12,1.12.8.1 symtable.py,1.4,1.4.4.1 uu.py,1.16,1.16.6.1
- Next message: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.26,1.1.2.27 acconfig.h,1.46.4.1,1.46.4.2 config.h.in,2.92.2.1,2.92.2.2 configure,1.209.2.1,1.209.2.2 configure.in,1.217.2.1,1.217.2.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/python/python/dist/src/Lib/test
In directory usw-pr-cvs1:/tmp/cvs-serv29618/descr/dist/src/Lib/test
Modified Files:
Tag: descr-branch
test_cfgparser.py test_gc.py test_generators.py test_pow.py
test_scope.py test_sundry.py
Added Files:
Tag: descr-branch
test_fileinput.py test_socketserver.py test_uu.py
Log Message:
Merge of trunk tag date2001-07-13 into descr-branch. See PLAN.txt.
--- NEW FILE: test_fileinput.py ---
'''
Tests for fileinput module.
Nick Mathewson
'''
from test_support import verify, verbose, TESTFN
import sys, os, re
from StringIO import StringIO
from fileinput import FileInput
# The fileinput module has 2 interfaces: the FileInput class which does
# all the work, and a few functions (input, etc.) that use a global _state
# variable. We only test the FileInput class, since the other functions
# only provide a thin facade over FileInput.
# Write lines (a list of lines) to temp file number i, and return the
# temp file's name.
def writeTmp(i, lines):
name = TESTFN + str(i)
f = open(name, 'w')
f.writelines(lines)
f.close()
return name
pat = re.compile(r'LINE (\d+) OF FILE (\d+)')
def remove_tempfiles(*names):
for name in names:
try:
os.unlink(name)
except:
pass
def runTests(t1, t2, t3, t4, bs=0, round=0):
start = 1 + round*6
if verbose:
print '%s. Simple iteration (bs=%s)' % (start+0, bs)
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
lines = list(fi)
fi.close()
verify(len(lines) == 31)
verify(lines[4] == 'Line 5 of file 1\n')
verify(lines[30] == 'Line 1 of file 4\n')
verify(fi.lineno() == 31)
verify(fi.filename() == t4)
if verbose:
print '%s. Status variables (bs=%s)' % (start+1, bs)
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
s = "x"
while s and s != 'Line 6 of file 2\n':
s = fi.readline()
verify(fi.filename() == t2)
verify(fi.lineno() == 21)
verify(fi.filelineno() == 6)
verify(not fi.isfirstline())
verify(not fi.isstdin())
if verbose:
print '%s. Nextfile (bs=%s)' % (start+2, bs)
fi.nextfile()
verify(fi.readline() == 'Line 1 of file 3\n')
verify(fi.lineno() == 22)
fi.close()
if verbose:
print '%s. Stdin (bs=%s)' % (start+3, bs)
fi = FileInput(files=(t1, t2, t3, t4, '-'), bufsize=bs)
savestdin = sys.stdin
try:
sys.stdin = StringIO("Line 1 of stdin\nLine 2 of stdin\n")
lines = list(fi)
verify(len(lines) == 33)
verify(lines[32] == 'Line 2 of stdin\n')
verify(fi.filename() == '<stdin>')
fi.nextfile()
finally:
sys.stdin = savestdin
if verbose:
print '%s. Boundary conditions (bs=%s)' % (start+4, bs)
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
verify(fi.lineno() == 0)
verify(fi.filename() == None)
fi.nextfile()
verify(fi.lineno() == 0)
verify(fi.filename() == None)
if verbose:
print '%s. Inplace (bs=%s)' % (start+5, bs)
savestdout = sys.stdout
try:
fi = FileInput(files=(t1, t2, t3, t4), inplace=1, bufsize=bs)
for line in fi:
line = line[:-1].upper()
print line
fi.close()
finally:
sys.stdout = savestdout
fi = FileInput(files=(t1, t2, t3, t4), bufsize=bs)
for line in fi:
verify(line[-1] == '\n')
m = pat.match(line[:-1])
verify(m != None)
verify(int(m.group(1)) == fi.filelineno())
fi.close()
def writeFiles():
global t1, t2, t3, t4
t1 = writeTmp(1, ["Line %s of file 1\n" % (i+1) for i in range(15)])
t2 = writeTmp(2, ["Line %s of file 2\n" % (i+1) for i in range(10)])
t3 = writeTmp(3, ["Line %s of file 3\n" % (i+1) for i in range(5)])
t4 = writeTmp(4, ["Line %s of file 4\n" % (i+1) for i in range(1)])
# First, run the tests with default and teeny buffer size.
for round, bs in (0, 0), (1, 30):
try:
writeFiles()
runTests(t1, t2, t3, t4, bs, round)
finally:
remove_tempfiles(t1, t2, t3, t4)
# Next, check for proper behavior with 0-byte files.
if verbose:
print "13. 0-byte files"
try:
t1 = writeTmp(1, [""])
t2 = writeTmp(2, [""])
t3 = writeTmp(3, ["The only line there is.\n"])
t4 = writeTmp(4, [""])
fi = FileInput(files=(t1, t2, t3, t4))
line = fi.readline()
verify(line == 'The only line there is.\n')
verify(fi.lineno() == 1)
verify(fi.filelineno() == 1)
verify(fi.filename() == t3)
line = fi.readline()
verify(not line)
verify(fi.lineno() == 1)
verify(fi.filelineno() == 0)
verify(fi.filename() == t4)
fi.close()
finally:
remove_tempfiles(t1, t2, t3, t4)
if verbose:
print "14. Files that don't end with newline"
try:
t1 = writeTmp(1, ["A\nB\nC"])
t2 = writeTmp(2, ["D\nE\nF"])
fi = FileInput(files=(t1, t2))
lines = list(fi)
verify(lines == ["A\n", "B\n", "C", "D\n", "E\n", "F"])
verify(fi.filelineno() == 3)
verify(fi.lineno() == 6)
finally:
remove_tempfiles(t1, t2)
--- NEW FILE: test_socketserver.py ---
# Test suite for SocketServer.py
# XXX This must be run manually -- somehow the I/O redirection of the
# regression test breaks the test.
from test_support import verbose, verify, TESTFN, TestSkipped
if not verbose:
raise TestSkipped, "test_socketserver can only be run manually"
from SocketServer import *
import socket
import select
import time
import threading
import os
NREQ = 3
DELAY = 0.5
class MyMixinHandler:
def handle(self):
time.sleep(DELAY)
line = self.rfile.readline()
time.sleep(DELAY)
self.wfile.write(line)
class MyStreamHandler(MyMixinHandler, StreamRequestHandler):
pass
class MyDatagramHandler(MyMixinHandler, DatagramRequestHandler):
pass
class MyMixinServer:
def serve_a_few(self):
for i in range(NREQ):
self.handle_request()
def handle_error(self, request, client_address):
self.close_request(request)
self.server_close()
raise
teststring = "hello world\n"
def receive(sock, n, timeout=20):
r, w, x = select.select([sock], [], [], timeout)
if sock in r:
return sock.recv(n)
else:
raise RuntimeError, "timed out on %s" % `sock`
def testdgram(proto, addr):
s = socket.socket(proto, socket.SOCK_DGRAM)
s.sendto(teststring, addr)
buf = data = receive(s, 100)
while data and '\n' not in buf:
data = receive(s, 100)
buf += data
verify(buf == teststring)
s.close()
def teststream(proto, addr):
s = socket.socket(proto, socket.SOCK_STREAM)
s.connect(addr)
s.send(teststring)
buf = data = receive(s, 100)
while data and '\n' not in buf:
data = receive(s, 100)
buf += data
verify(buf == teststring)
s.close()
class ServerThread(threading.Thread):
def __init__(self, addr, svrcls, hdlrcls):
threading.Thread.__init__(self)
self.__addr = addr
self.__svrcls = svrcls
self.__hdlrcls = hdlrcls
def run(self):
class svrcls(MyMixinServer, self.__svrcls):
pass
if verbose: print "thread: creating server"
svr = svrcls(self.__addr, self.__hdlrcls)
if verbose: print "thread: serving three times"
svr.serve_a_few()
if verbose: print "thread: done"
seed = 0
def pickport():
global seed
seed += 1
return 10000 + (os.getpid() % 1000)*10 + seed
host = "localhost"
testfiles = []
def pickaddr(proto):
if proto == socket.AF_INET:
return (host, pickport())
else:
fn = TESTFN + str(pickport())
testfiles.append(fn)
return fn
def cleanup():
for fn in testfiles:
try:
os.remove(fn)
except os.error:
pass
testfiles[:] = []
def testloop(proto, servers, hdlrcls, testfunc):
for svrcls in servers:
addr = pickaddr(proto)
if verbose:
print "ADDR =", addr
print "CLASS =", svrcls
t = ServerThread(addr, svrcls, hdlrcls)
if verbose: print "server created"
t.start()
if verbose: print "server running"
for i in range(NREQ):
time.sleep(DELAY)
if verbose: print "test client", i
testfunc(proto, addr)
if verbose: print "waiting for server"
t.join()
if verbose: print "done"
tcpservers = [TCPServer, ThreadingTCPServer]
if hasattr(os, 'fork'):
tcpservers.append(ForkingTCPServer)
udpservers = [UDPServer, ThreadingUDPServer]
if hasattr(os, 'fork'):
udpservers.append(ForkingUDPServer)
if not hasattr(socket, 'AF_UNIX'):
streamservers = []
dgramservers = []
else:
class ForkingUnixStreamServer(ForkingMixIn, UnixStreamServer): pass
streamservers = [UnixStreamServer, ThreadingUnixStreamServer,
ForkingUnixStreamServer]
class ForkingUnixDatagramServer(ForkingMixIn, UnixDatagramServer): pass
dgramservers = [UnixDatagramServer, ThreadingUnixDatagramServer,
ForkingUnixDatagramServer]
def testall():
testloop(socket.AF_INET, tcpservers, MyStreamHandler, teststream)
testloop(socket.AF_INET, udpservers, MyDatagramHandler, testdgram)
if hasattr(socket, 'AF_UNIX'):
testloop(socket.AF_UNIX, streamservers, MyStreamHandler, teststream)
# Alas, on Linux (at least) recvfrom() doesn't return a meaningful
# client address so this cannot work:
##testloop(socket.AF_UNIX, dgramservers, MyDatagramHandler, testdgram)
def main():
try:
testall()
finally:
cleanup()
main()
--- NEW FILE: test_uu.py ---
"""
Tests for uu module.
Nick Mathewson
"""
from test_support import verify, TestFailed, verbose, TESTFN
import sys, os
import uu
from StringIO import StringIO
teststr = "The smooth-scaled python crept over the sleeping dog\n"
expected = """\
M5&AE('-M;V]T:\"US8V%L960@<'ET:&]N(&-R97!T(&]V97(@=&AE('-L965P
(:6YG(&1O9PH """
encoded1 = "begin 666 t1\n"+expected+"\n \nend\n"
if verbose:
print '1. encode file->file'
inp = StringIO(teststr)
out = StringIO()
uu.encode(inp, out, "t1")
verify(out.getvalue() == encoded1)
inp = StringIO(teststr)
out = StringIO()
uu.encode(inp, out, "t1", 0644)
verify(out.getvalue() == "begin 644 t1\n"+expected+"\n \nend\n")
if verbose:
print '2. decode file->file'
inp = StringIO(encoded1)
out = StringIO()
uu.decode(inp, out)
verify(out.getvalue() == teststr)
inp = StringIO("""UUencoded files may contain many lines,
even some that have 'begin' in them.\n"""+encoded1)
out = StringIO()
uu.decode(inp, out)
verify(out.getvalue() == teststr)
stdinsave = sys.stdin
stdoutsave = sys.stdout
try:
if verbose:
print '3. encode stdin->stdout'
sys.stdin = StringIO(teststr)
sys.stdout = StringIO()
uu.encode("-", "-", "t1", 0666)
verify(sys.stdout.getvalue() == encoded1)
if verbose:
print >>stdoutsave, '4. decode stdin->stdout'
sys.stdin = StringIO(encoded1)
sys.stdout = StringIO()
uu.decode("-", "-")
verify(sys.stdout.getvalue() == teststr)
finally:
sys.stdin = stdinsave
sys.stdout = stdoutsave
if verbose:
print '5. encode file->file'
tmpIn = TESTFN + "i"
tmpOut = TESTFN + "o"
try:
fin = open(tmpIn, 'w')
fin.write(teststr)
fin.close()
fin = open(tmpIn, 'r')
fout = open(tmpOut, 'w')
uu.encode(fin, fout, tmpIn, mode=0644)
fin.close()
fout.close()
fout = open(tmpOut, 'r')
s = fout.read()
fout.close()
verify(s == 'begin 644 ' + tmpIn + '\n' + expected + '\n \nend\n')
os.unlink(tmpIn)
if verbose:
print '6. decode file-> file'
uu.decode(tmpOut)
fin = open(tmpIn, 'r')
s = fin.read()
fin.close()
verify(s == teststr)
# XXX is there an xp way to verify the mode?
finally:
try:
fin.close()
except:
pass
try:
fout.close()
except:
pass
try:
os.unlink(tmpIn)
except:
pass
try:
os.unlink(tmpOut)
except:
pass
if verbose:
print '7. error: truncated input'
inp = StringIO("begin 644 t1\n"+expected)
out = StringIO()
try:
uu.decode(inp, out)
raise TestFailed("No exception thrown")
except uu.Error, e:
verify(str(e) == 'Truncated input file')
if verbose:
print '8. error: missing begin'
inp = StringIO("")
out = StringIO()
try:
uu.decode(inp, out)
raise TestFailed("No exception thrown")
except uu.Error, e:
verify(str(e) == 'No valid begin line found in input file')
Index: test_cfgparser.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_cfgparser.py,v
retrieving revision 1.7
retrieving revision 1.7.6.1
diff -C2 -r1.7 -r1.7.6.1
*** test_cfgparser.py 2001/02/26 21:55:34 1.7
--- test_cfgparser.py 2001/07/14 07:47:34 1.7.6.1
***************
*** 71,74 ****
--- 71,81 ----
verify(cf.options("a") == [])
+ # SF bug #432369:
+ cf = ConfigParser.ConfigParser()
+ sio = StringIO.StringIO("[MySection]\nOption: first line\n\tsecond line\n")
+ cf.readfp(sio)
+ verify(cf.options("MySection") == ["option"])
+ verify(cf.get("MySection", "Option") == "first line\nsecond line")
+
def interpolation(src):
Index: test_gc.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_gc.py,v
retrieving revision 1.7
retrieving revision 1.7.6.1
diff -C2 -r1.7 -r1.7.6.1
*** test_gc.py 2001/01/17 19:11:13 1.7
--- test_gc.py 2001/07/14 07:47:34 1.7.6.1
***************
*** 1,3 ****
--- 1,4 ----
from test_support import verify, verbose, TestFailed
+ import sys
import gc
***************
*** 108,111 ****
--- 109,121 ----
raise TestFailed
+ def test_frame():
+ def f():
+ frame = sys._getframe()
+ gc.collect()
+ f()
+ if gc.collect() != 1:
+ raise TestFailed
+
+
def test_saveall():
# Verify that cyclic garbage like lists show up in gc.garbage if the
***************
*** 153,156 ****
--- 163,167 ----
run_test("methods", test_method)
run_test("functions", test_function)
+ run_test("frames", test_frame)
run_test("finalizers", test_finalizer)
run_test("__del__", test_del)
Index: test_generators.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v
retrieving revision 1.17.2.3
retrieving revision 1.17.2.4
diff -C2 -r1.17.2.3 -r1.17.2.4
*** test_generators.py 2001/07/13 21:49:33 1.17.2.3
--- test_generators.py 2001/07/14 07:47:34 1.17.2.4
***************
*** 1,4 ****
- from __future__ import nested_scopes
-
tutorial_tests = """
Let's try a simple generator:
--- 1,2 ----
***************
*** 50,54 ****
>>> def f():
... yield 1
! ... return
... yield 2 # never reached
...
--- 48,52 ----
>>> def f():
... yield 1
! ... raise StopIteration
... yield 2 # never reached
...
***************
*** 444,450 ****
... def __str__(self):
... return self.name
- ...
- ... def clear(self):
- ... self.__dict__.clear()
>>> names = "ABCDEFGHIJKLM"
--- 442,445 ----
***************
*** 491,496 ****
merged A into G
A->G B->G C->G D->G E->G F->G G->G H->G I->G J->G K->G L->G M->G
- >>> for s in sets: # XXX memory leak without this
- ... s.clear()
"""
--- 486,489 ----
***************
*** 605,611 ****
... sofar.append(fetch())
... return sofar[i]
- ...
- ... def clear(self):
- ... self.__dict__.clear()
>>> def m235():
--- 598,601 ----
***************
*** 621,625 ****
Print as many of these as you like -- *this* implementation is memory-
! efficient. XXX Except that it leaks unless you clear the dict!
>>> m235 = LazyList(m235())
--- 611,615 ----
Print as many of these as you like -- *this* implementation is memory-
! efficient.
>>> m235 = LazyList(m235())
***************
*** 632,638 ****
[400, 405, 432, 450, 480, 486, 500, 512, 540, 576, 600, 625, 640, 648, 675]
- >>> m235.clear() # XXX memory leak without this
-
Ye olde Fibonacci generator, LazyList style.
--- 622,626 ----
***************
*** 657,662 ****
>>> firstn(iter(fib), 17)
[1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584]
-
- >>> fib.clear() # XXX memory leak without this
"""
--- 645,648 ----
***************
*** 924,928 ****
# NOTE WELL: This allows large problems to be solved with only trivial
# demands on stack space. Without explicitly resumable generators, this is
! # much harder to achieve.
def flat_conjoin(gs): # rename to conjoin to run tests with this instead
--- 910,915 ----
# NOTE WELL: This allows large problems to be solved with only trivial
# demands on stack space. Without explicitly resumable generators, this is
! # much harder to achieve. OTOH, this is much slower (up to a factor of 2)
! # than the fancy unrolled recursive conjoin.
def flat_conjoin(gs): # rename to conjoin to run tests with this instead
***************
*** 930,954 ****
values = [None] * n
iters = [None] * n
i = 0
! while i >= 0:
! # Need a fresh iterator.
! if i >= n:
! yield values
! # Backtrack.
! i -= 1
else:
! iters[i] = gs[i]().next
! # Need next value from current iterator.
while i >= 0:
try:
values[i] = iters[i]()
! except StopIteration:
! # Backtrack.
! i -= 1
! else:
! # Start fresh at next level.
i += 1
break
# A conjoin-based N-Queens solver.
--- 917,949 ----
values = [None] * n
iters = [None] * n
+ _StopIteration = StopIteration # make local because caught a *lot*
i = 0
! while 1:
! # Descend.
! try:
! while i < n:
! it = iters[i] = gs[i]().next
! values[i] = it()
! i += 1
! except _StopIteration:
! pass
else:
! assert i == n
! yield values
! # Backtrack until an older iterator can be resumed.
! i -= 1
while i >= 0:
try:
values[i] = iters[i]()
! # Success! Start fresh at next level.
i += 1
break
+ except _StopIteration:
+ # Continue backtracking.
+ i -= 1
+ else:
+ assert i < 0
+ break
# A conjoin-based N-Queens solver.
***************
*** 1007,1035 ****
# (e.g., when used with flat_conjoin above, and passing hard=1 to the
# constructor, a 200x200 Knight's Tour was found quickly -- note that we're
! # creating 10s of thousands of generators then!), so goes on at some length
class Knights:
! def __init__(self, n, hard=0):
! self.n = n
!
! def coords2index(i, j):
! return i*n + j
! offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2),
! (-1, -2), (-2, -1), (-2, 1), (-1, 2)]
! succs = []
! for i in range(n):
! for j in range(n):
! s = [coords2index(i+io, j+jo) for io, jo in offsets
! if 0 <= i+io < n and
! 0 <= j+jo < n]
! succs.append(s)
! del s
! del offsets
! free = [0] * n**2 # 0 if occupied, 1 if visited
! nexits = free[:] # number of free successors
!
! def decrexits(i0):
# If we remove all exits from a free square, we're dead:
# even if we move to it next, we can't leave it again.
--- 1002,1020 ----
# (e.g., when used with flat_conjoin above, and passing hard=1 to the
# constructor, a 200x200 Knight's Tour was found quickly -- note that we're
! # creating 10s of thousands of generators then!), and is lengthy.
class Knights:
! def __init__(self, m, n, hard=0):
! self.m, self.n = m, n
! # solve() will set up succs[i] to be a list of square #i's
! # successors.
! succs = self.succs = []
!
! # Remove i0 from each of its successor's successor lists, i.e.
! # successors can't go back to i0 again. Return 0 if we can
! # detect this makes a solution impossible, else return 1.
! def remove_from_successors(i0, len=len):
# If we remove all exits from a free square, we're dead:
# even if we move to it next, we can't leave it again.
***************
*** 1042,1120 ****
ne0 = ne1 = 0
for i in succs[i0]:
! if free[i]:
! e = nexits[i] - 1
! nexits[i] = e
! if e == 0:
! ne0 += 1
! elif e == 1:
! ne1 += 1
return ne0 == 0 and ne1 < 2
! def increxits(i0):
for i in succs[i0]:
! if free[i]:
! nexits[i] += 1
# Generate the first move.
def first():
! if n < 1:
return
- # Initialize board structures.
- for i in xrange(n**2):
- free[i] = 1
- nexits[i] = len(succs[i])
-
# Since we're looking for a cycle, it doesn't matter where we
# start. Starting in a corner makes the 2nd move easy.
! corner = coords2index(0, 0)
! free[corner] = 0
! decrexits(corner)
self.lastij = corner
yield corner
! increxits(corner)
! free[corner] = 1
# Generate the second moves.
def second():
! corner = coords2index(0, 0)
assert self.lastij == corner # i.e., we started in the corner
! if n < 3:
return
! assert nexits[corner] == len(succs[corner]) == 2
! assert coords2index(1, 2) in succs[corner]
! assert coords2index(2, 1) in succs[corner]
# Only two choices. Whichever we pick, the other must be the
! # square picked on move n**2, as it's the only way to get back
# to (0, 0). Save its index in self.final so that moves before
# the last know it must be kept free.
for i, j in (1, 2), (2, 1):
! this, final = coords2index(i, j), coords2index(3-i, 3-j)
! assert free[this] and free[final]
self.final = final
- nexits[final] += 1 # it has an exit back to 0,0
! free[this] = 0
! decrexits(this)
self.lastij = this
yield this
! increxits(this)
! free[this] = 1
!
! nexits[final] -= 1
! # Generate moves 3 thru n**2-1.
! def advance():
# If some successor has only one exit, must take it.
# Else favor successors with fewer exits.
candidates = []
for i in succs[self.lastij]:
! if free[i]:
! e = nexits[i]
! assert e > 0, "else decrexits() pruning flawed"
! if e == 1:
! candidates = [(e, i)]
! break
! candidates.append((e, i))
else:
candidates.sort()
--- 1027,1095 ----
ne0 = ne1 = 0
for i in succs[i0]:
! s = succs[i]
! s.remove(i0)
! e = len(s)
! if e == 0:
! ne0 += 1
! elif e == 1:
! ne1 += 1
return ne0 == 0 and ne1 < 2
+
+ # Put i0 back in each of its successor's successor lists.
! def add_to_successors(i0):
for i in succs[i0]:
! succs[i].append(i0)
# Generate the first move.
def first():
! if m < 1 or n < 1:
return
# Since we're looking for a cycle, it doesn't matter where we
# start. Starting in a corner makes the 2nd move easy.
! corner = self.coords2index(0, 0)
! remove_from_successors(corner)
self.lastij = corner
yield corner
! add_to_successors(corner)
# Generate the second moves.
def second():
! corner = self.coords2index(0, 0)
assert self.lastij == corner # i.e., we started in the corner
! if m < 3 or n < 3:
return
! assert len(succs[corner]) == 2
! assert self.coords2index(1, 2) in succs[corner]
! assert self.coords2index(2, 1) in succs[corner]
# Only two choices. Whichever we pick, the other must be the
! # square picked on move m*n, as it's the only way to get back
# to (0, 0). Save its index in self.final so that moves before
# the last know it must be kept free.
for i, j in (1, 2), (2, 1):
! this = self.coords2index(i, j)
! final = self.coords2index(3-i, 3-j)
self.final = final
! remove_from_successors(this)
! succs[final].append(corner)
self.lastij = this
yield this
! succs[final].remove(corner)
! add_to_successors(this)
! # Generate moves 3 thru m*n-1.
! def advance(len=len):
# If some successor has only one exit, must take it.
# Else favor successors with fewer exits.
candidates = []
for i in succs[self.lastij]:
! e = len(succs[i])
! assert e > 0, "else remove_from_successors() pruning flawed"
! if e == 1:
! candidates = [(e, i)]
! break
! candidates.append((e, i))
else:
candidates.sort()
***************
*** 1122,1138 ****
for e, i in candidates:
if i != self.final:
! if decrexits(i):
! free[i] = 0
self.lastij = i
yield i
! free[i] = 1
! increxits(i)
! # Generate moves 3 thru n**2-1. Alternative version using a
# stronger (but more expensive) heuristic to order successors.
! # Since the # of backtracking levels is n**2, a poor move early on
! # can take eons to undo. Smallest n for which this matters a lot is
! # n==52.
! def advance_hard(midpoint=(n-1)/2.0):
# If some successor has only one exit, must take it.
# Else favor successors with fewer exits.
--- 1097,1111 ----
for e, i in candidates:
if i != self.final:
! if remove_from_successors(i):
self.lastij = i
yield i
! add_to_successors(i)
! # Generate moves 3 thru m*n-1. Alternative version using a
# stronger (but more expensive) heuristic to order successors.
! # Since the # of backtracking levels is m*n, a poor move early on
! # can take eons to undo. Smallest square board for which this
! # matters a lot is 52x52.
! def advance_hard(vmid=(m-1)/2.0, hmid=(n-1)/2.0, len=len):
# If some successor has only one exit, must take it.
# Else favor successors with fewer exits.
***************
*** 1141,1153 ****
candidates = []
for i in succs[self.lastij]:
! if free[i]:
! e = nexits[i]
! assert e > 0, "else decrexits() pruning flawed"
! if e == 1:
! candidates = [(e, 0, i)]
! break
! i1, j1 = divmod(i, n)
! d = (i1 - midpoint)**2 + (j1 - midpoint)**2
! candidates.append((e, -d, i))
else:
candidates.sort()
--- 1114,1125 ----
candidates = []
for i in succs[self.lastij]:
! e = len(succs[i])
! assert e > 0, "else remove_from_successors() pruning flawed"
! if e == 1:
! candidates = [(e, 0, i)]
! break
! i1, j1 = self.index2coords(i)
! d = (i1 - vmid)**2 + (j1 - hmid)**2
! candidates.append((e, -d, i))
else:
candidates.sort()
***************
*** 1155,1164 ****
for e, d, i in candidates:
if i != self.final:
! if decrexits(i):
! free[i] = 0
self.lastij = i
yield i
! free[i] = 1
! increxits(i)
# Generate the last move.
--- 1127,1134 ----
for e, d, i in candidates:
if i != self.final:
! if remove_from_successors(i):
self.lastij = i
yield i
! add_to_successors(i)
# Generate the last move.
***************
*** 1167,1192 ****
yield self.final
! if n <= 1:
! self.rowgenerators = [first]
else:
! self.rowgenerators = [first, second] + \
! [hard and advance_hard or advance] * (n**2 - 3) + \
[last]
# Generate solutions.
def solve(self):
! for x in conjoin(self.rowgenerators):
yield x
def printsolution(self, x):
! n = self.n
! assert len(x) == n**2
! w = len(str(n**2 + 1))
format = "%" + str(w) + "d"
! squares = [[None] * n for i in range(n)]
k = 1
for i in x:
! i1, j1 = divmod(i, n)
squares[i1][j1] = format % k
k += 1
--- 1137,1188 ----
yield self.final
! if m*n < 4:
! self.squaregenerators = [first]
else:
! self.squaregenerators = [first, second] + \
! [hard and advance_hard or advance] * (m*n - 3) + \
[last]
+ def coords2index(self, i, j):
+ assert 0 <= i < self.m
+ assert 0 <= j < self.n
+ return i * self.n + j
+
+ def index2coords(self, index):
+ assert 0 <= index < self.m * self.n
+ return divmod(index, self.n)
+
+ def _init_board(self):
+ succs = self.succs
+ del succs[:]
+ m, n = self.m, self.n
+ c2i = self.coords2index
+
+ offsets = [( 1, 2), ( 2, 1), ( 2, -1), ( 1, -2),
+ (-1, -2), (-2, -1), (-2, 1), (-1, 2)]
+ rangen = range(n)
+ for i in range(m):
+ for j in rangen:
+ s = [c2i(i+io, j+jo) for io, jo in offsets
+ if 0 <= i+io < m and
+ 0 <= j+jo < n]
+ succs.append(s)
+
# Generate solutions.
def solve(self):
! self._init_board()
! for x in conjoin(self.squaregenerators):
yield x
def printsolution(self, x):
! m, n = self.m, self.n
! assert len(x) == m*n
! w = len(str(m*n))
format = "%" + str(w) + "d"
! squares = [[None] * n for i in range(m)]
k = 1
for i in x:
! i1, j1 = self.index2coords(i)
squares[i1][j1] = format % k
k += 1
***************
*** 1194,1198 ****
sep = "+" + ("-" * w + "+") * n
print sep
! for i in range(n):
row = squares[i]
print "|" + "|".join(row) + "|"
--- 1190,1194 ----
sep = "+" + ("-" * w + "+") * n
print sep
! for i in range(m):
row = squares[i]
print "|" + "|".join(row) + "|"
***************
*** 1290,1294 ****
20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion.
! >>> k = Knights(10)
>>> LIMIT = 2
>>> count = 0
--- 1286,1290 ----
20,000 solutions even on a 6x6 board, so don't dare run this to exhaustion.
! >>> k = Knights(10, 10)
>>> LIMIT = 2
>>> count = 0
***************
*** 1359,1370 ****
def test_main():
import doctest, test_generators
! if 0:
! # Temporary block to help track down leaks. So far, the blame
! # fell mostly on doctest. Later: the only leaks remaining are
! # in fun_tests, and only if you comment out the two LazyList.clear()
! # calls.
! for i in range(10000):
doctest.master = None
doctest.testmod(test_generators)
else:
doctest.testmod(test_generators)
--- 1355,1363 ----
def test_main():
import doctest, test_generators
! if 0: # change to 1 to run forever (to check for leaks)
! while 1:
doctest.master = None
doctest.testmod(test_generators)
+ print ".",
else:
doctest.testmod(test_generators)
Index: test_pow.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v
retrieving revision 1.7
retrieving revision 1.7.6.1
diff -C2 -r1.7 -r1.7.6.1
*** test_pow.py 2000/12/12 23:11:42 1.7
--- test_pow.py 2001/07/14 07:47:34 1.7.6.1
***************
*** 33,39 ****
pow(ii, jj)
except ValueError:
! pass # taking an int to a neg int power should fail
! else:
! raise ValueError, "pow(%s, %s) did not fail" % (ii, jj)
for othertype in int, long, float:
--- 33,37 ----
pow(ii, jj)
except ValueError:
! raise ValueError, "pow(%s, %s) failed" % (ii, jj)
for othertype in int, long, float:
Index: test_scope.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v
retrieving revision 1.14.4.1
retrieving revision 1.14.4.2
diff -C2 -r1.14.4.1 -r1.14.4.2
*** test_scope.py 2001/07/07 22:55:29 1.14.4.1
--- test_scope.py 2001/07/14 07:47:34 1.14.4.2
***************
*** 1,4 ****
- from __future__ import nested_scopes
-
from test.test_support import verify, TestFailed, check_syntax
--- 1,2 ----
***************
*** 180,184 ****
print "11. unoptimized namespaces"
! check_syntax("""from __future__ import nested_scopes
def unoptimized_clash1(strip):
def f(s):
--- 178,182 ----
print "11. unoptimized namespaces"
! check_syntax("""\
def unoptimized_clash1(strip):
def f(s):
***************
*** 188,192 ****
""")
! check_syntax("""from __future__ import nested_scopes
def unoptimized_clash2():
from string import *
--- 186,190 ----
""")
! check_syntax("""\
def unoptimized_clash2():
from string import *
***************
*** 196,200 ****
""")
! check_syntax("""from __future__ import nested_scopes
def unoptimized_clash2():
from string import *
--- 194,198 ----
""")
! check_syntax("""\
def unoptimized_clash2():
from string import *
***************
*** 206,210 ****
# XXX could allow this for exec with const argument, but what's the point
! check_syntax("""from __future__ import nested_scopes
def error(y):
exec "a = 1"
--- 204,208 ----
# XXX could allow this for exec with const argument, but what's the point
! check_syntax("""\
def error(y):
exec "a = 1"
***************
*** 214,218 ****
""")
! check_syntax("""from __future__ import nested_scopes
def f(x):
def g():
--- 212,216 ----
""")
! check_syntax("""\
def f(x):
def g():
***************
*** 221,225 ****
""")
! check_syntax("""from __future__ import nested_scopes
def f():
def g():
--- 219,223 ----
""")
! check_syntax("""\
def f():
def g():
Index: test_sundry.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sundry.py,v
retrieving revision 1.4
retrieving revision 1.4.4.1
diff -C2 -r1.4 -r1.4.4.1
*** test_sundry.py 2001/04/06 18:59:17 1.4
--- test_sundry.py 2001/07/14 07:47:34 1.4.4.1
***************
*** 31,35 ****
import encodings
import filecmp
- import fileinput
import fnmatch
import formatter
--- 31,34 ----
***************
*** 97,101 ****
# can screw up all sorts of things (esp. if it prints!).
#import user
- import uu
import webbrowser
import whichdb
--- 96,99 ----
- Previous message: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,NONE,1.1.2.1 ConfigParser.py,1.32,1.32.6.1 SocketServer.py,1.24,1.24.4.1 __future__.py,1.5,1.5.4.1 site.py,1.26.4.1,1.26.4.2 sre.py,1.31,1.31.4.1 symbol.py,1.12,1.12.8.1 symtable.py,1.4,1.4.4.1 uu.py,1.16,1.16.6.1
- Next message: [Python-checkins] CVS: python/dist/src PLAN.txt,1.1.2.26,1.1.2.27 acconfig.h,1.46.4.1,1.46.4.2 config.h.in,2.92.2.1,2.92.2.2 configure,1.209.2.1,1.209.2.2 configure.in,1.217.2.1,1.217.2.2
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]