mirror of
				https://github.com/python/cpython.git
				synced 2025-11-02 22:51:25 +00:00 
			
		
		
		
	Some new blood and some updated versions.
This commit is contained in:
		
							parent
							
								
									fdb8fb8b31
								
							
						
					
					
						commit
						64e736ba4e
					
				
					 7 changed files with 1105 additions and 14 deletions
				
			
		| 
						 | 
					@ -1,19 +1,23 @@
 | 
				
			||||||
"""Class based built-in exception hierarchy.
 | 
					"""Class based built-in exception hierarchy.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
This is a new feature whereby all the standard built-in exceptions,
 | 
					New with Python 1.5, all standard built-in exceptions are now class objects by
 | 
				
			||||||
traditionally string objects, are replaced with classes.  This gives
 | 
					default.  This gives Python's exception handling mechanism a more
 | 
				
			||||||
Python's exception handling mechanism a more object-oriented feel.
 | 
					object-oriented feel.  Traditionally they were string objects.  Python will
 | 
				
			||||||
 | 
					fallback to string based exceptions if the interpreter is invoked with the -X
 | 
				
			||||||
 | 
					option, or if some failure occurs during class exception initialization (in
 | 
				
			||||||
 | 
					this case a warning will be printed).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Most existing code should continue to work with class based
 | 
					Most existing code should continue to work with class based exceptions.  Some
 | 
				
			||||||
exceptions.  Some tricky uses of IOError may break, but the most
 | 
					tricky uses of IOError may break, but the most common uses should work.
 | 
				
			||||||
common uses should work.
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
To disable this feature, start the Python executable with the -X option.
 | 
					Here is a rundown of the class hierarchy.  You can change this by editing this
 | 
				
			||||||
 | 
					file, but it isn't recommended.  The class names described here are expected
 | 
				
			||||||
 | 
					to be found by the bltinmodule.c file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Here is a rundown of the class hierarchy.  You can change this by
 | 
					The classes with a `*' are new as of Python 1.5.  They are defined as tuples
 | 
				
			||||||
editing this file, but it isn't recommended.  The classes with a `*'
 | 
					containing the derived exceptions when string-based exceptions are used.  If
 | 
				
			||||||
are new with this feature.  They are defined as tuples containing the
 | 
					you define your own class based exceptions, they should be derived from
 | 
				
			||||||
derived exceptions when string-based exceptions are used.
 | 
					Exception.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Exception(*)
 | 
					Exception(*)
 | 
				
			||||||
 |
 | 
					 |
 | 
				
			||||||
| 
						 | 
					@ -22,7 +26,11 @@
 | 
				
			||||||
      +-- SystemExit
 | 
					      +-- SystemExit
 | 
				
			||||||
      +-- KeyboardInterrupt
 | 
					      +-- KeyboardInterrupt
 | 
				
			||||||
      +-- ImportError
 | 
					      +-- ImportError
 | 
				
			||||||
      +-- IOError
 | 
					      +-- EnvironmentError(*)
 | 
				
			||||||
 | 
					      |    |
 | 
				
			||||||
 | 
					      |    +-- IOError
 | 
				
			||||||
 | 
					      |    +-- OSError(*)
 | 
				
			||||||
 | 
					      |
 | 
				
			||||||
      +-- EOFError
 | 
					      +-- EOFError
 | 
				
			||||||
      +-- RuntimeError
 | 
					      +-- RuntimeError
 | 
				
			||||||
      +-- NameError
 | 
					      +-- NameError
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,6 +354,8 @@ def normpath(path):
 | 
				
			||||||
    while i < len(comps):
 | 
					    while i < len(comps):
 | 
				
			||||||
        if comps[i] == '.':
 | 
					        if comps[i] == '.':
 | 
				
			||||||
            del comps[i]
 | 
					            del comps[i]
 | 
				
			||||||
 | 
					            while i < len(comps) and comps[i] == '':
 | 
				
			||||||
 | 
					                del comps[i]
 | 
				
			||||||
        elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'):
 | 
					        elif comps[i] == '..' and i > 0 and comps[i-1] not in ('', '..'):
 | 
				
			||||||
            del comps[i-1:i+1]
 | 
					            del comps[i-1:i+1]
 | 
				
			||||||
            i = i-1
 | 
					            i = i-1
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,15 @@ def compile(file, cfile=None, dfile=None):
 | 
				
			||||||
    f.close()
 | 
					    f.close()
 | 
				
			||||||
    if codestring and codestring[-1] != '\n':
 | 
					    if codestring and codestring[-1] != '\n':
 | 
				
			||||||
        codestring = codestring + '\n'
 | 
					        codestring = codestring + '\n'
 | 
				
			||||||
    codeobject = __builtin__.compile(codestring, dfile or file, 'exec')
 | 
					    try:
 | 
				
			||||||
 | 
					        codeobject = __builtin__.compile(codestring, dfile or file, 'exec')
 | 
				
			||||||
 | 
					    except SyntaxError, detail:
 | 
				
			||||||
 | 
					        import traceback, sys, string
 | 
				
			||||||
 | 
					        lines = traceback.format_exception_only(SyntaxError, detail)
 | 
				
			||||||
 | 
					        for line in lines:
 | 
				
			||||||
 | 
					            sys.stderr.write(string.replace(line, 'File "<string>"',
 | 
				
			||||||
 | 
					                                            'File "%s"' % (dfile or file)))
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
    if not cfile:
 | 
					    if not cfile:
 | 
				
			||||||
        cfile = file + (__debug__ and 'c' or 'o')
 | 
					        cfile = file + (__debug__ and 'c' or 'o')
 | 
				
			||||||
    fc = open(cfile, 'wb')
 | 
					    fc = open(cfile, 'wb')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,8 +41,12 @@ def close(self):
 | 
				
			||||||
			self.closed = 1
 | 
								self.closed = 1
 | 
				
			||||||
			del self.buf, self.pos
 | 
								del self.buf, self.pos
 | 
				
			||||||
	def isatty(self):
 | 
						def isatty(self):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	def seek(self, pos, mode = 0):
 | 
						def seek(self, pos, mode = 0):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		if self.buflist:
 | 
							if self.buflist:
 | 
				
			||||||
			self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
								self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
				
			||||||
			self.buflist = []
 | 
								self.buflist = []
 | 
				
			||||||
| 
						 | 
					@ -52,8 +56,12 @@ def seek(self, pos, mode = 0):
 | 
				
			||||||
			pos = pos + self.len
 | 
								pos = pos + self.len
 | 
				
			||||||
		self.pos = max(0, pos)
 | 
							self.pos = max(0, pos)
 | 
				
			||||||
	def tell(self):
 | 
						def tell(self):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		return self.pos
 | 
							return self.pos
 | 
				
			||||||
	def read(self, n = -1):
 | 
						def read(self, n = -1):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		if self.buflist:
 | 
							if self.buflist:
 | 
				
			||||||
			self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
								self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
				
			||||||
			self.buflist = []
 | 
								self.buflist = []
 | 
				
			||||||
| 
						 | 
					@ -65,6 +73,8 @@ def read(self, n = -1):
 | 
				
			||||||
		self.pos = newpos
 | 
							self.pos = newpos
 | 
				
			||||||
		return r
 | 
							return r
 | 
				
			||||||
	def readline(self, length=None):
 | 
						def readline(self, length=None):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		if self.buflist:
 | 
							if self.buflist:
 | 
				
			||||||
			self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
								self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
				
			||||||
			self.buflist = []
 | 
								self.buflist = []
 | 
				
			||||||
| 
						 | 
					@ -87,6 +97,8 @@ def readlines(self):
 | 
				
			||||||
			line = self.readline()
 | 
								line = self.readline()
 | 
				
			||||||
		return lines
 | 
							return lines
 | 
				
			||||||
	def write(self, s):
 | 
						def write(self, s):
 | 
				
			||||||
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
		if not s: return
 | 
							if not s: return
 | 
				
			||||||
		if self.pos > self.len:
 | 
							if self.pos > self.len:
 | 
				
			||||||
			self.buflist.append('\0'*(self.pos - self.len))
 | 
								self.buflist.append('\0'*(self.pos - self.len))
 | 
				
			||||||
| 
						 | 
					@ -105,7 +117,8 @@ def write(self, s):
 | 
				
			||||||
	def writelines(self, list):
 | 
						def writelines(self, list):
 | 
				
			||||||
		self.write(string.joinfields(list, ''))
 | 
							self.write(string.joinfields(list, ''))
 | 
				
			||||||
	def flush(self):
 | 
						def flush(self):
 | 
				
			||||||
		pass
 | 
							if self.closed:
 | 
				
			||||||
 | 
								raise ValueError, "I/O operation on closed file"
 | 
				
			||||||
	def getvalue(self):
 | 
						def getvalue(self):
 | 
				
			||||||
		if self.buflist:
 | 
							if self.buflist:
 | 
				
			||||||
			self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
								self.buf = self.buf + string.joinfields(self.buflist, '')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										252
									
								
								Lib/dos-8x3/test_lon.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										252
									
								
								Lib/dos-8x3/test_lon.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,252 @@
 | 
				
			||||||
 | 
					from test_support import TestFailed, verbose
 | 
				
			||||||
 | 
					from string import join
 | 
				
			||||||
 | 
					from random import random, randint
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# SHIFT should match the value in longintrepr.h for best testing.
 | 
				
			||||||
 | 
					SHIFT = 15
 | 
				
			||||||
 | 
					BASE = 2 ** SHIFT
 | 
				
			||||||
 | 
					MASK = BASE - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Max number of base BASE digits to use in test cases.  Doubling
 | 
				
			||||||
 | 
					# this will at least quadruple the runtime.
 | 
				
			||||||
 | 
					MAXDIGITS = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# build some special values
 | 
				
			||||||
 | 
					special = map(long, [0, 1, 2, BASE, BASE >> 1])
 | 
				
			||||||
 | 
					special.append(0x5555555555555555L)
 | 
				
			||||||
 | 
					special.append(0xaaaaaaaaaaaaaaaaL)
 | 
				
			||||||
 | 
					#  some solid strings of one bits
 | 
				
			||||||
 | 
					p2 = 4L  # 0 and 1 already added
 | 
				
			||||||
 | 
					for i in range(2*SHIFT):
 | 
				
			||||||
 | 
					    special.append(p2 - 1)
 | 
				
			||||||
 | 
					    p2 = p2 << 1
 | 
				
			||||||
 | 
					del p2
 | 
				
			||||||
 | 
					# add complements & negations
 | 
				
			||||||
 | 
					special = special + map(lambda x: ~x, special) + \
 | 
				
			||||||
 | 
					                    map(lambda x: -x, special)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ------------------------------------------------------------ utilities
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Use check instead of assert so the test still does something
 | 
				
			||||||
 | 
					# under -O.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def check(ok, *args):
 | 
				
			||||||
 | 
					    if not ok:
 | 
				
			||||||
 | 
					        raise TestFailed, join(map(str, args), " ")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Get quasi-random long consisting of ndigits digits (in base BASE).
 | 
				
			||||||
 | 
					# quasi == the most-significant digit will not be 0, and the number
 | 
				
			||||||
 | 
					# is constructed to contain long strings of 0 and 1 bits.  These are
 | 
				
			||||||
 | 
					# more likely than random bits to provoke digit-boundary errors.
 | 
				
			||||||
 | 
					# The sign of the number is also random.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def getran(ndigits):
 | 
				
			||||||
 | 
					    assert ndigits > 0
 | 
				
			||||||
 | 
					    nbits_hi = ndigits * SHIFT
 | 
				
			||||||
 | 
					    nbits_lo = nbits_hi - SHIFT + 1
 | 
				
			||||||
 | 
					    answer = 0L
 | 
				
			||||||
 | 
					    nbits = 0
 | 
				
			||||||
 | 
					    r = int(random() * (SHIFT * 2)) | 1  # force 1 bits to start
 | 
				
			||||||
 | 
					    while nbits < nbits_lo:
 | 
				
			||||||
 | 
					        bits = (r >> 1) + 1
 | 
				
			||||||
 | 
					        bits = min(bits, nbits_hi - nbits)
 | 
				
			||||||
 | 
					        assert 1 <= bits <= SHIFT
 | 
				
			||||||
 | 
					        nbits = nbits + bits
 | 
				
			||||||
 | 
					        answer = answer << bits
 | 
				
			||||||
 | 
					        if r & 1:
 | 
				
			||||||
 | 
					            answer = answer | ((1 << bits) - 1)
 | 
				
			||||||
 | 
					        r = int(random() * (SHIFT * 2))
 | 
				
			||||||
 | 
					    assert nbits_lo <= nbits <= nbits_hi
 | 
				
			||||||
 | 
					    if random() < 0.5:
 | 
				
			||||||
 | 
					        answer = -answer
 | 
				
			||||||
 | 
					    return answer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Get random long consisting of ndigits random digits (relative to base
 | 
				
			||||||
 | 
					# BASE).  The sign bit is also random.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def getran2(ndigits):
 | 
				
			||||||
 | 
					    answer = 0L
 | 
				
			||||||
 | 
					    for i in range(ndigits):
 | 
				
			||||||
 | 
					        answer = (answer << SHIFT) | randint(0, MASK)
 | 
				
			||||||
 | 
					    if random() < 0.5:
 | 
				
			||||||
 | 
					        answer = -answer
 | 
				
			||||||
 | 
					    return answer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# --------------------------------------------------------------- divmod
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_division_2(x, y):
 | 
				
			||||||
 | 
					    q, r = divmod(x, y)
 | 
				
			||||||
 | 
					    q2, r2 = x/y, x%y
 | 
				
			||||||
 | 
					    check(q == q2, "divmod returns different quotient than / for", x, y)
 | 
				
			||||||
 | 
					    check(r == r2, "divmod returns different mod than % for", x, y)
 | 
				
			||||||
 | 
					    check(x == q*y + r, "x != q*y + r after divmod on", x, y)
 | 
				
			||||||
 | 
					    if y > 0:
 | 
				
			||||||
 | 
					        check(0 <= r < y, "bad mod from divmod on", x, y)
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        check(y < r <= 0, "bad mod from divmod on", x, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_division(maxdigits=MAXDIGITS):
 | 
				
			||||||
 | 
					    print "long / * % divmod"
 | 
				
			||||||
 | 
					    digits = range(1, maxdigits+1)
 | 
				
			||||||
 | 
					    for lenx in digits:
 | 
				
			||||||
 | 
					        x = getran(lenx)
 | 
				
			||||||
 | 
					        for leny in digits:
 | 
				
			||||||
 | 
					            y = getran(leny) or 1L
 | 
				
			||||||
 | 
					            test_division_2(x, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# -------------------------------------------------------------- ~ & | ^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_bitop_identities_1(x):
 | 
				
			||||||
 | 
					    check(x & 0 == 0, "x & 0 != 0 for", x)
 | 
				
			||||||
 | 
					    check(x | 0 == x, "x | 0 != x for", x)
 | 
				
			||||||
 | 
					    check(x ^ 0 == x, "x ^ 0 != x for", x)
 | 
				
			||||||
 | 
					    check(x & -1 == x, "x & -1 != x for", x)
 | 
				
			||||||
 | 
					    check(x | -1 == -1, "x | -1 != -1 for", x)
 | 
				
			||||||
 | 
					    check(x ^ -1 == ~x, "x ^ -1 != ~x for", x)
 | 
				
			||||||
 | 
					    check(x == ~~x, "x != ~~x for", x)
 | 
				
			||||||
 | 
					    check(x & x == x, "x & x != x for", x)
 | 
				
			||||||
 | 
					    check(x | x == x, "x | x != x for", x)
 | 
				
			||||||
 | 
					    check(x ^ x == 0, "x ^ x != 0 for", x)
 | 
				
			||||||
 | 
					    check(x & ~x == 0, "x & ~x != 0 for", x)
 | 
				
			||||||
 | 
					    check(x | ~x == -1, "x | ~x != -1 for", x)
 | 
				
			||||||
 | 
					    check(x ^ ~x == -1, "x ^ ~x != -1 for", x)
 | 
				
			||||||
 | 
					    check(-x == 1 + ~x == ~(x-1), "not -x == 1 + ~x == ~(x-1) for", x)
 | 
				
			||||||
 | 
					    for n in range(2*SHIFT):
 | 
				
			||||||
 | 
					        p2 = 2L ** n
 | 
				
			||||||
 | 
					        check(x << n >> n == x, "x << n >> n != x for", x, n)
 | 
				
			||||||
 | 
					        check(x / p2 == x >> n, "x / p2 != x >> n for x n p2", x, n, p2)
 | 
				
			||||||
 | 
					        check(x * p2 == x << n, "x * p2 != x << n for x n p2", x, n, p2)
 | 
				
			||||||
 | 
					        check(x & -p2 == x >> n << n == x & ~(p2 - 1),
 | 
				
			||||||
 | 
					            "not x & -p2 == x >> n << n == x & ~(p2 - 1) for x n p2",
 | 
				
			||||||
 | 
					            x, n, p2)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_bitop_identities_2(x, y):
 | 
				
			||||||
 | 
					    check(x & y == y & x, "x & y != y & x for", x, y)
 | 
				
			||||||
 | 
					    check(x | y == y | x, "x | y != y | x for", x, y)
 | 
				
			||||||
 | 
					    check(x ^ y == y ^ x, "x ^ y != y ^ x for", x, y)
 | 
				
			||||||
 | 
					    check(x ^ y ^ x == y, "x ^ y ^ x != y for", x, y)
 | 
				
			||||||
 | 
					    check(x & y == ~(~x | ~y), "x & y != ~(~x | ~y) for", x, y)
 | 
				
			||||||
 | 
					    check(x | y == ~(~x & ~y), "x | y != ~(~x & ~y) for", x, y)
 | 
				
			||||||
 | 
					    check(x ^ y == (x | y) & ~(x & y),
 | 
				
			||||||
 | 
					         "x ^ y != (x | y) & ~(x & y) for", x, y)
 | 
				
			||||||
 | 
					    check(x ^ y == (x & ~y) | (~x & y),
 | 
				
			||||||
 | 
					         "x ^ y == (x & ~y) | (~x & y) for", x, y)
 | 
				
			||||||
 | 
					    check(x ^ y == (x | y) & (~x | ~y),
 | 
				
			||||||
 | 
					         "x ^ y == (x | y) & (~x | ~y) for", x, y)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_bitop_identities_3(x, y, z):
 | 
				
			||||||
 | 
					    check((x & y) & z == x & (y & z),
 | 
				
			||||||
 | 
					         "(x & y) & z != x & (y & z) for", x, y, z)
 | 
				
			||||||
 | 
					    check((x | y) | z == x | (y | z),
 | 
				
			||||||
 | 
					         "(x | y) | z != x | (y | z) for", x, y, z)
 | 
				
			||||||
 | 
					    check((x ^ y) ^ z == x ^ (y ^ z),
 | 
				
			||||||
 | 
					         "(x ^ y) ^ z != x ^ (y ^ z) for", x, y, z)
 | 
				
			||||||
 | 
					    check(x & (y | z) == (x & y) | (x & z),
 | 
				
			||||||
 | 
					         "x & (y | z) != (x & y) | (x & z) for", x, y, z)
 | 
				
			||||||
 | 
					    check(x | (y & z) == (x | y) & (x | z),
 | 
				
			||||||
 | 
					         "x | (y & z) != (x | y) & (x | z) for", x, y, z)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_bitop_identities(maxdigits=MAXDIGITS):
 | 
				
			||||||
 | 
					    print "long bit-operation identities"
 | 
				
			||||||
 | 
					    for x in special:
 | 
				
			||||||
 | 
					        test_bitop_identities_1(x)
 | 
				
			||||||
 | 
					    digits = range(1, maxdigits+1)
 | 
				
			||||||
 | 
					    for lenx in digits:
 | 
				
			||||||
 | 
					        x = getran(lenx)
 | 
				
			||||||
 | 
					        test_bitop_identities_1(x)
 | 
				
			||||||
 | 
					        for leny in digits:
 | 
				
			||||||
 | 
					            y = getran(leny)
 | 
				
			||||||
 | 
					            test_bitop_identities_2(x, y)
 | 
				
			||||||
 | 
					            test_bitop_identities_3(x, y, getran((lenx + leny)/2))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ------------------------------------------------------ hex oct str atol
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def slow_format(x, base):
 | 
				
			||||||
 | 
					    if (x, base) == (0, 8):
 | 
				
			||||||
 | 
					        # this is an oddball!
 | 
				
			||||||
 | 
					        return "0L"
 | 
				
			||||||
 | 
					    digits = []
 | 
				
			||||||
 | 
					    sign = 0
 | 
				
			||||||
 | 
					    if x < 0:
 | 
				
			||||||
 | 
					        sign, x = 1, -x
 | 
				
			||||||
 | 
					    while x:
 | 
				
			||||||
 | 
					        x, r = divmod(x, base)
 | 
				
			||||||
 | 
					        digits.append(int(r))
 | 
				
			||||||
 | 
					    digits.reverse()
 | 
				
			||||||
 | 
					    digits = digits or [0]
 | 
				
			||||||
 | 
					    return '-'[:sign] + \
 | 
				
			||||||
 | 
					           {8: '0', 10: '', 16: '0x'}[base] + \
 | 
				
			||||||
 | 
					           join(map(lambda i: "0123456789ABCDEF"[i], digits), '') + \
 | 
				
			||||||
 | 
					           "L"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_format_1(x):
 | 
				
			||||||
 | 
					    from string import atol
 | 
				
			||||||
 | 
					    for base, mapper in (8, oct), (10, str), (16, hex):
 | 
				
			||||||
 | 
					        got = mapper(x)
 | 
				
			||||||
 | 
					        expected = slow_format(x, base)
 | 
				
			||||||
 | 
					        check(got == expected, mapper.__name__, "returned",
 | 
				
			||||||
 | 
					              got, "but expected", expected, "for", x)
 | 
				
			||||||
 | 
					        check(atol(got, 0) == x, 'atol("%s", 0) !=' % got, x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_format(maxdigits=MAXDIGITS):
 | 
				
			||||||
 | 
					    print "long str/hex/oct/atol"
 | 
				
			||||||
 | 
					    for x in special:
 | 
				
			||||||
 | 
					        test_format_1(x)
 | 
				
			||||||
 | 
					    for i in range(10):
 | 
				
			||||||
 | 
					        for lenx in range(1, maxdigits+1):
 | 
				
			||||||
 | 
					            x = getran(lenx)
 | 
				
			||||||
 | 
					            test_format_1(x)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ----------------------------------------------------------------- misc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_misc(maxdigits=MAXDIGITS):
 | 
				
			||||||
 | 
					    print "long miscellaneous operations"
 | 
				
			||||||
 | 
					    import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # check the extremes in int<->long conversion
 | 
				
			||||||
 | 
					    hugepos = sys.maxint
 | 
				
			||||||
 | 
					    hugeneg = -hugepos - 1
 | 
				
			||||||
 | 
					    hugepos_aslong = long(hugepos)
 | 
				
			||||||
 | 
					    hugeneg_aslong = long(hugeneg)
 | 
				
			||||||
 | 
					    check(hugepos == hugepos_aslong, "long(sys.maxint) != sys.maxint")
 | 
				
			||||||
 | 
					    check(hugeneg == hugeneg_aslong,
 | 
				
			||||||
 | 
					        "long(-sys.maxint-1) != -sys.maxint-1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # long -> int should not fail for hugepos_aslong or hugeneg_aslong
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        check(int(hugepos_aslong) == hugepos,
 | 
				
			||||||
 | 
					              "converting sys.maxint to long and back to int fails")
 | 
				
			||||||
 | 
					    except OverflowError:
 | 
				
			||||||
 | 
					        raise TestFailed, "int(long(sys.maxint)) overflowed!"
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        check(int(hugeneg_aslong) == hugeneg,
 | 
				
			||||||
 | 
					              "converting -sys.maxint-1 to long and back to int fails")
 | 
				
			||||||
 | 
					    except OverflowError:
 | 
				
			||||||
 | 
					        raise TestFailed, "int(long(-sys.maxint-1)) overflowed!"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # but long -> int should overflow for hugepos+1 and hugeneg-1
 | 
				
			||||||
 | 
					    x = hugepos_aslong + 1
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        int(x)
 | 
				
			||||||
 | 
					        raise ValueError
 | 
				
			||||||
 | 
					    except OverflowError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        raise TestFailed, "int(long(sys.maxint) + 1) didn't overflow"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    x = hugeneg_aslong - 1
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        int(x)
 | 
				
			||||||
 | 
					        raise ValueError
 | 
				
			||||||
 | 
					    except OverflowError:
 | 
				
			||||||
 | 
					        pass
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        raise TestFailed, "int(long(-sys.maxint-1) - 1) didn't overflow"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# ---------------------------------------------------------------- do it
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_division()
 | 
				
			||||||
 | 
					test_bitop_identities()
 | 
				
			||||||
 | 
					test_format()
 | 
				
			||||||
 | 
					test_misc()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										170
									
								
								Lib/dos-8x3/test_mim.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										170
									
								
								Lib/dos-8x3/test_mim.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,170 @@
 | 
				
			||||||
 | 
					"""Test program for MimeWriter module.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					The test program was too big to comfortably fit in the MimeWriter
 | 
				
			||||||
 | 
					class, so it's here in its own file.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					This should generate Barry's example, modulo some quotes and newlines.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from MimeWriter import MimeWriter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SELLER = '''\
 | 
				
			||||||
 | 
					INTERFACE Seller-1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					TYPE Seller = OBJECT
 | 
				
			||||||
 | 
					    DOCUMENTATION "A simple Seller interface to test ILU"
 | 
				
			||||||
 | 
					    METHODS
 | 
				
			||||||
 | 
					            price():INTEGER,
 | 
				
			||||||
 | 
					    END;
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					BUYER = '''\
 | 
				
			||||||
 | 
					class Buyer:
 | 
				
			||||||
 | 
					    def __setup__(self, maxprice):
 | 
				
			||||||
 | 
					        self._maxprice = maxprice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __main__(self, kos):
 | 
				
			||||||
 | 
					        """Entry point upon arrival at a new KOS."""
 | 
				
			||||||
 | 
					        broker = kos.broker()
 | 
				
			||||||
 | 
					        # B4 == Barry's Big Bass Business :-)
 | 
				
			||||||
 | 
					        seller = broker.lookup('Seller_1.Seller', 'B4')
 | 
				
			||||||
 | 
					        if seller:
 | 
				
			||||||
 | 
					            price = seller.price()
 | 
				
			||||||
 | 
					            print 'Seller wants $', price, '... '
 | 
				
			||||||
 | 
					            if price > self._maxprice:
 | 
				
			||||||
 | 
					                print 'too much!'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                print "I'll take it!"
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            print 'no seller found here'
 | 
				
			||||||
 | 
					'''                                     # Don't ask why this comment is here
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					STATE = '''\
 | 
				
			||||||
 | 
					# instantiate a buyer instance and put it in a magic place for the KOS
 | 
				
			||||||
 | 
					# to find.
 | 
				
			||||||
 | 
					__kp__ = Buyer()
 | 
				
			||||||
 | 
					__kp__.__setup__(500)
 | 
				
			||||||
 | 
					'''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SIMPLE_METADATA = [
 | 
				
			||||||
 | 
					        ("Interpreter", "python"),
 | 
				
			||||||
 | 
					        ("Interpreter-Version", "1.3"),
 | 
				
			||||||
 | 
					        ("Owner-Name", "Barry Warsaw"),
 | 
				
			||||||
 | 
					        ("Owner-Rendezvous", "bwarsaw@cnri.reston.va.us"),
 | 
				
			||||||
 | 
					        ("Home-KSS", "kss.cnri.reston.va.us"),
 | 
				
			||||||
 | 
					        ("Identifier", "hdl://cnri.kss/my_first_knowbot"),
 | 
				
			||||||
 | 
					        ("Launch-Date", "Mon Feb 12 16:39:03 EST 1996"),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					COMPLEX_METADATA = [
 | 
				
			||||||
 | 
					        ("Metadata-Type", "complex"),
 | 
				
			||||||
 | 
					        ("Metadata-Key", "connection"),
 | 
				
			||||||
 | 
					        ("Access", "read-only"),
 | 
				
			||||||
 | 
					        ("Connection-Description", "Barry's Big Bass Business"),
 | 
				
			||||||
 | 
					        ("Connection-Id", "B4"),
 | 
				
			||||||
 | 
					        ("Connection-Direction", "client"),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					EXTERNAL_METADATA = [
 | 
				
			||||||
 | 
					        ("Metadata-Type", "complex"),
 | 
				
			||||||
 | 
					        ("Metadata-Key", "generic-interface"),
 | 
				
			||||||
 | 
					        ("Access", "read-only"),
 | 
				
			||||||
 | 
					        ("Connection-Description", "Generic Interface for All Knowbots"),
 | 
				
			||||||
 | 
					        ("Connection-Id", "generic-kp"),
 | 
				
			||||||
 | 
					        ("Connection-Direction", "client"),
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def main():
 | 
				
			||||||
 | 
					    import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Toplevel headers
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    toplevel = MimeWriter(sys.stdout)
 | 
				
			||||||
 | 
					    toplevel.addheader("From", "bwarsaw@cnri.reston.va.us")
 | 
				
			||||||
 | 
					    toplevel.addheader("Date", "Mon Feb 12 17:21:48 EST 1996")
 | 
				
			||||||
 | 
					    toplevel.addheader("To", "kss-submit@cnri.reston.va.us")
 | 
				
			||||||
 | 
					    toplevel.addheader("MIME-Version", "1.0")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Toplevel body parts
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    f = toplevel.startmultipartbody("knowbot", "801spam999",
 | 
				
			||||||
 | 
					                                    [("version", "0.1")], prefix=0)
 | 
				
			||||||
 | 
					    f.write("This is a multi-part message in MIME format.\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # First toplevel body part: metadata
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md = toplevel.nextpart()
 | 
				
			||||||
 | 
					    md.startmultipartbody("knowbot-metadata", "802spam999")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Metadata part 1
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    md1 = md.nextpart()
 | 
				
			||||||
 | 
					    md1.addheader("KP-Metadata-Type", "simple")
 | 
				
			||||||
 | 
					    md1.addheader("KP-Access", "read-only")
 | 
				
			||||||
 | 
					    m = MimeWriter(md1.startbody("message/rfc822"))
 | 
				
			||||||
 | 
					    for key, value in SIMPLE_METADATA:
 | 
				
			||||||
 | 
					        m.addheader("KPMD-" + key, value)
 | 
				
			||||||
 | 
					    m.flushheaders()
 | 
				
			||||||
 | 
					    del md1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Metadata part 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md2 = md.nextpart()
 | 
				
			||||||
 | 
					    for key, value in COMPLEX_METADATA:
 | 
				
			||||||
 | 
					        md2.addheader("KP-" + key, value)
 | 
				
			||||||
 | 
					    f = md2.startbody("text/isl")
 | 
				
			||||||
 | 
					    f.write(SELLER)
 | 
				
			||||||
 | 
					    del md2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Metadata part 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md3 = md.nextpart()
 | 
				
			||||||
 | 
					    f = md3.startbody("message/external-body",
 | 
				
			||||||
 | 
					                      [("access-type", "URL"),
 | 
				
			||||||
 | 
					                       ("URL", "hdl://cnri.kss/generic-knowbot")])
 | 
				
			||||||
 | 
					    m = MimeWriter(f)
 | 
				
			||||||
 | 
					    for key, value in EXTERNAL_METADATA:
 | 
				
			||||||
 | 
					        md3.addheader("KP-" + key, value)
 | 
				
			||||||
 | 
					    md3.startbody("text/isl")
 | 
				
			||||||
 | 
					    # Phantom body doesn't need to be written
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    md.lastpart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Second toplevel body part: code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    code = toplevel.nextpart()
 | 
				
			||||||
 | 
					    code.startmultipartbody("knowbot-code", "803spam999")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Code: buyer program source
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    buyer = code.nextpart()
 | 
				
			||||||
 | 
					    buyer.addheader("KP-Module-Name", "BuyerKP")
 | 
				
			||||||
 | 
					    f = buyer.startbody("text/plain")
 | 
				
			||||||
 | 
					    f.write(BUYER)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    code.lastpart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Third toplevel body part: state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state = toplevel.nextpart()
 | 
				
			||||||
 | 
					    state.addheader("KP-Main-Module", "main")
 | 
				
			||||||
 | 
					    state.startmultipartbody("knowbot-state", "804spam999")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # State: a bunch of assignments
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    st = state.nextpart()
 | 
				
			||||||
 | 
					    st.addheader("KP-Module-Name", "main")
 | 
				
			||||||
 | 
					    f = st.startbody("text/plain")
 | 
				
			||||||
 | 
					    f.write(STATE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    state.lastpart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # End toplevel body parts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    toplevel.lastpart()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					main()
 | 
				
			||||||
							
								
								
									
										638
									
								
								Lib/dos-8x3/threadin.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										638
									
								
								Lib/dos-8x3/threadin.py
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,638 @@
 | 
				
			||||||
 | 
					# threading.py:
 | 
				
			||||||
 | 
					# Proposed new threading module, emulating a subset of Java's threading model
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import thread
 | 
				
			||||||
 | 
					import traceback
 | 
				
			||||||
 | 
					import StringIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Rename some stuff so "from threading import *" is safe
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_sys = sys
 | 
				
			||||||
 | 
					del sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_time = time.time
 | 
				
			||||||
 | 
					_sleep = time.sleep
 | 
				
			||||||
 | 
					del time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_start_new_thread = thread.start_new_thread
 | 
				
			||||||
 | 
					_allocate_lock = thread.allocate_lock
 | 
				
			||||||
 | 
					_get_ident = thread.get_ident
 | 
				
			||||||
 | 
					del thread
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_print_exc = traceback.print_exc
 | 
				
			||||||
 | 
					del traceback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_StringIO = StringIO.StringIO
 | 
				
			||||||
 | 
					del StringIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Debug support (adapted from ihooks.py)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_VERBOSE = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __debug__:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class _Verbose:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __init__(self, verbose=None):
 | 
				
			||||||
 | 
					            if verbose is None:
 | 
				
			||||||
 | 
					                verbose = _VERBOSE
 | 
				
			||||||
 | 
					            self.__verbose = verbose
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def _note(self, format, *args):
 | 
				
			||||||
 | 
					            if self.__verbose:
 | 
				
			||||||
 | 
					                format = format % args
 | 
				
			||||||
 | 
					                format = "%s: %s\n" % (
 | 
				
			||||||
 | 
					                    currentThread().getName(), format)
 | 
				
			||||||
 | 
					                _sys.stderr.write(format)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    # Disable this when using "python -O"
 | 
				
			||||||
 | 
					    class _Verbose:
 | 
				
			||||||
 | 
					        def __init__(self, verbose=None):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        def _note(self, *args):
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Synchronization classes
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Lock = _allocate_lock
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def RLock(*args, **kwargs):
 | 
				
			||||||
 | 
					    return apply(_RLock, args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _RLock(_Verbose):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def __init__(self, verbose=None):
 | 
				
			||||||
 | 
					        _Verbose.__init__(self, verbose)
 | 
				
			||||||
 | 
					        self.__block = _allocate_lock()
 | 
				
			||||||
 | 
					        self.__owner = None
 | 
				
			||||||
 | 
					        self.__count = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return "<%s(%s, %d)>" % (
 | 
				
			||||||
 | 
					                self.__class__.__name__,
 | 
				
			||||||
 | 
					                self.__owner and self.__owner.getName(),
 | 
				
			||||||
 | 
					                self.__count)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def acquire(self, blocking=1):
 | 
				
			||||||
 | 
					        me = currentThread()
 | 
				
			||||||
 | 
					        if self.__owner is me:
 | 
				
			||||||
 | 
					            self.__count = self.__count + 1
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.acquire(%s): recursive success", self, blocking)
 | 
				
			||||||
 | 
					            return 1
 | 
				
			||||||
 | 
					        rc = self.__block.acquire(blocking)
 | 
				
			||||||
 | 
					        if rc:
 | 
				
			||||||
 | 
					            self.__owner = me
 | 
				
			||||||
 | 
					            self.__count = 1
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.acquire(%s): initial succes", self, blocking)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.acquire(%s): failure", self, blocking)
 | 
				
			||||||
 | 
					        return rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def release(self):
 | 
				
			||||||
 | 
					        me = currentThread()
 | 
				
			||||||
 | 
					        assert self.__owner is me, "release() of un-acquire()d lock"
 | 
				
			||||||
 | 
					        self.__count = count = self.__count - 1
 | 
				
			||||||
 | 
					        if not count:
 | 
				
			||||||
 | 
					            self.__owner = None
 | 
				
			||||||
 | 
					            self.__block.release()
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.release(): final release", self)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.release(): non-final release", self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # Internal methods used by condition variables
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _acquire_restore(self, (count, owner)):
 | 
				
			||||||
 | 
					        self.__block.acquire()
 | 
				
			||||||
 | 
					        self.__count = count
 | 
				
			||||||
 | 
					        self.__owner = owner
 | 
				
			||||||
 | 
					        if __debug__:
 | 
				
			||||||
 | 
					            self._note("%s._acquire_restore()", self)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _release_save(self):
 | 
				
			||||||
 | 
					        if __debug__:
 | 
				
			||||||
 | 
					            self._note("%s._release_save()", self)
 | 
				
			||||||
 | 
					        count = self.__count
 | 
				
			||||||
 | 
					        self.__count = 0
 | 
				
			||||||
 | 
					        owner = self.__owner
 | 
				
			||||||
 | 
					        self.__owner = None
 | 
				
			||||||
 | 
					        self.__block.release()
 | 
				
			||||||
 | 
					        return (count, owner)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _is_owned(self):
 | 
				
			||||||
 | 
					        return self.__owner is currentThread()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def Condition(*args, **kwargs):
 | 
				
			||||||
 | 
					    return apply(_Condition, args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _Condition(_Verbose):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, lock=None, verbose=None):
 | 
				
			||||||
 | 
					        _Verbose.__init__(self, verbose)
 | 
				
			||||||
 | 
					        if lock is None:
 | 
				
			||||||
 | 
					            lock = RLock()
 | 
				
			||||||
 | 
					        self.__lock = lock
 | 
				
			||||||
 | 
					        # Export the lock's acquire() and release() methods
 | 
				
			||||||
 | 
					        self.acquire = lock.acquire
 | 
				
			||||||
 | 
					        self.release = lock.release
 | 
				
			||||||
 | 
					        # If the lock defines _release_save() and/or _acquire_restore(),
 | 
				
			||||||
 | 
					        # these override the default implementations (which just call
 | 
				
			||||||
 | 
					        # release() and acquire() on the lock).  Ditto for _is_owned().
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self._release_save = lock._release_save
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self._acquire_restore = lock._acquire_restore
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self._is_owned = lock._is_owned
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            pass
 | 
				
			||||||
 | 
					        self.__waiters = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        return "<Condition(%s, %d)>" % (self.__lock, len(self.__waiters))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _release_save(self):
 | 
				
			||||||
 | 
					        self.__lock.release()           # No state to save
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _acquire_restore(self, x):
 | 
				
			||||||
 | 
					        self.__lock.acquire()           # Ignore saved state
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _is_owned(self):
 | 
				
			||||||
 | 
					        if self.__lock.acquire(0):
 | 
				
			||||||
 | 
					            self.__lock.release()
 | 
				
			||||||
 | 
					            return 0
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def wait(self, timeout=None):
 | 
				
			||||||
 | 
					        me = currentThread()
 | 
				
			||||||
 | 
					        assert self._is_owned(), "wait() of un-acquire()d lock"
 | 
				
			||||||
 | 
					        waiter = _allocate_lock()
 | 
				
			||||||
 | 
					        waiter.acquire()
 | 
				
			||||||
 | 
					        self.__waiters.append(waiter)
 | 
				
			||||||
 | 
					        saved_state = self._release_save()
 | 
				
			||||||
 | 
					        if timeout is None:
 | 
				
			||||||
 | 
					            waiter.acquire()
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.wait(): got it", self)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            endtime = _time() + timeout
 | 
				
			||||||
 | 
					            delay = 0.000001 # 1 usec
 | 
				
			||||||
 | 
					            while 1:
 | 
				
			||||||
 | 
					                gotit = waiter.acquire(0)
 | 
				
			||||||
 | 
					                if gotit or _time() >= endtime:
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					                _sleep(delay)
 | 
				
			||||||
 | 
					                if delay < 1.0:
 | 
				
			||||||
 | 
					                    delay = delay * 2.0
 | 
				
			||||||
 | 
					            if not gotit:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.wait(%s): timed out", self, timeout)
 | 
				
			||||||
 | 
					                try:
 | 
				
			||||||
 | 
					                    self.__waiters.remove(waiter)
 | 
				
			||||||
 | 
					                except ValueError:
 | 
				
			||||||
 | 
					                    pass
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.wait(%s): got it", self, timeout)
 | 
				
			||||||
 | 
					        self._acquire_restore(saved_state)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def notify(self, n=1):
 | 
				
			||||||
 | 
					        me = currentThread()
 | 
				
			||||||
 | 
					        assert self._is_owned(), "notify() of un-acquire()d lock"
 | 
				
			||||||
 | 
					        __waiters = self.__waiters
 | 
				
			||||||
 | 
					        waiters = __waiters[:n]
 | 
				
			||||||
 | 
					        if not waiters:
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.notify(): no waiters", self)
 | 
				
			||||||
 | 
					            return
 | 
				
			||||||
 | 
					        self._note("%s.notify(): notifying %d waiter%s", self, n,
 | 
				
			||||||
 | 
					                   n!=1 and "s" or "")
 | 
				
			||||||
 | 
					        for waiter in waiters:
 | 
				
			||||||
 | 
					            waiter.release()
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                __waiters.remove(waiter)
 | 
				
			||||||
 | 
					            except ValueError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def notifyAll(self):
 | 
				
			||||||
 | 
					        self.notify(len(self.__waiters))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def Semaphore(*args, **kwargs):
 | 
				
			||||||
 | 
					    return apply(_Semaphore, args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _Semaphore(_Verbose):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # After Tim Peters' semaphore class, but bnot quite the same (no maximum)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, value=1, verbose=None):
 | 
				
			||||||
 | 
					        assert value >= 0, "Semaphore initial value must be >= 0"
 | 
				
			||||||
 | 
					        _Verbose.__init__(self, verbose)
 | 
				
			||||||
 | 
					        self.__cond = Condition(Lock())
 | 
				
			||||||
 | 
					        self.__value = value
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def acquire(self, blocking=1):
 | 
				
			||||||
 | 
					        rc = 0
 | 
				
			||||||
 | 
					        self.__cond.acquire()
 | 
				
			||||||
 | 
					        while self.__value == 0:
 | 
				
			||||||
 | 
					            if not blocking:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					            self.__cond.wait()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            self.__value = self.__value - 1
 | 
				
			||||||
 | 
					            rc = 1
 | 
				
			||||||
 | 
					        self.__cond.release()
 | 
				
			||||||
 | 
					        return rc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def release(self):
 | 
				
			||||||
 | 
					        self.__cond.acquire()
 | 
				
			||||||
 | 
					        self.__value = self.__value + 1
 | 
				
			||||||
 | 
					        self.__cond.notify()
 | 
				
			||||||
 | 
					        self.__cond.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def Event(*args, **kwargs):
 | 
				
			||||||
 | 
					    return apply(_Event, args, kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _Event(_Verbose):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # After Tim Peters' event class (without is_posted())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, verbose=None):
 | 
				
			||||||
 | 
					        _Verbose.__init__(self, verbose)
 | 
				
			||||||
 | 
					        self.__cond = Condition(Lock())
 | 
				
			||||||
 | 
					        self.__flag = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def isSet(self):
 | 
				
			||||||
 | 
					        return self.__flag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def set(self):
 | 
				
			||||||
 | 
					        self.__cond.acquire()
 | 
				
			||||||
 | 
					        self.__flag = 1
 | 
				
			||||||
 | 
					        self.__cond.notifyAll()
 | 
				
			||||||
 | 
					        self.__cond.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def clear(self):
 | 
				
			||||||
 | 
					        self.__cond.acquire()
 | 
				
			||||||
 | 
					        self.__flag = 0
 | 
				
			||||||
 | 
					        self.__cond.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def wait(self, timeout=None):
 | 
				
			||||||
 | 
					        self.__cond.acquire()
 | 
				
			||||||
 | 
					        if not self.__flag:
 | 
				
			||||||
 | 
					            self.__cond.wait(timeout)
 | 
				
			||||||
 | 
					        self.__cond.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Helper to generate new thread names
 | 
				
			||||||
 | 
					_counter = 0
 | 
				
			||||||
 | 
					def _newname(template="Thread-%d"):
 | 
				
			||||||
 | 
					    global _counter
 | 
				
			||||||
 | 
					    _counter = _counter + 1
 | 
				
			||||||
 | 
					    return template % _counter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Active thread administration
 | 
				
			||||||
 | 
					_active_limbo_lock = _allocate_lock()
 | 
				
			||||||
 | 
					_active = {}
 | 
				
			||||||
 | 
					_limbo = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Main class for threads
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Thread(_Verbose):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    __initialized = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, group=None, target=None, name=None,
 | 
				
			||||||
 | 
					                 args=(), kwargs={}, verbose=None):
 | 
				
			||||||
 | 
					        assert group is None, "group argument must be None for now"
 | 
				
			||||||
 | 
					        _Verbose.__init__(self, verbose)
 | 
				
			||||||
 | 
					        self.__target = target
 | 
				
			||||||
 | 
					        self.__name = str(name or _newname())
 | 
				
			||||||
 | 
					        self.__args = args
 | 
				
			||||||
 | 
					        self.__kwargs = kwargs
 | 
				
			||||||
 | 
					        self.__daemonic = self._set_daemon()
 | 
				
			||||||
 | 
					        self.__started = 0
 | 
				
			||||||
 | 
					        self.__stopped = 0
 | 
				
			||||||
 | 
					        self.__block = Condition(Lock())
 | 
				
			||||||
 | 
					        self.__initialized = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_daemon(self):
 | 
				
			||||||
 | 
					        # Overridden in _MainThread and _DummyThread
 | 
				
			||||||
 | 
					        return currentThread().isDaemon()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __repr__(self):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() was not called"
 | 
				
			||||||
 | 
					        status = "initial"
 | 
				
			||||||
 | 
					        if self.__started:
 | 
				
			||||||
 | 
					            status = "started"
 | 
				
			||||||
 | 
					        if self.__stopped:
 | 
				
			||||||
 | 
					            status = "stopped"
 | 
				
			||||||
 | 
					        if self.__daemonic:
 | 
				
			||||||
 | 
					            status = status + " daemon"
 | 
				
			||||||
 | 
					        return "<%s(%s, %s)>" % (self.__class__.__name__, self.__name, status)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def start(self):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        assert not self.__started, "thread already started"
 | 
				
			||||||
 | 
					        if __debug__:
 | 
				
			||||||
 | 
					            self._note("%s.start(): starting thread", self)
 | 
				
			||||||
 | 
					        _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					        _limbo[self] = self
 | 
				
			||||||
 | 
					        _active_limbo_lock.release()
 | 
				
			||||||
 | 
					        _start_new_thread(self.__bootstrap, ())
 | 
				
			||||||
 | 
					        self.__started = 1
 | 
				
			||||||
 | 
					        _sleep(0.000001)    # 1 usec, to let the thread run (Solaris hack)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def run(self):
 | 
				
			||||||
 | 
					        if self.__target:
 | 
				
			||||||
 | 
					            apply(self.__target, self.__args, self.__kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __bootstrap(self):
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self.__started = 1
 | 
				
			||||||
 | 
					            _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					            _active[_get_ident()] = self
 | 
				
			||||||
 | 
					            del _limbo[self]
 | 
				
			||||||
 | 
					            _active_limbo_lock.release()
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.__bootstrap(): thread started", self)
 | 
				
			||||||
 | 
					            try:
 | 
				
			||||||
 | 
					                self.run()
 | 
				
			||||||
 | 
					            except SystemExit:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.__bootstrap(): raised SystemExit", self)
 | 
				
			||||||
 | 
					            except:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.__bootstrap(): unhandled exception", self)
 | 
				
			||||||
 | 
					                s = _StringIO()
 | 
				
			||||||
 | 
					                _print_exc(file=s)
 | 
				
			||||||
 | 
					                _sys.stderr.write("Exception in thread %s:\n%s\n" %
 | 
				
			||||||
 | 
					                                 (self.getName(), s.getvalue()))
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.__bootstrap(): normal return", self)
 | 
				
			||||||
 | 
					        finally:
 | 
				
			||||||
 | 
					            self.__stop()
 | 
				
			||||||
 | 
					            self.__delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __stop(self):
 | 
				
			||||||
 | 
					        self.__block.acquire()
 | 
				
			||||||
 | 
					        self.__stopped = 1
 | 
				
			||||||
 | 
					        self.__block.notifyAll()
 | 
				
			||||||
 | 
					        self.__block.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __delete(self):
 | 
				
			||||||
 | 
					        _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					        del _active[_get_ident()]
 | 
				
			||||||
 | 
					        _active_limbo_lock.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def join(self, timeout=None):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        assert self.__started, "cannot join thread before it is started"
 | 
				
			||||||
 | 
					        assert self is not currentThread(), "cannot join current thread"
 | 
				
			||||||
 | 
					        if __debug__:
 | 
				
			||||||
 | 
					            if not self.__stopped:
 | 
				
			||||||
 | 
					                self._note("%s.join(): waiting until thread stops", self)
 | 
				
			||||||
 | 
					        self.__block.acquire()
 | 
				
			||||||
 | 
					        if timeout is None:
 | 
				
			||||||
 | 
					            while not self.__stopped:
 | 
				
			||||||
 | 
					                self.__block.wait()
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s.join(): thread stopped", self)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            deadline = _time() + timeout
 | 
				
			||||||
 | 
					            while not self.__stopped:
 | 
				
			||||||
 | 
					                delay = deadline - _time()
 | 
				
			||||||
 | 
					                if delay <= 0:
 | 
				
			||||||
 | 
					                    if __debug__:
 | 
				
			||||||
 | 
					                        self._note("%s.join(): timed out", self)
 | 
				
			||||||
 | 
					                    break
 | 
				
			||||||
 | 
					                self.__block.wait(delay)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                if __debug__:
 | 
				
			||||||
 | 
					                    self._note("%s.join(): thread stopped", self)
 | 
				
			||||||
 | 
					        self.__block.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getName(self):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        return self.__name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setName(self, name):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        self.__name = str(name)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def isAlive(self):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        return self.__started and not self.__stopped
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def isDaemon(self):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        return self.__daemonic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def setDaemon(self, daemonic):
 | 
				
			||||||
 | 
					        assert self.__initialized, "Thread.__init__() not called"
 | 
				
			||||||
 | 
					        assert not self.__started, "cannot set daemon status of active thread"
 | 
				
			||||||
 | 
					        self.__daemonic = daemonic
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Special thread class to represent the main thread
 | 
				
			||||||
 | 
					# This is garbage collected through an exit handler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _MainThread(Thread):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        Thread.__init__(self, name="MainThread")
 | 
				
			||||||
 | 
					        self._Thread__started = 1
 | 
				
			||||||
 | 
					        _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					        _active[_get_ident()] = self
 | 
				
			||||||
 | 
					        _active_limbo_lock.release()
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            self.__oldexitfunc = _sys.exitfunc
 | 
				
			||||||
 | 
					        except AttributeError:
 | 
				
			||||||
 | 
					            self.__oldexitfunc = None
 | 
				
			||||||
 | 
					        _sys.exitfunc = self.__exitfunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_daemon(self):
 | 
				
			||||||
 | 
					        return 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __exitfunc(self):
 | 
				
			||||||
 | 
					        self._Thread__stop()
 | 
				
			||||||
 | 
					        t = _pickSomeNonDaemonThread()
 | 
				
			||||||
 | 
					        if t:
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s: waiting for other threads", self)
 | 
				
			||||||
 | 
					        while t:
 | 
				
			||||||
 | 
					            t.join()
 | 
				
			||||||
 | 
					            t = _pickSomeNonDaemonThread()
 | 
				
			||||||
 | 
					        if self.__oldexitfunc:
 | 
				
			||||||
 | 
					            if __debug__:
 | 
				
			||||||
 | 
					                self._note("%s: calling exit handler", self)
 | 
				
			||||||
 | 
					            self.__oldexitfunc()
 | 
				
			||||||
 | 
					        if __debug__:
 | 
				
			||||||
 | 
					            self._note("%s: exiting", self)
 | 
				
			||||||
 | 
					        self._Thread__delete()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _pickSomeNonDaemonThread():
 | 
				
			||||||
 | 
					    for t in enumerate():
 | 
				
			||||||
 | 
					        if not t.isDaemon() and t.isAlive():
 | 
				
			||||||
 | 
					            return t
 | 
				
			||||||
 | 
					    return None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Dummy thread class to represent threads not started here.
 | 
				
			||||||
 | 
					# These aren't garbage collected when they die,
 | 
				
			||||||
 | 
					# nor can they be waited for.
 | 
				
			||||||
 | 
					# Their purpose is to return *something* from currentThread().
 | 
				
			||||||
 | 
					# They are marked as daemon threads so we won't wait for them
 | 
				
			||||||
 | 
					# when we exit (conform previous semantics).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class _DummyThread(Thread):
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    def __init__(self):
 | 
				
			||||||
 | 
					        Thread.__init__(self, name=_newname("Dummy-%d"))
 | 
				
			||||||
 | 
					        self.__Thread_started = 1
 | 
				
			||||||
 | 
					        _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					        _active[_get_ident()] = self
 | 
				
			||||||
 | 
					        _active_limbo_lock.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def _set_daemon(self):
 | 
				
			||||||
 | 
					        return 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def join(self):
 | 
				
			||||||
 | 
					        assert 0, "cannot join a dummy thread"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Global API functions
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def currentThread():
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        return _active[_get_ident()]
 | 
				
			||||||
 | 
					    except KeyError:
 | 
				
			||||||
 | 
					        print "currentThread(): no current thread for", _get_ident()
 | 
				
			||||||
 | 
					        return _DummyThread()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def activeCount():
 | 
				
			||||||
 | 
					    _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					    count = len(_active) + len(_limbo)
 | 
				
			||||||
 | 
					    _active_limbo_lock.release()
 | 
				
			||||||
 | 
					    return count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def enumerate():
 | 
				
			||||||
 | 
					    _active_limbo_lock.acquire()
 | 
				
			||||||
 | 
					    active = _active.values() + _limbo.values()
 | 
				
			||||||
 | 
					    _active_limbo_lock.release()
 | 
				
			||||||
 | 
					    return active
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Create the main thread object
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_MainThread()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Self-test code
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def _test():
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import random
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class BoundedQueue(_Verbose):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __init__(self, limit):
 | 
				
			||||||
 | 
					            _Verbose.__init__(self)
 | 
				
			||||||
 | 
					            self.mon = RLock()
 | 
				
			||||||
 | 
					            self.rc = Condition(self.mon)
 | 
				
			||||||
 | 
					            self.wc = Condition(self.mon)
 | 
				
			||||||
 | 
					            self.limit = limit
 | 
				
			||||||
 | 
					            self.queue = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def put(self, item):
 | 
				
			||||||
 | 
					            self.mon.acquire()
 | 
				
			||||||
 | 
					            while len(self.queue) >= self.limit:
 | 
				
			||||||
 | 
					                self._note("put(%s): queue full", item)
 | 
				
			||||||
 | 
					                self.wc.wait()
 | 
				
			||||||
 | 
					            self.queue.append(item)
 | 
				
			||||||
 | 
					            self._note("put(%s): appended, length now %d",
 | 
				
			||||||
 | 
					                       item, len(self.queue))
 | 
				
			||||||
 | 
					            self.rc.notify()
 | 
				
			||||||
 | 
					            self.mon.release()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def get(self):
 | 
				
			||||||
 | 
					            self.mon.acquire()
 | 
				
			||||||
 | 
					            while not self.queue:
 | 
				
			||||||
 | 
					                self._note("get(): queue empty")
 | 
				
			||||||
 | 
					                self.rc.wait()
 | 
				
			||||||
 | 
					            item = self.queue[0]
 | 
				
			||||||
 | 
					            del self.queue[0]
 | 
				
			||||||
 | 
					            self._note("get(): got %s, %d left", item, len(self.queue))
 | 
				
			||||||
 | 
					            self.wc.notify()
 | 
				
			||||||
 | 
					            self.mon.release()
 | 
				
			||||||
 | 
					            return item
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class ProducerThread(Thread):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __init__(self, queue, quota):
 | 
				
			||||||
 | 
					            Thread.__init__(self, name="Producer")
 | 
				
			||||||
 | 
					            self.queue = queue
 | 
				
			||||||
 | 
					            self.quota = quota
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def run(self):
 | 
				
			||||||
 | 
					            from random import random
 | 
				
			||||||
 | 
					            counter = 0
 | 
				
			||||||
 | 
					            while counter < self.quota:
 | 
				
			||||||
 | 
					                counter = counter + 1
 | 
				
			||||||
 | 
					                self.queue.put("%s.%d" % (self.getName(), counter))
 | 
				
			||||||
 | 
					                _sleep(random() * 0.00001)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    class ConsumerThread(Thread):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def __init__(self, queue, count):
 | 
				
			||||||
 | 
					            Thread.__init__(self, name="Consumer")
 | 
				
			||||||
 | 
					            self.queue = queue
 | 
				
			||||||
 | 
					            self.count = count
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        def run(self):
 | 
				
			||||||
 | 
					            while self.count > 0:
 | 
				
			||||||
 | 
					                item = self.queue.get()
 | 
				
			||||||
 | 
					                print item
 | 
				
			||||||
 | 
					                self.count = self.count - 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    import time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    NP = 3
 | 
				
			||||||
 | 
					    QL = 4
 | 
				
			||||||
 | 
					    NI = 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Q = BoundedQueue(QL)
 | 
				
			||||||
 | 
					    P = []
 | 
				
			||||||
 | 
					    for i in range(NP):
 | 
				
			||||||
 | 
					        t = ProducerThread(Q, NI)
 | 
				
			||||||
 | 
					        t.setName("Producer-%d" % (i+1))
 | 
				
			||||||
 | 
					        P.append(t)
 | 
				
			||||||
 | 
					    C = ConsumerThread(Q, NI*NP)
 | 
				
			||||||
 | 
					    for t in P:
 | 
				
			||||||
 | 
					        t.start()
 | 
				
			||||||
 | 
					        _sleep(0.000001)
 | 
				
			||||||
 | 
					    C.start()
 | 
				
			||||||
 | 
					    for t in P:
 | 
				
			||||||
 | 
					        t.join()
 | 
				
			||||||
 | 
					    C.join()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if __name__ == '__main__':
 | 
				
			||||||
 | 
					    _test()
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue