mirror of
https://github.com/python/cpython.git
synced 2025-08-03 00:23:06 +00:00
The usual.
This commit is contained in:
parent
65e5399081
commit
548703a1b8
43 changed files with 2463 additions and 2323 deletions
|
@ -89,19 +89,19 @@ DEFAULT_ERROR_MESSAGE = """\
|
|||
class HTTPServer(SocketServer.TCPServer):
|
||||
|
||||
def server_bind(self):
|
||||
"""Override server_bind to store the server name."""
|
||||
SocketServer.TCPServer.server_bind(self)
|
||||
host, port = self.socket.getsockname()
|
||||
if not host or host == '0.0.0.0':
|
||||
host = socket.gethostname()
|
||||
hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)
|
||||
if '.' not in hostname:
|
||||
for host in hostnames:
|
||||
if '.' in host:
|
||||
hostname = host
|
||||
break
|
||||
self.server_name = hostname
|
||||
self.server_port = port
|
||||
"""Override server_bind to store the server name."""
|
||||
SocketServer.TCPServer.server_bind(self)
|
||||
host, port = self.socket.getsockname()
|
||||
if not host or host == '0.0.0.0':
|
||||
host = socket.gethostname()
|
||||
hostname, hostnames, hostaddrs = socket.gethostbyaddr(host)
|
||||
if '.' not in hostname:
|
||||
for host in hostnames:
|
||||
if '.' in host:
|
||||
hostname = host
|
||||
break
|
||||
self.server_name = hostname
|
||||
self.server_port = port
|
||||
|
||||
|
||||
class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
|
||||
|
@ -217,196 +217,196 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
|
|||
server_version = "BaseHTTP/" + __version__
|
||||
|
||||
def handle(self):
|
||||
"""Handle a single HTTP request.
|
||||
"""Handle a single HTTP request.
|
||||
|
||||
You normally don't need to override this method; see the class
|
||||
__doc__ string for information on how to handle specific HTTP
|
||||
commands such as GET and POST.
|
||||
You normally don't need to override this method; see the class
|
||||
__doc__ string for information on how to handle specific HTTP
|
||||
commands such as GET and POST.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
self.raw_requestline = self.rfile.readline()
|
||||
self.request_version = version = "HTTP/0.9" # Default
|
||||
requestline = self.raw_requestline
|
||||
if requestline[-2:] == '\r\n':
|
||||
requestline = requestline[:-2]
|
||||
elif requestline[-1:] == '\n':
|
||||
requestline = requestline[:-1]
|
||||
self.requestline = requestline
|
||||
words = string.split(requestline)
|
||||
if len(words) == 3:
|
||||
[command, path, version] = words
|
||||
if version[:5] != 'HTTP/':
|
||||
self.send_error(400, "Bad request version (%s)" % `version`)
|
||||
return
|
||||
elif len(words) == 2:
|
||||
[command, path] = words
|
||||
if command != 'GET':
|
||||
self.send_error(400,
|
||||
"Bad HTTP/0.9 request type (%s)" % `command`)
|
||||
return
|
||||
else:
|
||||
self.send_error(400, "Bad request syntax (%s)" % `requestline`)
|
||||
return
|
||||
self.command, self.path, self.request_version = command, path, version
|
||||
self.headers = self.MessageClass(self.rfile, 0)
|
||||
mname = 'do_' + command
|
||||
if not hasattr(self, mname):
|
||||
self.send_error(501, "Unsupported method (%s)" % `mname`)
|
||||
return
|
||||
method = getattr(self, mname)
|
||||
method()
|
||||
self.raw_requestline = self.rfile.readline()
|
||||
self.request_version = version = "HTTP/0.9" # Default
|
||||
requestline = self.raw_requestline
|
||||
if requestline[-2:] == '\r\n':
|
||||
requestline = requestline[:-2]
|
||||
elif requestline[-1:] == '\n':
|
||||
requestline = requestline[:-1]
|
||||
self.requestline = requestline
|
||||
words = string.split(requestline)
|
||||
if len(words) == 3:
|
||||
[command, path, version] = words
|
||||
if version[:5] != 'HTTP/':
|
||||
self.send_error(400, "Bad request version (%s)" % `version`)
|
||||
return
|
||||
elif len(words) == 2:
|
||||
[command, path] = words
|
||||
if command != 'GET':
|
||||
self.send_error(400,
|
||||
"Bad HTTP/0.9 request type (%s)" % `command`)
|
||||
return
|
||||
else:
|
||||
self.send_error(400, "Bad request syntax (%s)" % `requestline`)
|
||||
return
|
||||
self.command, self.path, self.request_version = command, path, version
|
||||
self.headers = self.MessageClass(self.rfile, 0)
|
||||
mname = 'do_' + command
|
||||
if not hasattr(self, mname):
|
||||
self.send_error(501, "Unsupported method (%s)" % `mname`)
|
||||
return
|
||||
method = getattr(self, mname)
|
||||
method()
|
||||
|
||||
def send_error(self, code, message=None):
|
||||
"""Send and log an error reply.
|
||||
"""Send and log an error reply.
|
||||
|
||||
Arguments are the error code, and a detailed message.
|
||||
The detailed message defaults to the short entry matching the
|
||||
response code.
|
||||
Arguments are the error code, and a detailed message.
|
||||
The detailed message defaults to the short entry matching the
|
||||
response code.
|
||||
|
||||
This sends an error response (so it must be called before any
|
||||
output has been generated), logs the error, and finally sends
|
||||
a piece of HTML explaining the error to the user.
|
||||
This sends an error response (so it must be called before any
|
||||
output has been generated), logs the error, and finally sends
|
||||
a piece of HTML explaining the error to the user.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
try:
|
||||
short, long = self.responses[code]
|
||||
except KeyError:
|
||||
short, long = '???', '???'
|
||||
if not message:
|
||||
message = short
|
||||
explain = long
|
||||
self.log_error("code %d, message %s", code, message)
|
||||
self.send_response(code, message)
|
||||
self.end_headers()
|
||||
self.wfile.write(self.error_message_format %
|
||||
{'code': code,
|
||||
'message': message,
|
||||
'explain': explain})
|
||||
try:
|
||||
short, long = self.responses[code]
|
||||
except KeyError:
|
||||
short, long = '???', '???'
|
||||
if not message:
|
||||
message = short
|
||||
explain = long
|
||||
self.log_error("code %d, message %s", code, message)
|
||||
self.send_response(code, message)
|
||||
self.end_headers()
|
||||
self.wfile.write(self.error_message_format %
|
||||
{'code': code,
|
||||
'message': message,
|
||||
'explain': explain})
|
||||
|
||||
error_message_format = DEFAULT_ERROR_MESSAGE
|
||||
|
||||
def send_response(self, code, message=None):
|
||||
"""Send the response header and log the response code.
|
||||
"""Send the response header and log the response code.
|
||||
|
||||
Also send two standard headers with the server software
|
||||
version and the current date.
|
||||
Also send two standard headers with the server software
|
||||
version and the current date.
|
||||
|
||||
"""
|
||||
self.log_request(code)
|
||||
if message is None:
|
||||
if self.responses.has_key(code):
|
||||
message = self.responses[code][0]
|
||||
else:
|
||||
message = ''
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("%s %s %s\r\n" %
|
||||
(self.protocol_version, str(code), message))
|
||||
self.send_header('Server', self.version_string())
|
||||
self.send_header('Date', self.date_time_string())
|
||||
"""
|
||||
self.log_request(code)
|
||||
if message is None:
|
||||
if self.responses.has_key(code):
|
||||
message = self.responses[code][0]
|
||||
else:
|
||||
message = ''
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("%s %s %s\r\n" %
|
||||
(self.protocol_version, str(code), message))
|
||||
self.send_header('Server', self.version_string())
|
||||
self.send_header('Date', self.date_time_string())
|
||||
|
||||
def send_header(self, keyword, value):
|
||||
"""Send a MIME header."""
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("%s: %s\r\n" % (keyword, value))
|
||||
"""Send a MIME header."""
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("%s: %s\r\n" % (keyword, value))
|
||||
|
||||
def end_headers(self):
|
||||
"""Send the blank line ending the MIME headers."""
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("\r\n")
|
||||
"""Send the blank line ending the MIME headers."""
|
||||
if self.request_version != 'HTTP/0.9':
|
||||
self.wfile.write("\r\n")
|
||||
|
||||
def log_request(self, code='-', size='-'):
|
||||
"""Log an accepted request.
|
||||
"""Log an accepted request.
|
||||
|
||||
This is called by send_reponse().
|
||||
This is called by send_reponse().
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
self.log_message('"%s" %s %s',
|
||||
self.requestline, str(code), str(size))
|
||||
self.log_message('"%s" %s %s',
|
||||
self.requestline, str(code), str(size))
|
||||
|
||||
def log_error(self, *args):
|
||||
"""Log an error.
|
||||
"""Log an error.
|
||||
|
||||
This is called when a request cannot be fulfilled. By
|
||||
default it passes the message on to log_message().
|
||||
This is called when a request cannot be fulfilled. By
|
||||
default it passes the message on to log_message().
|
||||
|
||||
Arguments are the same as for log_message().
|
||||
Arguments are the same as for log_message().
|
||||
|
||||
XXX This should go to the separate error log.
|
||||
XXX This should go to the separate error log.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
apply(self.log_message, args)
|
||||
apply(self.log_message, args)
|
||||
|
||||
def log_message(self, format, *args):
|
||||
"""Log an arbitrary message.
|
||||
"""Log an arbitrary message.
|
||||
|
||||
This is used by all other logging functions. Override
|
||||
it if you have specific logging wishes.
|
||||
This is used by all other logging functions. Override
|
||||
it if you have specific logging wishes.
|
||||
|
||||
The first argument, FORMAT, is a format string for the
|
||||
message to be logged. If the format string contains
|
||||
any % escapes requiring parameters, they should be
|
||||
specified as subsequent arguments (it's just like
|
||||
printf!).
|
||||
The first argument, FORMAT, is a format string for the
|
||||
message to be logged. If the format string contains
|
||||
any % escapes requiring parameters, they should be
|
||||
specified as subsequent arguments (it's just like
|
||||
printf!).
|
||||
|
||||
The client host and current date/time are prefixed to
|
||||
every message.
|
||||
The client host and current date/time are prefixed to
|
||||
every message.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
sys.stderr.write("%s - - [%s] %s\n" %
|
||||
(self.address_string(),
|
||||
self.log_date_time_string(),
|
||||
format%args))
|
||||
sys.stderr.write("%s - - [%s] %s\n" %
|
||||
(self.address_string(),
|
||||
self.log_date_time_string(),
|
||||
format%args))
|
||||
|
||||
def version_string(self):
|
||||
"""Return the server software version string."""
|
||||
return self.server_version + ' ' + self.sys_version
|
||||
"""Return the server software version string."""
|
||||
return self.server_version + ' ' + self.sys_version
|
||||
|
||||
def date_time_string(self):
|
||||
"""Return the current date and time formatted for a message header."""
|
||||
now = time.time()
|
||||
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
|
||||
s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
|
||||
self.weekdayname[wd],
|
||||
day, self.monthname[month], year,
|
||||
hh, mm, ss)
|
||||
return s
|
||||
"""Return the current date and time formatted for a message header."""
|
||||
now = time.time()
|
||||
year, month, day, hh, mm, ss, wd, y, z = time.gmtime(now)
|
||||
s = "%s, %02d %3s %4d %02d:%02d:%02d GMT" % (
|
||||
self.weekdayname[wd],
|
||||
day, self.monthname[month], year,
|
||||
hh, mm, ss)
|
||||
return s
|
||||
|
||||
def log_date_time_string(self):
|
||||
"""Return the current time formatted for logging."""
|
||||
now = time.time()
|
||||
year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
|
||||
s = "%02d/%3s/%04d %02d:%02d:%02d" % (
|
||||
day, self.monthname[month], year, hh, mm, ss)
|
||||
return s
|
||||
"""Return the current time formatted for logging."""
|
||||
now = time.time()
|
||||
year, month, day, hh, mm, ss, x, y, z = time.localtime(now)
|
||||
s = "%02d/%3s/%04d %02d:%02d:%02d" % (
|
||||
day, self.monthname[month], year, hh, mm, ss)
|
||||
return s
|
||||
|
||||
weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
|
||||
monthname = [None,
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
|
||||
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
|
||||
|
||||
def address_string(self):
|
||||
"""Return the client address formatted for logging.
|
||||
"""Return the client address formatted for logging.
|
||||
|
||||
This version looks up the full hostname using gethostbyaddr(),
|
||||
and tries to find a name that contains at least one dot.
|
||||
This version looks up the full hostname using gethostbyaddr(),
|
||||
and tries to find a name that contains at least one dot.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
(host, port) = self.client_address
|
||||
try:
|
||||
name, names, addresses = socket.gethostbyaddr(host)
|
||||
except socket.error, msg:
|
||||
return host
|
||||
names.insert(0, name)
|
||||
for name in names:
|
||||
if '.' in name: return name
|
||||
return names[0]
|
||||
(host, port) = self.client_address
|
||||
try:
|
||||
name, names, addresses = socket.gethostbyaddr(host)
|
||||
except socket.error, msg:
|
||||
return host
|
||||
names.insert(0, name)
|
||||
for name in names:
|
||||
if '.' in name: return name
|
||||
return names[0]
|
||||
|
||||
|
||||
# Essentially static class variables
|
||||
|
@ -423,42 +423,42 @@ class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler):
|
|||
# form {code: (shortmessage, longmessage)}.
|
||||
# See http://www.w3.org/hypertext/WWW/Protocols/HTTP/HTRESP.html
|
||||
responses = {
|
||||
200: ('OK', 'Request fulfilled, document follows'),
|
||||
201: ('Created', 'Document created, URL follows'),
|
||||
202: ('Accepted',
|
||||
'Request accepted, processing continues off-line'),
|
||||
203: ('Partial information', 'Request fulfilled from cache'),
|
||||
204: ('No response', 'Request fulfilled, nothing follows'),
|
||||
200: ('OK', 'Request fulfilled, document follows'),
|
||||
201: ('Created', 'Document created, URL follows'),
|
||||
202: ('Accepted',
|
||||
'Request accepted, processing continues off-line'),
|
||||
203: ('Partial information', 'Request fulfilled from cache'),
|
||||
204: ('No response', 'Request fulfilled, nothing follows'),
|
||||
|
||||
301: ('Moved', 'Object moved permanently -- see URI list'),
|
||||
302: ('Found', 'Object moved temporarily -- see URI list'),
|
||||
303: ('Method', 'Object moved -- see Method and URL list'),
|
||||
304: ('Not modified',
|
||||
'Document has not changed singe given time'),
|
||||
301: ('Moved', 'Object moved permanently -- see URI list'),
|
||||
302: ('Found', 'Object moved temporarily -- see URI list'),
|
||||
303: ('Method', 'Object moved -- see Method and URL list'),
|
||||
304: ('Not modified',
|
||||
'Document has not changed singe given time'),
|
||||
|
||||
400: ('Bad request',
|
||||
'Bad request syntax or unsupported method'),
|
||||
401: ('Unauthorized',
|
||||
'No permission -- see authorization schemes'),
|
||||
402: ('Payment required',
|
||||
'No payment -- see charging schemes'),
|
||||
403: ('Forbidden',
|
||||
'Request forbidden -- authorization will not help'),
|
||||
404: ('Not found', 'Nothing matches the given URI'),
|
||||
400: ('Bad request',
|
||||
'Bad request syntax or unsupported method'),
|
||||
401: ('Unauthorized',
|
||||
'No permission -- see authorization schemes'),
|
||||
402: ('Payment required',
|
||||
'No payment -- see charging schemes'),
|
||||
403: ('Forbidden',
|
||||
'Request forbidden -- authorization will not help'),
|
||||
404: ('Not found', 'Nothing matches the given URI'),
|
||||
|
||||
500: ('Internal error', 'Server got itself in trouble'),
|
||||
501: ('Not implemented',
|
||||
'Server does not support this operation'),
|
||||
502: ('Service temporarily overloaded',
|
||||
'The server cannot process the request due to a high load'),
|
||||
503: ('Gateway timeout',
|
||||
'The gateway server did not receive a timely response'),
|
||||
500: ('Internal error', 'Server got itself in trouble'),
|
||||
501: ('Not implemented',
|
||||
'Server does not support this operation'),
|
||||
502: ('Service temporarily overloaded',
|
||||
'The server cannot process the request due to a high load'),
|
||||
503: ('Gateway timeout',
|
||||
'The gateway server did not receive a timely response'),
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
def test(HandlerClass = BaseHTTPRequestHandler,
|
||||
ServerClass = HTTPServer):
|
||||
ServerClass = HTTPServer):
|
||||
"""Test the HTTP request handler class.
|
||||
|
||||
This runs an HTTP server on port 8000 (or the first command line
|
||||
|
@ -467,9 +467,9 @@ def test(HandlerClass = BaseHTTPRequestHandler,
|
|||
"""
|
||||
|
||||
if sys.argv[1:]:
|
||||
port = string.atoi(sys.argv[1])
|
||||
port = string.atoi(sys.argv[1])
|
||||
else:
|
||||
port = 8000
|
||||
port = 8000
|
||||
server_address = ('', port)
|
||||
|
||||
httpd = ServerClass(server_address, HandlerClass)
|
||||
|
|
|
@ -41,47 +41,47 @@ class BastionClass:
|
|||
"""
|
||||
|
||||
def __init__(self, get, name):
|
||||
"""Constructor.
|
||||
"""Constructor.
|
||||
|
||||
Arguments:
|
||||
Arguments:
|
||||
|
||||
get - a function that gets the attribute value (by name)
|
||||
name - a human-readable name for the original object
|
||||
(suggestion: use repr(object))
|
||||
get - a function that gets the attribute value (by name)
|
||||
name - a human-readable name for the original object
|
||||
(suggestion: use repr(object))
|
||||
|
||||
"""
|
||||
self._get_ = get
|
||||
self._name_ = name
|
||||
"""
|
||||
self._get_ = get
|
||||
self._name_ = name
|
||||
|
||||
def __repr__(self):
|
||||
"""Return a representation string.
|
||||
"""Return a representation string.
|
||||
|
||||
This includes the name passed in to the constructor, so that
|
||||
if you print the bastion during debugging, at least you have
|
||||
some idea of what it is.
|
||||
This includes the name passed in to the constructor, so that
|
||||
if you print the bastion during debugging, at least you have
|
||||
some idea of what it is.
|
||||
|
||||
"""
|
||||
return "<Bastion for %s>" % self._name_
|
||||
"""
|
||||
return "<Bastion for %s>" % self._name_
|
||||
|
||||
def __getattr__(self, name):
|
||||
"""Get an as-yet undefined attribute value.
|
||||
"""Get an as-yet undefined attribute value.
|
||||
|
||||
This calls the get() function that was passed to the
|
||||
constructor. The result is stored as an instance variable so
|
||||
that the next time the same attribute is requested,
|
||||
__getattr__() won't be invoked.
|
||||
This calls the get() function that was passed to the
|
||||
constructor. The result is stored as an instance variable so
|
||||
that the next time the same attribute is requested,
|
||||
__getattr__() won't be invoked.
|
||||
|
||||
If the get() function raises an exception, this is simply
|
||||
passed on -- exceptions are not cached.
|
||||
If the get() function raises an exception, this is simply
|
||||
passed on -- exceptions are not cached.
|
||||
|
||||
"""
|
||||
attribute = self._get_(name)
|
||||
self.__dict__[name] = attribute
|
||||
return attribute
|
||||
"""
|
||||
attribute = self._get_(name)
|
||||
self.__dict__[name] = attribute
|
||||
return attribute
|
||||
|
||||
|
||||
def Bastion(object, filter = lambda name: name[:1] != '_',
|
||||
name=None, bastionclass=BastionClass):
|
||||
name=None, bastionclass=BastionClass):
|
||||
"""Create a bastion for an object, using an optional filter.
|
||||
|
||||
See the Bastion module's documentation for background.
|
||||
|
@ -109,33 +109,33 @@ def Bastion(object, filter = lambda name: name[:1] != '_',
|
|||
# the user has full access to all instance variables!
|
||||
|
||||
def get1(name, object=object, filter=filter):
|
||||
"""Internal function for Bastion(). See source comments."""
|
||||
if filter(name):
|
||||
attribute = getattr(object, name)
|
||||
if type(attribute) == MethodType:
|
||||
return attribute
|
||||
raise AttributeError, name
|
||||
"""Internal function for Bastion(). See source comments."""
|
||||
if filter(name):
|
||||
attribute = getattr(object, name)
|
||||
if type(attribute) == MethodType:
|
||||
return attribute
|
||||
raise AttributeError, name
|
||||
|
||||
def get2(name, get1=get1):
|
||||
"""Internal function for Bastion(). See source comments."""
|
||||
return get1(name)
|
||||
"""Internal function for Bastion(). See source comments."""
|
||||
return get1(name)
|
||||
|
||||
if name is None:
|
||||
name = `object`
|
||||
name = `object`
|
||||
return bastionclass(get2, name)
|
||||
|
||||
|
||||
def _test():
|
||||
"""Test the Bastion() function."""
|
||||
class Original:
|
||||
def __init__(self):
|
||||
self.sum = 0
|
||||
def add(self, n):
|
||||
self._add(n)
|
||||
def _add(self, n):
|
||||
self.sum = self.sum + n
|
||||
def total(self):
|
||||
return self.sum
|
||||
def __init__(self):
|
||||
self.sum = 0
|
||||
def add(self, n):
|
||||
self._add(n)
|
||||
def _add(self, n):
|
||||
self.sum = self.sum + n
|
||||
def total(self):
|
||||
return self.sum
|
||||
o = Original()
|
||||
b = Bastion(o)
|
||||
testcode = """if 1:
|
||||
|
@ -143,23 +143,23 @@ def _test():
|
|||
b.add(18)
|
||||
print "b.total() =", b.total()
|
||||
try:
|
||||
print "b.sum =", b.sum,
|
||||
print "b.sum =", b.sum,
|
||||
except:
|
||||
print "inaccessible"
|
||||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
print "accessible"
|
||||
try:
|
||||
print "b._add =", b._add,
|
||||
print "b._add =", b._add,
|
||||
except:
|
||||
print "inaccessible"
|
||||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
print "accessible"
|
||||
try:
|
||||
print "b._get_.func_defaults =", b._get_.func_defaults,
|
||||
print "b._get_.func_defaults =", b._get_.func_defaults,
|
||||
except:
|
||||
print "inaccessible"
|
||||
print "inaccessible"
|
||||
else:
|
||||
print "accessible"
|
||||
print "accessible"
|
||||
\n"""
|
||||
exec testcode
|
||||
print '='*20, "Using rexec:", '='*20
|
||||
|
|
|
@ -30,138 +30,138 @@ class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
|
|||
"""
|
||||
|
||||
def do_POST(self):
|
||||
"""Serve a POST request.
|
||||
"""Serve a POST request.
|
||||
|
||||
This is only implemented for CGI scripts.
|
||||
This is only implemented for CGI scripts.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
if self.is_cgi():
|
||||
self.run_cgi()
|
||||
else:
|
||||
self.send_error(501, "Can only POST to CGI scripts")
|
||||
if self.is_cgi():
|
||||
self.run_cgi()
|
||||
else:
|
||||
self.send_error(501, "Can only POST to CGI scripts")
|
||||
|
||||
def send_head(self):
|
||||
"""Version of send_head that support CGI scripts"""
|
||||
if self.is_cgi():
|
||||
return self.run_cgi()
|
||||
else:
|
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
|
||||
"""Version of send_head that support CGI scripts"""
|
||||
if self.is_cgi():
|
||||
return self.run_cgi()
|
||||
else:
|
||||
return SimpleHTTPServer.SimpleHTTPRequestHandler.send_head(self)
|
||||
|
||||
def is_cgi(self):
|
||||
"""test whether PATH corresponds to a CGI script.
|
||||
"""test whether PATH corresponds to a CGI script.
|
||||
|
||||
Return a tuple (dir, rest) if PATH requires running a
|
||||
CGI script, None if not. Note that rest begins with a
|
||||
slash if it is not empty.
|
||||
Return a tuple (dir, rest) if PATH requires running a
|
||||
CGI script, None if not. Note that rest begins with a
|
||||
slash if it is not empty.
|
||||
|
||||
The default implementation tests whether the path
|
||||
begins with one of the strings in the list
|
||||
self.cgi_directories (and the next character is a '/'
|
||||
or the end of the string).
|
||||
The default implementation tests whether the path
|
||||
begins with one of the strings in the list
|
||||
self.cgi_directories (and the next character is a '/'
|
||||
or the end of the string).
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
path = self.path
|
||||
path = self.path
|
||||
|
||||
for x in self.cgi_directories:
|
||||
i = len(x)
|
||||
if path[:i] == x and (not path[i:] or path[i] == '/'):
|
||||
self.cgi_info = path[:i], path[i+1:]
|
||||
return 1
|
||||
return 0
|
||||
for x in self.cgi_directories:
|
||||
i = len(x)
|
||||
if path[:i] == x and (not path[i:] or path[i] == '/'):
|
||||
self.cgi_info = path[:i], path[i+1:]
|
||||
return 1
|
||||
return 0
|
||||
|
||||
cgi_directories = ['/cgi-bin', '/htbin']
|
||||
|
||||
def run_cgi(self):
|
||||
"""Execute a CGI script."""
|
||||
dir, rest = self.cgi_info
|
||||
i = string.rfind(rest, '?')
|
||||
if i >= 0:
|
||||
rest, query = rest[:i], rest[i+1:]
|
||||
else:
|
||||
query = ''
|
||||
i = string.find(rest, '/')
|
||||
if i >= 0:
|
||||
script, rest = rest[:i], rest[i:]
|
||||
else:
|
||||
script, rest = rest, ''
|
||||
scriptname = dir + '/' + script
|
||||
scriptfile = self.translate_path(scriptname)
|
||||
if not os.path.exists(scriptfile):
|
||||
self.send_error(404, "No such CGI script (%s)" % `scriptname`)
|
||||
return
|
||||
if not os.path.isfile(scriptfile):
|
||||
self.send_error(403, "CGI script is not a plain file (%s)" %
|
||||
`scriptname`)
|
||||
return
|
||||
if not executable(scriptfile):
|
||||
self.send_error(403, "CGI script is not executable (%s)" %
|
||||
`scriptname`)
|
||||
return
|
||||
nobody = nobody_uid()
|
||||
self.send_response(200, "Script output follows")
|
||||
self.wfile.flush() # Always flush before forking
|
||||
pid = os.fork()
|
||||
if pid != 0:
|
||||
# Parent
|
||||
pid, sts = os.waitpid(pid, 0)
|
||||
if sts:
|
||||
self.log_error("CGI script exit status x%x" % sts)
|
||||
return
|
||||
# Child
|
||||
try:
|
||||
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
|
||||
# XXX Much of the following could be prepared ahead of time!
|
||||
env = {}
|
||||
env['SERVER_SOFTWARE'] = self.version_string()
|
||||
env['SERVER_NAME'] = self.server.server_name
|
||||
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
|
||||
env['SERVER_PROTOCOL'] = self.protocol_version
|
||||
env['SERVER_PORT'] = str(self.server.server_port)
|
||||
env['REQUEST_METHOD'] = self.command
|
||||
uqrest = urllib.unquote(rest)
|
||||
env['PATH_INFO'] = uqrest
|
||||
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
|
||||
env['SCRIPT_NAME'] = scriptname
|
||||
if query:
|
||||
env['QUERY_STRING'] = query
|
||||
host = self.address_string()
|
||||
if host != self.client_address[0]:
|
||||
env['REMOTE_HOST'] = host
|
||||
env['REMOTE_ADDR'] = self.client_address[0]
|
||||
# AUTH_TYPE
|
||||
# REMOTE_USER
|
||||
# REMOTE_IDENT
|
||||
env['CONTENT_TYPE'] = self.headers.type
|
||||
length = self.headers.getheader('content-length')
|
||||
if length:
|
||||
env['CONTENT_LENGTH'] = length
|
||||
accept = []
|
||||
for line in self.headers.getallmatchingheaders('accept'):
|
||||
if line[:1] in string.whitespace:
|
||||
accept.append(string.strip(line))
|
||||
else:
|
||||
accept = accept + string.split(line[7:])
|
||||
env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
|
||||
ua = self.headers.getheader('user-agent')
|
||||
if ua:
|
||||
env['HTTP_USER_AGENT'] = ua
|
||||
# XXX Other HTTP_* headers
|
||||
decoded_query = string.replace(query, '+', ' ')
|
||||
try:
|
||||
os.setuid(nobody)
|
||||
except os.error:
|
||||
pass
|
||||
os.dup2(self.rfile.fileno(), 0)
|
||||
os.dup2(self.wfile.fileno(), 1)
|
||||
print scriptfile, script, decoded_query
|
||||
os.execve(scriptfile,
|
||||
[script, decoded_query],
|
||||
env)
|
||||
except:
|
||||
self.server.handle_error(self.request, self.client_address)
|
||||
os._exit(127)
|
||||
"""Execute a CGI script."""
|
||||
dir, rest = self.cgi_info
|
||||
i = string.rfind(rest, '?')
|
||||
if i >= 0:
|
||||
rest, query = rest[:i], rest[i+1:]
|
||||
else:
|
||||
query = ''
|
||||
i = string.find(rest, '/')
|
||||
if i >= 0:
|
||||
script, rest = rest[:i], rest[i:]
|
||||
else:
|
||||
script, rest = rest, ''
|
||||
scriptname = dir + '/' + script
|
||||
scriptfile = self.translate_path(scriptname)
|
||||
if not os.path.exists(scriptfile):
|
||||
self.send_error(404, "No such CGI script (%s)" % `scriptname`)
|
||||
return
|
||||
if not os.path.isfile(scriptfile):
|
||||
self.send_error(403, "CGI script is not a plain file (%s)" %
|
||||
`scriptname`)
|
||||
return
|
||||
if not executable(scriptfile):
|
||||
self.send_error(403, "CGI script is not executable (%s)" %
|
||||
`scriptname`)
|
||||
return
|
||||
nobody = nobody_uid()
|
||||
self.send_response(200, "Script output follows")
|
||||
self.wfile.flush() # Always flush before forking
|
||||
pid = os.fork()
|
||||
if pid != 0:
|
||||
# Parent
|
||||
pid, sts = os.waitpid(pid, 0)
|
||||
if sts:
|
||||
self.log_error("CGI script exit status x%x" % sts)
|
||||
return
|
||||
# Child
|
||||
try:
|
||||
# Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html
|
||||
# XXX Much of the following could be prepared ahead of time!
|
||||
env = {}
|
||||
env['SERVER_SOFTWARE'] = self.version_string()
|
||||
env['SERVER_NAME'] = self.server.server_name
|
||||
env['GATEWAY_INTERFACE'] = 'CGI/1.1'
|
||||
env['SERVER_PROTOCOL'] = self.protocol_version
|
||||
env['SERVER_PORT'] = str(self.server.server_port)
|
||||
env['REQUEST_METHOD'] = self.command
|
||||
uqrest = urllib.unquote(rest)
|
||||
env['PATH_INFO'] = uqrest
|
||||
env['PATH_TRANSLATED'] = self.translate_path(uqrest)
|
||||
env['SCRIPT_NAME'] = scriptname
|
||||
if query:
|
||||
env['QUERY_STRING'] = query
|
||||
host = self.address_string()
|
||||
if host != self.client_address[0]:
|
||||
env['REMOTE_HOST'] = host
|
||||
env['REMOTE_ADDR'] = self.client_address[0]
|
||||
# AUTH_TYPE
|
||||
# REMOTE_USER
|
||||
# REMOTE_IDENT
|
||||
env['CONTENT_TYPE'] = self.headers.type
|
||||
length = self.headers.getheader('content-length')
|
||||
if length:
|
||||
env['CONTENT_LENGTH'] = length
|
||||
accept = []
|
||||
for line in self.headers.getallmatchingheaders('accept'):
|
||||
if line[:1] in string.whitespace:
|
||||
accept.append(string.strip(line))
|
||||
else:
|
||||
accept = accept + string.split(line[7:])
|
||||
env['HTTP_ACCEPT'] = string.joinfields(accept, ',')
|
||||
ua = self.headers.getheader('user-agent')
|
||||
if ua:
|
||||
env['HTTP_USER_AGENT'] = ua
|
||||
# XXX Other HTTP_* headers
|
||||
decoded_query = string.replace(query, '+', ' ')
|
||||
try:
|
||||
os.setuid(nobody)
|
||||
except os.error:
|
||||
pass
|
||||
os.dup2(self.rfile.fileno(), 0)
|
||||
os.dup2(self.wfile.fileno(), 1)
|
||||
print scriptfile, script, decoded_query
|
||||
os.execve(scriptfile,
|
||||
[script, decoded_query],
|
||||
env)
|
||||
except:
|
||||
self.server.handle_error(self.request, self.client_address)
|
||||
os._exit(127)
|
||||
|
||||
|
||||
nobody = None
|
||||
|
@ -170,26 +170,26 @@ def nobody_uid():
|
|||
"""Internal routine to get nobody's uid"""
|
||||
global nobody
|
||||
if nobody:
|
||||
return nobody
|
||||
return nobody
|
||||
import pwd
|
||||
try:
|
||||
nobody = pwd.getpwnam('nobody')[2]
|
||||
nobody = pwd.getpwnam('nobody')[2]
|
||||
except pwd.error:
|
||||
nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
|
||||
nobody = 1 + max(map(lambda x: x[2], pwd.getpwall()))
|
||||
return nobody
|
||||
|
||||
|
||||
def executable(path):
|
||||
"""Test for executable file."""
|
||||
try:
|
||||
st = os.stat(path)
|
||||
st = os.stat(path)
|
||||
except os.error:
|
||||
return 0
|
||||
return 0
|
||||
return st[0] & 0111 != 0
|
||||
|
||||
|
||||
def test(HandlerClass = CGIHTTPRequestHandler,
|
||||
ServerClass = BaseHTTPServer.HTTPServer):
|
||||
ServerClass = BaseHTTPServer.HTTPServer):
|
||||
SimpleHTTPServer.test(HandlerClass, ServerClass)
|
||||
|
||||
|
||||
|
|
|
@ -1,70 +1,109 @@
|
|||
# Routines to force "compilation" of all .py files in a directory
|
||||
# tree or on sys.path. By default recursion is pruned at a depth of
|
||||
# 10 and the current directory, if it occurs in sys.path, is skipped.
|
||||
# When called as a script, compiles argument directories, or sys.path
|
||||
# if no arguments.
|
||||
# After a similar module by Sjoerd Mullender.
|
||||
"""Module/script to "compile" all .py files to .pyc (or .pyo) file.
|
||||
|
||||
When called as a script with arguments, this compiles the directories
|
||||
given as arguments recursively; the -l option prevents it from
|
||||
recursing into directories.
|
||||
|
||||
Without arguments, if compiles all modules on sys.path, without
|
||||
recursing into subdirectories. (Even though it should do so for
|
||||
packages -- for now, you'll have to deal with packages separately.)
|
||||
|
||||
See module py_compile for details of the actual byte-compilation.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import py_compile
|
||||
|
||||
def compile_dir(dir, maxlevels = 10):
|
||||
print 'Listing', dir, '...'
|
||||
try:
|
||||
names = os.listdir(dir)
|
||||
except os.error:
|
||||
print "Can't list", dir
|
||||
names = []
|
||||
names.sort()
|
||||
for name in names:
|
||||
fullname = os.path.join(dir, name)
|
||||
if os.path.isfile(fullname):
|
||||
head, tail = name[:-3], name[-3:]
|
||||
if tail == '.py':
|
||||
print 'Compiling', fullname, '...'
|
||||
try:
|
||||
py_compile.compile(fullname)
|
||||
except KeyboardInterrupt:
|
||||
del names[:]
|
||||
print '\n[interrupt]'
|
||||
break
|
||||
except:
|
||||
if type(sys.exc_type) == type(''):
|
||||
exc_type_name = sys.exc_type
|
||||
else: exc_type_name = sys.exc_type.__name__
|
||||
print 'Sorry:', exc_type_name + ':',
|
||||
print sys.exc_value
|
||||
elif maxlevels > 0 and \
|
||||
name != os.curdir and name != os.pardir and \
|
||||
os.path.isdir(fullname) and \
|
||||
not os.path.islink(fullname):
|
||||
compile_dir(fullname, maxlevels - 1)
|
||||
def compile_dir(dir, maxlevels=10, ddir=None):
|
||||
"""Byte-compile all modules in the given directory tree.
|
||||
|
||||
def compile_path(skip_curdir = 1):
|
||||
for dir in sys.path:
|
||||
if (not dir or dir == os.curdir) and skip_curdir:
|
||||
print 'Skipping current directory'
|
||||
else:
|
||||
compile_dir(dir, 0)
|
||||
Arguments (only dir is required):
|
||||
|
||||
dir: the directory to byte-compile
|
||||
maxlevels: maximum recursion level (default 10)
|
||||
ddir: if given, purported directory name (this is the
|
||||
directory name that will show up in error messages)
|
||||
|
||||
"""
|
||||
print 'Listing', dir, '...'
|
||||
try:
|
||||
names = os.listdir(dir)
|
||||
except os.error:
|
||||
print "Can't list", dir
|
||||
names = []
|
||||
names.sort()
|
||||
for name in names:
|
||||
fullname = os.path.join(dir, name)
|
||||
if ddir:
|
||||
dfile = os.path.join(ddir, name)
|
||||
else:
|
||||
dfile = None
|
||||
if os.path.isfile(fullname):
|
||||
head, tail = name[:-3], name[-3:]
|
||||
if tail == '.py':
|
||||
print 'Compiling', fullname, '...'
|
||||
try:
|
||||
py_compile.compile(fullname, None, dfile)
|
||||
except KeyboardInterrupt:
|
||||
raise KeyboardInterrupt
|
||||
except:
|
||||
if type(sys.exc_type) == type(''):
|
||||
exc_type_name = sys.exc_type
|
||||
else: exc_type_name = sys.exc_type.__name__
|
||||
print 'Sorry:', exc_type_name + ':',
|
||||
print sys.exc_value
|
||||
elif maxlevels > 0 and \
|
||||
name != os.curdir and name != os.pardir and \
|
||||
os.path.isdir(fullname) and \
|
||||
not os.path.islink(fullname):
|
||||
compile_dir(fullname, maxlevels - 1, dfile)
|
||||
|
||||
def compile_path(skip_curdir=1, maxlevels=0):
|
||||
"""Byte-compile all module on sys.path.
|
||||
|
||||
Arguments (all optional):
|
||||
|
||||
skip_curdir: if true, skip current directory (default true)
|
||||
maxlevels: max recursion level (default 0)
|
||||
|
||||
"""
|
||||
for dir in sys.path:
|
||||
if (not dir or dir == os.curdir) and skip_curdir:
|
||||
print 'Skipping current directory'
|
||||
else:
|
||||
compile_dir(dir, maxlevels)
|
||||
|
||||
def main():
|
||||
import getopt
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'l')
|
||||
except getopt.error, msg:
|
||||
print msg
|
||||
print "usage: compileall [-l] [directory ...]"
|
||||
print "-l: don't recurse down"
|
||||
print "if no arguments, -l sys.path is assumed"
|
||||
maxlevels = 10
|
||||
for o, a in opts:
|
||||
if o == '-l': maxlevels = 0
|
||||
if args:
|
||||
for dir in sys.argv[1:]:
|
||||
compile_dir(dir, maxlevels)
|
||||
else:
|
||||
compile_path()
|
||||
"""Script main program."""
|
||||
import getopt
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'ld:')
|
||||
except getopt.error, msg:
|
||||
print msg
|
||||
print "usage: compileall [-l] [-d destdir] [directory ...]"
|
||||
print "-l: don't recurse down"
|
||||
print "-d destdir: purported directory name for error messages"
|
||||
print "if no arguments, -l sys.path is assumed"
|
||||
sys.exit(2)
|
||||
maxlevels = 10
|
||||
ddir = None
|
||||
for o, a in opts:
|
||||
if o == '-l': maxlevels = 0
|
||||
if o == '-d': ddir = a
|
||||
if ddir:
|
||||
if len(args) != 1:
|
||||
print "-d destdir require exactly one directory argument"
|
||||
sys.exit(2)
|
||||
try:
|
||||
if args:
|
||||
for dir in args:
|
||||
compile_dir(dir, maxlevels, ddir)
|
||||
else:
|
||||
compile_path()
|
||||
except KeyboardInterrupt:
|
||||
print "\n[interrupt]"
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -34,23 +34,23 @@ ConfigParser -- responsible for for parsing a list of
|
|||
sections() -- return all the configuration section names, sans DEFAULT
|
||||
|
||||
options(section) -- return list of configuration options for the named
|
||||
section
|
||||
section
|
||||
|
||||
read(*filenames) -- read and parse the list of named configuration files
|
||||
|
||||
get(section, option, raw=0) -- return a string value for the named
|
||||
option. All % interpolations are
|
||||
expanded in the return values, based on
|
||||
the defaults passed into the constructor
|
||||
and the DEFAULT section.
|
||||
option. All % interpolations are
|
||||
expanded in the return values, based on
|
||||
the defaults passed into the constructor
|
||||
and the DEFAULT section.
|
||||
|
||||
getint(section, options) -- like get(), but convert value to an integer
|
||||
|
||||
getfloat(section, options) -- like get(), but convert value to a float
|
||||
|
||||
getboolean(section, options) -- like get(), but convert value to
|
||||
a boolean (currently defined as 0
|
||||
or 1, only)
|
||||
a boolean (currently defined as 0
|
||||
or 1, only)
|
||||
"""
|
||||
|
||||
import sys
|
||||
|
@ -71,185 +71,186 @@ DEFAULTSECT = "DEFAULT"
|
|||
# exception classes
|
||||
class Error:
|
||||
def __init__(self, msg=''):
|
||||
self.__msg = msg
|
||||
self.__msg = msg
|
||||
def __repr__(self):
|
||||
return self.__msg
|
||||
return self.__msg
|
||||
|
||||
class NoSectionError(Error):
|
||||
def __init__(self, section):
|
||||
Error.__init__(self, 'No section: %s' % section)
|
||||
self.section = section
|
||||
Error.__init__(self, 'No section: %s' % section)
|
||||
self.section = section
|
||||
|
||||
class DuplicateSectionError(Error):
|
||||
def __init__(self, section):
|
||||
Error.__init__(self, "Section %s already exists" % section)
|
||||
self.section = section
|
||||
Error.__init__(self, "Section %s already exists" % section)
|
||||
self.section = section
|
||||
|
||||
class NoOptionError(Error):
|
||||
def __init__(self, option, section):
|
||||
Error.__init__(self, "No option `%s' in section: %s" %
|
||||
(option, section))
|
||||
self.option = option
|
||||
self.section = section
|
||||
Error.__init__(self, "No option `%s' in section: %s" %
|
||||
(option, section))
|
||||
self.option = option
|
||||
self.section = section
|
||||
|
||||
class InterpolationError(Error):
|
||||
def __init__(self, reference, option, section):
|
||||
Error.__init__(self,
|
||||
"Bad value substitution: sect `%s', opt `%s', ref `%s'"
|
||||
% (section, option, reference))
|
||||
self.reference = reference
|
||||
self.option = option
|
||||
self.section = section
|
||||
Error.__init__(self,
|
||||
"Bad value substitution: sect `%s', opt `%s', ref `%s'"
|
||||
% (section, option, reference))
|
||||
self.reference = reference
|
||||
self.option = option
|
||||
self.section = section
|
||||
|
||||
|
||||
|
||||
class ConfigParser:
|
||||
def __init__(self, defaults=None):
|
||||
self.__sections = {}
|
||||
if defaults is None:
|
||||
self.__defaults = {}
|
||||
else:
|
||||
self.__defaults = defaults
|
||||
self.__sections = {}
|
||||
if defaults is None:
|
||||
self.__defaults = {}
|
||||
else:
|
||||
self.__defaults = defaults
|
||||
|
||||
def defaults(self):
|
||||
return self.__defaults
|
||||
return self.__defaults
|
||||
|
||||
def sections(self):
|
||||
"""Return a list of section names, excluding [DEFAULT]"""
|
||||
# self.__sections will never have [DEFAULT] in it
|
||||
return self.__sections.keys()
|
||||
"""Return a list of section names, excluding [DEFAULT]"""
|
||||
# self.__sections will never have [DEFAULT] in it
|
||||
return self.__sections.keys()
|
||||
|
||||
def add_section(self, section):
|
||||
"""Create a new section in the configuration.
|
||||
"""Create a new section in the configuration.
|
||||
|
||||
Raise DuplicateSectionError if a section by the specified name
|
||||
already exists.
|
||||
"""
|
||||
if self.__sections.has_key(section):
|
||||
raise DuplicateSectionError(section)
|
||||
self.__sections[section] = {}
|
||||
Raise DuplicateSectionError if a section by the specified name
|
||||
already exists.
|
||||
"""
|
||||
if self.__sections.has_key(section):
|
||||
raise DuplicateSectionError(section)
|
||||
self.__sections[section] = {}
|
||||
|
||||
def has_section(self, section):
|
||||
"""Indicate whether the named section is present in the configuration.
|
||||
"""Indicate whether the named section is present in the configuration.
|
||||
|
||||
The DEFAULT section is not acknowledged.
|
||||
"""
|
||||
return self.__sections.has_key(section)
|
||||
The DEFAULT section is not acknowledged.
|
||||
"""
|
||||
return self.__sections.has_key(section)
|
||||
|
||||
def options(self, section):
|
||||
try:
|
||||
opts = self.__sections[section].copy()
|
||||
except KeyError:
|
||||
raise NoSectionError(section)
|
||||
opts.update(self.__defaults)
|
||||
return opts.keys()
|
||||
try:
|
||||
opts = self.__sections[section].copy()
|
||||
except KeyError:
|
||||
raise NoSectionError(section)
|
||||
opts.update(self.__defaults)
|
||||
return opts.keys()
|
||||
|
||||
def read(self, filenames):
|
||||
"""Read and parse a list of filenames."""
|
||||
if type(filenames) is type(''):
|
||||
filenames = [filenames]
|
||||
for file in filenames:
|
||||
try:
|
||||
fp = open(file, 'r')
|
||||
self.__read(fp)
|
||||
except IOError:
|
||||
pass
|
||||
"""Read and parse a list of filenames."""
|
||||
if type(filenames) is type(''):
|
||||
filenames = [filenames]
|
||||
for file in filenames:
|
||||
try:
|
||||
fp = open(file, 'r')
|
||||
self.__read(fp)
|
||||
except IOError:
|
||||
pass
|
||||
|
||||
def get(self, section, option, raw=0):
|
||||
"""Get an option value for a given section.
|
||||
"""Get an option value for a given section.
|
||||
|
||||
All % interpolations are expanded in the return values, based
|
||||
on the defaults passed into the constructor.
|
||||
All % interpolations are expanded in the return values, based
|
||||
on the defaults passed into the constructor.
|
||||
|
||||
The section DEFAULT is special.
|
||||
"""
|
||||
try:
|
||||
d = self.__sections[section].copy()
|
||||
except KeyError:
|
||||
if section == DEFAULTSECT:
|
||||
d = {}
|
||||
else:
|
||||
raise NoSectionError(section)
|
||||
d.update(self.__defaults)
|
||||
option = string.lower(option)
|
||||
try:
|
||||
rawval = d[option]
|
||||
except KeyError:
|
||||
raise NoOptionError(option, section)
|
||||
# do the string interpolation
|
||||
if raw:
|
||||
return rawval
|
||||
try:
|
||||
return rawval % d
|
||||
except KeyError, key:
|
||||
raise InterpolationError(key, option, section)
|
||||
The section DEFAULT is special.
|
||||
"""
|
||||
try:
|
||||
sectdict = self.__sections[section].copy()
|
||||
except KeyError:
|
||||
if section == DEFAULTSECT:
|
||||
sectdict = {}
|
||||
else:
|
||||
raise NoSectionError(section)
|
||||
d = self.__defaults.copy()
|
||||
d.update(sectdict)
|
||||
option = string.lower(option)
|
||||
try:
|
||||
rawval = d[option]
|
||||
except KeyError:
|
||||
raise NoOptionError(option, section)
|
||||
# do the string interpolation
|
||||
if raw:
|
||||
return rawval
|
||||
try:
|
||||
return rawval % d
|
||||
except KeyError, key:
|
||||
raise InterpolationError(key, option, section)
|
||||
|
||||
def __get(self, section, conv, option):
|
||||
return conv(self.get(section, option))
|
||||
return conv(self.get(section, option))
|
||||
|
||||
def getint(self, section, option):
|
||||
return self.__get(section, string.atoi, option)
|
||||
return self.__get(section, string.atoi, option)
|
||||
|
||||
def getfloat(self, section, option):
|
||||
return self.__get(section, string.atof, option)
|
||||
return self.__get(section, string.atof, option)
|
||||
|
||||
def getboolean(self, section, option):
|
||||
v = self.get(section, option)
|
||||
val = string.atoi(v)
|
||||
if val not in (0, 1):
|
||||
raise ValueError, 'Not a boolean: %s' % v
|
||||
return val
|
||||
v = self.get(section, option)
|
||||
val = string.atoi(v)
|
||||
if val not in (0, 1):
|
||||
raise ValueError, 'Not a boolean: %s' % v
|
||||
return val
|
||||
|
||||
def __read(self, fp):
|
||||
"""Parse a sectioned setup file.
|
||||
"""Parse a sectioned setup file.
|
||||
|
||||
The sections in setup file contains a title line at the top,
|
||||
indicated by a name in square brackets (`[]'), plus key/value
|
||||
options lines, indicated by `name: value' format lines.
|
||||
Continuation are represented by an embedded newline then
|
||||
leading whitespace. Blank lines, lines beginning with a '#',
|
||||
and just about everything else is ignored.
|
||||
"""
|
||||
cursect = None # None, or a dictionary
|
||||
optname = None
|
||||
lineno = 0
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
lineno = lineno + 1
|
||||
# comment or blank line?
|
||||
if string.strip(line) == '' or line[0] in '#;':
|
||||
continue
|
||||
if string.lower(string.split(line)[0]) == 'rem' \
|
||||
and line[0] == "r": # no leading whitespace
|
||||
continue
|
||||
# continuation line?
|
||||
if line[0] in ' \t' and cursect <> None and optname:
|
||||
value = string.strip(line)
|
||||
if value:
|
||||
cursect = cursect[optname] + '\n ' + value
|
||||
# a section header?
|
||||
elif secthead_cre.match(line) >= 0:
|
||||
sectname = secthead_cre.group(1)
|
||||
if self.__sections.has_key(sectname):
|
||||
cursect = self.__sections[sectname]
|
||||
elif sectname == DEFAULTSECT:
|
||||
cursect = self.__defaults
|
||||
else:
|
||||
cursect = {'name': sectname}
|
||||
self.__sections[sectname] = cursect
|
||||
# So sections can't start with a continuation line.
|
||||
optname = None
|
||||
# an option line?
|
||||
elif option_cre.match(line) >= 0:
|
||||
optname, optval = option_cre.group(1, 3)
|
||||
optname = string.lower(optname)
|
||||
optval = string.strip(optval)
|
||||
# allow empty values
|
||||
if optval == '""':
|
||||
optval = ''
|
||||
cursect[optname] = optval
|
||||
# an error
|
||||
else:
|
||||
print 'Error in %s at %d: %s', (fp.name, lineno, `line`)
|
||||
The sections in setup file contains a title line at the top,
|
||||
indicated by a name in square brackets (`[]'), plus key/value
|
||||
options lines, indicated by `name: value' format lines.
|
||||
Continuation are represented by an embedded newline then
|
||||
leading whitespace. Blank lines, lines beginning with a '#',
|
||||
and just about everything else is ignored.
|
||||
"""
|
||||
cursect = None # None, or a dictionary
|
||||
optname = None
|
||||
lineno = 0
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
lineno = lineno + 1
|
||||
# comment or blank line?
|
||||
if string.strip(line) == '' or line[0] in '#;':
|
||||
continue
|
||||
if string.lower(string.split(line)[0]) == 'rem' \
|
||||
and line[0] == "r": # no leading whitespace
|
||||
continue
|
||||
# continuation line?
|
||||
if line[0] in ' \t' and cursect <> None and optname:
|
||||
value = string.strip(line)
|
||||
if value:
|
||||
cursect = cursect[optname] + '\n ' + value
|
||||
# a section header?
|
||||
elif secthead_cre.match(line) >= 0:
|
||||
sectname = secthead_cre.group(1)
|
||||
if self.__sections.has_key(sectname):
|
||||
cursect = self.__sections[sectname]
|
||||
elif sectname == DEFAULTSECT:
|
||||
cursect = self.__defaults
|
||||
else:
|
||||
cursect = {'name': sectname}
|
||||
self.__sections[sectname] = cursect
|
||||
# So sections can't start with a continuation line.
|
||||
optname = None
|
||||
# an option line?
|
||||
elif option_cre.match(line) >= 0:
|
||||
optname, optval = option_cre.group(1, 3)
|
||||
optname = string.lower(optname)
|
||||
optval = string.strip(optval)
|
||||
# allow empty values
|
||||
if optval == '""':
|
||||
optval = ''
|
||||
cursect[optname] = optval
|
||||
# an error
|
||||
else:
|
||||
print 'Error in %s at %d: %s', (fp.name, lineno, `line`)
|
||||
|
|
|
@ -48,18 +48,18 @@ Exception(*)
|
|||
|
||||
class Exception:
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.args = args
|
||||
|
||||
def __str__(self):
|
||||
if not self.args:
|
||||
return ''
|
||||
elif len(self.args) == 1:
|
||||
return str(self.args[0])
|
||||
else:
|
||||
return str(self.args)
|
||||
elif len(self.args) == 1:
|
||||
return str(self.args[0])
|
||||
else:
|
||||
return str(self.args)
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.args[i]
|
||||
return self.args[i]
|
||||
|
||||
class StandardError(Exception):
|
||||
pass
|
||||
|
@ -68,21 +68,21 @@ class SyntaxError(StandardError):
|
|||
filename = lineno = offset = text = None
|
||||
msg = ""
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
if len(self.args) >= 1:
|
||||
self.msg = self.args[0]
|
||||
if len(self.args) == 2:
|
||||
info = self.args[1]
|
||||
try:
|
||||
self.filename, self.lineno, self.offset, self.text = info
|
||||
except:
|
||||
pass
|
||||
self.args = args
|
||||
if len(self.args) >= 1:
|
||||
self.msg = self.args[0]
|
||||
if len(self.args) == 2:
|
||||
info = self.args[1]
|
||||
try:
|
||||
self.filename, self.lineno, self.offset, self.text = info
|
||||
except:
|
||||
pass
|
||||
def __str__(self):
|
||||
return str(self.msg)
|
||||
|
||||
class IOError(StandardError):
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.args = args
|
||||
self.errno = None
|
||||
self.strerror = None
|
||||
if len(args) == 2:
|
||||
|
@ -146,7 +146,7 @@ class MemoryError(StandardError):
|
|||
|
||||
class SystemExit(Exception):
|
||||
def __init__(self, *args):
|
||||
self.args = args
|
||||
self.args = args
|
||||
if len(args) == 0:
|
||||
self.code = None
|
||||
elif len(args) == 1:
|
||||
|
|
|
@ -80,7 +80,7 @@ _state = None
|
|||
def input(files=(), inplace=0, backup=""):
|
||||
global _state
|
||||
if _state and _state._file:
|
||||
raise RuntimeError, "input() already active"
|
||||
raise RuntimeError, "input() already active"
|
||||
_state = FileInput(files, inplace, backup)
|
||||
return _state
|
||||
|
||||
|
@ -89,151 +89,151 @@ def close():
|
|||
state = _state
|
||||
_state = None
|
||||
if state:
|
||||
state.close()
|
||||
state.close()
|
||||
|
||||
def nextfile():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.nextfile()
|
||||
|
||||
def filename():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.filename()
|
||||
|
||||
def lineno():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.lineno()
|
||||
|
||||
def filelineno():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.filelineno()
|
||||
|
||||
def isfirstline():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.isfirstline()
|
||||
|
||||
def isstdin():
|
||||
if not _state:
|
||||
raise RuntimeError, "no active input()"
|
||||
raise RuntimeError, "no active input()"
|
||||
return _state.isstdin()
|
||||
|
||||
class FileInput:
|
||||
|
||||
def __init__(self, files=(), inplace=0, backup=""):
|
||||
if type(files) == type(''):
|
||||
files = (files,)
|
||||
else:
|
||||
files = tuple(files)
|
||||
if not files:
|
||||
files = tuple(sys.argv[1:])
|
||||
if not files:
|
||||
files = ('-',)
|
||||
self._files = files
|
||||
self._inplace = inplace
|
||||
self._backup = backup
|
||||
self._savestdout = None
|
||||
self._output = None
|
||||
self._filename = None
|
||||
self._lineno = 0
|
||||
self._filelineno = 0
|
||||
self._file = None
|
||||
self._isstdin = 0
|
||||
if type(files) == type(''):
|
||||
files = (files,)
|
||||
else:
|
||||
files = tuple(files)
|
||||
if not files:
|
||||
files = tuple(sys.argv[1:])
|
||||
if not files:
|
||||
files = ('-',)
|
||||
self._files = files
|
||||
self._inplace = inplace
|
||||
self._backup = backup
|
||||
self._savestdout = None
|
||||
self._output = None
|
||||
self._filename = None
|
||||
self._lineno = 0
|
||||
self._filelineno = 0
|
||||
self._file = None
|
||||
self._isstdin = 0
|
||||
|
||||
def __del__(self):
|
||||
self.close()
|
||||
self.close()
|
||||
|
||||
def close(self):
|
||||
self.nextfile()
|
||||
self._files = ()
|
||||
self.nextfile()
|
||||
self._files = ()
|
||||
|
||||
def __getitem__(self, i):
|
||||
if i != self._lineno:
|
||||
raise RuntimeError, "accessing lines out of order"
|
||||
line = self.readline()
|
||||
if not line:
|
||||
raise IndexError, "end of input reached"
|
||||
return line
|
||||
if i != self._lineno:
|
||||
raise RuntimeError, "accessing lines out of order"
|
||||
line = self.readline()
|
||||
if not line:
|
||||
raise IndexError, "end of input reached"
|
||||
return line
|
||||
|
||||
def nextfile(self):
|
||||
savestdout = self._savestdout
|
||||
self._savestdout = 0
|
||||
if savestdout:
|
||||
sys.stdout = savestdout
|
||||
savestdout = self._savestdout
|
||||
self._savestdout = 0
|
||||
if savestdout:
|
||||
sys.stdout = savestdout
|
||||
|
||||
output = self._output
|
||||
self._output = 0
|
||||
if output:
|
||||
output.close()
|
||||
output = self._output
|
||||
self._output = 0
|
||||
if output:
|
||||
output.close()
|
||||
|
||||
file = self._file
|
||||
self._file = 0
|
||||
if file and not self._isstdin:
|
||||
file.close()
|
||||
file = self._file
|
||||
self._file = 0
|
||||
if file and not self._isstdin:
|
||||
file.close()
|
||||
|
||||
backupfilename = self._backupfilename
|
||||
self._backupfilename = 0
|
||||
if backupfilename and not self._backup:
|
||||
try: os.unlink(backupfilename)
|
||||
except: pass
|
||||
backupfilename = self._backupfilename
|
||||
self._backupfilename = 0
|
||||
if backupfilename and not self._backup:
|
||||
try: os.unlink(backupfilename)
|
||||
except: pass
|
||||
|
||||
self._isstdin = 0
|
||||
self._isstdin = 0
|
||||
|
||||
def readline(self):
|
||||
if not self._file:
|
||||
if not self._files:
|
||||
return ""
|
||||
self._filename = self._files[0]
|
||||
self._files = self._files[1:]
|
||||
self._filelineno = 0
|
||||
self._file = None
|
||||
self._isstdin = 0
|
||||
self._backupfilename = 0
|
||||
if self._filename == '-':
|
||||
self._filename = '<stdin>'
|
||||
self._file = sys.stdin
|
||||
self._isstdin = 1
|
||||
else:
|
||||
if self._inplace:
|
||||
self._backupfilename = (
|
||||
self._filename + (self._backup or ".bak"))
|
||||
try: os.unlink(self._backupfilename)
|
||||
except os.error: pass
|
||||
# The next three lines may raise IOError
|
||||
os.rename(self._filename, self._backupfilename)
|
||||
self._file = open(self._backupfilename, "r")
|
||||
self._output = open(self._filename, "w")
|
||||
self._savestdout = sys.stdout
|
||||
sys.stdout = self._output
|
||||
else:
|
||||
# This may raise IOError
|
||||
self._file = open(self._filename, "r")
|
||||
line = self._file.readline()
|
||||
if line:
|
||||
self._lineno = self._lineno + 1
|
||||
self._filelineno = self._filelineno + 1
|
||||
return line
|
||||
self.nextfile()
|
||||
# Recursive call
|
||||
return self.readline()
|
||||
if not self._file:
|
||||
if not self._files:
|
||||
return ""
|
||||
self._filename = self._files[0]
|
||||
self._files = self._files[1:]
|
||||
self._filelineno = 0
|
||||
self._file = None
|
||||
self._isstdin = 0
|
||||
self._backupfilename = 0
|
||||
if self._filename == '-':
|
||||
self._filename = '<stdin>'
|
||||
self._file = sys.stdin
|
||||
self._isstdin = 1
|
||||
else:
|
||||
if self._inplace:
|
||||
self._backupfilename = (
|
||||
self._filename + (self._backup or ".bak"))
|
||||
try: os.unlink(self._backupfilename)
|
||||
except os.error: pass
|
||||
# The next three lines may raise IOError
|
||||
os.rename(self._filename, self._backupfilename)
|
||||
self._file = open(self._backupfilename, "r")
|
||||
self._output = open(self._filename, "w")
|
||||
self._savestdout = sys.stdout
|
||||
sys.stdout = self._output
|
||||
else:
|
||||
# This may raise IOError
|
||||
self._file = open(self._filename, "r")
|
||||
line = self._file.readline()
|
||||
if line:
|
||||
self._lineno = self._lineno + 1
|
||||
self._filelineno = self._filelineno + 1
|
||||
return line
|
||||
self.nextfile()
|
||||
# Recursive call
|
||||
return self.readline()
|
||||
|
||||
def filename(self):
|
||||
return self._filename
|
||||
return self._filename
|
||||
|
||||
def lineno(self):
|
||||
return self._lineno
|
||||
return self._lineno
|
||||
|
||||
def filelineno(self):
|
||||
return self._filelineno
|
||||
return self._filelineno
|
||||
|
||||
def isfirstline(self):
|
||||
return self._filelineno == 1
|
||||
return self._filelineno == 1
|
||||
|
||||
def isstdin(self):
|
||||
return self._isstdin
|
||||
return self._isstdin
|
||||
|
||||
def _test():
|
||||
import getopt
|
||||
|
@ -241,13 +241,13 @@ def _test():
|
|||
backup = 0
|
||||
opts, args = getopt.getopt(sys.argv[1:], "ib:")
|
||||
for o, a in opts:
|
||||
if o == '-i': inplace = 1
|
||||
if o == '-b': backup = a
|
||||
if o == '-i': inplace = 1
|
||||
if o == '-b': backup = a
|
||||
for line in input(args, inplace=inplace, backup=backup):
|
||||
if line[-1:] == '\n': line = line[:-1]
|
||||
if line[-1:] == '\r': line = line[:-1]
|
||||
print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
|
||||
isfirstline() and "*" or "", line)
|
||||
if line[-1:] == '\n': line = line[:-1]
|
||||
if line[-1:] == '\r': line = line[:-1]
|
||||
print "%d: %s[%d]%s %s" % (lineno(), filename(), filelineno(),
|
||||
isfirstline() and "*" or "", line)
|
||||
print "%d: %s[%d]" % (lineno(), filename(), filelineno())
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -9,9 +9,9 @@ AS_IS = None
|
|||
class NullFormatter:
|
||||
|
||||
def __init__(self, writer=None):
|
||||
if not writer:
|
||||
writer = NullWriter()
|
||||
self.writer = writer
|
||||
if not writer:
|
||||
writer = NullWriter()
|
||||
self.writer = writer
|
||||
def end_paragraph(self, blankline): pass
|
||||
def add_line_break(self): pass
|
||||
def add_hor_rule(self, *args, **kw): pass
|
||||
|
@ -39,88 +39,88 @@ class AbstractFormatter:
|
|||
# in all circumstances.
|
||||
|
||||
def __init__(self, writer):
|
||||
self.writer = writer # Output device
|
||||
self.align = None # Current alignment
|
||||
self.align_stack = [] # Alignment stack
|
||||
self.font_stack = [] # Font state
|
||||
self.margin_stack = [] # Margin state
|
||||
self.spacing = None # Vertical spacing state
|
||||
self.style_stack = [] # Other state, e.g. color
|
||||
self.nospace = 1 # Should leading space be suppressed
|
||||
self.softspace = 0 # Should a space be inserted
|
||||
self.para_end = 1 # Just ended a paragraph
|
||||
self.parskip = 0 # Skipped space between paragraphs?
|
||||
self.hard_break = 1 # Have a hard break
|
||||
self.have_label = 0
|
||||
self.writer = writer # Output device
|
||||
self.align = None # Current alignment
|
||||
self.align_stack = [] # Alignment stack
|
||||
self.font_stack = [] # Font state
|
||||
self.margin_stack = [] # Margin state
|
||||
self.spacing = None # Vertical spacing state
|
||||
self.style_stack = [] # Other state, e.g. color
|
||||
self.nospace = 1 # Should leading space be suppressed
|
||||
self.softspace = 0 # Should a space be inserted
|
||||
self.para_end = 1 # Just ended a paragraph
|
||||
self.parskip = 0 # Skipped space between paragraphs?
|
||||
self.hard_break = 1 # Have a hard break
|
||||
self.have_label = 0
|
||||
|
||||
def end_paragraph(self, blankline):
|
||||
if not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
self.have_label = 0
|
||||
if self.parskip < blankline and not self.have_label:
|
||||
self.writer.send_paragraph(blankline - self.parskip)
|
||||
self.parskip = blankline
|
||||
self.have_label = 0
|
||||
self.hard_break = self.nospace = self.para_end = 1
|
||||
self.softspace = 0
|
||||
if not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
self.have_label = 0
|
||||
if self.parskip < blankline and not self.have_label:
|
||||
self.writer.send_paragraph(blankline - self.parskip)
|
||||
self.parskip = blankline
|
||||
self.have_label = 0
|
||||
self.hard_break = self.nospace = self.para_end = 1
|
||||
self.softspace = 0
|
||||
|
||||
def add_line_break(self):
|
||||
if not (self.hard_break or self.para_end):
|
||||
self.writer.send_line_break()
|
||||
self.have_label = self.parskip = 0
|
||||
self.hard_break = self.nospace = 1
|
||||
self.softspace = 0
|
||||
if not (self.hard_break or self.para_end):
|
||||
self.writer.send_line_break()
|
||||
self.have_label = self.parskip = 0
|
||||
self.hard_break = self.nospace = 1
|
||||
self.softspace = 0
|
||||
|
||||
def add_hor_rule(self, *args, **kw):
|
||||
if not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
apply(self.writer.send_hor_rule, args, kw)
|
||||
self.hard_break = self.nospace = 1
|
||||
self.have_label = self.para_end = self.softspace = self.parskip = 0
|
||||
if not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
apply(self.writer.send_hor_rule, args, kw)
|
||||
self.hard_break = self.nospace = 1
|
||||
self.have_label = self.para_end = self.softspace = self.parskip = 0
|
||||
|
||||
def add_label_data(self, format, counter, blankline = None):
|
||||
if self.have_label or not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
if not self.para_end:
|
||||
self.writer.send_paragraph((blankline and 1) or 0)
|
||||
if type(format) is StringType:
|
||||
self.writer.send_label_data(self.format_counter(format, counter))
|
||||
else:
|
||||
self.writer.send_label_data(format)
|
||||
self.nospace = self.have_label = self.hard_break = self.para_end = 1
|
||||
self.softspace = self.parskip = 0
|
||||
if self.have_label or not self.hard_break:
|
||||
self.writer.send_line_break()
|
||||
if not self.para_end:
|
||||
self.writer.send_paragraph((blankline and 1) or 0)
|
||||
if type(format) is StringType:
|
||||
self.writer.send_label_data(self.format_counter(format, counter))
|
||||
else:
|
||||
self.writer.send_label_data(format)
|
||||
self.nospace = self.have_label = self.hard_break = self.para_end = 1
|
||||
self.softspace = self.parskip = 0
|
||||
|
||||
def format_counter(self, format, counter):
|
||||
label = ''
|
||||
for c in format:
|
||||
try:
|
||||
if c == '1':
|
||||
label = label + ('%d' % counter)
|
||||
label = label + ('%d' % counter)
|
||||
elif c in 'aA':
|
||||
if counter > 0:
|
||||
label = label + self.format_letter(c, counter)
|
||||
if counter > 0:
|
||||
label = label + self.format_letter(c, counter)
|
||||
elif c in 'iI':
|
||||
if counter > 0:
|
||||
label = label + self.format_roman(c, counter)
|
||||
else:
|
||||
label = label + c
|
||||
if counter > 0:
|
||||
label = label + self.format_roman(c, counter)
|
||||
else:
|
||||
label = label + c
|
||||
except:
|
||||
label = label + c
|
||||
return label
|
||||
|
||||
def format_letter(self, case, counter):
|
||||
label = ''
|
||||
while counter > 0:
|
||||
counter, x = divmod(counter-1, 26)
|
||||
s = chr(ord(case) + x)
|
||||
label = s + label
|
||||
return label
|
||||
label = ''
|
||||
while counter > 0:
|
||||
counter, x = divmod(counter-1, 26)
|
||||
s = chr(ord(case) + x)
|
||||
label = s + label
|
||||
return label
|
||||
|
||||
def format_roman(self, case, counter):
|
||||
ones = ['i', 'x', 'c', 'm']
|
||||
fives = ['v', 'l', 'd']
|
||||
label, index = '', 0
|
||||
# This will die of IndexError when counter is too big
|
||||
# This will die of IndexError when counter is too big
|
||||
while counter > 0:
|
||||
counter, x = divmod(counter, 10)
|
||||
if x == 9:
|
||||
|
@ -134,132 +134,132 @@ class AbstractFormatter:
|
|||
else:
|
||||
s = ''
|
||||
s = s + ones[index]*x
|
||||
label = s + label
|
||||
label = s + label
|
||||
index = index + 1
|
||||
if case == 'I':
|
||||
return string.upper(label)
|
||||
return string.upper(label)
|
||||
return label
|
||||
|
||||
def add_flowing_data(self, data,
|
||||
# These are only here to load them into locals:
|
||||
whitespace = string.whitespace,
|
||||
join = string.join, split = string.split):
|
||||
if not data: return
|
||||
# The following looks a bit convoluted but is a great improvement over
|
||||
# data = regsub.gsub('[' + string.whitespace + ']+', ' ', data)
|
||||
prespace = data[:1] in whitespace
|
||||
postspace = data[-1:] in whitespace
|
||||
data = join(split(data))
|
||||
if self.nospace and not data:
|
||||
return
|
||||
elif prespace or self.softspace:
|
||||
if not data:
|
||||
if not self.nospace:
|
||||
self.softspace = 1
|
||||
self.parskip = 0
|
||||
return
|
||||
if not self.nospace:
|
||||
data = ' ' + data
|
||||
self.hard_break = self.nospace = self.para_end = \
|
||||
self.parskip = self.have_label = 0
|
||||
self.softspace = postspace
|
||||
self.writer.send_flowing_data(data)
|
||||
# These are only here to load them into locals:
|
||||
whitespace = string.whitespace,
|
||||
join = string.join, split = string.split):
|
||||
if not data: return
|
||||
# The following looks a bit convoluted but is a great improvement over
|
||||
# data = regsub.gsub('[' + string.whitespace + ']+', ' ', data)
|
||||
prespace = data[:1] in whitespace
|
||||
postspace = data[-1:] in whitespace
|
||||
data = join(split(data))
|
||||
if self.nospace and not data:
|
||||
return
|
||||
elif prespace or self.softspace:
|
||||
if not data:
|
||||
if not self.nospace:
|
||||
self.softspace = 1
|
||||
self.parskip = 0
|
||||
return
|
||||
if not self.nospace:
|
||||
data = ' ' + data
|
||||
self.hard_break = self.nospace = self.para_end = \
|
||||
self.parskip = self.have_label = 0
|
||||
self.softspace = postspace
|
||||
self.writer.send_flowing_data(data)
|
||||
|
||||
def add_literal_data(self, data):
|
||||
if not data: return
|
||||
if self.softspace:
|
||||
self.writer.send_flowing_data(" ")
|
||||
self.hard_break = data[-1:] == '\n'
|
||||
self.nospace = self.para_end = self.softspace = \
|
||||
self.parskip = self.have_label = 0
|
||||
self.writer.send_literal_data(data)
|
||||
if not data: return
|
||||
if self.softspace:
|
||||
self.writer.send_flowing_data(" ")
|
||||
self.hard_break = data[-1:] == '\n'
|
||||
self.nospace = self.para_end = self.softspace = \
|
||||
self.parskip = self.have_label = 0
|
||||
self.writer.send_literal_data(data)
|
||||
|
||||
def flush_softspace(self):
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.parskip = \
|
||||
self.have_label = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.parskip = \
|
||||
self.have_label = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
|
||||
def push_alignment(self, align):
|
||||
if align and align != self.align:
|
||||
self.writer.new_alignment(align)
|
||||
self.align = align
|
||||
self.align_stack.append(align)
|
||||
else:
|
||||
self.align_stack.append(self.align)
|
||||
if align and align != self.align:
|
||||
self.writer.new_alignment(align)
|
||||
self.align = align
|
||||
self.align_stack.append(align)
|
||||
else:
|
||||
self.align_stack.append(self.align)
|
||||
|
||||
def pop_alignment(self):
|
||||
if self.align_stack:
|
||||
del self.align_stack[-1]
|
||||
if self.align_stack:
|
||||
self.align = align = self.align_stack[-1]
|
||||
self.writer.new_alignment(align)
|
||||
else:
|
||||
self.align = None
|
||||
self.writer.new_alignment(None)
|
||||
if self.align_stack:
|
||||
del self.align_stack[-1]
|
||||
if self.align_stack:
|
||||
self.align = align = self.align_stack[-1]
|
||||
self.writer.new_alignment(align)
|
||||
else:
|
||||
self.align = None
|
||||
self.writer.new_alignment(None)
|
||||
|
||||
def push_font(self, (size, i, b, tt)):
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
csize, ci, cb, ctt = self.font_stack[-1]
|
||||
if size is AS_IS: size = csize
|
||||
if i is AS_IS: i = ci
|
||||
if b is AS_IS: b = cb
|
||||
if tt is AS_IS: tt = ctt
|
||||
font = (size, i, b, tt)
|
||||
self.font_stack.append(font)
|
||||
self.writer.new_font(font)
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
if self.font_stack:
|
||||
csize, ci, cb, ctt = self.font_stack[-1]
|
||||
if size is AS_IS: size = csize
|
||||
if i is AS_IS: i = ci
|
||||
if b is AS_IS: b = cb
|
||||
if tt is AS_IS: tt = ctt
|
||||
font = (size, i, b, tt)
|
||||
self.font_stack.append(font)
|
||||
self.writer.new_font(font)
|
||||
|
||||
def pop_font(self):
|
||||
if self.font_stack:
|
||||
del self.font_stack[-1]
|
||||
if self.font_stack:
|
||||
font = self.font_stack[-1]
|
||||
else:
|
||||
font = None
|
||||
self.writer.new_font(font)
|
||||
if self.font_stack:
|
||||
del self.font_stack[-1]
|
||||
if self.font_stack:
|
||||
font = self.font_stack[-1]
|
||||
else:
|
||||
font = None
|
||||
self.writer.new_font(font)
|
||||
|
||||
def push_margin(self, margin):
|
||||
self.margin_stack.append(margin)
|
||||
fstack = filter(None, self.margin_stack)
|
||||
if not margin and fstack:
|
||||
margin = fstack[-1]
|
||||
self.writer.new_margin(margin, len(fstack))
|
||||
self.margin_stack.append(margin)
|
||||
fstack = filter(None, self.margin_stack)
|
||||
if not margin and fstack:
|
||||
margin = fstack[-1]
|
||||
self.writer.new_margin(margin, len(fstack))
|
||||
|
||||
def pop_margin(self):
|
||||
if self.margin_stack:
|
||||
del self.margin_stack[-1]
|
||||
fstack = filter(None, self.margin_stack)
|
||||
if fstack:
|
||||
margin = fstack[-1]
|
||||
else:
|
||||
margin = None
|
||||
self.writer.new_margin(margin, len(fstack))
|
||||
if self.margin_stack:
|
||||
del self.margin_stack[-1]
|
||||
fstack = filter(None, self.margin_stack)
|
||||
if fstack:
|
||||
margin = fstack[-1]
|
||||
else:
|
||||
margin = None
|
||||
self.writer.new_margin(margin, len(fstack))
|
||||
|
||||
def set_spacing(self, spacing):
|
||||
self.spacing = spacing
|
||||
self.writer.new_spacing(spacing)
|
||||
self.spacing = spacing
|
||||
self.writer.new_spacing(spacing)
|
||||
|
||||
def push_style(self, *styles):
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
for style in styles:
|
||||
self.style_stack.append(style)
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
if self.softspace:
|
||||
self.hard_break = self.para_end = self.softspace = 0
|
||||
self.nospace = 1
|
||||
self.writer.send_flowing_data(' ')
|
||||
for style in styles:
|
||||
self.style_stack.append(style)
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def pop_style(self, n=1):
|
||||
del self.style_stack[-n:]
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
del self.style_stack[-n:]
|
||||
self.writer.new_styles(tuple(self.style_stack))
|
||||
|
||||
def assert_line_data(self, flag=1):
|
||||
self.nospace = self.hard_break = not flag
|
||||
self.para_end = self.parskip = self.have_label = 0
|
||||
self.nospace = self.hard_break = not flag
|
||||
self.para_end = self.parskip = self.have_label = 0
|
||||
|
||||
|
||||
class NullWriter:
|
||||
|
@ -282,119 +282,119 @@ class NullWriter:
|
|||
class AbstractWriter(NullWriter):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
def new_alignment(self, align):
|
||||
print "new_alignment(%s)" % `align`
|
||||
print "new_alignment(%s)" % `align`
|
||||
|
||||
def new_font(self, font):
|
||||
print "new_font(%s)" % `font`
|
||||
print "new_font(%s)" % `font`
|
||||
|
||||
def new_margin(self, margin, level):
|
||||
print "new_margin(%s, %d)" % (`margin`, level)
|
||||
print "new_margin(%s, %d)" % (`margin`, level)
|
||||
|
||||
def new_spacing(self, spacing):
|
||||
print "new_spacing(%s)" % `spacing`
|
||||
print "new_spacing(%s)" % `spacing`
|
||||
|
||||
def new_styles(self, styles):
|
||||
print "new_styles(%s)" % `styles`
|
||||
print "new_styles(%s)" % `styles`
|
||||
|
||||
def send_paragraph(self, blankline):
|
||||
print "send_paragraph(%s)" % `blankline`
|
||||
print "send_paragraph(%s)" % `blankline`
|
||||
|
||||
def send_line_break(self):
|
||||
print "send_line_break()"
|
||||
print "send_line_break()"
|
||||
|
||||
def send_hor_rule(self, *args, **kw):
|
||||
print "send_hor_rule()"
|
||||
print "send_hor_rule()"
|
||||
|
||||
def send_label_data(self, data):
|
||||
print "send_label_data(%s)" % `data`
|
||||
print "send_label_data(%s)" % `data`
|
||||
|
||||
def send_flowing_data(self, data):
|
||||
print "send_flowing_data(%s)" % `data`
|
||||
print "send_flowing_data(%s)" % `data`
|
||||
|
||||
def send_literal_data(self, data):
|
||||
print "send_literal_data(%s)" % `data`
|
||||
print "send_literal_data(%s)" % `data`
|
||||
|
||||
|
||||
class DumbWriter(NullWriter):
|
||||
|
||||
def __init__(self, file=None, maxcol=72):
|
||||
self.file = file or sys.stdout
|
||||
self.maxcol = maxcol
|
||||
NullWriter.__init__(self)
|
||||
self.reset()
|
||||
self.file = file or sys.stdout
|
||||
self.maxcol = maxcol
|
||||
NullWriter.__init__(self)
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
|
||||
def send_paragraph(self, blankline):
|
||||
self.file.write('\n' + '\n'*blankline)
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
self.file.write('\n' + '\n'*blankline)
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
|
||||
def send_line_break(self):
|
||||
self.file.write('\n')
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
self.file.write('\n')
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
|
||||
def send_hor_rule(self, *args, **kw):
|
||||
self.file.write('\n')
|
||||
self.file.write('-'*self.maxcol)
|
||||
self.file.write('\n')
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
self.file.write('\n')
|
||||
self.file.write('-'*self.maxcol)
|
||||
self.file.write('\n')
|
||||
self.col = 0
|
||||
self.atbreak = 0
|
||||
|
||||
def send_literal_data(self, data):
|
||||
self.file.write(data)
|
||||
i = string.rfind(data, '\n')
|
||||
if i >= 0:
|
||||
self.col = 0
|
||||
data = data[i+1:]
|
||||
data = string.expandtabs(data)
|
||||
self.col = self.col + len(data)
|
||||
self.atbreak = 0
|
||||
self.file.write(data)
|
||||
i = string.rfind(data, '\n')
|
||||
if i >= 0:
|
||||
self.col = 0
|
||||
data = data[i+1:]
|
||||
data = string.expandtabs(data)
|
||||
self.col = self.col + len(data)
|
||||
self.atbreak = 0
|
||||
|
||||
def send_flowing_data(self, data):
|
||||
if not data: return
|
||||
atbreak = self.atbreak or data[0] in string.whitespace
|
||||
col = self.col
|
||||
maxcol = self.maxcol
|
||||
write = self.file.write
|
||||
for word in string.split(data):
|
||||
if atbreak:
|
||||
if col + len(word) >= maxcol:
|
||||
write('\n')
|
||||
col = 0
|
||||
else:
|
||||
write(' ')
|
||||
col = col + 1
|
||||
write(word)
|
||||
col = col + len(word)
|
||||
atbreak = 1
|
||||
self.col = col
|
||||
self.atbreak = data[-1] in string.whitespace
|
||||
if not data: return
|
||||
atbreak = self.atbreak or data[0] in string.whitespace
|
||||
col = self.col
|
||||
maxcol = self.maxcol
|
||||
write = self.file.write
|
||||
for word in string.split(data):
|
||||
if atbreak:
|
||||
if col + len(word) >= maxcol:
|
||||
write('\n')
|
||||
col = 0
|
||||
else:
|
||||
write(' ')
|
||||
col = col + 1
|
||||
write(word)
|
||||
col = col + len(word)
|
||||
atbreak = 1
|
||||
self.col = col
|
||||
self.atbreak = data[-1] in string.whitespace
|
||||
|
||||
|
||||
def test(file = None):
|
||||
w = DumbWriter()
|
||||
f = AbstractFormatter(w)
|
||||
if file:
|
||||
fp = open(file)
|
||||
fp = open(file)
|
||||
elif sys.argv[1:]:
|
||||
fp = open(sys.argv[1])
|
||||
fp = open(sys.argv[1])
|
||||
else:
|
||||
fp = sys.stdin
|
||||
fp = sys.stdin
|
||||
while 1:
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
if line == '\n':
|
||||
f.end_paragraph(1)
|
||||
else:
|
||||
f.add_flowing_data(line)
|
||||
line = fp.readline()
|
||||
if not line:
|
||||
break
|
||||
if line == '\n':
|
||||
f.end_paragraph(1)
|
||||
else:
|
||||
f.add_flowing_data(line)
|
||||
f.end_paragraph(0)
|
||||
|
||||
|
||||
|
|
|
@ -38,10 +38,10 @@ A_PLUS_SOUND = '<'
|
|||
|
||||
# Function mapping all file types to strings; unknown types become TYPE='x'
|
||||
_names = dir()
|
||||
_type_to_name_map = None
|
||||
_type_to_name_map = {}
|
||||
def type_to_name(gtype):
|
||||
global _type_to_name_map
|
||||
if not _type_to_name_map:
|
||||
if _type_to_name_map=={}:
|
||||
for name in _names:
|
||||
if name[:2] == 'A_':
|
||||
_type_to_name_map[eval(name)] = name[2:]
|
||||
|
@ -75,6 +75,22 @@ def send_selector(selector, host, port = 0):
|
|||
def send_query(selector, query, host, port = 0):
|
||||
return send_selector(selector + '\t' + query, host, port)
|
||||
|
||||
# Takes a path as returned by urlparse and returns the appropriate selector
|
||||
def path_to_selector(path):
|
||||
if path=="/":
|
||||
return "/"
|
||||
else:
|
||||
return path[2:] # Cuts initial slash and data type identifier
|
||||
|
||||
# Takes a path as returned by urlparse and maps it to a string
|
||||
# See section 3.4 of RFC 1738 for details
|
||||
def path_to_datatype_name(path):
|
||||
if path=="/":
|
||||
# No way to tell, although "INDEX" is likely
|
||||
return "TYPE='unknown'"
|
||||
else:
|
||||
return type_to_name(path[1])
|
||||
|
||||
# The following functions interpret the data returned by the gopher
|
||||
# server according to the expected type, e.g. textfile or directory
|
||||
|
||||
|
@ -103,7 +119,8 @@ def get_directory(f):
|
|||
continue
|
||||
if len(parts) > 4:
|
||||
if parts[4:] != ['+']:
|
||||
print '(Extra info from server:', parts[4:], ')'
|
||||
print '(Extra info from server:',
|
||||
print parts[4:], ')'
|
||||
else:
|
||||
parts.append('')
|
||||
parts.insert(0, gtype)
|
||||
|
|
|
@ -12,71 +12,71 @@ def url2pathname(pathname):
|
|||
#
|
||||
tp = urllib.splittype(pathname)[0]
|
||||
if tp and tp <> 'file':
|
||||
raise RuntimeError, 'Cannot convert non-local URL to pathname'
|
||||
raise RuntimeError, 'Cannot convert non-local URL to pathname'
|
||||
components = string.split(pathname, '/')
|
||||
# Remove . and embedded ..
|
||||
i = 0
|
||||
while i < len(components):
|
||||
if components[i] == '.':
|
||||
del components[i]
|
||||
elif components[i] == '..' and i > 0 and \
|
||||
components[i-1] not in ('', '..'):
|
||||
del components[i-1:i+1]
|
||||
i = i-1
|
||||
elif components[i] == '' and i > 0 and components[i-1] <> '':
|
||||
del components[i]
|
||||
else:
|
||||
i = i+1
|
||||
if components[i] == '.':
|
||||
del components[i]
|
||||
elif components[i] == '..' and i > 0 and \
|
||||
components[i-1] not in ('', '..'):
|
||||
del components[i-1:i+1]
|
||||
i = i-1
|
||||
elif components[i] == '' and i > 0 and components[i-1] <> '':
|
||||
del components[i]
|
||||
else:
|
||||
i = i+1
|
||||
if not components[0]:
|
||||
# Absolute unix path, don't start with colon
|
||||
return string.join(components[1:], ':')
|
||||
# Absolute unix path, don't start with colon
|
||||
return string.join(components[1:], ':')
|
||||
else:
|
||||
# relative unix path, start with colon. First replace
|
||||
# leading .. by empty strings (giving ::file)
|
||||
i = 0
|
||||
while i < len(components) and components[i] == '..':
|
||||
components[i] = ''
|
||||
i = i + 1
|
||||
return ':' + string.join(components, ':')
|
||||
# relative unix path, start with colon. First replace
|
||||
# leading .. by empty strings (giving ::file)
|
||||
i = 0
|
||||
while i < len(components) and components[i] == '..':
|
||||
components[i] = ''
|
||||
i = i + 1
|
||||
return ':' + string.join(components, ':')
|
||||
|
||||
def pathname2url(pathname):
|
||||
"convert mac pathname to /-delimited pathname"
|
||||
if '/' in pathname:
|
||||
raise RuntimeError, "Cannot convert pathname containing slashes"
|
||||
raise RuntimeError, "Cannot convert pathname containing slashes"
|
||||
components = string.split(pathname, ':')
|
||||
# Remove empty first and/or last component
|
||||
if components[0] == '':
|
||||
del components[0]
|
||||
del components[0]
|
||||
if components[-1] == '':
|
||||
del components[-1]
|
||||
del components[-1]
|
||||
# Replace empty string ('::') by .. (will result in '/../' later)
|
||||
for i in range(len(components)):
|
||||
if components[i] == '':
|
||||
components[i] = '..'
|
||||
if components[i] == '':
|
||||
components[i] = '..'
|
||||
# Truncate names longer than 31 bytes
|
||||
components = map(lambda x: x[:31], components)
|
||||
|
||||
if os.path.isabs(pathname):
|
||||
return '/' + string.join(components, '/')
|
||||
return '/' + string.join(components, '/')
|
||||
else:
|
||||
return string.join(components, '/')
|
||||
return string.join(components, '/')
|
||||
|
||||
def test():
|
||||
for url in ["index.html",
|
||||
"bar/index.html",
|
||||
"/foo/bar/index.html",
|
||||
"/foo/bar/",
|
||||
"/"]:
|
||||
print `url`, '->', `url2pathname(url)`
|
||||
"bar/index.html",
|
||||
"/foo/bar/index.html",
|
||||
"/foo/bar/",
|
||||
"/"]:
|
||||
print `url`, '->', `url2pathname(url)`
|
||||
for path in ["drive:",
|
||||
"drive:dir:",
|
||||
"drive:dir:file",
|
||||
"drive:file",
|
||||
"file",
|
||||
":file",
|
||||
":dir:",
|
||||
":dir:file"]:
|
||||
print `path`, '->', `pathname2url(path)`
|
||||
"drive:dir:",
|
||||
"drive:dir:file",
|
||||
"drive:file",
|
||||
"file",
|
||||
":file",
|
||||
":dir:",
|
||||
":dir:file"]:
|
||||
print `path`, '->', `pathname2url(path)`
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
||||
|
|
|
@ -48,49 +48,49 @@ def guess_type(url):
|
|||
|
||||
"""
|
||||
if not inited:
|
||||
init()
|
||||
init()
|
||||
base, ext = posixpath.splitext(url)
|
||||
while suffix_map.has_key(ext):
|
||||
base, ext = posixpath.splitext(base + suffix_map[ext])
|
||||
base, ext = posixpath.splitext(base + suffix_map[ext])
|
||||
if encodings_map.has_key(ext):
|
||||
encoding = encodings_map[ext]
|
||||
base, ext = posixpath.splitext(base)
|
||||
encoding = encodings_map[ext]
|
||||
base, ext = posixpath.splitext(base)
|
||||
else:
|
||||
encoding = None
|
||||
encoding = None
|
||||
if types_map.has_key(ext):
|
||||
return types_map[ext], encoding
|
||||
return types_map[ext], encoding
|
||||
elif types_map.has_key(string.lower(ext)):
|
||||
return types_map[string.lower(ext)], encoding
|
||||
return types_map[string.lower(ext)], encoding
|
||||
else:
|
||||
return None, encoding
|
||||
return None, encoding
|
||||
|
||||
def init(files=None):
|
||||
global inited
|
||||
for file in files or knownfiles:
|
||||
s = read_mime_types(file)
|
||||
if s:
|
||||
for key, value in s.items():
|
||||
types_map[key] = value
|
||||
s = read_mime_types(file)
|
||||
if s:
|
||||
for key, value in s.items():
|
||||
types_map[key] = value
|
||||
inited = 1
|
||||
|
||||
def read_mime_types(file):
|
||||
try:
|
||||
f = open(file)
|
||||
f = open(file)
|
||||
except IOError:
|
||||
return None
|
||||
return None
|
||||
map = {}
|
||||
while 1:
|
||||
line = f.readline()
|
||||
if not line: break
|
||||
words = string.split(line)
|
||||
for i in range(len(words)):
|
||||
if words[i][0] == '#':
|
||||
del words[i:]
|
||||
break
|
||||
if not words: continue
|
||||
type, suffixes = words[0], words[1:]
|
||||
for suff in suffixes:
|
||||
map['.'+suff] = type
|
||||
line = f.readline()
|
||||
if not line: break
|
||||
words = string.split(line)
|
||||
for i in range(len(words)):
|
||||
if words[i][0] == '#':
|
||||
del words[i:]
|
||||
break
|
||||
if not words: continue
|
||||
type, suffixes = words[0], words[1:]
|
||||
for suff in suffixes:
|
||||
map['.'+suff] = type
|
||||
f.close()
|
||||
return map
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ class MimeWriter:
|
|||
w.startmultipartbody(subtype)
|
||||
for each part:
|
||||
subwriter = w.nextpart()
|
||||
...use the subwriter's methods to create the subpart...
|
||||
...use the subwriter's methods to create the subpart...
|
||||
w.lastpart()
|
||||
|
||||
The subwriter is another MimeWriter instance, and should be
|
||||
|
@ -82,46 +82,46 @@ class MimeWriter:
|
|||
"""
|
||||
|
||||
def __init__(self, fp):
|
||||
self._fp = fp
|
||||
self._headers = []
|
||||
self._fp = fp
|
||||
self._headers = []
|
||||
|
||||
def addheader(self, key, value, prefix=0):
|
||||
lines = string.splitfields(value, "\n")
|
||||
while lines and not lines[-1]: del lines[-1]
|
||||
while lines and not lines[0]: del lines[0]
|
||||
for i in range(1, len(lines)):
|
||||
lines[i] = " " + string.strip(lines[i])
|
||||
value = string.joinfields(lines, "\n") + "\n"
|
||||
line = key + ": " + value
|
||||
if prefix:
|
||||
self._headers.insert(0, line)
|
||||
else:
|
||||
self._headers.append(line)
|
||||
lines = string.splitfields(value, "\n")
|
||||
while lines and not lines[-1]: del lines[-1]
|
||||
while lines and not lines[0]: del lines[0]
|
||||
for i in range(1, len(lines)):
|
||||
lines[i] = " " + string.strip(lines[i])
|
||||
value = string.joinfields(lines, "\n") + "\n"
|
||||
line = key + ": " + value
|
||||
if prefix:
|
||||
self._headers.insert(0, line)
|
||||
else:
|
||||
self._headers.append(line)
|
||||
|
||||
def flushheaders(self):
|
||||
self._fp.writelines(self._headers)
|
||||
self._headers = []
|
||||
self._fp.writelines(self._headers)
|
||||
self._headers = []
|
||||
|
||||
def startbody(self, ctype, plist=[], prefix=1):
|
||||
for name, value in plist:
|
||||
ctype = ctype + ';\n %s=\"%s\"' % (name, value)
|
||||
self.addheader("Content-Type", ctype, prefix=prefix)
|
||||
self.flushheaders()
|
||||
self._fp.write("\n")
|
||||
return self._fp
|
||||
for name, value in plist:
|
||||
ctype = ctype + ';\n %s=\"%s\"' % (name, value)
|
||||
self.addheader("Content-Type", ctype, prefix=prefix)
|
||||
self.flushheaders()
|
||||
self._fp.write("\n")
|
||||
return self._fp
|
||||
|
||||
def startmultipartbody(self, subtype, boundary=None, plist=[], prefix=1):
|
||||
self._boundary = boundary or mimetools.choose_boundary()
|
||||
return self.startbody("multipart/" + subtype,
|
||||
[("boundary", self._boundary)] + plist,
|
||||
prefix=prefix)
|
||||
self._boundary = boundary or mimetools.choose_boundary()
|
||||
return self.startbody("multipart/" + subtype,
|
||||
[("boundary", self._boundary)] + plist,
|
||||
prefix=prefix)
|
||||
|
||||
def nextpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "\n")
|
||||
return self.__class__(self._fp)
|
||||
self._fp.write("\n--" + self._boundary + "\n")
|
||||
return self.__class__(self._fp)
|
||||
|
||||
def lastpart(self):
|
||||
self._fp.write("\n--" + self._boundary + "--\n")
|
||||
self._fp.write("\n--" + self._boundary + "--\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -44,8 +44,17 @@ class MultiFile:
|
|||
return self.lastpos
|
||||
return self.fp.tell() - self.start
|
||||
#
|
||||
def seek(self, pos):
|
||||
if not 0 <= pos <= self.tell() or \
|
||||
def seek(self, pos, whence=0):
|
||||
here = self.tell()
|
||||
if whence:
|
||||
if whence == 1:
|
||||
pos = pos + here
|
||||
elif whence == 2:
|
||||
if self.level > 0:
|
||||
pos = pos + self.lastpos
|
||||
else:
|
||||
raise Error, "can't use whence=2 yet"
|
||||
if not 0 <= pos <= here or \
|
||||
self.level > 0 and pos > self.lastpos:
|
||||
raise Error, 'bad MultiFile.seek() call'
|
||||
self.fp.seek(pos + self.start)
|
||||
|
|
|
@ -6,56 +6,56 @@
|
|||
# Extended file operations
|
||||
#
|
||||
# f = posixfile.open(filename, [mode, [bufsize]])
|
||||
# will create a new posixfile object
|
||||
# will create a new posixfile object
|
||||
#
|
||||
# f = posixfile.fileopen(fileobject)
|
||||
# will create a posixfile object from a builtin file object
|
||||
# will create a posixfile object from a builtin file object
|
||||
#
|
||||
# f.file()
|
||||
# will return the original builtin file object
|
||||
# will return the original builtin file object
|
||||
#
|
||||
# f.dup()
|
||||
# will return a new file object based on a new filedescriptor
|
||||
# will return a new file object based on a new filedescriptor
|
||||
#
|
||||
# f.dup2(fd)
|
||||
# will return a new file object based on the given filedescriptor
|
||||
# will return a new file object based on the given filedescriptor
|
||||
#
|
||||
# f.flags(mode)
|
||||
# will turn on the associated flag (merge)
|
||||
# mode can contain the following characters:
|
||||
# will turn on the associated flag (merge)
|
||||
# mode can contain the following characters:
|
||||
#
|
||||
# (character representing a flag)
|
||||
# a append only flag
|
||||
# c close on exec flag
|
||||
# n no delay flag
|
||||
# s synchronization flag
|
||||
# a append only flag
|
||||
# c close on exec flag
|
||||
# n no delay flag
|
||||
# s synchronization flag
|
||||
# (modifiers)
|
||||
# ! turn flags 'off' instead of default 'on'
|
||||
# = copy flags 'as is' instead of default 'merge'
|
||||
# ? return a string in which the characters represent the flags
|
||||
# that are set
|
||||
# ! turn flags 'off' instead of default 'on'
|
||||
# = copy flags 'as is' instead of default 'merge'
|
||||
# ? return a string in which the characters represent the flags
|
||||
# that are set
|
||||
#
|
||||
# note: - the '!' and '=' modifiers are mutually exclusive.
|
||||
# - the '?' modifier will return the status of the flags after they
|
||||
# have been changed by other characters in the mode string
|
||||
# note: - the '!' and '=' modifiers are mutually exclusive.
|
||||
# - the '?' modifier will return the status of the flags after they
|
||||
# have been changed by other characters in the mode string
|
||||
#
|
||||
# f.lock(mode [, len [, start [, whence]]])
|
||||
# will (un)lock a region
|
||||
# mode can contain the following characters:
|
||||
# will (un)lock a region
|
||||
# mode can contain the following characters:
|
||||
#
|
||||
# (character representing type of lock)
|
||||
# u unlock
|
||||
# r read lock
|
||||
# w write lock
|
||||
# u unlock
|
||||
# r read lock
|
||||
# w write lock
|
||||
# (modifiers)
|
||||
# | wait until the lock can be granted
|
||||
# ? return the first lock conflicting with the requested lock
|
||||
# or 'None' if there is no conflict. The lock returned is in the
|
||||
# format (mode, len, start, whence, pid) where mode is a
|
||||
# character representing the type of lock ('r' or 'w')
|
||||
# | wait until the lock can be granted
|
||||
# ? return the first lock conflicting with the requested lock
|
||||
# or 'None' if there is no conflict. The lock returned is in the
|
||||
# format (mode, len, start, whence, pid) where mode is a
|
||||
# character representing the type of lock ('r' or 'w')
|
||||
#
|
||||
# note: - the '?' modifier prevents a region from being locked; it is
|
||||
# query only
|
||||
# note: - the '?' modifier prevents a region from being locked; it is
|
||||
# query only
|
||||
#
|
||||
|
||||
class _posixfile_:
|
||||
|
@ -65,149 +65,149 @@ class _posixfile_:
|
|||
# Internal routines
|
||||
#
|
||||
def __repr__(self):
|
||||
file = self._file_
|
||||
return "<%s posixfile '%s', mode '%s' at %s>" % \
|
||||
(self.states[file.closed], file.name, file.mode, \
|
||||
hex(id(self))[2:])
|
||||
file = self._file_
|
||||
return "<%s posixfile '%s', mode '%s' at %s>" % \
|
||||
(self.states[file.closed], file.name, file.mode, \
|
||||
hex(id(self))[2:])
|
||||
|
||||
def __del__(self):
|
||||
self._file_.close()
|
||||
self._file_.close()
|
||||
|
||||
#
|
||||
# Initialization routines
|
||||
#
|
||||
def open(self, name, mode='r', bufsize=-1):
|
||||
import __builtin__
|
||||
return self.fileopen(__builtin__.open(name, mode, bufsize))
|
||||
import __builtin__
|
||||
return self.fileopen(__builtin__.open(name, mode, bufsize))
|
||||
|
||||
def fileopen(self, file):
|
||||
if `type(file)` != "<type 'file'>":
|
||||
raise TypeError, 'posixfile.fileopen() arg must be file object'
|
||||
self._file_ = file
|
||||
# Copy basic file methods
|
||||
for method in file.__methods__:
|
||||
setattr(self, method, getattr(file, method))
|
||||
return self
|
||||
if `type(file)` != "<type 'file'>":
|
||||
raise TypeError, 'posixfile.fileopen() arg must be file object'
|
||||
self._file_ = file
|
||||
# Copy basic file methods
|
||||
for method in file.__methods__:
|
||||
setattr(self, method, getattr(file, method))
|
||||
return self
|
||||
|
||||
#
|
||||
# New methods
|
||||
#
|
||||
def file(self):
|
||||
return self._file_
|
||||
return self._file_
|
||||
|
||||
def dup(self):
|
||||
import posix
|
||||
import posix
|
||||
|
||||
try: ignore = posix.fdopen
|
||||
except: raise AttributeError, 'dup() method unavailable'
|
||||
try: ignore = posix.fdopen
|
||||
except: raise AttributeError, 'dup() method unavailable'
|
||||
|
||||
return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
|
||||
return posix.fdopen(posix.dup(self._file_.fileno()), self._file_.mode)
|
||||
|
||||
def dup2(self, fd):
|
||||
import posix
|
||||
import posix
|
||||
|
||||
try: ignore = posix.fdopen
|
||||
except: raise AttributeError, 'dup() method unavailable'
|
||||
try: ignore = posix.fdopen
|
||||
except: raise AttributeError, 'dup() method unavailable'
|
||||
|
||||
posix.dup2(self._file_.fileno(), fd)
|
||||
return posix.fdopen(fd, self._file_.mode)
|
||||
posix.dup2(self._file_.fileno(), fd)
|
||||
return posix.fdopen(fd, self._file_.mode)
|
||||
|
||||
def flags(self, *which):
|
||||
import fcntl, FCNTL
|
||||
import fcntl, FCNTL
|
||||
|
||||
if which:
|
||||
if len(which) > 1:
|
||||
raise TypeError, 'Too many arguments'
|
||||
which = which[0]
|
||||
else: which = '?'
|
||||
if which:
|
||||
if len(which) > 1:
|
||||
raise TypeError, 'Too many arguments'
|
||||
which = which[0]
|
||||
else: which = '?'
|
||||
|
||||
l_flags = 0
|
||||
if 'n' in which: l_flags = l_flags | FCNTL.O_NDELAY
|
||||
if 'a' in which: l_flags = l_flags | FCNTL.O_APPEND
|
||||
if 's' in which: l_flags = l_flags | FCNTL.O_SYNC
|
||||
l_flags = 0
|
||||
if 'n' in which: l_flags = l_flags | FCNTL.O_NDELAY
|
||||
if 'a' in which: l_flags = l_flags | FCNTL.O_APPEND
|
||||
if 's' in which: l_flags = l_flags | FCNTL.O_SYNC
|
||||
|
||||
file = self._file_
|
||||
file = self._file_
|
||||
|
||||
if '=' not in which:
|
||||
cur_fl = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0)
|
||||
if '!' in which: l_flags = cur_fl & ~ l_flags
|
||||
else: l_flags = cur_fl | l_flags
|
||||
if '=' not in which:
|
||||
cur_fl = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0)
|
||||
if '!' in which: l_flags = cur_fl & ~ l_flags
|
||||
else: l_flags = cur_fl | l_flags
|
||||
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFL, l_flags)
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFL, l_flags)
|
||||
|
||||
if 'c' in which:
|
||||
arg = ('!' not in which) # 0 is don't, 1 is do close on exec
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFD, arg)
|
||||
if 'c' in which:
|
||||
arg = ('!' not in which) # 0 is don't, 1 is do close on exec
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_SETFD, arg)
|
||||
|
||||
if '?' in which:
|
||||
which = '' # Return current flags
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0)
|
||||
if FCNTL.O_APPEND & l_flags: which = which + 'a'
|
||||
if fcntl.fcntl(file.fileno(), FCNTL.F_GETFD, 0) & 1:
|
||||
which = which + 'c'
|
||||
if FCNTL.O_NDELAY & l_flags: which = which + 'n'
|
||||
if FCNTL.O_SYNC & l_flags: which = which + 's'
|
||||
return which
|
||||
if '?' in which:
|
||||
which = '' # Return current flags
|
||||
l_flags = fcntl.fcntl(file.fileno(), FCNTL.F_GETFL, 0)
|
||||
if FCNTL.O_APPEND & l_flags: which = which + 'a'
|
||||
if fcntl.fcntl(file.fileno(), FCNTL.F_GETFD, 0) & 1:
|
||||
which = which + 'c'
|
||||
if FCNTL.O_NDELAY & l_flags: which = which + 'n'
|
||||
if FCNTL.O_SYNC & l_flags: which = which + 's'
|
||||
return which
|
||||
|
||||
def lock(self, how, *args):
|
||||
import struct, fcntl, FCNTL
|
||||
import struct, fcntl, FCNTL
|
||||
|
||||
if 'w' in how: l_type = FCNTL.F_WRLCK
|
||||
elif 'r' in how: l_type = FCNTL.F_RDLCK
|
||||
elif 'u' in how: l_type = FCNTL.F_UNLCK
|
||||
else: raise TypeError, 'no type of lock specified'
|
||||
if 'w' in how: l_type = FCNTL.F_WRLCK
|
||||
elif 'r' in how: l_type = FCNTL.F_RDLCK
|
||||
elif 'u' in how: l_type = FCNTL.F_UNLCK
|
||||
else: raise TypeError, 'no type of lock specified'
|
||||
|
||||
if '|' in how: cmd = FCNTL.F_SETLKW
|
||||
elif '?' in how: cmd = FCNTL.F_GETLK
|
||||
else: cmd = FCNTL.F_SETLK
|
||||
if '|' in how: cmd = FCNTL.F_SETLKW
|
||||
elif '?' in how: cmd = FCNTL.F_GETLK
|
||||
else: cmd = FCNTL.F_SETLK
|
||||
|
||||
l_whence = 0
|
||||
l_start = 0
|
||||
l_len = 0
|
||||
l_whence = 0
|
||||
l_start = 0
|
||||
l_len = 0
|
||||
|
||||
if len(args) == 1:
|
||||
l_len = args[0]
|
||||
elif len(args) == 2:
|
||||
l_len, l_start = args
|
||||
elif len(args) == 3:
|
||||
l_len, l_start, l_whence = args
|
||||
elif len(args) > 3:
|
||||
raise TypeError, 'too many arguments'
|
||||
if len(args) == 1:
|
||||
l_len = args[0]
|
||||
elif len(args) == 2:
|
||||
l_len, l_start = args
|
||||
elif len(args) == 3:
|
||||
l_len, l_start, l_whence = args
|
||||
elif len(args) > 3:
|
||||
raise TypeError, 'too many arguments'
|
||||
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd;
|
||||
# additions for AIX by Vladimir.Marangozov@imag.fr
|
||||
# Hack by davem@magnet.com to get locking to go on freebsd;
|
||||
# additions for AIX by Vladimir.Marangozov@imag.fr
|
||||
import sys, os
|
||||
if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
|
||||
flock = struct.pack('lxxxxlxxxxlhh', \
|
||||
l_start, l_len, os.getpid(), l_type, l_whence)
|
||||
flock = struct.pack('lxxxxlxxxxlhh', \
|
||||
l_start, l_len, os.getpid(), l_type, l_whence)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
flock = struct.pack('hhlllii', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0, 0)
|
||||
else:
|
||||
flock = struct.pack('hhllhh', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0)
|
||||
else:
|
||||
flock = struct.pack('hhllhh', \
|
||||
l_type, l_whence, l_start, l_len, 0, 0)
|
||||
|
||||
flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
|
||||
flock = fcntl.fcntl(self._file_.fileno(), cmd, flock)
|
||||
|
||||
if '?' in how:
|
||||
if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
|
||||
l_start, l_len, l_pid, l_type, l_whence = \
|
||||
struct.unpack('lxxxxlxxxxlhh', flock)
|
||||
if '?' in how:
|
||||
if sys.platform in ('netbsd1', 'freebsd2', 'freebsd3'):
|
||||
l_start, l_len, l_pid, l_type, l_whence = \
|
||||
struct.unpack('lxxxxlxxxxlhh', flock)
|
||||
elif sys.platform in ['aix3', 'aix4']:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid, l_vfs = \
|
||||
struct.unpack('hhlllii', flock)
|
||||
elif sys.platform == "linux2":
|
||||
l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
else:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
elif sys.platform == "linux2":
|
||||
l_type, l_whence, l_start, l_len, l_pid, l_sysid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
else:
|
||||
l_type, l_whence, l_start, l_len, l_sysid, l_pid = \
|
||||
struct.unpack('hhllhh', flock)
|
||||
|
||||
if l_type != FCNTL.F_UNLCK:
|
||||
if l_type == FCNTL.F_RDLCK:
|
||||
return 'r', l_len, l_start, l_whence, l_pid
|
||||
else:
|
||||
return 'w', l_len, l_start, l_whence, l_pid
|
||||
if l_type != FCNTL.F_UNLCK:
|
||||
if l_type == FCNTL.F_RDLCK:
|
||||
return 'r', l_len, l_start, l_whence, l_pid
|
||||
else:
|
||||
return 'w', l_len, l_start, l_whence, l_pid
|
||||
|
||||
#
|
||||
# Public routine to obtain a posixfile object
|
||||
|
|
|
@ -1,37 +1,68 @@
|
|||
# Routine to "compile" a .py file to a .pyc file.
|
||||
# This has intimate knowledge of how Python/import.c does it.
|
||||
# By Sjoerd Mullender (I forced him to write it :-).
|
||||
"""Routine to "compile" a .py file to a .pyc (or .pyo) file.
|
||||
|
||||
This module has intimate knowledge of the format of .pyc files.
|
||||
"""
|
||||
|
||||
import imp
|
||||
MAGIC = imp.get_magic()
|
||||
|
||||
def wr_long(f, x):
|
||||
f.write(chr( x & 0xff))
|
||||
f.write(chr((x >> 8) & 0xff))
|
||||
f.write(chr((x >> 16) & 0xff))
|
||||
f.write(chr((x >> 24) & 0xff))
|
||||
"Internal; write a 32-bit int to a file in little-endian order."
|
||||
f.write(chr( x & 0xff))
|
||||
f.write(chr((x >> 8) & 0xff))
|
||||
f.write(chr((x >> 16) & 0xff))
|
||||
f.write(chr((x >> 24) & 0xff))
|
||||
|
||||
def compile(file, cfile = None):
|
||||
import os, marshal, __builtin__
|
||||
f = open(file)
|
||||
try:
|
||||
timestamp = os.fstat(file.fileno())
|
||||
except AttributeError:
|
||||
timestamp = long(os.stat(file)[8])
|
||||
codestring = f.read()
|
||||
f.close()
|
||||
codeobject = __builtin__.compile(codestring, file, 'exec')
|
||||
if not cfile:
|
||||
cfile = file + (__debug__ and 'c' or 'o')
|
||||
fc = open(cfile, 'wb')
|
||||
fc.write('\0\0\0\0')
|
||||
wr_long(fc, timestamp)
|
||||
marshal.dump(codeobject, fc)
|
||||
fc.flush()
|
||||
fc.seek(0, 0)
|
||||
fc.write(MAGIC)
|
||||
fc.close()
|
||||
if os.name == 'mac':
|
||||
import macfs
|
||||
macfs.FSSpec(cfile).SetCreatorType('Pyth', 'PYC ')
|
||||
macfs.FSSpec(file).SetCreatorType('Pyth', 'TEXT')
|
||||
def compile(file, cfile=None, dfile=None):
|
||||
"""Byte-compile one Python source file to Python bytecode.
|
||||
|
||||
Arguments:
|
||||
|
||||
file: source filename
|
||||
cfile: target filename; defaults to source with 'c' or 'o' appended
|
||||
('c' normally, 'o' in optimizing mode, giving .pyc or .pyo)
|
||||
dfile: purported filename; defaults to source (this is the filename
|
||||
that will show up in error messages)
|
||||
|
||||
Note that it isn't necessary to byte-compile Python modules for
|
||||
execution efficiency -- Python itself byte-compiles a module when
|
||||
it is loaded, and if it can, writes out the bytecode to the
|
||||
corresponding .pyc (or .pyo) file.
|
||||
|
||||
However, if a Python installation is shared between users, it is a
|
||||
good idea to byte-compile all modules upon installation, since
|
||||
other users may not be able to write in the source directories,
|
||||
and thus they won't be able to write the .pyc/.pyo file, and then
|
||||
they would be byte-compiling every module each time it is loaded.
|
||||
This can slow down program start-up considerably.
|
||||
|
||||
See compileall.py for a script/module that uses this module to
|
||||
byte-compile all installed files (or all files in selected
|
||||
directories).
|
||||
|
||||
"""
|
||||
import os, marshal, __builtin__
|
||||
f = open(file)
|
||||
try:
|
||||
timestamp = os.fstat(file.fileno())
|
||||
except AttributeError:
|
||||
timestamp = long(os.stat(file)[8])
|
||||
codestring = f.read()
|
||||
f.close()
|
||||
if codestring and codestring[-1] != '\n':
|
||||
codestring = codestring + '\n'
|
||||
codeobject = __builtin__.compile(codestring, dfile or file, 'exec')
|
||||
if not cfile:
|
||||
cfile = file + (__debug__ and 'c' or 'o')
|
||||
fc = open(cfile, 'wb')
|
||||
fc.write('\0\0\0\0')
|
||||
wr_long(fc, timestamp)
|
||||
marshal.dump(codeobject, fc)
|
||||
fc.flush()
|
||||
fc.seek(0, 0)
|
||||
fc.write(MAGIC)
|
||||
fc.close()
|
||||
if os.name == 'mac':
|
||||
import macfs
|
||||
macfs.FSSpec(cfile).SetCreatorType('Pyth', 'PYC ')
|
||||
macfs.FSSpec(file).SetCreatorType('Pyth', 'TEXT')
|
||||
|
|
|
@ -4,102 +4,102 @@
|
|||
# exceptions, but also when -X option is used.
|
||||
try:
|
||||
class Empty(Exception):
|
||||
pass
|
||||
pass
|
||||
except TypeError:
|
||||
# string based exceptions
|
||||
Empty = 'Queue.Empty' # Exception raised by get_nowait()
|
||||
Empty = 'Queue.Empty' # Exception raised by get_nowait()
|
||||
|
||||
class Queue:
|
||||
def __init__(self, maxsize):
|
||||
"""Initialize a queue object with a given maximum size.
|
||||
"""Initialize a queue object with a given maximum size.
|
||||
|
||||
If maxsize is <= 0, the queue size is infinite.
|
||||
"""
|
||||
import thread
|
||||
self._init(maxsize)
|
||||
self.mutex = thread.allocate_lock()
|
||||
self.esema = thread.allocate_lock()
|
||||
self.esema.acquire_lock()
|
||||
self.fsema = thread.allocate_lock()
|
||||
If maxsize is <= 0, the queue size is infinite.
|
||||
"""
|
||||
import thread
|
||||
self._init(maxsize)
|
||||
self.mutex = thread.allocate_lock()
|
||||
self.esema = thread.allocate_lock()
|
||||
self.esema.acquire_lock()
|
||||
self.fsema = thread.allocate_lock()
|
||||
|
||||
def qsize(self):
|
||||
"""Returns the approximate size of the queue (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._qsize()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
"""Returns the approximate size of the queue (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._qsize()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
|
||||
def empty(self):
|
||||
"""Returns 1 if the queue is empty, 0 otherwise (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._empty()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
"""Returns 1 if the queue is empty, 0 otherwise (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._empty()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
|
||||
def full(self):
|
||||
"""Returns 1 if the queue is full, 0 otherwise (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._full()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
"""Returns 1 if the queue is full, 0 otherwise (not reliable!)."""
|
||||
self.mutex.acquire_lock()
|
||||
n = self._full()
|
||||
self.mutex.release_lock()
|
||||
return n
|
||||
|
||||
def put(self, item):
|
||||
"""Put an item into the queue."""
|
||||
self.fsema.acquire_lock()
|
||||
self.mutex.acquire_lock()
|
||||
was_empty = self._empty()
|
||||
self._put(item)
|
||||
if was_empty:
|
||||
self.esema.release_lock()
|
||||
if not self._full():
|
||||
self.fsema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
"""Put an item into the queue."""
|
||||
self.fsema.acquire_lock()
|
||||
self.mutex.acquire_lock()
|
||||
was_empty = self._empty()
|
||||
self._put(item)
|
||||
if was_empty:
|
||||
self.esema.release_lock()
|
||||
if not self._full():
|
||||
self.fsema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
|
||||
def get(self):
|
||||
"""Gets and returns an item from the queue.
|
||||
This method blocks if necessary until an item is available.
|
||||
"""
|
||||
self.esema.acquire_lock()
|
||||
self.mutex.acquire_lock()
|
||||
was_full = self._full()
|
||||
item = self._get()
|
||||
if was_full:
|
||||
self.fsema.release_lock()
|
||||
if not self._empty():
|
||||
self.esema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
return item
|
||||
"""Gets and returns an item from the queue.
|
||||
This method blocks if necessary until an item is available.
|
||||
"""
|
||||
self.esema.acquire_lock()
|
||||
self.mutex.acquire_lock()
|
||||
was_full = self._full()
|
||||
item = self._get()
|
||||
if was_full:
|
||||
self.fsema.release_lock()
|
||||
if not self._empty():
|
||||
self.esema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
return item
|
||||
|
||||
# Get an item from the queue if one is immediately available,
|
||||
# raise Empty if the queue is empty or temporarily unavailable
|
||||
def get_nowait(self):
|
||||
"""Gets and returns an item from the queue.
|
||||
Only gets an item if one is immediately available, Otherwise
|
||||
this raises the Empty exception if the queue is empty or
|
||||
temporarily unavailable.
|
||||
"""
|
||||
locked = self.esema.acquire_lock(0)
|
||||
self.mutex.acquire_lock()
|
||||
if self._empty():
|
||||
# The queue is empty -- we can't have esema
|
||||
self.mutex.release_lock()
|
||||
raise Empty
|
||||
if not locked:
|
||||
locked = self.esema.acquire_lock(0)
|
||||
if not locked:
|
||||
# Somebody else has esema
|
||||
# but we have mutex --
|
||||
# go out of their way
|
||||
self.mutex.release_lock()
|
||||
raise Empty
|
||||
was_full = self._full()
|
||||
item = self._get()
|
||||
if was_full:
|
||||
self.fsema.release_lock()
|
||||
if not self._empty():
|
||||
self.esema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
return item
|
||||
"""Gets and returns an item from the queue.
|
||||
Only gets an item if one is immediately available, Otherwise
|
||||
this raises the Empty exception if the queue is empty or
|
||||
temporarily unavailable.
|
||||
"""
|
||||
locked = self.esema.acquire_lock(0)
|
||||
self.mutex.acquire_lock()
|
||||
if self._empty():
|
||||
# The queue is empty -- we can't have esema
|
||||
self.mutex.release_lock()
|
||||
raise Empty
|
||||
if not locked:
|
||||
locked = self.esema.acquire_lock(0)
|
||||
if not locked:
|
||||
# Somebody else has esema
|
||||
# but we have mutex --
|
||||
# go out of their way
|
||||
self.mutex.release_lock()
|
||||
raise Empty
|
||||
was_full = self._full()
|
||||
item = self._get()
|
||||
if was_full:
|
||||
self.fsema.release_lock()
|
||||
if not self._empty():
|
||||
self.esema.release_lock()
|
||||
self.mutex.release_lock()
|
||||
return item
|
||||
|
||||
# XXX Need to define put_nowait() as well.
|
||||
|
||||
|
@ -110,26 +110,26 @@ class Queue:
|
|||
|
||||
# Initialize the queue representation
|
||||
def _init(self, maxsize):
|
||||
self.maxsize = maxsize
|
||||
self.queue = []
|
||||
self.maxsize = maxsize
|
||||
self.queue = []
|
||||
|
||||
def _qsize(self):
|
||||
return len(self.queue)
|
||||
return len(self.queue)
|
||||
|
||||
# Check wheter the queue is empty
|
||||
def _empty(self):
|
||||
return not self.queue
|
||||
return not self.queue
|
||||
|
||||
# Check whether the queue is full
|
||||
def _full(self):
|
||||
return self.maxsize > 0 and len(self.queue) == self.maxsize
|
||||
return self.maxsize > 0 and len(self.queue) == self.maxsize
|
||||
|
||||
# Put a new item in the queue
|
||||
def _put(self, item):
|
||||
self.queue.append(item)
|
||||
self.queue.append(item)
|
||||
|
||||
# Get an item from the queue
|
||||
def _get(self):
|
||||
item = self.queue[0]
|
||||
del self.queue[0]
|
||||
return item
|
||||
item = self.queue[0]
|
||||
del self.queue[0]
|
||||
return item
|
||||
|
|
|
@ -108,36 +108,36 @@ def convert(s, syntax=None):
|
|||
"""
|
||||
table = mastertable.copy()
|
||||
if syntax is None:
|
||||
syntax = regex.get_syntax()
|
||||
syntax = regex.get_syntax()
|
||||
if syntax & RE_NO_BK_PARENS:
|
||||
del table[r'\('], table[r'\)']
|
||||
del table['('], table[')']
|
||||
del table[r'\('], table[r'\)']
|
||||
del table['('], table[')']
|
||||
if syntax & RE_NO_BK_VBAR:
|
||||
del table[r'\|']
|
||||
del table['|']
|
||||
del table[r'\|']
|
||||
del table['|']
|
||||
if syntax & RE_BK_PLUS_QM:
|
||||
table['+'] = r'\+'
|
||||
table['?'] = r'\?'
|
||||
table[r'\+'] = '+'
|
||||
table[r'\?'] = '?'
|
||||
table['+'] = r'\+'
|
||||
table['?'] = r'\?'
|
||||
table[r'\+'] = '+'
|
||||
table[r'\?'] = '?'
|
||||
if syntax & RE_NEWLINE_OR:
|
||||
table['\n'] = '|'
|
||||
table['\n'] = '|'
|
||||
res = ""
|
||||
|
||||
i = 0
|
||||
end = len(s)
|
||||
while i < end:
|
||||
c = s[i]
|
||||
i = i+1
|
||||
if c == '\\':
|
||||
c = s[i]
|
||||
i = i+1
|
||||
key = '\\' + c
|
||||
key = table.get(key, key)
|
||||
res = res + key
|
||||
else:
|
||||
c = table.get(c, c)
|
||||
res = res + c
|
||||
c = s[i]
|
||||
i = i+1
|
||||
if c == '\\':
|
||||
c = s[i]
|
||||
i = i+1
|
||||
key = '\\' + c
|
||||
key = table.get(key, key)
|
||||
res = res + key
|
||||
else:
|
||||
c = table.get(c, c)
|
||||
res = res + c
|
||||
return res
|
||||
|
||||
|
||||
|
@ -155,21 +155,21 @@ def quote(s, quote=None):
|
|||
|
||||
"""
|
||||
if quote is None:
|
||||
q = "'"
|
||||
altq = "'"
|
||||
if q in s and altq not in s:
|
||||
q = altq
|
||||
q = "'"
|
||||
altq = "'"
|
||||
if q in s and altq not in s:
|
||||
q = altq
|
||||
else:
|
||||
assert quote in ('"', "'")
|
||||
q = quote
|
||||
assert quote in ('"', "'")
|
||||
q = quote
|
||||
res = q
|
||||
for c in s:
|
||||
if c == q: c = '\\' + c
|
||||
elif c < ' ' or c > '~': c = "\\%03o" % ord(c)
|
||||
res = res + c
|
||||
if c == q: c = '\\' + c
|
||||
elif c < ' ' or c > '~': c = "\\%03o" % ord(c)
|
||||
res = res + c
|
||||
res = res + q
|
||||
if '\\' in res:
|
||||
res = 'r' + res
|
||||
res = 'r' + res
|
||||
return res
|
||||
|
||||
|
||||
|
@ -179,7 +179,7 @@ def main():
|
|||
s = eval(sys.stdin.read())
|
||||
sys.stdout.write(quote(convert(s)))
|
||||
if sys.stdout.isatty():
|
||||
sys.stdout.write("\n")
|
||||
sys.stdout.write("\n")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
|
@ -47,60 +47,60 @@ import __main__
|
|||
class Completer:
|
||||
|
||||
def complete(self, text, state):
|
||||
"""Return the next possible completion for 'text'.
|
||||
"""Return the next possible completion for 'text'.
|
||||
|
||||
This is called successively with state == 0, 1, 2, ... until it
|
||||
returns None. The completion should begin with 'text'.
|
||||
This is called successively with state == 0, 1, 2, ... until it
|
||||
returns None. The completion should begin with 'text'.
|
||||
|
||||
"""
|
||||
if state == 0:
|
||||
if "." in text:
|
||||
self.matches = self.attr_matches(text)
|
||||
else:
|
||||
self.matches = self.global_matches(text)
|
||||
return self.matches[state]
|
||||
"""
|
||||
if state == 0:
|
||||
if "." in text:
|
||||
self.matches = self.attr_matches(text)
|
||||
else:
|
||||
self.matches = self.global_matches(text)
|
||||
return self.matches[state]
|
||||
|
||||
def global_matches(self, text):
|
||||
"""Compute matches when text is a simple name.
|
||||
"""Compute matches when text is a simple name.
|
||||
|
||||
Return a list of all keywords, built-in functions and names
|
||||
currently defines in __main__ that match.
|
||||
Return a list of all keywords, built-in functions and names
|
||||
currently defines in __main__ that match.
|
||||
|
||||
"""
|
||||
import keyword
|
||||
matches = []
|
||||
n = len(text)
|
||||
for list in [keyword.kwlist,
|
||||
__builtin__.__dict__.keys(),
|
||||
__main__.__dict__.keys()]:
|
||||
for word in list:
|
||||
if word[:n] == text:
|
||||
matches.append(word)
|
||||
return matches
|
||||
"""
|
||||
import keyword
|
||||
matches = []
|
||||
n = len(text)
|
||||
for list in [keyword.kwlist,
|
||||
__builtin__.__dict__.keys(),
|
||||
__main__.__dict__.keys()]:
|
||||
for word in list:
|
||||
if word[:n] == text:
|
||||
matches.append(word)
|
||||
return matches
|
||||
|
||||
def attr_matches(self, text):
|
||||
"""Compute matches when text contains a dot.
|
||||
"""Compute matches when text contains a dot.
|
||||
|
||||
Assuming the text is of the form NAME.NAME....[NAME], and is
|
||||
evaluabable in the globals of __main__, it will be evaluated
|
||||
and its attributes (as revealed by dir()) are used as possible
|
||||
completions.
|
||||
Assuming the text is of the form NAME.NAME....[NAME], and is
|
||||
evaluabable in the globals of __main__, it will be evaluated
|
||||
and its attributes (as revealed by dir()) are used as possible
|
||||
completions.
|
||||
|
||||
WARNING: this can still invoke arbitrary C code, if an object
|
||||
with a __getattr__ hook is evaluated.
|
||||
WARNING: this can still invoke arbitrary C code, if an object
|
||||
with a __getattr__ hook is evaluated.
|
||||
|
||||
"""
|
||||
import re
|
||||
m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
|
||||
if not m:
|
||||
return
|
||||
expr, attr = m.group(1, 3)
|
||||
words = dir(eval(expr, __main__.__dict__))
|
||||
matches = []
|
||||
n = len(attr)
|
||||
for word in words:
|
||||
if word[:n] == attr:
|
||||
matches.append("%s.%s" % (expr, word))
|
||||
return matches
|
||||
"""
|
||||
import re
|
||||
m = re.match(r"(\w+(\.\w+)*)\.(\w*)", text)
|
||||
if not m:
|
||||
return
|
||||
expr, attr = m.group(1, 3)
|
||||
words = dir(eval(expr, __main__.__dict__))
|
||||
matches = []
|
||||
n = len(attr)
|
||||
for word in words:
|
||||
if word[:n] == attr:
|
||||
matches.append("%s.%s" % (expr, word))
|
||||
return matches
|
||||
|
||||
readline.set_completer(Completer().complete)
|
||||
|
|
|
@ -36,119 +36,119 @@ class SimpleHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
|
|||
server_version = "SimpleHTTP/" + __version__
|
||||
|
||||
def do_GET(self):
|
||||
"""Serve a GET request."""
|
||||
f = self.send_head()
|
||||
if f:
|
||||
self.copyfile(f, self.wfile)
|
||||
f.close()
|
||||
"""Serve a GET request."""
|
||||
f = self.send_head()
|
||||
if f:
|
||||
self.copyfile(f, self.wfile)
|
||||
f.close()
|
||||
|
||||
def do_HEAD(self):
|
||||
"""Serve a HEAD request."""
|
||||
f = self.send_head()
|
||||
if f:
|
||||
f.close()
|
||||
"""Serve a HEAD request."""
|
||||
f = self.send_head()
|
||||
if f:
|
||||
f.close()
|
||||
|
||||
def send_head(self):
|
||||
"""Common code for GET and HEAD commands.
|
||||
"""Common code for GET and HEAD commands.
|
||||
|
||||
This sends the response code and MIME headers.
|
||||
This sends the response code and MIME headers.
|
||||
|
||||
Return value is either a file object (which has to be copied
|
||||
to the outputfile by the caller unless the command was HEAD,
|
||||
and must be closed by the caller under all circumstances), or
|
||||
None, in which case the caller has nothing further to do.
|
||||
Return value is either a file object (which has to be copied
|
||||
to the outputfile by the caller unless the command was HEAD,
|
||||
and must be closed by the caller under all circumstances), or
|
||||
None, in which case the caller has nothing further to do.
|
||||
|
||||
"""
|
||||
path = self.translate_path(self.path)
|
||||
if os.path.isdir(path):
|
||||
self.send_error(403, "Directory listing not supported")
|
||||
return None
|
||||
try:
|
||||
f = open(path)
|
||||
except IOError:
|
||||
self.send_error(404, "File not found")
|
||||
return None
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", self.guess_type(path))
|
||||
self.end_headers()
|
||||
return f
|
||||
"""
|
||||
path = self.translate_path(self.path)
|
||||
if os.path.isdir(path):
|
||||
self.send_error(403, "Directory listing not supported")
|
||||
return None
|
||||
try:
|
||||
f = open(path)
|
||||
except IOError:
|
||||
self.send_error(404, "File not found")
|
||||
return None
|
||||
self.send_response(200)
|
||||
self.send_header("Content-type", self.guess_type(path))
|
||||
self.end_headers()
|
||||
return f
|
||||
|
||||
def translate_path(self, path):
|
||||
"""Translate a /-separated PATH to the local filename syntax.
|
||||
"""Translate a /-separated PATH to the local filename syntax.
|
||||
|
||||
Components that mean special things to the local file system
|
||||
(e.g. drive or directory names) are ignored. (XXX They should
|
||||
probably be diagnosed.)
|
||||
Components that mean special things to the local file system
|
||||
(e.g. drive or directory names) are ignored. (XXX They should
|
||||
probably be diagnosed.)
|
||||
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
words = string.splitfields(path, '/')
|
||||
words = filter(None, words)
|
||||
path = os.getcwd()
|
||||
for word in words:
|
||||
drive, word = os.path.splitdrive(word)
|
||||
head, word = os.path.split(word)
|
||||
if word in (os.curdir, os.pardir): continue
|
||||
path = os.path.join(path, word)
|
||||
return path
|
||||
"""
|
||||
path = posixpath.normpath(path)
|
||||
words = string.splitfields(path, '/')
|
||||
words = filter(None, words)
|
||||
path = os.getcwd()
|
||||
for word in words:
|
||||
drive, word = os.path.splitdrive(word)
|
||||
head, word = os.path.split(word)
|
||||
if word in (os.curdir, os.pardir): continue
|
||||
path = os.path.join(path, word)
|
||||
return path
|
||||
|
||||
def copyfile(self, source, outputfile):
|
||||
"""Copy all data between two file objects.
|
||||
"""Copy all data between two file objects.
|
||||
|
||||
The SOURCE argument is a file object open for reading
|
||||
(or anything with a read() method) and the DESTINATION
|
||||
argument is a file object open for writing (or
|
||||
anything with a write() method).
|
||||
The SOURCE argument is a file object open for reading
|
||||
(or anything with a read() method) and the DESTINATION
|
||||
argument is a file object open for writing (or
|
||||
anything with a write() method).
|
||||
|
||||
The only reason for overriding this would be to change
|
||||
the block size or perhaps to replace newlines by CRLF
|
||||
-- note however that this the default server uses this
|
||||
to copy binary data as well.
|
||||
The only reason for overriding this would be to change
|
||||
the block size or perhaps to replace newlines by CRLF
|
||||
-- note however that this the default server uses this
|
||||
to copy binary data as well.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
BLOCKSIZE = 8192
|
||||
while 1:
|
||||
data = source.read(BLOCKSIZE)
|
||||
if not data: break
|
||||
outputfile.write(data)
|
||||
BLOCKSIZE = 8192
|
||||
while 1:
|
||||
data = source.read(BLOCKSIZE)
|
||||
if not data: break
|
||||
outputfile.write(data)
|
||||
|
||||
def guess_type(self, path):
|
||||
"""Guess the type of a file.
|
||||
"""Guess the type of a file.
|
||||
|
||||
Argument is a PATH (a filename).
|
||||
Argument is a PATH (a filename).
|
||||
|
||||
Return value is a string of the form type/subtype,
|
||||
usable for a MIME Content-type header.
|
||||
Return value is a string of the form type/subtype,
|
||||
usable for a MIME Content-type header.
|
||||
|
||||
The default implementation looks the file's extension
|
||||
up in the table self.extensions_map, using text/plain
|
||||
as a default; however it would be permissible (if
|
||||
slow) to look inside the data to make a better guess.
|
||||
The default implementation looks the file's extension
|
||||
up in the table self.extensions_map, using text/plain
|
||||
as a default; however it would be permissible (if
|
||||
slow) to look inside the data to make a better guess.
|
||||
|
||||
"""
|
||||
"""
|
||||
|
||||
base, ext = posixpath.splitext(path)
|
||||
if self.extensions_map.has_key(ext):
|
||||
return self.extensions_map[ext]
|
||||
ext = string.lower(ext)
|
||||
if self.extensions_map.has_key(ext):
|
||||
return self.extensions_map[ext]
|
||||
else:
|
||||
return self.extensions_map['']
|
||||
base, ext = posixpath.splitext(path)
|
||||
if self.extensions_map.has_key(ext):
|
||||
return self.extensions_map[ext]
|
||||
ext = string.lower(ext)
|
||||
if self.extensions_map.has_key(ext):
|
||||
return self.extensions_map[ext]
|
||||
else:
|
||||
return self.extensions_map['']
|
||||
|
||||
extensions_map = {
|
||||
'': 'text/plain', # Default, *must* be present
|
||||
'.html': 'text/html',
|
||||
'.htm': 'text/html',
|
||||
'.gif': 'image/gif',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
}
|
||||
'': 'text/plain', # Default, *must* be present
|
||||
'.html': 'text/html',
|
||||
'.htm': 'text/html',
|
||||
'.gif': 'image/gif',
|
||||
'.jpg': 'image/jpeg',
|
||||
'.jpeg': 'image/jpeg',
|
||||
}
|
||||
|
||||
|
||||
def test(HandlerClass = SimpleHTTPRequestHandler,
|
||||
ServerClass = SocketServer.TCPServer):
|
||||
ServerClass = SocketServer.TCPServer):
|
||||
BaseHTTPServer.test(HandlerClass, ServerClass)
|
||||
|
||||
|
||||
|
|
|
@ -3,19 +3,19 @@
|
|||
This module tries to capture the various aspects of defining a server:
|
||||
|
||||
- address family:
|
||||
- AF_INET: IP (Internet Protocol) sockets (default)
|
||||
- AF_UNIX: Unix domain sockets
|
||||
- others, e.g. AF_DECNET are conceivable (see <socket.h>
|
||||
- AF_INET: IP (Internet Protocol) sockets (default)
|
||||
- AF_UNIX: Unix domain sockets
|
||||
- others, e.g. AF_DECNET are conceivable (see <socket.h>
|
||||
- socket type:
|
||||
- SOCK_STREAM (reliable stream, e.g. TCP)
|
||||
- SOCK_DGRAM (datagrams, e.g. UDP)
|
||||
- SOCK_STREAM (reliable stream, e.g. TCP)
|
||||
- SOCK_DGRAM (datagrams, e.g. UDP)
|
||||
- client address verification before further looking at the request
|
||||
(This is actually a hook for any processing that needs to look
|
||||
at the request before anything else, e.g. logging)
|
||||
(This is actually a hook for any processing that needs to look
|
||||
at the request before anything else, e.g. logging)
|
||||
- how to handle multiple requests:
|
||||
- synchronous (one request is handled at a time)
|
||||
- forking (each request is handled by a new process)
|
||||
- threading (each request is handled by a new thread)
|
||||
- synchronous (one request is handled at a time)
|
||||
- forking (each request is handled by a new process)
|
||||
- threading (each request is handled by a new thread)
|
||||
|
||||
The classes in this module favor the server type that is simplest to
|
||||
write: a synchronous TCP/IP server. This is bad class design, but
|
||||
|
@ -25,14 +25,14 @@ slows down method lookups.)
|
|||
There are four classes in an inheritance diagram that represent
|
||||
synchronous servers of four types:
|
||||
|
||||
+-----------+ +------------------+
|
||||
| TCPServer |------->| UnixStreamServer |
|
||||
+-----------+ +------------------+
|
||||
|
|
||||
v
|
||||
+-----------+ +--------------------+
|
||||
| UDPServer |------->| UnixDatagramServer |
|
||||
+-----------+ +--------------------+
|
||||
+-----------+ +------------------+
|
||||
| TCPServer |------->| UnixStreamServer |
|
||||
+-----------+ +------------------+
|
||||
|
|
||||
v
|
||||
+-----------+ +--------------------+
|
||||
| UDPServer |------->| UnixDatagramServer |
|
||||
+-----------+ +--------------------+
|
||||
|
||||
Note that UnixDatagramServer derives from UDPServer, not from
|
||||
UnixStreamServer -- the only difference between an IP and a Unix
|
||||
|
@ -43,7 +43,7 @@ Forking and threading versions of each type of server can be created
|
|||
using the ForkingServer and ThreadingServer mix-in classes. For
|
||||
instance, a threading UDP server class is created as follows:
|
||||
|
||||
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
|
||||
class ThreadingUDPServer(ThreadingMixIn, UDPServer): pass
|
||||
|
||||
The Mix-in class must come first, since it overrides a method defined
|
||||
in UDPServer!
|
||||
|
@ -119,8 +119,8 @@ class TCPServer:
|
|||
|
||||
- __init__(server_address, RequestHandlerClass)
|
||||
- serve_forever()
|
||||
- handle_request() # if you don't use serve_forever()
|
||||
- fileno() -> int # for select()
|
||||
- handle_request() # if you don't use serve_forever()
|
||||
- fileno() -> int # for select()
|
||||
|
||||
Methods that may be overridden:
|
||||
|
||||
|
@ -157,42 +157,42 @@ class TCPServer:
|
|||
request_queue_size = 5
|
||||
|
||||
def __init__(self, server_address, RequestHandlerClass):
|
||||
"""Constructor. May be extended, do not override."""
|
||||
self.server_address = server_address
|
||||
self.RequestHandlerClass = RequestHandlerClass
|
||||
self.socket = socket.socket(self.address_family,
|
||||
self.socket_type)
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
"""Constructor. May be extended, do not override."""
|
||||
self.server_address = server_address
|
||||
self.RequestHandlerClass = RequestHandlerClass
|
||||
self.socket = socket.socket(self.address_family,
|
||||
self.socket_type)
|
||||
self.server_bind()
|
||||
self.server_activate()
|
||||
|
||||
def server_bind(self):
|
||||
"""Called by constructor to bind the socket.
|
||||
"""Called by constructor to bind the socket.
|
||||
|
||||
May be overridden.
|
||||
May be overridden.
|
||||
|
||||
"""
|
||||
self.socket.bind(self.server_address)
|
||||
"""
|
||||
self.socket.bind(self.server_address)
|
||||
|
||||
def server_activate(self):
|
||||
"""Called by constructor to activate the server.
|
||||
"""Called by constructor to activate the server.
|
||||
|
||||
May be overridden.
|
||||
May be overridden.
|
||||
|
||||
"""
|
||||
self.socket.listen(self.request_queue_size)
|
||||
"""
|
||||
self.socket.listen(self.request_queue_size)
|
||||
|
||||
def fileno(self):
|
||||
"""Return socket file number.
|
||||
"""Return socket file number.
|
||||
|
||||
Interface required by select().
|
||||
Interface required by select().
|
||||
|
||||
"""
|
||||
return self.socket.fileno()
|
||||
"""
|
||||
return self.socket.fileno()
|
||||
|
||||
def serve_forever(self):
|
||||
"""Handle one request at a time until doomsday."""
|
||||
while 1:
|
||||
self.handle_request()
|
||||
"""Handle one request at a time until doomsday."""
|
||||
while 1:
|
||||
self.handle_request()
|
||||
|
||||
# The distinction between handling, getting, processing and
|
||||
# finishing a request is fairly arbitrary. Remember:
|
||||
|
@ -206,54 +206,54 @@ class TCPServer:
|
|||
# this constructor will handle the request all by itself
|
||||
|
||||
def handle_request(self):
|
||||
"""Handle one request, possibly blocking."""
|
||||
request, client_address = self.get_request()
|
||||
if self.verify_request(request, client_address):
|
||||
try:
|
||||
self.process_request(request, client_address)
|
||||
except:
|
||||
self.handle_error(request, client_address)
|
||||
"""Handle one request, possibly blocking."""
|
||||
request, client_address = self.get_request()
|
||||
if self.verify_request(request, client_address):
|
||||
try:
|
||||
self.process_request(request, client_address)
|
||||
except:
|
||||
self.handle_error(request, client_address)
|
||||
|
||||
def get_request(self):
|
||||
"""Get the request and client address from the socket.
|
||||
"""Get the request and client address from the socket.
|
||||
|
||||
May be overridden.
|
||||
May be overridden.
|
||||
|
||||
"""
|
||||
return self.socket.accept()
|
||||
"""
|
||||
return self.socket.accept()
|
||||
|
||||
def verify_request(self, request, client_address):
|
||||
"""Verify the request. May be overridden.
|
||||
"""Verify the request. May be overridden.
|
||||
|
||||
Return true if we should proceed with this request.
|
||||
Return true if we should proceed with this request.
|
||||
|
||||
"""
|
||||
return 1
|
||||
"""
|
||||
return 1
|
||||
|
||||
def process_request(self, request, client_address):
|
||||
"""Call finish_request.
|
||||
"""Call finish_request.
|
||||
|
||||
Overridden by ForkingMixIn and ThreadingMixIn.
|
||||
Overridden by ForkingMixIn and ThreadingMixIn.
|
||||
|
||||
"""
|
||||
self.finish_request(request, client_address)
|
||||
"""
|
||||
self.finish_request(request, client_address)
|
||||
|
||||
def finish_request(self, request, client_address):
|
||||
"""Finish one request by instantiating RequestHandlerClass."""
|
||||
self.RequestHandlerClass(request, client_address, self)
|
||||
"""Finish one request by instantiating RequestHandlerClass."""
|
||||
self.RequestHandlerClass(request, client_address, self)
|
||||
|
||||
def handle_error(self, request, client_address):
|
||||
"""Handle an error gracefully. May be overridden.
|
||||
"""Handle an error gracefully. May be overridden.
|
||||
|
||||
The default is to print a traceback and continue.
|
||||
The default is to print a traceback and continue.
|
||||
|
||||
"""
|
||||
print '-'*40
|
||||
print 'Exception happened during processing of request from',
|
||||
print client_address
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
print '-'*40
|
||||
"""
|
||||
print '-'*40
|
||||
print 'Exception happened during processing of request from',
|
||||
print client_address
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
print '-'*40
|
||||
|
||||
|
||||
class UDPServer(TCPServer):
|
||||
|
@ -265,19 +265,19 @@ class UDPServer(TCPServer):
|
|||
max_packet_size = 8192
|
||||
|
||||
def get_request(self):
|
||||
return self.socket.recvfrom(self.max_packet_size)
|
||||
return self.socket.recvfrom(self.max_packet_size)
|
||||
|
||||
|
||||
if hasattr(socket, 'AF_UNIX'):
|
||||
|
||||
class UnixStreamServer(TCPServer):
|
||||
|
||||
address_family = socket.AF_UNIX
|
||||
address_family = socket.AF_UNIX
|
||||
|
||||
|
||||
class UnixDatagramServer(UDPServer):
|
||||
|
||||
address_family = socket.AF_UNIX
|
||||
address_family = socket.AF_UNIX
|
||||
|
||||
|
||||
class ForkingMixIn:
|
||||
|
@ -287,34 +287,34 @@ class ForkingMixIn:
|
|||
active_children = None
|
||||
|
||||
def collect_children(self):
|
||||
"""Internal routine to wait for died children."""
|
||||
while self.active_children:
|
||||
pid, status = os.waitpid(0, os.WNOHANG)
|
||||
if not pid: break
|
||||
self.active_children.remove(pid)
|
||||
"""Internal routine to wait for died children."""
|
||||
while self.active_children:
|
||||
pid, status = os.waitpid(0, os.WNOHANG)
|
||||
if not pid: break
|
||||
self.active_children.remove(pid)
|
||||
|
||||
def process_request(self, request, client_address):
|
||||
"""Fork a new subprocess to process the request."""
|
||||
self.collect_children()
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
# Parent process
|
||||
if self.active_children is None:
|
||||
self.active_children = []
|
||||
self.active_children.append(pid)
|
||||
return
|
||||
else:
|
||||
# Child process.
|
||||
# This must never return, hence os._exit()!
|
||||
try:
|
||||
self.finish_request(request, client_address)
|
||||
os._exit(0)
|
||||
except:
|
||||
try:
|
||||
self.handle_error(request,
|
||||
client_address)
|
||||
finally:
|
||||
os._exit(1)
|
||||
"""Fork a new subprocess to process the request."""
|
||||
self.collect_children()
|
||||
pid = os.fork()
|
||||
if pid:
|
||||
# Parent process
|
||||
if self.active_children is None:
|
||||
self.active_children = []
|
||||
self.active_children.append(pid)
|
||||
return
|
||||
else:
|
||||
# Child process.
|
||||
# This must never return, hence os._exit()!
|
||||
try:
|
||||
self.finish_request(request, client_address)
|
||||
os._exit(0)
|
||||
except:
|
||||
try:
|
||||
self.handle_error(request,
|
||||
client_address)
|
||||
finally:
|
||||
os._exit(1)
|
||||
|
||||
|
||||
class ThreadingMixIn:
|
||||
|
@ -322,10 +322,10 @@ class ThreadingMixIn:
|
|||
"""Mix-in class to handle each request in a new thread."""
|
||||
|
||||
def process_request(self, request, client_address):
|
||||
"""Start a new thread to process the request."""
|
||||
import thread
|
||||
thread.start_new_thread(self.finish_request,
|
||||
(request, client_address))
|
||||
"""Start a new thread to process the request."""
|
||||
import thread
|
||||
thread.start_new_thread(self.finish_request,
|
||||
(request, client_address))
|
||||
|
||||
|
||||
class ForkingUDPServer(ForkingMixIn, UDPServer): pass
|
||||
|
@ -354,27 +354,27 @@ class BaseRequestHandler:
|
|||
"""
|
||||
|
||||
def __init__(self, request, client_address, server):
|
||||
self.request = request
|
||||
self.client_address = client_address
|
||||
self.server = server
|
||||
try:
|
||||
self.setup()
|
||||
self.handle()
|
||||
self.finish()
|
||||
finally:
|
||||
sys.exc_traceback = None # Help garbage collection
|
||||
self.request = request
|
||||
self.client_address = client_address
|
||||
self.server = server
|
||||
try:
|
||||
self.setup()
|
||||
self.handle()
|
||||
self.finish()
|
||||
finally:
|
||||
sys.exc_traceback = None # Help garbage collection
|
||||
|
||||
def setup(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
def __del__(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
def handle(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
def finish(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
|
||||
# The following two classes make it possible to use the same service
|
||||
|
@ -390,12 +390,12 @@ class StreamRequestHandler(BaseRequestHandler):
|
|||
"""Define self.rfile and self.wfile for stream sockets."""
|
||||
|
||||
def setup(self):
|
||||
self.connection = self.request
|
||||
self.rfile = self.connection.makefile('rb', 0)
|
||||
self.wfile = self.connection.makefile('wb', 0)
|
||||
self.connection = self.request
|
||||
self.rfile = self.connection.makefile('rb', 0)
|
||||
self.wfile = self.connection.makefile('wb', 0)
|
||||
|
||||
def finish(self):
|
||||
self.wfile.flush()
|
||||
self.wfile.flush()
|
||||
|
||||
|
||||
class DatagramRequestHandler(BaseRequestHandler):
|
||||
|
@ -403,10 +403,10 @@ class DatagramRequestHandler(BaseRequestHandler):
|
|||
"""Define self.rfile and self.wfile for datagram sockets."""
|
||||
|
||||
def setup(self):
|
||||
import StringIO
|
||||
self.packet, self.socket = self.request
|
||||
self.rfile = StringIO.StringIO(self.packet)
|
||||
self.wfile = StringIO.StringIO(self.packet)
|
||||
import StringIO
|
||||
self.packet, self.socket = self.request
|
||||
self.rfile = StringIO.StringIO(self.packet)
|
||||
self.wfile = StringIO.StringIO(self.packet)
|
||||
|
||||
def finish(self):
|
||||
self.socket.send(self.wfile.getvalue())
|
||||
self.socket.send(self.wfile.getvalue())
|
||||
|
|
|
@ -76,7 +76,7 @@ class Telnet:
|
|||
|
||||
read_until(expected, [timeout])
|
||||
Read until the expected string has been seen, or a timeout is
|
||||
hit (default is no timeout); may block.
|
||||
hit (default is no timeout); may block.
|
||||
|
||||
read_all()
|
||||
Read all data until EOF; may block.
|
||||
|
@ -86,360 +86,362 @@ class Telnet:
|
|||
|
||||
read_very_eager()
|
||||
Read all data available already queued or on the socket,
|
||||
without blocking.
|
||||
without blocking.
|
||||
|
||||
read_eager()
|
||||
Read either data already queued or some data available on the
|
||||
socket, without blocking.
|
||||
socket, without blocking.
|
||||
|
||||
read_lazy()
|
||||
Read all data in the raw queue (processing it first), without
|
||||
doing any socket I/O.
|
||||
doing any socket I/O.
|
||||
|
||||
read_very_lazy()
|
||||
Reads all data in the cooked queue, without doing any socket
|
||||
I/O.
|
||||
I/O.
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, host=None, port=0):
|
||||
"""Constructor.
|
||||
"""Constructor.
|
||||
|
||||
When called without arguments, create an unconnected instance.
|
||||
With a hostname argument, it connects the instance; a port
|
||||
number is optional.
|
||||
When called without arguments, create an unconnected instance.
|
||||
With a hostname argument, it connects the instance; a port
|
||||
number is optional.
|
||||
|
||||
"""
|
||||
self.debuglevel = DEBUGLEVEL
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = None
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
self.cookedq = ''
|
||||
self.eof = 0
|
||||
if host:
|
||||
self.open(host, port)
|
||||
"""
|
||||
self.debuglevel = DEBUGLEVEL
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = None
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
self.cookedq = ''
|
||||
self.eof = 0
|
||||
if host:
|
||||
self.open(host, port)
|
||||
|
||||
def open(self, host, port=0):
|
||||
"""Connect to a host.
|
||||
"""Connect to a host.
|
||||
|
||||
The optional second argument is the port number, which
|
||||
defaults to the standard telnet port (23).
|
||||
The optional second argument is the port number, which
|
||||
defaults to the standard telnet port (23).
|
||||
|
||||
Don't try to reopen an already connected instance.
|
||||
Don't try to reopen an already connected instance.
|
||||
|
||||
"""
|
||||
self.eof = 0
|
||||
if not port:
|
||||
port = TELNET_PORT
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((self.host, self.port))
|
||||
"""
|
||||
self.eof = 0
|
||||
if not port:
|
||||
port = TELNET_PORT
|
||||
self.host = host
|
||||
self.port = port
|
||||
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
self.sock.connect((self.host, self.port))
|
||||
|
||||
def __del__(self):
|
||||
"""Destructor -- close the connection."""
|
||||
self.close()
|
||||
"""Destructor -- close the connection."""
|
||||
self.close()
|
||||
|
||||
def msg(self, msg, *args):
|
||||
"""Print a debug message, when the debug level is > 0.
|
||||
"""Print a debug message, when the debug level is > 0.
|
||||
|
||||
If extra arguments are present, they are substituted in the
|
||||
message using the standard string formatting operator.
|
||||
If extra arguments are present, they are substituted in the
|
||||
message using the standard string formatting operator.
|
||||
|
||||
"""
|
||||
if self.debuglevel > 0:
|
||||
print 'Telnet(%s,%d):' % (self.host, self.port),
|
||||
if args:
|
||||
print msg % args
|
||||
else:
|
||||
print msg
|
||||
"""
|
||||
if self.debuglevel > 0:
|
||||
print 'Telnet(%s,%d):' % (self.host, self.port),
|
||||
if args:
|
||||
print msg % args
|
||||
else:
|
||||
print msg
|
||||
|
||||
def set_debuglevel(self, debuglevel):
|
||||
"""Set the debug level.
|
||||
"""Set the debug level.
|
||||
|
||||
The higher it is, the more debug output you get (on sys.stdout).
|
||||
The higher it is, the more debug output you get (on sys.stdout).
|
||||
|
||||
"""
|
||||
self.debuglevel = debuglevel
|
||||
"""
|
||||
self.debuglevel = debuglevel
|
||||
|
||||
def close(self):
|
||||
"""Close the connection."""
|
||||
if self.sock:
|
||||
self.sock.close()
|
||||
self.sock = 0
|
||||
self.eof = 1
|
||||
"""Close the connection."""
|
||||
if self.sock:
|
||||
self.sock.close()
|
||||
self.sock = 0
|
||||
self.eof = 1
|
||||
|
||||
def get_socket(self):
|
||||
"""Return the socket object used internally."""
|
||||
return self.sock
|
||||
"""Return the socket object used internally."""
|
||||
return self.sock
|
||||
|
||||
def fileno(self):
|
||||
"""Return the fileno() of the socket object used internally."""
|
||||
return self.sock.fileno()
|
||||
"""Return the fileno() of the socket object used internally."""
|
||||
return self.sock.fileno()
|
||||
|
||||
def write(self, buffer):
|
||||
"""Write a string to the socket, doubling any IAC characters.
|
||||
"""Write a string to the socket, doubling any IAC characters.
|
||||
|
||||
Can block if the connection is blocked. May raise
|
||||
socket.error if the connection is closed.
|
||||
Can block if the connection is blocked. May raise
|
||||
socket.error if the connection is closed.
|
||||
|
||||
"""
|
||||
if IAC in buffer:
|
||||
buffer = string.replace(buffer, IAC, IAC+IAC)
|
||||
self.sock.send(buffer)
|
||||
"""
|
||||
if IAC in buffer:
|
||||
buffer = string.replace(buffer, IAC, IAC+IAC)
|
||||
self.msg("send %s", `buffer`)
|
||||
self.sock.send(buffer)
|
||||
|
||||
def read_until(self, match, timeout=None):
|
||||
"""Read until a given string is encountered or until timeout.
|
||||
"""Read until a given string is encountered or until timeout.
|
||||
|
||||
When no match is found, return whatever is available instead,
|
||||
possibly the empty string. Raise EOFError if the connection
|
||||
is closed and no cooked data is available.
|
||||
When no match is found, return whatever is available instead,
|
||||
possibly the empty string. Raise EOFError if the connection
|
||||
is closed and no cooked data is available.
|
||||
|
||||
"""
|
||||
n = len(match)
|
||||
self.process_rawq()
|
||||
i = string.find(self.cookedq, match)
|
||||
if i >= 0:
|
||||
i = i+n
|
||||
buf = self.cookedq[:i]
|
||||
self.cookedq = self.cookedq[i:]
|
||||
return buf
|
||||
s_reply = ([self], [], [])
|
||||
s_args = s_reply
|
||||
if timeout is not None:
|
||||
s_args = s_args + (timeout,)
|
||||
while not self.eof and apply(select.select, s_args) == s_reply:
|
||||
i = max(0, len(self.cookedq)-n)
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
i = string.find(self.cookedq, match, i)
|
||||
if i >= 0:
|
||||
i = i+n
|
||||
buf = self.cookedq[:i]
|
||||
self.cookedq = self.cookedq[i:]
|
||||
return buf
|
||||
return self.read_very_lazy()
|
||||
"""
|
||||
n = len(match)
|
||||
self.process_rawq()
|
||||
i = string.find(self.cookedq, match)
|
||||
if i >= 0:
|
||||
i = i+n
|
||||
buf = self.cookedq[:i]
|
||||
self.cookedq = self.cookedq[i:]
|
||||
return buf
|
||||
s_reply = ([self], [], [])
|
||||
s_args = s_reply
|
||||
if timeout is not None:
|
||||
s_args = s_args + (timeout,)
|
||||
while not self.eof and apply(select.select, s_args) == s_reply:
|
||||
i = max(0, len(self.cookedq)-n)
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
i = string.find(self.cookedq, match, i)
|
||||
if i >= 0:
|
||||
i = i+n
|
||||
buf = self.cookedq[:i]
|
||||
self.cookedq = self.cookedq[i:]
|
||||
return buf
|
||||
return self.read_very_lazy()
|
||||
|
||||
def read_all(self):
|
||||
"""Read all data until EOF; block until connection closed."""
|
||||
self.process_rawq()
|
||||
while not self.eof:
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
return buf
|
||||
"""Read all data until EOF; block until connection closed."""
|
||||
self.process_rawq()
|
||||
while not self.eof:
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
return buf
|
||||
|
||||
def read_some(self):
|
||||
"""Read at least one byte of cooked data unless EOF is hit.
|
||||
"""Read at least one byte of cooked data unless EOF is hit.
|
||||
|
||||
Return '' if EOF is hit. Block if no data is immediately
|
||||
available.
|
||||
Return '' if EOF is hit. Block if no data is immediately
|
||||
available.
|
||||
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.cookedq and not self.eof:
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
return buf
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.cookedq and not self.eof:
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
return buf
|
||||
|
||||
def read_very_eager(self):
|
||||
"""Read everything that's possible without blocking in I/O (eager).
|
||||
"""Read everything that's possible without blocking in I/O (eager).
|
||||
|
||||
Raise EOFError if connection closed and no cooked data
|
||||
available. Return '' if no cooked data available otherwise.
|
||||
Don't block unless in the midst of an IAC sequence.
|
||||
Raise EOFError if connection closed and no cooked data
|
||||
available. Return '' if no cooked data available otherwise.
|
||||
Don't block unless in the midst of an IAC sequence.
|
||||
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.eof and self.sock_avail():
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.eof and self.sock_avail():
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
|
||||
def read_eager(self):
|
||||
"""Read readily available data.
|
||||
"""Read readily available data.
|
||||
|
||||
Raise EOFError if connection closed and no cooked data
|
||||
available. Return '' if no cooked data available otherwise.
|
||||
Don't block unless in the midst of an IAC sequence.
|
||||
Raise EOFError if connection closed and no cooked data
|
||||
available. Return '' if no cooked data available otherwise.
|
||||
Don't block unless in the midst of an IAC sequence.
|
||||
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.cookedq and not self.eof and self.sock_avail():
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
"""
|
||||
self.process_rawq()
|
||||
while not self.cookedq and not self.eof and self.sock_avail():
|
||||
self.fill_rawq()
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
|
||||
def read_lazy(self):
|
||||
"""Process and return data that's already in the queues (lazy).
|
||||
"""Process and return data that's already in the queues (lazy).
|
||||
|
||||
Raise EOFError if connection closed and no data available.
|
||||
Return '' if no cooked data available otherwise. Don't block
|
||||
unless in the midst of an IAC sequence.
|
||||
Raise EOFError if connection closed and no data available.
|
||||
Return '' if no cooked data available otherwise. Don't block
|
||||
unless in the midst of an IAC sequence.
|
||||
|
||||
"""
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
"""
|
||||
self.process_rawq()
|
||||
return self.read_very_lazy()
|
||||
|
||||
def read_very_lazy(self):
|
||||
"""Return any data available in the cooked queue (very lazy).
|
||||
"""Return any data available in the cooked queue (very lazy).
|
||||
|
||||
Raise EOFError if connection closed and no data available.
|
||||
Return '' if no cooked data available otherwise. Don't block.
|
||||
Raise EOFError if connection closed and no data available.
|
||||
Return '' if no cooked data available otherwise. Don't block.
|
||||
|
||||
"""
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
if not buf and self.eof and not self.rawq:
|
||||
raise EOFError, 'telnet connection closed'
|
||||
return buf
|
||||
"""
|
||||
buf = self.cookedq
|
||||
self.cookedq = ''
|
||||
if not buf and self.eof and not self.rawq:
|
||||
raise EOFError, 'telnet connection closed'
|
||||
return buf
|
||||
|
||||
def process_rawq(self):
|
||||
"""Transfer from raw queue to cooked queue.
|
||||
"""Transfer from raw queue to cooked queue.
|
||||
|
||||
Set self.eof when connection is closed. Don't block unless in
|
||||
the midst of an IAC sequence.
|
||||
Set self.eof when connection is closed. Don't block unless in
|
||||
the midst of an IAC sequence.
|
||||
|
||||
"""
|
||||
buf = ''
|
||||
try:
|
||||
while self.rawq:
|
||||
c = self.rawq_getchar()
|
||||
if c == theNULL:
|
||||
continue
|
||||
if c == "\021":
|
||||
continue
|
||||
if c != IAC:
|
||||
buf = buf + c
|
||||
continue
|
||||
c = self.rawq_getchar()
|
||||
if c == IAC:
|
||||
buf = buf + c
|
||||
elif c in (DO, DONT):
|
||||
opt = self.rawq_getchar()
|
||||
self.msg('IAC %s %d', c == DO and 'DO' or 'DONT', ord(c))
|
||||
self.sock.send(IAC + WONT + opt)
|
||||
elif c in (WILL, WONT):
|
||||
opt = self.rawq_getchar()
|
||||
self.msg('IAC %s %d',
|
||||
c == WILL and 'WILL' or 'WONT', ord(c))
|
||||
else:
|
||||
self.msg('IAC %s not recognized' % `c`)
|
||||
except EOFError: # raised by self.rawq_getchar()
|
||||
pass
|
||||
self.cookedq = self.cookedq + buf
|
||||
"""
|
||||
buf = ''
|
||||
try:
|
||||
while self.rawq:
|
||||
c = self.rawq_getchar()
|
||||
if c == theNULL:
|
||||
continue
|
||||
if c == "\021":
|
||||
continue
|
||||
if c != IAC:
|
||||
buf = buf + c
|
||||
continue
|
||||
c = self.rawq_getchar()
|
||||
if c == IAC:
|
||||
buf = buf + c
|
||||
elif c in (DO, DONT):
|
||||
opt = self.rawq_getchar()
|
||||
self.msg('IAC %s %d', c == DO and 'DO' or 'DONT', ord(c))
|
||||
self.sock.send(IAC + WONT + opt)
|
||||
elif c in (WILL, WONT):
|
||||
opt = self.rawq_getchar()
|
||||
self.msg('IAC %s %d',
|
||||
c == WILL and 'WILL' or 'WONT', ord(c))
|
||||
else:
|
||||
self.msg('IAC %s not recognized' % `c`)
|
||||
except EOFError: # raised by self.rawq_getchar()
|
||||
pass
|
||||
self.cookedq = self.cookedq + buf
|
||||
|
||||
def rawq_getchar(self):
|
||||
"""Get next char from raw queue.
|
||||
"""Get next char from raw queue.
|
||||
|
||||
Block if no data is immediately available. Raise EOFError
|
||||
when connection is closed.
|
||||
Block if no data is immediately available. Raise EOFError
|
||||
when connection is closed.
|
||||
|
||||
"""
|
||||
if not self.rawq:
|
||||
self.fill_rawq()
|
||||
if self.eof:
|
||||
raise EOFError
|
||||
c = self.rawq[self.irawq]
|
||||
self.irawq = self.irawq + 1
|
||||
if self.irawq >= len(self.rawq):
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
return c
|
||||
"""
|
||||
if not self.rawq:
|
||||
self.fill_rawq()
|
||||
if self.eof:
|
||||
raise EOFError
|
||||
c = self.rawq[self.irawq]
|
||||
self.irawq = self.irawq + 1
|
||||
if self.irawq >= len(self.rawq):
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
return c
|
||||
|
||||
def fill_rawq(self):
|
||||
"""Fill raw queue from exactly one recv() system call.
|
||||
"""Fill raw queue from exactly one recv() system call.
|
||||
|
||||
Block if no data is immediately available. Set self.eof when
|
||||
connection is closed.
|
||||
Block if no data is immediately available. Set self.eof when
|
||||
connection is closed.
|
||||
|
||||
"""
|
||||
if self.irawq >= len(self.rawq):
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
# The buffer size should be fairly small so as to avoid quadratic
|
||||
# behavior in process_rawq() above
|
||||
buf = self.sock.recv(50)
|
||||
self.eof = (not buf)
|
||||
self.rawq = self.rawq + buf
|
||||
"""
|
||||
if self.irawq >= len(self.rawq):
|
||||
self.rawq = ''
|
||||
self.irawq = 0
|
||||
# The buffer size should be fairly small so as to avoid quadratic
|
||||
# behavior in process_rawq() above
|
||||
buf = self.sock.recv(50)
|
||||
self.msg("recv %s", `buf`)
|
||||
self.eof = (not buf)
|
||||
self.rawq = self.rawq + buf
|
||||
|
||||
def sock_avail(self):
|
||||
"""Test whether data is available on the socket."""
|
||||
return select.select([self], [], [], 0) == ([self], [], [])
|
||||
"""Test whether data is available on the socket."""
|
||||
return select.select([self], [], [], 0) == ([self], [], [])
|
||||
|
||||
def interact(self):
|
||||
"""Interaction function, emulates a very dumb telnet client."""
|
||||
while 1:
|
||||
rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
|
||||
if self in rfd:
|
||||
try:
|
||||
text = self.read_eager()
|
||||
except EOFError:
|
||||
print '*** Connection closed by remote host ***'
|
||||
break
|
||||
if text:
|
||||
sys.stdout.write(text)
|
||||
sys.stdout.flush()
|
||||
if sys.stdin in rfd:
|
||||
line = sys.stdin.readline()
|
||||
if not line:
|
||||
break
|
||||
self.write(line)
|
||||
"""Interaction function, emulates a very dumb telnet client."""
|
||||
while 1:
|
||||
rfd, wfd, xfd = select.select([self, sys.stdin], [], [])
|
||||
if self in rfd:
|
||||
try:
|
||||
text = self.read_eager()
|
||||
except EOFError:
|
||||
print '*** Connection closed by remote host ***'
|
||||
break
|
||||
if text:
|
||||
sys.stdout.write(text)
|
||||
sys.stdout.flush()
|
||||
if sys.stdin in rfd:
|
||||
line = sys.stdin.readline()
|
||||
if not line:
|
||||
break
|
||||
self.write(line)
|
||||
|
||||
def expect(self, list, timeout=None):
|
||||
"""Read until one from a list of a regular expressions matches.
|
||||
"""Read until one from a list of a regular expressions matches.
|
||||
|
||||
The first argument is a list of regular expressions, either
|
||||
compiled (re.RegexObject instances) or uncompiled (strings).
|
||||
The optional second argument is a timeout, in seconds; default
|
||||
is no timeout.
|
||||
The first argument is a list of regular expressions, either
|
||||
compiled (re.RegexObject instances) or uncompiled (strings).
|
||||
The optional second argument is a timeout, in seconds; default
|
||||
is no timeout.
|
||||
|
||||
Return a tuple of three items: the index in the list of the
|
||||
first regular expression that matches; the match object
|
||||
returned; and the text read up till and including the match.
|
||||
Return a tuple of three items: the index in the list of the
|
||||
first regular expression that matches; the match object
|
||||
returned; and the text read up till and including the match.
|
||||
|
||||
If EOF is read and no text was read, raise EOFError.
|
||||
Otherwise, when nothing matches, return (-1, None, text) where
|
||||
text is the text received so far (may be the empty string if a
|
||||
timeout happened).
|
||||
If EOF is read and no text was read, raise EOFError.
|
||||
Otherwise, when nothing matches, return (-1, None, text) where
|
||||
text is the text received so far (may be the empty string if a
|
||||
timeout happened).
|
||||
|
||||
If a regular expression ends with a greedy match (e.g. '.*')
|
||||
or if more than one expression can match the same input, the
|
||||
results are undeterministic, and may depend on the I/O timing.
|
||||
If a regular expression ends with a greedy match (e.g. '.*')
|
||||
or if more than one expression can match the same input, the
|
||||
results are undeterministic, and may depend on the I/O timing.
|
||||
|
||||
"""
|
||||
re = None
|
||||
list = list[:]
|
||||
indices = range(len(list))
|
||||
for i in indices:
|
||||
if not hasattr(list[i], "search"):
|
||||
if not re: import re
|
||||
list[i] = re.compile(list[i])
|
||||
while 1:
|
||||
self.process_rawq()
|
||||
for i in indices:
|
||||
m = list[i].search(self.cookedq)
|
||||
if m:
|
||||
e = m.end()
|
||||
text = self.cookedq[:e]
|
||||
self.cookedq = self.cookedq[e:]
|
||||
return (i, m, text)
|
||||
if self.eof:
|
||||
break
|
||||
if timeout is not None:
|
||||
r, w, x = select.select([self.fileno()], [], [], timeout)
|
||||
if not r:
|
||||
break
|
||||
self.fill_rawq()
|
||||
text = self.read_very_lazy()
|
||||
if not text and self.eof:
|
||||
raise EOFError
|
||||
return (-1, None, text)
|
||||
"""
|
||||
re = None
|
||||
list = list[:]
|
||||
indices = range(len(list))
|
||||
for i in indices:
|
||||
if not hasattr(list[i], "search"):
|
||||
if not re: import re
|
||||
list[i] = re.compile(list[i])
|
||||
while 1:
|
||||
self.process_rawq()
|
||||
for i in indices:
|
||||
m = list[i].search(self.cookedq)
|
||||
if m:
|
||||
e = m.end()
|
||||
text = self.cookedq[:e]
|
||||
self.cookedq = self.cookedq[e:]
|
||||
return (i, m, text)
|
||||
if self.eof:
|
||||
break
|
||||
if timeout is not None:
|
||||
r, w, x = select.select([self.fileno()], [], [], timeout)
|
||||
if not r:
|
||||
break
|
||||
self.fill_rawq()
|
||||
text = self.read_very_lazy()
|
||||
if not text and self.eof:
|
||||
raise EOFError
|
||||
return (-1, None, text)
|
||||
|
||||
|
||||
def test():
|
||||
|
@ -452,18 +454,18 @@ def test():
|
|||
"""
|
||||
debuglevel = 0
|
||||
while sys.argv[1:] and sys.argv[1] == '-d':
|
||||
debuglevel = debuglevel+1
|
||||
del sys.argv[1]
|
||||
debuglevel = debuglevel+1
|
||||
del sys.argv[1]
|
||||
host = 'localhost'
|
||||
if sys.argv[1:]:
|
||||
host = sys.argv[1]
|
||||
host = sys.argv[1]
|
||||
port = 0
|
||||
if sys.argv[2:]:
|
||||
portstr = sys.argv[2]
|
||||
try:
|
||||
port = int(portstr)
|
||||
except ValueError:
|
||||
port = socket.getservbyname(portstr, 'tcp')
|
||||
portstr = sys.argv[2]
|
||||
try:
|
||||
port = int(portstr)
|
||||
except ValueError:
|
||||
port = socket.getservbyname(portstr, 'tcp')
|
||||
tn = Telnet()
|
||||
tn.set_debuglevel(debuglevel)
|
||||
tn.open(host, port)
|
||||
|
|
|
@ -10,49 +10,49 @@ def main():
|
|||
testtype('c', 'c')
|
||||
|
||||
for type in (['b', 'h', 'i', 'l', 'f', 'd']):
|
||||
testtype(type, 1)
|
||||
testtype(type, 1)
|
||||
|
||||
unlink(TESTFN)
|
||||
|
||||
|
||||
def testtype(type, example):
|
||||
|
||||
a = array.array(type)
|
||||
a.append(example)
|
||||
if verbose:
|
||||
print 40*'*'
|
||||
print 'array after append: ', a
|
||||
a.typecode
|
||||
a.itemsize
|
||||
if a.typecode in ('i', 'b', 'h', 'l'):
|
||||
a.byteswap()
|
||||
a = array.array(type)
|
||||
a.append(example)
|
||||
if verbose:
|
||||
print 40*'*'
|
||||
print 'array after append: ', a
|
||||
a.typecode
|
||||
a.itemsize
|
||||
if a.typecode in ('i', 'b', 'h', 'l'):
|
||||
a.byteswap()
|
||||
|
||||
if a.typecode == 'c':
|
||||
f = open(TESTFN, "w")
|
||||
f.write("The quick brown fox jumps over the lazy dog.\n")
|
||||
f.close()
|
||||
f = open(TESTFN, 'r')
|
||||
a.fromfile(f, 10)
|
||||
f.close()
|
||||
if verbose:
|
||||
print 'char array with 10 bytes of TESTFN appended: ', a
|
||||
a.fromlist(['a', 'b', 'c'])
|
||||
if verbose:
|
||||
print 'char array with list appended: ', a
|
||||
if a.typecode == 'c':
|
||||
f = open(TESTFN, "w")
|
||||
f.write("The quick brown fox jumps over the lazy dog.\n")
|
||||
f.close()
|
||||
f = open(TESTFN, 'r')
|
||||
a.fromfile(f, 10)
|
||||
f.close()
|
||||
if verbose:
|
||||
print 'char array with 10 bytes of TESTFN appended: ', a
|
||||
a.fromlist(['a', 'b', 'c'])
|
||||
if verbose:
|
||||
print 'char array with list appended: ', a
|
||||
|
||||
a.insert(0, example)
|
||||
if verbose:
|
||||
print 'array of %s after inserting another:' % a.typecode, a
|
||||
f = open(TESTFN, 'w')
|
||||
a.tofile(f)
|
||||
f.close()
|
||||
a.tolist()
|
||||
a.tostring()
|
||||
if verbose:
|
||||
print 'array of %s converted to a list: ' % a.typecode, a.tolist()
|
||||
if verbose:
|
||||
print 'array of %s converted to a string: ' \
|
||||
% a.typecode, `a.tostring()`
|
||||
a.insert(0, example)
|
||||
if verbose:
|
||||
print 'array of %s after inserting another:' % a.typecode, a
|
||||
f = open(TESTFN, 'w')
|
||||
a.tofile(f)
|
||||
f.close()
|
||||
a.tolist()
|
||||
a.tostring()
|
||||
if verbose:
|
||||
print 'array of %s converted to a list: ' % a.typecode, a.tolist()
|
||||
if verbose:
|
||||
print 'array of %s converted to a string: ' \
|
||||
% a.typecode, `a.tostring()`
|
||||
|
||||
|
||||
main()
|
||||
|
|
|
@ -7,166 +7,166 @@ def gendata1():
|
|||
|
||||
def gendata2():
|
||||
if verbose:
|
||||
print 'getsample'
|
||||
print 'getsample'
|
||||
if audioop.getsample('\0\1', 2, 0) == 1:
|
||||
return '\0\0\0\1\0\2'
|
||||
return '\0\0\0\1\0\2'
|
||||
else:
|
||||
return '\0\0\1\0\2\0'
|
||||
return '\0\0\1\0\2\0'
|
||||
|
||||
def gendata4():
|
||||
if verbose:
|
||||
print 'getsample'
|
||||
print 'getsample'
|
||||
if audioop.getsample('\0\0\0\1', 4, 0) == 1:
|
||||
return '\0\0\0\0\0\0\0\1\0\0\0\2'
|
||||
return '\0\0\0\0\0\0\0\1\0\0\0\2'
|
||||
else:
|
||||
return '\0\0\0\0\1\0\0\0\2\0\0\0'
|
||||
return '\0\0\0\0\1\0\0\0\2\0\0\0'
|
||||
|
||||
def testmax(data):
|
||||
if verbose:
|
||||
print 'max'
|
||||
print 'max'
|
||||
if audioop.max(data[0], 1) <> 2 or \
|
||||
audioop.max(data[1], 2) <> 2 or \
|
||||
audioop.max(data[2], 4) <> 2:
|
||||
return 0
|
||||
audioop.max(data[1], 2) <> 2 or \
|
||||
audioop.max(data[2], 4) <> 2:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testminmax(data):
|
||||
if verbose:
|
||||
print 'minmax'
|
||||
print 'minmax'
|
||||
if audioop.minmax(data[0], 1) <> (0, 2) or \
|
||||
audioop.minmax(data[1], 2) <> (0, 2) or \
|
||||
audioop.minmax(data[2], 4) <> (0, 2):
|
||||
return 0
|
||||
audioop.minmax(data[1], 2) <> (0, 2) or \
|
||||
audioop.minmax(data[2], 4) <> (0, 2):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testmaxpp(data):
|
||||
if verbose:
|
||||
print 'maxpp'
|
||||
print 'maxpp'
|
||||
if audioop.maxpp(data[0], 1) <> 0 or \
|
||||
audioop.maxpp(data[1], 2) <> 0 or \
|
||||
audioop.maxpp(data[2], 4) <> 0:
|
||||
return 0
|
||||
audioop.maxpp(data[1], 2) <> 0 or \
|
||||
audioop.maxpp(data[2], 4) <> 0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testavg(data):
|
||||
if verbose:
|
||||
print 'avg'
|
||||
print 'avg'
|
||||
if audioop.avg(data[0], 1) <> 1 or \
|
||||
audioop.avg(data[1], 2) <> 1 or \
|
||||
audioop.avg(data[2], 4) <> 1:
|
||||
return 0
|
||||
audioop.avg(data[1], 2) <> 1 or \
|
||||
audioop.avg(data[2], 4) <> 1:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testavgpp(data):
|
||||
if verbose:
|
||||
print 'avgpp'
|
||||
print 'avgpp'
|
||||
if audioop.avgpp(data[0], 1) <> 0 or \
|
||||
audioop.avgpp(data[1], 2) <> 0 or \
|
||||
audioop.avgpp(data[2], 4) <> 0:
|
||||
return 0
|
||||
audioop.avgpp(data[1], 2) <> 0 or \
|
||||
audioop.avgpp(data[2], 4) <> 0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testrms(data):
|
||||
if audioop.rms(data[0], 1) <> 1 or \
|
||||
audioop.rms(data[1], 2) <> 1 or \
|
||||
audioop.rms(data[2], 4) <> 1:
|
||||
return 0
|
||||
audioop.rms(data[1], 2) <> 1 or \
|
||||
audioop.rms(data[2], 4) <> 1:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testcross(data):
|
||||
if verbose:
|
||||
print 'cross'
|
||||
print 'cross'
|
||||
if audioop.cross(data[0], 1) <> 0 or \
|
||||
audioop.cross(data[1], 2) <> 0 or \
|
||||
audioop.cross(data[2], 4) <> 0:
|
||||
return 0
|
||||
audioop.cross(data[1], 2) <> 0 or \
|
||||
audioop.cross(data[2], 4) <> 0:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testadd(data):
|
||||
if verbose:
|
||||
print 'add'
|
||||
print 'add'
|
||||
data2 = []
|
||||
for d in data:
|
||||
str = ''
|
||||
for s in d:
|
||||
str = str + chr(ord(s)*2)
|
||||
data2.append(str)
|
||||
str = ''
|
||||
for s in d:
|
||||
str = str + chr(ord(s)*2)
|
||||
data2.append(str)
|
||||
if audioop.add(data[0], data[0], 1) <> data2[0] or \
|
||||
audioop.add(data[1], data[1], 2) <> data2[1] or \
|
||||
audioop.add(data[2], data[2], 4) <> data2[2]:
|
||||
return 0
|
||||
audioop.add(data[1], data[1], 2) <> data2[1] or \
|
||||
audioop.add(data[2], data[2], 4) <> data2[2]:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testbias(data):
|
||||
if verbose:
|
||||
print 'bias'
|
||||
print 'bias'
|
||||
# Note: this test assumes that avg() works
|
||||
d1 = audioop.bias(data[0], 1, 100)
|
||||
d2 = audioop.bias(data[1], 2, 100)
|
||||
d4 = audioop.bias(data[2], 4, 100)
|
||||
if audioop.avg(d1, 1) <> 101 or \
|
||||
audioop.avg(d2, 2) <> 101 or \
|
||||
audioop.avg(d4, 4) <> 101:
|
||||
return 0
|
||||
audioop.avg(d2, 2) <> 101 or \
|
||||
audioop.avg(d4, 4) <> 101:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testlin2lin(data):
|
||||
if verbose:
|
||||
print 'lin2lin'
|
||||
print 'lin2lin'
|
||||
# too simple: we test only the size
|
||||
for d1 in data:
|
||||
for d2 in data:
|
||||
got = len(d1)/3
|
||||
wtd = len(d2)/3
|
||||
if len(audioop.lin2lin(d1, got, wtd)) <> len(d2):
|
||||
return 0
|
||||
for d2 in data:
|
||||
got = len(d1)/3
|
||||
wtd = len(d2)/3
|
||||
if len(audioop.lin2lin(d1, got, wtd)) <> len(d2):
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testadpcm2lin(data):
|
||||
# Very cursory test
|
||||
if audioop.adpcm2lin('\0\0', 1, None) <> ('\0\0\0\0', (0,0)):
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testlin2adpcm(data):
|
||||
if verbose:
|
||||
print 'lin2adpcm'
|
||||
print 'lin2adpcm'
|
||||
# Very cursory test
|
||||
if audioop.lin2adpcm('\0\0\0\0', 1, None) <> ('\0\0', (0,0)):
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testlin2ulaw(data):
|
||||
if verbose:
|
||||
print 'lin2ulaw'
|
||||
print 'lin2ulaw'
|
||||
if audioop.lin2ulaw(data[0], 1) <> '\377\347\333' or \
|
||||
audioop.lin2ulaw(data[1], 2) <> '\377\377\377' or \
|
||||
audioop.lin2ulaw(data[2], 4) <> '\377\377\377':
|
||||
return 0
|
||||
audioop.lin2ulaw(data[1], 2) <> '\377\377\377' or \
|
||||
audioop.lin2ulaw(data[2], 4) <> '\377\377\377':
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testulaw2lin(data):
|
||||
if verbose:
|
||||
print 'ulaw2lin'
|
||||
print 'ulaw2lin'
|
||||
# Cursory
|
||||
d = audioop.lin2ulaw(data[0], 1)
|
||||
if audioop.ulaw2lin(d, 1) <> data[0]:
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testmul(data):
|
||||
if verbose:
|
||||
print 'mul'
|
||||
print 'mul'
|
||||
data2 = []
|
||||
for d in data:
|
||||
str = ''
|
||||
for s in d:
|
||||
str = str + chr(ord(s)*2)
|
||||
data2.append(str)
|
||||
str = ''
|
||||
for s in d:
|
||||
str = str + chr(ord(s)*2)
|
||||
data2.append(str)
|
||||
if audioop.mul(data[0], 1, 2) <> data2[0] or \
|
||||
audioop.mul(data[1],2, 2) <> data2[1] or \
|
||||
audioop.mul(data[2], 4, 2) <> data2[2]:
|
||||
return 0
|
||||
audioop.mul(data[1],2, 2) <> data2[1] or \
|
||||
audioop.mul(data[2], 4, 2) <> data2[2]:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testratecv(data):
|
||||
|
@ -181,75 +181,75 @@ def testratecv(data):
|
|||
|
||||
def testreverse(data):
|
||||
if verbose:
|
||||
print 'reverse'
|
||||
print 'reverse'
|
||||
if audioop.reverse(data[0], 1) <> '\2\1\0':
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testtomono(data):
|
||||
if verbose:
|
||||
print 'tomono'
|
||||
print 'tomono'
|
||||
data2 = ''
|
||||
for d in data[0]:
|
||||
data2 = data2 + d + d
|
||||
data2 = data2 + d + d
|
||||
if audioop.tomono(data2, 1, 0.5, 0.5) <> data[0]:
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testtostereo(data):
|
||||
if verbose:
|
||||
print 'tostereo'
|
||||
print 'tostereo'
|
||||
data2 = ''
|
||||
for d in data[0]:
|
||||
data2 = data2 + d + d
|
||||
data2 = data2 + d + d
|
||||
if audioop.tostereo(data[0], 1, 1, 1) <> data2:
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testfindfactor(data):
|
||||
if verbose:
|
||||
print 'findfactor'
|
||||
print 'findfactor'
|
||||
if audioop.findfactor(data[1], data[1]) <> 1.0:
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testfindfit(data):
|
||||
if verbose:
|
||||
print 'findfit'
|
||||
print 'findfit'
|
||||
if audioop.findfit(data[1], data[1]) <> (0, 1.0):
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testfindmax(data):
|
||||
if verbose:
|
||||
print 'findmax'
|
||||
print 'findmax'
|
||||
if audioop.findmax(data[1], 1) <> 2:
|
||||
return 0
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testgetsample(data):
|
||||
if verbose:
|
||||
print 'getsample'
|
||||
print 'getsample'
|
||||
for i in range(3):
|
||||
if audioop.getsample(data[0], 1, i) <> i or \
|
||||
audioop.getsample(data[1], 2, i) <> i or \
|
||||
audioop.getsample(data[2], 4, i) <> i:
|
||||
return 0
|
||||
if audioop.getsample(data[0], 1, i) <> i or \
|
||||
audioop.getsample(data[1], 2, i) <> i or \
|
||||
audioop.getsample(data[2], 4, i) <> i:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
def testone(name, data):
|
||||
try:
|
||||
func = eval('test'+name)
|
||||
func = eval('test'+name)
|
||||
except NameError:
|
||||
print 'No test found for audioop.'+name+'()'
|
||||
return
|
||||
print 'No test found for audioop.'+name+'()'
|
||||
return
|
||||
try:
|
||||
rv = func(data)
|
||||
rv = func(data)
|
||||
except 'xx':
|
||||
print 'Test FAILED for audioop.'+name+'() (with an exception)'
|
||||
return
|
||||
print 'Test FAILED for audioop.'+name+'() (with an exception)'
|
||||
return
|
||||
if not rv:
|
||||
print 'Test FAILED for audioop.'+name+'()'
|
||||
print 'Test FAILED for audioop.'+name+'()'
|
||||
|
||||
def testall():
|
||||
data = [gendata1(), gendata2(), gendata4()]
|
||||
|
@ -257,8 +257,8 @@ def testall():
|
|||
# We know there is a routine 'add'
|
||||
routines = []
|
||||
for n in names:
|
||||
if type(eval('audioop.'+n)) == type(audioop.add):
|
||||
routines.append(n)
|
||||
if type(eval('audioop.'+n)) == type(audioop.add):
|
||||
routines.append(n)
|
||||
for n in routines:
|
||||
testone(n, data)
|
||||
testone(n, data)
|
||||
testall()
|
||||
|
|
|
@ -11,11 +11,11 @@ from test_support import verbose
|
|||
def test():
|
||||
|
||||
try:
|
||||
fname1 = tempfile.mktemp()
|
||||
fname2 = tempfile.mktemp()
|
||||
f = open(fname1, 'w')
|
||||
fname1 = tempfile.mktemp()
|
||||
fname2 = tempfile.mktemp()
|
||||
f = open(fname1, 'w')
|
||||
except:
|
||||
raise ImportError, "Cannot test binascii without a temp file"
|
||||
raise ImportError, "Cannot test binascii without a temp file"
|
||||
|
||||
start = 'Jack is my hero'
|
||||
f.write(start)
|
||||
|
@ -23,24 +23,24 @@ def test():
|
|||
|
||||
binhex.binhex(fname1, fname2)
|
||||
if verbose:
|
||||
print 'binhex'
|
||||
print 'binhex'
|
||||
|
||||
binhex.hexbin(fname2, fname1)
|
||||
if verbose:
|
||||
print 'hexbin'
|
||||
print 'hexbin'
|
||||
|
||||
f = open(fname1, 'r')
|
||||
finish = f.readline()
|
||||
|
||||
if start <> finish:
|
||||
print 'Error: binhex <> hexbin'
|
||||
print 'Error: binhex <> hexbin'
|
||||
elif verbose:
|
||||
print 'binhex == hexbin'
|
||||
print 'binhex == hexbin'
|
||||
|
||||
try:
|
||||
import os
|
||||
os.unlink(fname1)
|
||||
os.unlink(fname2)
|
||||
import os
|
||||
os.unlink(fname1)
|
||||
os.unlink(fname2)
|
||||
except:
|
||||
pass
|
||||
pass
|
||||
test()
|
||||
|
|
|
@ -9,12 +9,12 @@ from test_support import verbose
|
|||
def test(openmethod, what):
|
||||
|
||||
if verbose:
|
||||
print '\nTesting: ', what
|
||||
print '\nTesting: ', what
|
||||
|
||||
fname = tempfile.mktemp()
|
||||
f = openmethod(fname, 'c')
|
||||
if verbose:
|
||||
print 'creation...'
|
||||
print 'creation...'
|
||||
f['0'] = ''
|
||||
f['a'] = 'Guido'
|
||||
f['b'] = 'van'
|
||||
|
@ -22,47 +22,47 @@ def test(openmethod, what):
|
|||
f['d'] = 'invented'
|
||||
f['f'] = 'Python'
|
||||
if verbose:
|
||||
print '%s %s %s' % (f['a'], f['b'], f['c'])
|
||||
print '%s %s %s' % (f['a'], f['b'], f['c'])
|
||||
|
||||
if what == 'BTree' :
|
||||
if verbose:
|
||||
print 'key ordering...'
|
||||
f.set_location(f.first()[0])
|
||||
while 1:
|
||||
try:
|
||||
rec = f.next()
|
||||
except KeyError:
|
||||
if rec <> f.last():
|
||||
print 'Error, last <> last!'
|
||||
f.previous()
|
||||
break
|
||||
if verbose:
|
||||
print rec
|
||||
if not f.has_key('a'):
|
||||
print 'Error, missing key!'
|
||||
if verbose:
|
||||
print 'key ordering...'
|
||||
f.set_location(f.first()[0])
|
||||
while 1:
|
||||
try:
|
||||
rec = f.next()
|
||||
except KeyError:
|
||||
if rec <> f.last():
|
||||
print 'Error, last <> last!'
|
||||
f.previous()
|
||||
break
|
||||
if verbose:
|
||||
print rec
|
||||
if not f.has_key('a'):
|
||||
print 'Error, missing key!'
|
||||
|
||||
f.sync()
|
||||
f.close()
|
||||
if verbose:
|
||||
print 'modification...'
|
||||
print 'modification...'
|
||||
f = openmethod(fname, 'w')
|
||||
f['d'] = 'discovered'
|
||||
|
||||
if verbose:
|
||||
print 'access...'
|
||||
print 'access...'
|
||||
for key in f.keys():
|
||||
word = f[key]
|
||||
if verbose:
|
||||
print word
|
||||
word = f[key]
|
||||
if verbose:
|
||||
print word
|
||||
|
||||
f.close()
|
||||
|
||||
types = [(bsddb.btopen, 'BTree'),
|
||||
(bsddb.hashopen, 'Hash Table'),
|
||||
# (bsddb.rnopen,'Record Numbers'), 'put' for RECNO for bsddb 1.85
|
||||
(bsddb.hashopen, 'Hash Table'),
|
||||
# (bsddb.rnopen,'Record Numbers'), 'put' for RECNO for bsddb 1.85
|
||||
# appears broken... at least on
|
||||
# Solaris Intel - rmasse 1/97
|
||||
]
|
||||
# Solaris Intel - rmasse 1/97
|
||||
]
|
||||
|
||||
for type in types:
|
||||
test(type[0], type[1])
|
||||
|
|
|
@ -6,27 +6,27 @@ import cmath
|
|||
from test_support import verbose
|
||||
|
||||
testdict = {'acos' : 1.0,
|
||||
'acosh' : 1.0,
|
||||
'asin' : 1.0,
|
||||
'asinh' : 1.0,
|
||||
'atan' : 0.2,
|
||||
'atanh' : 0.2,
|
||||
'cos' : 1.0,
|
||||
'cosh' : 1.0,
|
||||
'exp' : 1.0,
|
||||
'log' : 1.0,
|
||||
'log10' : 1.0,
|
||||
'sin' : 1.0,
|
||||
'sinh' : 1.0,
|
||||
'sqrt' : 1.0,
|
||||
'tan' : 1.0,
|
||||
'tanh' : 1.0}
|
||||
'acosh' : 1.0,
|
||||
'asin' : 1.0,
|
||||
'asinh' : 1.0,
|
||||
'atan' : 0.2,
|
||||
'atanh' : 0.2,
|
||||
'cos' : 1.0,
|
||||
'cosh' : 1.0,
|
||||
'exp' : 1.0,
|
||||
'log' : 1.0,
|
||||
'log10' : 1.0,
|
||||
'sin' : 1.0,
|
||||
'sinh' : 1.0,
|
||||
'sqrt' : 1.0,
|
||||
'tan' : 1.0,
|
||||
'tanh' : 1.0}
|
||||
|
||||
for func in testdict.keys():
|
||||
f = getattr(cmath, func)
|
||||
r = f(testdict[func])
|
||||
if verbose:
|
||||
print 'Calling %s(%f) = %f' % (func, testdict[func], abs(r))
|
||||
print 'Calling %s(%f) = %f' % (func, testdict[func], abs(r))
|
||||
|
||||
p = cmath.pi
|
||||
e = cmath.e
|
||||
|
|
|
@ -7,31 +7,31 @@ import errno
|
|||
from test_support import verbose
|
||||
|
||||
errors = ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', 'EADV',
|
||||
'EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADE', 'EBADF',
|
||||
'EBADFD', 'EBADMSG', 'EBADR', 'EBADRQC', 'EBADSLT',
|
||||
'EBFONT', 'EBUSY', 'ECHILD', 'ECHRNG', 'ECOMM',
|
||||
'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET',
|
||||
'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOM',
|
||||
'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN',
|
||||
'EHOSTUNREACH', 'EIDRM', 'EILSEQ', 'EINPROGRESS',
|
||||
'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR',
|
||||
'EL2HLT', 'EL2NSYNC', 'EL3HLT', 'EL3RST', 'ELIBACC',
|
||||
'ELIBBAD', 'ELIBEXEC', 'ELIBMAX', 'ELIBSCN', 'ELNRNG',
|
||||
'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'EMULTIHOP',
|
||||
'ENAMETOOLONG', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH',
|
||||
'ENFILE', 'ENOANO', 'ENOBUFS', 'ENOCSI', 'ENODATA',
|
||||
'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOLINK',
|
||||
'ENOMEM', 'ENOMSG', 'ENONET', 'ENOPKG', 'ENOPROTOOPT',
|
||||
'ENOSPC', 'ENOSR', 'ENOSTR', 'ENOSYS', 'ENOTBLK',
|
||||
'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTOBACCO', 'ENOTSOCK',
|
||||
'ENOTTY', 'ENOTUNIQ', 'ENXIO', 'EOPNOTSUPP',
|
||||
'EOVERFLOW', 'EPERM', 'EPFNOSUPPORT', 'EPIPE',
|
||||
'EPROTO', 'EPROTONOSUPPORT', 'EPROTOTYPE',
|
||||
'ERANGE', 'EREMCHG', 'EREMOTE', 'ERESTART',
|
||||
'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE',
|
||||
'ESRCH', 'ESRMNT', 'ESTALE', 'ESTRPIPE', 'ETIME',
|
||||
'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUNATCH',
|
||||
'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL']
|
||||
'EAFNOSUPPORT', 'EAGAIN', 'EALREADY', 'EBADE', 'EBADF',
|
||||
'EBADFD', 'EBADMSG', 'EBADR', 'EBADRQC', 'EBADSLT',
|
||||
'EBFONT', 'EBUSY', 'ECHILD', 'ECHRNG', 'ECOMM',
|
||||
'ECONNABORTED', 'ECONNREFUSED', 'ECONNRESET',
|
||||
'EDEADLK', 'EDEADLOCK', 'EDESTADDRREQ', 'EDOM',
|
||||
'EDQUOT', 'EEXIST', 'EFAULT', 'EFBIG', 'EHOSTDOWN',
|
||||
'EHOSTUNREACH', 'EIDRM', 'EILSEQ', 'EINPROGRESS',
|
||||
'EINTR', 'EINVAL', 'EIO', 'EISCONN', 'EISDIR',
|
||||
'EL2HLT', 'EL2NSYNC', 'EL3HLT', 'EL3RST', 'ELIBACC',
|
||||
'ELIBBAD', 'ELIBEXEC', 'ELIBMAX', 'ELIBSCN', 'ELNRNG',
|
||||
'ELOOP', 'EMFILE', 'EMLINK', 'EMSGSIZE', 'EMULTIHOP',
|
||||
'ENAMETOOLONG', 'ENETDOWN', 'ENETRESET', 'ENETUNREACH',
|
||||
'ENFILE', 'ENOANO', 'ENOBUFS', 'ENOCSI', 'ENODATA',
|
||||
'ENODEV', 'ENOENT', 'ENOEXEC', 'ENOLCK', 'ENOLINK',
|
||||
'ENOMEM', 'ENOMSG', 'ENONET', 'ENOPKG', 'ENOPROTOOPT',
|
||||
'ENOSPC', 'ENOSR', 'ENOSTR', 'ENOSYS', 'ENOTBLK',
|
||||
'ENOTCONN', 'ENOTDIR', 'ENOTEMPTY', 'ENOTOBACCO', 'ENOTSOCK',
|
||||
'ENOTTY', 'ENOTUNIQ', 'ENXIO', 'EOPNOTSUPP',
|
||||
'EOVERFLOW', 'EPERM', 'EPFNOSUPPORT', 'EPIPE',
|
||||
'EPROTO', 'EPROTONOSUPPORT', 'EPROTOTYPE',
|
||||
'ERANGE', 'EREMCHG', 'EREMOTE', 'ERESTART',
|
||||
'EROFS', 'ESHUTDOWN', 'ESOCKTNOSUPPORT', 'ESPIPE',
|
||||
'ESRCH', 'ESRMNT', 'ESTALE', 'ESTRPIPE', 'ETIME',
|
||||
'ETIMEDOUT', 'ETOOMANYREFS', 'ETXTBSY', 'EUNATCH',
|
||||
'EUSERS', 'EWOULDBLOCK', 'EXDEV', 'EXFULL']
|
||||
|
||||
#
|
||||
# This is is a wee bit bogus since the module only conditionally adds
|
||||
|
@ -40,10 +40,10 @@ errors = ['E2BIG', 'EACCES', 'EADDRINUSE', 'EADDRNOTAVAIL', 'EADV',
|
|||
#
|
||||
for error in errors:
|
||||
try:
|
||||
a = getattr(errno, error)
|
||||
a = getattr(errno, error)
|
||||
except AttributeError:
|
||||
if verbose:
|
||||
print '%s: not found' % error
|
||||
if verbose:
|
||||
print '%s: not found' % error
|
||||
else:
|
||||
if verbose:
|
||||
print '%s: %d' % (error, a)
|
||||
if verbose:
|
||||
print '%s: %d' % (error, a)
|
||||
|
|
|
@ -8,9 +8,9 @@ print '5. Built-in exceptions'
|
|||
|
||||
def r(thing):
|
||||
if type(thing) == ClassType:
|
||||
print thing.__name__
|
||||
print thing.__name__
|
||||
else:
|
||||
print thing
|
||||
print thing
|
||||
|
||||
r(AttributeError)
|
||||
import sys
|
||||
|
@ -24,14 +24,14 @@ fp.close()
|
|||
fp = open(TESTFN, 'r')
|
||||
savestdin = sys.stdin
|
||||
try:
|
||||
try:
|
||||
sys.stdin = fp
|
||||
x = raw_input()
|
||||
except EOFError:
|
||||
pass
|
||||
try:
|
||||
sys.stdin = fp
|
||||
x = raw_input()
|
||||
except EOFError:
|
||||
pass
|
||||
finally:
|
||||
sys.stdin = savestdin
|
||||
fp.close()
|
||||
sys.stdin = savestdin
|
||||
fp.close()
|
||||
|
||||
r(IOError)
|
||||
try: open('this file does not exist', 'r')
|
||||
|
@ -64,7 +64,7 @@ except NameError: pass
|
|||
r(OverflowError)
|
||||
x = 1
|
||||
try:
|
||||
while 1: x = x+x
|
||||
while 1: x = x+x
|
||||
except OverflowError: pass
|
||||
|
||||
r(RuntimeError)
|
||||
|
|
|
@ -15,14 +15,14 @@ def main(use_rgbimg=1):
|
|||
uu.decode(get_qualified_path('testrgb.uue'), 'test.rgb')
|
||||
|
||||
if use_rgbimg:
|
||||
image, width, height = getrgbimage('test.rgb')
|
||||
image, width, height = getrgbimage('test.rgb')
|
||||
else:
|
||||
image, width, height = getimage('test.rgb')
|
||||
image, width, height = getimage('test.rgb')
|
||||
|
||||
# Return the selected part of image, which should by width by height
|
||||
# in size and consist of pixels of psize bytes.
|
||||
if verbose:
|
||||
print 'crop'
|
||||
print 'crop'
|
||||
newimage = imageop.crop (image, 4, width, height, 0, 0, 1, 1)
|
||||
|
||||
# Return image scaled to size newwidth by newheight. No interpolation
|
||||
|
@ -30,7 +30,7 @@ def main(use_rgbimg=1):
|
|||
# Therefore, computer-generated images or dithered images will
|
||||
# not look nice after scaling.
|
||||
if verbose:
|
||||
print 'scale'
|
||||
print 'scale'
|
||||
scaleimage = imageop.scale(image, 4, width, height, 1, 1)
|
||||
|
||||
# Run a vertical low-pass filter over an image. It does so by computing
|
||||
|
@ -38,34 +38,34 @@ def main(use_rgbimg=1):
|
|||
# pixels. The main use of this routine is to forestall excessive flicker
|
||||
# if the image two vertically-aligned source pixels, hence the name.
|
||||
if verbose:
|
||||
print 'tovideo'
|
||||
print 'tovideo'
|
||||
videoimage = imageop.tovideo (image, 4, width, height)
|
||||
|
||||
# Convert an rgb image to an 8 bit rgb
|
||||
if verbose:
|
||||
print 'rgb2rgb8'
|
||||
print 'rgb2rgb8'
|
||||
greyimage = imageop.rgb2rgb8(image, width, height)
|
||||
|
||||
# Convert an 8 bit rgb image to a 24 bit rgb image
|
||||
if verbose:
|
||||
print 'rgb82rgb'
|
||||
print 'rgb82rgb'
|
||||
image = imageop.rgb82rgb(greyimage, width, height)
|
||||
|
||||
# Convert an rgb image to an 8 bit greyscale image
|
||||
if verbose:
|
||||
print 'rgb2grey'
|
||||
print 'rgb2grey'
|
||||
greyimage = imageop.rgb2grey(image, width, height)
|
||||
|
||||
# Convert an 8 bit greyscale image to a 24 bit rgb image
|
||||
if verbose:
|
||||
print 'grey2rgb'
|
||||
print 'grey2rgb'
|
||||
image = imageop.grey2rgb(greyimage, width, height)
|
||||
|
||||
# Convert a 8-bit deep greyscale image to a 1-bit deep image by
|
||||
# tresholding all the pixels. The resulting image is tightly packed
|
||||
# and is probably only useful as an argument to mono2grey.
|
||||
if verbose:
|
||||
print 'grey2mono'
|
||||
print 'grey2mono'
|
||||
monoimage = imageop.grey2mono (greyimage, width, height, 0)
|
||||
|
||||
# monoimage, width, height = getimage('monotest.rgb')
|
||||
|
@ -75,42 +75,42 @@ def main(use_rgbimg=1):
|
|||
# monochrome black-and-white image to greyscale pass the values 0 and
|
||||
# 255 respectively.
|
||||
if verbose:
|
||||
print 'mono2grey'
|
||||
print 'mono2grey'
|
||||
greyimage = imageop.mono2grey (monoimage, width, height, 0, 255)
|
||||
|
||||
# Convert an 8-bit greyscale image to a 1-bit monochrome image using a
|
||||
# (simple-minded) dithering algorithm.
|
||||
if verbose:
|
||||
print 'dither2mono'
|
||||
print 'dither2mono'
|
||||
monoimage = imageop.dither2mono (greyimage, width, height)
|
||||
|
||||
# Convert an 8-bit greyscale image to a 4-bit greyscale image without
|
||||
# dithering.
|
||||
if verbose:
|
||||
print 'grey2grey4'
|
||||
print 'grey2grey4'
|
||||
grey4image = imageop.grey2grey4 (greyimage, width, height)
|
||||
|
||||
# Convert an 8-bit greyscale image to a 2-bit greyscale image without
|
||||
# dithering.
|
||||
if verbose:
|
||||
print 'grey2grey2'
|
||||
print 'grey2grey2'
|
||||
grey2image = imageop.grey2grey2 (greyimage, width, height)
|
||||
|
||||
# Convert an 8-bit greyscale image to a 2-bit greyscale image with
|
||||
# dithering. As for dither2mono, the dithering algorithm is currently
|
||||
# very simple.
|
||||
if verbose:
|
||||
print 'dither2grey2'
|
||||
print 'dither2grey2'
|
||||
grey2image = imageop.dither2grey2 (greyimage, width, height)
|
||||
|
||||
# Convert a 4-bit greyscale image to an 8-bit greyscale image.
|
||||
if verbose:
|
||||
print 'grey42grey'
|
||||
print 'grey42grey'
|
||||
greyimage = imageop.grey42grey (grey4image, width, height)
|
||||
|
||||
# Convert a 2-bit greyscale image to an 8-bit greyscale image.
|
||||
if verbose:
|
||||
print 'grey22grey'
|
||||
print 'grey22grey'
|
||||
image = imageop.grey22grey (grey2image, width, height)
|
||||
|
||||
# Cleanup
|
||||
|
@ -123,12 +123,12 @@ def getrgbimage(name):
|
|||
import rgbimg
|
||||
|
||||
try:
|
||||
sizes = rgbimg.sizeofimage(name)
|
||||
sizes = rgbimg.sizeofimage(name)
|
||||
except rgbimg.error:
|
||||
name = get_qualified_path(name)
|
||||
sizes = rgbimg.sizeofimage(name)
|
||||
name = get_qualified_path(name)
|
||||
sizes = rgbimg.sizeofimage(name)
|
||||
if verbose:
|
||||
print 'rgbimg opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
print 'rgbimg opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
|
||||
image = rgbimg.longimagedata(name)
|
||||
return (image, sizes[0], sizes[1])
|
||||
|
@ -141,12 +141,12 @@ def getimage(name):
|
|||
import imgfile
|
||||
|
||||
try:
|
||||
sizes = imgfile.getsizes(name)
|
||||
sizes = imgfile.getsizes(name)
|
||||
except imgfile.error:
|
||||
name = get_qualified_path(name)
|
||||
sizes = imgfile.getsizes(name)
|
||||
name = get_qualified_path(name)
|
||||
sizes = imgfile.getsizes(name)
|
||||
if verbose:
|
||||
print 'imgfile opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
print 'imgfile opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
|
||||
image = imgfile.read(name)
|
||||
return (image, sizes[0], sizes[1])
|
||||
|
@ -157,13 +157,13 @@ def get_qualified_path(name):
|
|||
import os
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
pass
|
||||
for dir in path:
|
||||
fullname = os.path.join(dir, name)
|
||||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
fullname = os.path.join(dir, name)
|
||||
if os.path.exists(fullname):
|
||||
return fullname
|
||||
return name
|
||||
|
||||
# rgbimg (unlike imgfile) is portable to platforms other than SGI.
|
||||
|
|
|
@ -24,12 +24,12 @@ def main():
|
|||
unlink('greytest.rgb')
|
||||
|
||||
def findfile(file):
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
for dn in sys.path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
for dn in sys.path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
|
||||
def testimage(name):
|
||||
"""Run through the imgfile's battery of possible methods
|
||||
|
@ -44,23 +44,23 @@ def testimage(name):
|
|||
|
||||
# try opening the name directly
|
||||
try:
|
||||
# This function returns a tuple (x, y, z) where x and y are the size
|
||||
# of the image in pixels and z is the number of bytes per pixel. Only
|
||||
# 3 byte RGB pixels and 1 byte greyscale pixels are supported.
|
||||
sizes = imgfile.getsizes(name)
|
||||
# This function returns a tuple (x, y, z) where x and y are the size
|
||||
# of the image in pixels and z is the number of bytes per pixel. Only
|
||||
# 3 byte RGB pixels and 1 byte greyscale pixels are supported.
|
||||
sizes = imgfile.getsizes(name)
|
||||
except imgfile.error:
|
||||
# get a more qualified path component of the script...
|
||||
if __name__ == '__main__':
|
||||
ourname = sys.argv[0]
|
||||
else: # ...or the full path of the module
|
||||
ourname = sys.modules[__name__].__file__
|
||||
# get a more qualified path component of the script...
|
||||
if __name__ == '__main__':
|
||||
ourname = sys.argv[0]
|
||||
else: # ...or the full path of the module
|
||||
ourname = sys.modules[__name__].__file__
|
||||
|
||||
parts = string.splitfields(ourname, os.sep)
|
||||
parts[-1] = name
|
||||
name = string.joinfields(parts, os.sep)
|
||||
sizes = imgfile.getsizes(name)
|
||||
parts = string.splitfields(ourname, os.sep)
|
||||
parts[-1] = name
|
||||
name = string.joinfields(parts, os.sep)
|
||||
sizes = imgfile.getsizes(name)
|
||||
if verbose:
|
||||
print 'Opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
print 'Opening test image: %s, sizes: %s' % (name, str(sizes))
|
||||
# This function reads and decodes the image on the specified file,
|
||||
# and returns it as a python string. The string has either 1 byte
|
||||
# greyscale pixels or 4 byte RGBA pixels. The bottom left pixel
|
||||
|
@ -74,12 +74,12 @@ def testimage(name):
|
|||
# are stored as 4 byte values of which only the lower three
|
||||
# bytes are used). These are the formats returned by gl.lrectread.
|
||||
if verbose:
|
||||
print 'Writing output file'
|
||||
print 'Writing output file'
|
||||
imgfile.write (outputfile, image, sizes[0], sizes[1], sizes[2])
|
||||
|
||||
|
||||
if verbose:
|
||||
print 'Opening scaled test image: %s, sizes: %s' % (name, str(sizes))
|
||||
print 'Opening scaled test image: %s, sizes: %s' % (name, str(sizes))
|
||||
# This function is identical to read but it returns an image that
|
||||
# is scaled to the given x and y sizes. If the filter and blur
|
||||
# parameters are omitted scaling is done by simply dropping
|
||||
|
@ -93,7 +93,7 @@ def testimage(name):
|
|||
# makes no attempt to keep the aspect ratio correct, so that
|
||||
# is the users' responsibility.
|
||||
if verbose:
|
||||
print 'Filtering with "impulse"'
|
||||
print 'Filtering with "impulse"'
|
||||
simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'impulse', 2.0)
|
||||
|
||||
# This function sets a global flag which defines whether the
|
||||
|
@ -101,14 +101,14 @@ def testimage(name):
|
|||
# top (flag is zero, compatible with SGI GL) or from top to
|
||||
# bottom(flag is one, compatible with X). The default is zero.
|
||||
if verbose:
|
||||
print 'Switching to X compatibility'
|
||||
print 'Switching to X compatibility'
|
||||
imgfile.ttob (1)
|
||||
|
||||
if verbose:
|
||||
print 'Filtering with "triangle"'
|
||||
print 'Filtering with "triangle"'
|
||||
simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'triangle', 3.0)
|
||||
if verbose:
|
||||
print 'Switching back to SGI compatibility'
|
||||
print 'Switching back to SGI compatibility'
|
||||
imgfile.ttob (0)
|
||||
|
||||
if verbose: print 'Filtering with "quadratic"'
|
||||
|
@ -117,7 +117,7 @@ def testimage(name):
|
|||
simage = imgfile.readscaled (name, sizes[0]/2, sizes[1]/2, 'gaussian', 1.0)
|
||||
|
||||
if verbose:
|
||||
print 'Writing output file'
|
||||
print 'Writing output file'
|
||||
imgfile.write (outputfile, simage, sizes[0]/2, sizes[1]/2, sizes[2])
|
||||
|
||||
os.unlink(outputfile)
|
||||
|
|
|
@ -9,18 +9,18 @@ print 'XXX Not yet fully implemented'
|
|||
print '2.1 try inside for loop'
|
||||
n = 0
|
||||
for i in range(10):
|
||||
n = n+i
|
||||
try: 1/0
|
||||
except NameError: pass
|
||||
except ZeroDivisionError: pass
|
||||
except TypeError: pass
|
||||
try: pass
|
||||
except: pass
|
||||
try: pass
|
||||
finally: pass
|
||||
n = n+i
|
||||
n = n+i
|
||||
try: 1/0
|
||||
except NameError: pass
|
||||
except ZeroDivisionError: pass
|
||||
except TypeError: pass
|
||||
try: pass
|
||||
except: pass
|
||||
try: pass
|
||||
finally: pass
|
||||
n = n+i
|
||||
if n <> 90:
|
||||
raise TestFailed, 'try inside for'
|
||||
raise TestFailed, 'try inside for'
|
||||
|
||||
|
||||
print '2.2 raise class exceptions'
|
||||
|
@ -30,7 +30,7 @@ class BClass(AClass): pass
|
|||
class CClass: pass
|
||||
class DClass(AClass):
|
||||
def __init__(self, ignore):
|
||||
pass
|
||||
pass
|
||||
|
||||
try: raise AClass()
|
||||
except: pass
|
||||
|
@ -50,12 +50,12 @@ b = BClass()
|
|||
|
||||
try: raise AClass, b
|
||||
except BClass, v:
|
||||
if v != b: raise TestFailed
|
||||
if v != b: raise TestFailed
|
||||
else: raise TestFailed
|
||||
|
||||
try: raise b
|
||||
except AClass, v:
|
||||
if v != b: raise TestFailed
|
||||
if v != b: raise TestFailed
|
||||
|
||||
# not enough arguments
|
||||
try: raise BClass, a
|
||||
|
@ -64,7 +64,7 @@ except TypeError: pass
|
|||
try: raise DClass, a
|
||||
except DClass, v:
|
||||
if not isinstance(v, DClass):
|
||||
raise TestFailed
|
||||
raise TestFailed
|
||||
|
||||
print '2.3 comparing function objects'
|
||||
|
||||
|
|
|
@ -67,44 +67,44 @@ if verbose: print 'Running regex_tests test suite'
|
|||
for t in tests:
|
||||
pattern=s=outcome=repl=expected=None
|
||||
if len(t)==5:
|
||||
pattern, s, outcome, repl, expected = t
|
||||
pattern, s, outcome, repl, expected = t
|
||||
elif len(t)==3:
|
||||
pattern, s, outcome = t
|
||||
pattern, s, outcome = t
|
||||
else:
|
||||
raise ValueError, ('Test tuples should have 3 or 5 fields',t)
|
||||
raise ValueError, ('Test tuples should have 3 or 5 fields',t)
|
||||
|
||||
try:
|
||||
obj=regex.compile(pattern)
|
||||
obj=regex.compile(pattern)
|
||||
except regex.error:
|
||||
if outcome==SYNTAX_ERROR: pass # Expected a syntax error
|
||||
else:
|
||||
# Regex syntax errors aren't yet reported, so for
|
||||
# the official test suite they'll be quietly ignored.
|
||||
pass
|
||||
#print '=== Syntax error:', t
|
||||
if outcome==SYNTAX_ERROR: pass # Expected a syntax error
|
||||
else:
|
||||
# Regex syntax errors aren't yet reported, so for
|
||||
# the official test suite they'll be quietly ignored.
|
||||
pass
|
||||
#print '=== Syntax error:', t
|
||||
else:
|
||||
try:
|
||||
result=obj.search(s)
|
||||
except regex.error, msg:
|
||||
print '=== Unexpected exception', t, repr(msg)
|
||||
if outcome==SYNTAX_ERROR:
|
||||
# This should have been a syntax error; forget it.
|
||||
pass
|
||||
elif outcome==FAIL:
|
||||
if result==-1: pass # No match, as expected
|
||||
else: print '=== Succeeded incorrectly', t
|
||||
elif outcome==SUCCEED:
|
||||
if result!=-1:
|
||||
# Matched, as expected, so now we compute the
|
||||
# result string and compare it to our expected result.
|
||||
start, end = obj.regs[0]
|
||||
found=s[start:end]
|
||||
groups=obj.group(1,2,3,4,5,6,7,8,9,10)
|
||||
vardict=vars()
|
||||
for i in range(len(groups)):
|
||||
vardict['g'+str(i+1)]=str(groups[i])
|
||||
repl=eval(repl)
|
||||
if repl!=expected:
|
||||
print '=== grouping error', t, repr(repl)+' should be '+repr(expected)
|
||||
else:
|
||||
print '=== Failed incorrectly', t
|
||||
try:
|
||||
result=obj.search(s)
|
||||
except regex.error, msg:
|
||||
print '=== Unexpected exception', t, repr(msg)
|
||||
if outcome==SYNTAX_ERROR:
|
||||
# This should have been a syntax error; forget it.
|
||||
pass
|
||||
elif outcome==FAIL:
|
||||
if result==-1: pass # No match, as expected
|
||||
else: print '=== Succeeded incorrectly', t
|
||||
elif outcome==SUCCEED:
|
||||
if result!=-1:
|
||||
# Matched, as expected, so now we compute the
|
||||
# result string and compare it to our expected result.
|
||||
start, end = obj.regs[0]
|
||||
found=s[start:end]
|
||||
groups=obj.group(1,2,3,4,5,6,7,8,9,10)
|
||||
vardict=vars()
|
||||
for i in range(len(groups)):
|
||||
vardict['g'+str(i+1)]=str(groups[i])
|
||||
repl=eval(repl)
|
||||
if repl!=expected:
|
||||
print '=== grouping error', t, repr(repl)+' should be '+repr(expected)
|
||||
else:
|
||||
print '=== Failed incorrectly', t
|
||||
|
|
|
@ -9,32 +9,32 @@ error = 'test_rgbimg.error'
|
|||
print 'RGBimg test suite:'
|
||||
|
||||
def findfile(file):
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
for dn in path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
for dn in path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
|
||||
def testimg(rgb_file, raw_file):
|
||||
rgb_file = findfile(rgb_file)
|
||||
raw_file = findfile(raw_file)
|
||||
width, height = rgbimg.sizeofimage(rgb_file)
|
||||
rgb = rgbimg.longimagedata(rgb_file)
|
||||
if len(rgb) != width * height * 4:
|
||||
raise error, 'bad image length'
|
||||
raw = open(raw_file, 'rb').read()
|
||||
if rgb != raw:
|
||||
raise error, \
|
||||
'images don\'t match for '+rgb_file+' and '+raw_file
|
||||
for depth in [1, 3, 4]:
|
||||
rgbimg.longstoimage(rgb, width, height, depth, '@.rgb')
|
||||
os.unlink('@.rgb')
|
||||
rgb_file = findfile(rgb_file)
|
||||
raw_file = findfile(raw_file)
|
||||
width, height = rgbimg.sizeofimage(rgb_file)
|
||||
rgb = rgbimg.longimagedata(rgb_file)
|
||||
if len(rgb) != width * height * 4:
|
||||
raise error, 'bad image length'
|
||||
raw = open(raw_file, 'rb').read()
|
||||
if rgb != raw:
|
||||
raise error, \
|
||||
'images don\'t match for '+rgb_file+' and '+raw_file
|
||||
for depth in [1, 3, 4]:
|
||||
rgbimg.longstoimage(rgb, width, height, depth, '@.rgb')
|
||||
os.unlink('@.rgb')
|
||||
|
||||
table = [
|
||||
('testrgb.uue', 'test.rgb'),
|
||||
|
@ -45,7 +45,7 @@ for source, target in table:
|
|||
source = findfile(source)
|
||||
target = findfile(target)
|
||||
if verbose:
|
||||
print "uudecoding", source, "->", target, "..."
|
||||
print "uudecoding", source, "->", target, "..."
|
||||
uu.decode(source, target)
|
||||
|
||||
if verbose:
|
||||
|
@ -53,23 +53,23 @@ if verbose:
|
|||
|
||||
ttob = rgbimg.ttob(0)
|
||||
if ttob != 0:
|
||||
raise error, 'ttob should start out as zero'
|
||||
raise error, 'ttob should start out as zero'
|
||||
|
||||
testimg('test.rgb', 'test.rawimg')
|
||||
|
||||
ttob = rgbimg.ttob(1)
|
||||
if ttob != 0:
|
||||
raise error, 'ttob should be zero'
|
||||
raise error, 'ttob should be zero'
|
||||
|
||||
testimg('test.rgb', 'test.rawimg.rev')
|
||||
|
||||
ttob = rgbimg.ttob(0)
|
||||
if ttob != 1:
|
||||
raise error, 'ttob should be one'
|
||||
raise error, 'ttob should be one'
|
||||
|
||||
ttob = rgbimg.ttob(0)
|
||||
if ttob != 0:
|
||||
raise error, 'ttob should be zero'
|
||||
raise error, 'ttob should be zero'
|
||||
|
||||
for source, target in table:
|
||||
unlink(findfile(target))
|
||||
|
|
|
@ -16,7 +16,7 @@ class Nope:
|
|||
|
||||
class Almost:
|
||||
def fileno(self):
|
||||
return 'fileno'
|
||||
return 'fileno'
|
||||
|
||||
try:
|
||||
rfd, wfd, xfd = select.select([Nope()], [], [])
|
||||
|
@ -34,31 +34,31 @@ else:
|
|||
|
||||
|
||||
def test():
|
||||
import sys
|
||||
if sys.platform[:3] in ('win', 'mac', 'os2'):
|
||||
if verbose:
|
||||
print "Can't test select easily on", sys.platform
|
||||
return
|
||||
cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
|
||||
p = os.popen(cmd, 'r')
|
||||
for tout in (0, 1, 2, 4, 8, 16) + (None,)*10:
|
||||
if verbose:
|
||||
print 'timeout =', tout
|
||||
rfd, wfd, xfd = select.select([p], [], [], tout)
|
||||
## print rfd, wfd, xfd
|
||||
if (rfd, wfd, xfd) == ([], [], []):
|
||||
continue
|
||||
if (rfd, wfd, xfd) == ([p], [], []):
|
||||
line = p.readline()
|
||||
if verbose:
|
||||
print `line`
|
||||
if not line:
|
||||
if verbose:
|
||||
print 'EOF'
|
||||
break
|
||||
continue
|
||||
print 'Heh?'
|
||||
p.close()
|
||||
import sys
|
||||
if sys.platform[:3] in ('win', 'mac', 'os2'):
|
||||
if verbose:
|
||||
print "Can't test select easily on", sys.platform
|
||||
return
|
||||
cmd = 'for i in 0 1 2 3 4 5 6 7 8 9; do echo testing...; sleep 1; done'
|
||||
p = os.popen(cmd, 'r')
|
||||
for tout in (0, 1, 2, 4, 8, 16) + (None,)*10:
|
||||
if verbose:
|
||||
print 'timeout =', tout
|
||||
rfd, wfd, xfd = select.select([p], [], [], tout)
|
||||
## print rfd, wfd, xfd
|
||||
if (rfd, wfd, xfd) == ([], [], []):
|
||||
continue
|
||||
if (rfd, wfd, xfd) == ([p], [], []):
|
||||
line = p.readline()
|
||||
if verbose:
|
||||
print `line`
|
||||
if not line:
|
||||
if verbose:
|
||||
print 'EOF'
|
||||
break
|
||||
continue
|
||||
print 'Heh?'
|
||||
p.close()
|
||||
|
||||
test()
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
# Not tested:
|
||||
# socket.fromfd()
|
||||
# sktobj.getsockopt()
|
||||
# sktobj.recvfrom()
|
||||
# sktobj.sendto()
|
||||
# sktobj.setblocking()
|
||||
# sktobj.setsockopt()
|
||||
# sktobj.shutdown()
|
||||
# socket.fromfd()
|
||||
# sktobj.getsockopt()
|
||||
# sktobj.recvfrom()
|
||||
# sktobj.sendto()
|
||||
# sktobj.setblocking()
|
||||
# sktobj.setsockopt()
|
||||
# sktobj.shutdown()
|
||||
|
||||
|
||||
from test_support import verbose, TestFailed
|
||||
|
@ -16,9 +16,9 @@ import string
|
|||
|
||||
def missing_ok(str):
|
||||
try:
|
||||
getattr(socket, str)
|
||||
getattr(socket, str)
|
||||
except AttributeError:
|
||||
pass
|
||||
pass
|
||||
|
||||
try: raise socket.error
|
||||
except socket.error: print "socket.error"
|
||||
|
@ -33,37 +33,37 @@ socket.SOCK_SEQPACKET
|
|||
|
||||
for optional in ("AF_UNIX",
|
||||
|
||||
"SO_DEBUG", "SO_ACCEPTCONN", "SO_REUSEADDR", "SO_KEEPALIVE",
|
||||
"SO_DONTROUTE", "SO_BROADCAST", "SO_USELOOPBACK", "SO_LINGER",
|
||||
"SO_OOBINLINE", "SO_REUSEPORT", "SO_SNDBUF", "SO_RCVBUF",
|
||||
"SO_SNDLOWAT", "SO_RCVLOWAT", "SO_SNDTIMEO", "SO_RCVTIMEO",
|
||||
"SO_ERROR", "SO_TYPE", "SOMAXCONN",
|
||||
"SO_DEBUG", "SO_ACCEPTCONN", "SO_REUSEADDR", "SO_KEEPALIVE",
|
||||
"SO_DONTROUTE", "SO_BROADCAST", "SO_USELOOPBACK", "SO_LINGER",
|
||||
"SO_OOBINLINE", "SO_REUSEPORT", "SO_SNDBUF", "SO_RCVBUF",
|
||||
"SO_SNDLOWAT", "SO_RCVLOWAT", "SO_SNDTIMEO", "SO_RCVTIMEO",
|
||||
"SO_ERROR", "SO_TYPE", "SOMAXCONN",
|
||||
|
||||
"MSG_OOB", "MSG_PEEK", "MSG_DONTROUTE", "MSG_EOR",
|
||||
"MSG_TRUNC", "MSG_CTRUNC", "MSG_WAITALL", "MSG_BTAG",
|
||||
"MSG_ETAG",
|
||||
"MSG_OOB", "MSG_PEEK", "MSG_DONTROUTE", "MSG_EOR",
|
||||
"MSG_TRUNC", "MSG_CTRUNC", "MSG_WAITALL", "MSG_BTAG",
|
||||
"MSG_ETAG",
|
||||
|
||||
"SOL_SOCKET",
|
||||
"SOL_SOCKET",
|
||||
|
||||
"IPPROTO_IP", "IPPROTO_ICMP", "IPPROTO_IGMP",
|
||||
"IPPROTO_GGP", "IPPROTO_TCP", "IPPROTO_EGP",
|
||||
"IPPROTO_PUP", "IPPROTO_UDP", "IPPROTO_IDP",
|
||||
"IPPROTO_HELLO", "IPPROTO_ND", "IPPROTO_TP",
|
||||
"IPPROTO_XTP", "IPPROTO_EON", "IPPROTO_BIP",
|
||||
"IPPROTO_RAW", "IPPROTO_MAX",
|
||||
"IPPROTO_IP", "IPPROTO_ICMP", "IPPROTO_IGMP",
|
||||
"IPPROTO_GGP", "IPPROTO_TCP", "IPPROTO_EGP",
|
||||
"IPPROTO_PUP", "IPPROTO_UDP", "IPPROTO_IDP",
|
||||
"IPPROTO_HELLO", "IPPROTO_ND", "IPPROTO_TP",
|
||||
"IPPROTO_XTP", "IPPROTO_EON", "IPPROTO_BIP",
|
||||
"IPPROTO_RAW", "IPPROTO_MAX",
|
||||
|
||||
"IPPORT_RESERVED", "IPPORT_USERRESERVED",
|
||||
"IPPORT_RESERVED", "IPPORT_USERRESERVED",
|
||||
|
||||
"INADDR_ANY", "INADDR_BROADCAST", "INADDR_LOOPBACK",
|
||||
"INADDR_UNSPEC_GROUP", "INADDR_ALLHOSTS_GROUP",
|
||||
"INADDR_MAX_LOCAL_GROUP", "INADDR_NONE",
|
||||
"INADDR_ANY", "INADDR_BROADCAST", "INADDR_LOOPBACK",
|
||||
"INADDR_UNSPEC_GROUP", "INADDR_ALLHOSTS_GROUP",
|
||||
"INADDR_MAX_LOCAL_GROUP", "INADDR_NONE",
|
||||
|
||||
"IP_OPTIONS", "IP_HDRINCL", "IP_TOS", "IP_TTL",
|
||||
"IP_RECVOPTS", "IP_RECVRETOPTS", "IP_RECVDSTADDR",
|
||||
"IP_RETOPTS", "IP_MULTICAST_IF", "IP_MULTICAST_TTL",
|
||||
"IP_MULTICAST_LOOP", "IP_ADD_MEMBERSHIP",
|
||||
"IP_DROP_MEMBERSHIP",
|
||||
):
|
||||
"IP_OPTIONS", "IP_HDRINCL", "IP_TOS", "IP_TTL",
|
||||
"IP_RECVOPTS", "IP_RECVRETOPTS", "IP_RECVDSTADDR",
|
||||
"IP_RETOPTS", "IP_MULTICAST_IF", "IP_MULTICAST_TTL",
|
||||
"IP_MULTICAST_LOOP", "IP_ADD_MEMBERSHIP",
|
||||
"IP_DROP_MEMBERSHIP",
|
||||
):
|
||||
missing_ok(optional)
|
||||
|
||||
socktype = socket.SocketType
|
||||
|
@ -80,7 +80,7 @@ if verbose:
|
|||
|
||||
for name in all_host_names:
|
||||
if string.find(name, '.'):
|
||||
break
|
||||
break
|
||||
else:
|
||||
print 'FQDN not found'
|
||||
|
||||
|
@ -95,52 +95,52 @@ canfork = hasattr(os, 'fork')
|
|||
try:
|
||||
PORT = 50007
|
||||
if not canfork or os.fork():
|
||||
# parent is server
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind(hostname, PORT)
|
||||
s.listen(1)
|
||||
if verbose:
|
||||
print 'parent accepting'
|
||||
if canfork:
|
||||
conn, addr = s.accept()
|
||||
if verbose:
|
||||
print 'connected by', addr
|
||||
# couple of interesting tests while we've got a live socket
|
||||
f = conn.fileno()
|
||||
if verbose:
|
||||
print 'fileno:', f
|
||||
p = conn.getpeername()
|
||||
if verbose:
|
||||
print 'peer:', p
|
||||
n = conn.getsockname()
|
||||
if verbose:
|
||||
print 'sockname:', n
|
||||
f = conn.makefile()
|
||||
if verbose:
|
||||
print 'file obj:', f
|
||||
while 1:
|
||||
data = conn.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
if verbose:
|
||||
print 'received:', data
|
||||
conn.send(data)
|
||||
conn.close()
|
||||
# parent is server
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.bind(hostname, PORT)
|
||||
s.listen(1)
|
||||
if verbose:
|
||||
print 'parent accepting'
|
||||
if canfork:
|
||||
conn, addr = s.accept()
|
||||
if verbose:
|
||||
print 'connected by', addr
|
||||
# couple of interesting tests while we've got a live socket
|
||||
f = conn.fileno()
|
||||
if verbose:
|
||||
print 'fileno:', f
|
||||
p = conn.getpeername()
|
||||
if verbose:
|
||||
print 'peer:', p
|
||||
n = conn.getsockname()
|
||||
if verbose:
|
||||
print 'sockname:', n
|
||||
f = conn.makefile()
|
||||
if verbose:
|
||||
print 'file obj:', f
|
||||
while 1:
|
||||
data = conn.recv(1024)
|
||||
if not data:
|
||||
break
|
||||
if verbose:
|
||||
print 'received:', data
|
||||
conn.send(data)
|
||||
conn.close()
|
||||
else:
|
||||
try:
|
||||
# child is client
|
||||
time.sleep(5)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
if verbose:
|
||||
print 'child connecting'
|
||||
s.connect(hostname, PORT)
|
||||
msg = 'socket test'
|
||||
s.send(msg)
|
||||
data = s.recv(1024)
|
||||
if msg <> data:
|
||||
print 'parent/client mismatch'
|
||||
s.close()
|
||||
finally:
|
||||
os._exit(1)
|
||||
try:
|
||||
# child is client
|
||||
time.sleep(5)
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
if verbose:
|
||||
print 'child connecting'
|
||||
s.connect(hostname, PORT)
|
||||
msg = 'socket test'
|
||||
s.send(msg)
|
||||
data = s.recv(1024)
|
||||
if msg <> data:
|
||||
print 'parent/client mismatch'
|
||||
s.close()
|
||||
finally:
|
||||
os._exit(1)
|
||||
except socket.error, msg:
|
||||
raise TestFailed, msg
|
||||
|
|
|
@ -3,19 +3,19 @@ import strop, sys
|
|||
|
||||
def test(name, input, output, *args):
|
||||
if verbose:
|
||||
print 'string.%s%s =? %s... ' % (name, (input,) + args, output),
|
||||
print 'string.%s%s =? %s... ' % (name, (input,) + args, output),
|
||||
f = getattr(strop, name)
|
||||
try:
|
||||
value = apply(f, (input,) + args)
|
||||
value = apply(f, (input,) + args)
|
||||
except:
|
||||
value = sys.exc_type
|
||||
value = sys.exc_type
|
||||
if value != output:
|
||||
if verbose:
|
||||
print 'no'
|
||||
print f, `input`, `output`, `value`
|
||||
if verbose:
|
||||
print 'no'
|
||||
print f, `input`, `output`, `value`
|
||||
else:
|
||||
if verbose:
|
||||
print 'yes'
|
||||
if verbose:
|
||||
print 'yes'
|
||||
|
||||
test('atoi', " 1 ", 1)
|
||||
test('atoi', " 1x", ValueError)
|
||||
|
|
|
@ -3,24 +3,29 @@ import sunaudiodev
|
|||
import os
|
||||
|
||||
def findfile(file):
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
for dn in sys.path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
if os.path.isabs(file): return file
|
||||
import sys
|
||||
path = sys.path
|
||||
try:
|
||||
path = [os.path.dirname(__file__)] + path
|
||||
except NameError:
|
||||
pass
|
||||
for dn in path:
|
||||
fn = os.path.join(dn, file)
|
||||
if os.path.exists(fn): return fn
|
||||
return file
|
||||
|
||||
def play_sound_file(path):
|
||||
fp = open(path, 'r')
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
try:
|
||||
a = sunaudiodev.open('w')
|
||||
a = sunaudiodev.open('w')
|
||||
except sunaudiodev.error, msg:
|
||||
raise TestFailed, msg
|
||||
raise TestFailed, msg
|
||||
else:
|
||||
a.write(data)
|
||||
a.close()
|
||||
a.write(data)
|
||||
a.close()
|
||||
|
||||
def test():
|
||||
play_sound_file(findfile('audiotest.au'))
|
||||
|
|
|
@ -14,13 +14,13 @@ if long(time.mktime(time.localtime(t))) <> long(t):
|
|||
time.sleep(1.2)
|
||||
tt = time.gmtime(t)
|
||||
for directive in ('a', 'A', 'b', 'B', 'c', 'd', 'H', 'I',
|
||||
'j', 'm', 'M', 'p', 'S',
|
||||
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
|
||||
'j', 'm', 'M', 'p', 'S',
|
||||
'U', 'w', 'W', 'x', 'X', 'y', 'Y', 'Z', '%'):
|
||||
format = ' %' + directive
|
||||
try:
|
||||
time.strftime(format, tt)
|
||||
time.strftime(format, tt)
|
||||
except ValueError:
|
||||
print 'conversion specifier:', format, ' failed.'
|
||||
print 'conversion specifier:', format, ' failed.'
|
||||
|
||||
time.timezone
|
||||
time.tzname
|
||||
|
@ -33,7 +33,7 @@ except TypeError:
|
|||
|
||||
try:
|
||||
time.mktime((999999, 999999, 999999, 999999,
|
||||
999999, 999999, 999999, 999999,
|
||||
999999))
|
||||
999999, 999999, 999999, 999999,
|
||||
999999))
|
||||
except OverflowError:
|
||||
pass
|
||||
|
|
|
@ -161,6 +161,11 @@ if a <> [-2,-1,0,1,2]: raise TestFailed, 'list sort'
|
|||
def revcmp(a, b): return cmp(b, a)
|
||||
a.sort(revcmp)
|
||||
if a <> [2,1,0,-1,-2]: raise TestFailed, 'list sort with cmp func'
|
||||
# The following dumps core in unpatched Python 1.5:
|
||||
def myComparison(x,y):
|
||||
return cmp(x%3, y%7)
|
||||
z = range(12)
|
||||
z.sort(myComparison)
|
||||
|
||||
print '6.6 Mappings == Dictionaries'
|
||||
d = {}
|
||||
|
|
|
@ -5,8 +5,8 @@ l = [4, 5, 6]
|
|||
|
||||
class Seq:
|
||||
def __getitem__(self, i):
|
||||
if i >= 0 and i < 3: return i
|
||||
raise IndexError
|
||||
if i >= 0 and i < 3: return i
|
||||
raise IndexError
|
||||
|
||||
a = -1
|
||||
b = -1
|
||||
|
@ -104,12 +104,12 @@ BozoError = 'BozoError'
|
|||
|
||||
class BadSeq:
|
||||
def __getitem__(self, i):
|
||||
if i >= 0 and i < 3:
|
||||
return i
|
||||
elif i == 3:
|
||||
raise BozoError
|
||||
else:
|
||||
raise IndexError
|
||||
if i >= 0 and i < 3:
|
||||
return i
|
||||
elif i == 3:
|
||||
raise BozoError
|
||||
else:
|
||||
raise IndexError
|
||||
|
||||
|
||||
# trigger code while not expecting an IndexError
|
||||
|
|
25
Lib/dos-8x3/test_xml.py
Normal file
25
Lib/dos-8x3/test_xml.py
Normal file
|
@ -0,0 +1,25 @@
|
|||
'''Test module to thest the xmllib module.
|
||||
Sjoerd Mullender
|
||||
'''
|
||||
|
||||
from test_support import verbose
|
||||
|
||||
testdoc = """\
|
||||
<?xml version="1.0" encoding="UTF-8" standalone='yes' ?>
|
||||
<!-- comments aren't allowed before the <?xml?> tag,
|
||||
but they are allowed before the <!DOCTYPE> tag -->
|
||||
<!DOCTYPE greeting [
|
||||
<!ELEMENT greeting (#PCDATA)>
|
||||
]>
|
||||
<greeting>Hello, world!</greeting>
|
||||
"""
|
||||
|
||||
import xmllib
|
||||
if verbose:
|
||||
parser = xmllib.TestXMLParser()
|
||||
else:
|
||||
parser = xmllib.XMLParser()
|
||||
|
||||
for c in testdoc:
|
||||
parser.feed(c)
|
||||
parser.close()
|
|
@ -87,6 +87,8 @@ def format_exception(etype, value, tb, limit = None):
|
|||
if tb:
|
||||
list = ['Traceback (innermost last):\n']
|
||||
list = list + format_tb(tb, limit)
|
||||
else:
|
||||
list = []
|
||||
list = list + format_exception_only(etype, value)
|
||||
return list
|
||||
|
||||
|
@ -186,9 +188,13 @@ def extract_stack(f=None, limit = None):
|
|||
# with -O on).
|
||||
# Coded by Marc-Andre Lemburg from the example of PyCode_Addr2Line()
|
||||
# in compile.c.
|
||||
# Revised version by Jim Hugunin to work with JPython too.
|
||||
|
||||
def tb_lineno(tb):
|
||||
c = tb.tb_frame.f_code
|
||||
if not hasattr(c, 'co_lnotab'):
|
||||
return tb.tb_lineno
|
||||
|
||||
tab = c.co_lnotab
|
||||
line = c.co_firstlineno
|
||||
stopat = tb.tb_lasti
|
||||
|
|
|
@ -4,30 +4,30 @@ class UserDict:
|
|||
def __init__(self): self.data = {}
|
||||
def __repr__(self): return repr(self.data)
|
||||
def __cmp__(self, dict):
|
||||
if type(dict) == type(self.data):
|
||||
return cmp(self.data, dict)
|
||||
else:
|
||||
return cmp(self.data, dict.data)
|
||||
if type(dict) == type(self.data):
|
||||
return cmp(self.data, dict)
|
||||
else:
|
||||
return cmp(self.data, dict.data)
|
||||
def __len__(self): return len(self.data)
|
||||
def __getitem__(self, key): return self.data[key]
|
||||
def __setitem__(self, key, item): self.data[key] = item
|
||||
def __delitem__(self, key): del self.data[key]
|
||||
def clear(self): return self.data.clear()
|
||||
def copy(self):
|
||||
import copy
|
||||
return copy.copy(self)
|
||||
import copy
|
||||
return copy.copy(self)
|
||||
def keys(self): return self.data.keys()
|
||||
def items(self): return self.data.items()
|
||||
def values(self): return self.data.values()
|
||||
def has_key(self, key): return self.data.has_key(key)
|
||||
def update(self, other):
|
||||
if type(other) is type(self.data):
|
||||
self.data.update(other)
|
||||
else:
|
||||
for k, v in other.items():
|
||||
self.data[k] = v
|
||||
if type(other) is type(self.data):
|
||||
self.data.update(other)
|
||||
else:
|
||||
for k, v in other.items():
|
||||
self.data[k] = v
|
||||
def get(self, key, failobj=None):
|
||||
if self.data.has_key(key):
|
||||
return self.data[key]
|
||||
else:
|
||||
return failobj
|
||||
if self.data.has_key(key):
|
||||
return self.data[key]
|
||||
else:
|
||||
return failobj
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue