From 56baca328f7c018c4ae776dd87f44a145f502773 Mon Sep 17 00:00:00 2001 From: Guido van Rossum Date: Mon, 13 Nov 2000 17:11:45 +0000 Subject: Removing DOS 8x3 support --- Lib/dos-8x3/basehttp.py | 482 -------------------------------- Lib/dos-8x3/bastion.py | 174 ------------ Lib/dos-8x3/cgihttps.py | 305 -------------------- Lib/dos-8x3/compilea.py | 128 --------- Lib/dos-8x3/configpa.py | 469 ------------------------------- Lib/dos-8x3/cookie.py | 726 ------------------------------------------------ Lib/dos-8x3/fileinpu.py | 268 ------------------ Lib/dos-8x3/formatte.py | 422 ---------------------------- Lib/dos-8x3/gopherli.py | 208 -------------- Lib/dos-8x3/htmlenti.py | 257 ----------------- Lib/dos-8x3/linecach.py | 92 ------ Lib/dos-8x3/macurl2p.py | 94 ------- Lib/dos-8x3/mimetool.py | 229 --------------- Lib/dos-8x3/mimetype.py | 237 ---------------- Lib/dos-8x3/mimewrit.py | 128 --------- Lib/dos-8x3/multifil.py | 164 ----------- Lib/dos-8x3/nturl2pa.py | 66 ----- Lib/dos-8x3/posixfil.py | 229 --------------- Lib/dos-8x3/posixpat.py | 368 ------------------------ Lib/dos-8x3/py_compi.py | 80 ------ Lib/dos-8x3/queue.py | 138 --------- Lib/dos-8x3/reconver.py | 186 ------------- Lib/dos-8x3/regex_sy.py | 53 ---- Lib/dos-8x3/regex_te.py | 289 ------------------- Lib/dos-8x3/rlcomple.py | 120 -------- Lib/dos-8x3/robotpar.py | 97 ------- Lib/dos-8x3/simpleht.py | 198 ------------- Lib/dos-8x3/socketse.py | 447 ----------------------------- Lib/dos-8x3/sre_comp.py | 381 ------------------------- Lib/dos-8x3/sre_cons.py | 228 --------------- Lib/dos-8x3/sre_pars.py | 682 --------------------------------------------- Lib/dos-8x3/statcach.py | 75 ----- Lib/dos-8x3/string_t.py | 202 -------------- Lib/dos-8x3/stringio.py | 193 ------------- Lib/dos-8x3/stringol.py | 431 ---------------------------- Lib/dos-8x3/telnetli.py | 503 --------------------------------- Lib/dos-8x3/test_arr.py | 188 ------------- Lib/dos-8x3/test_ate.py | 24 -- Lib/dos-8x3/test_aud.py | 264 ------------------ Lib/dos-8x3/test_aug.py | 232 ---------------- Lib/dos-8x3/test_bin.py | 112 -------- Lib/dos-8x3/test_bsd.py | 74 ----- Lib/dos-8x3/test_bui.py | 13 - Lib/dos-8x3/test_cfg.py | 141 ---------- Lib/dos-8x3/test_cla.py | 219 --------------- Lib/dos-8x3/test_cma.py | 35 --- Lib/dos-8x3/test_com.py | 16 -- Lib/dos-8x3/test_con.py | 168 ----------- Lib/dos-8x3/test_coo.py | 40 --- Lib/dos-8x3/test_cop.py | 35 --- Lib/dos-8x3/test_cpi.py | 5 - Lib/dos-8x3/test_cry.py | 11 - Lib/dos-8x3/test_dos.py | 49 ---- Lib/dos-8x3/test_err.py | 49 ---- Lib/dos-8x3/test_exc.py | 170 ------------ Lib/dos-8x3/test_ext.py | 146 ---------- Lib/dos-8x3/test_fcn.py | 36 --- Lib/dos-8x3/test_fil.py | 45 --- Lib/dos-8x3/test_for.py | 78 ------ Lib/dos-8x3/test_gdb.py | 40 --- Lib/dos-8x3/test_get.py | 101 ------- Lib/dos-8x3/test_gra.py | 649 ------------------------------------------- Lib/dos-8x3/test_gzi.py | 54 ---- Lib/dos-8x3/test_has.py | 26 -- Lib/dos-8x3/test_ima.py | 171 ------------ Lib/dos-8x3/test_img.py | 117 -------- Lib/dos-8x3/test_imp.py | 44 --- Lib/dos-8x3/test_lar.py | 129 --------- Lib/dos-8x3/test_lin.py | 89 ------ Lib/dos-8x3/test_lon.py | 260 ----------------- Lib/dos-8x3/test_mat.py | 195 ------------- Lib/dos-8x3/test_mim.py | 170 ------------ Lib/dos-8x3/test_min.py | 413 --------------------------- Lib/dos-8x3/test_mma.py | 121 -------- Lib/dos-8x3/test_ntp.py | 51 ---- Lib/dos-8x3/test_opc.py | 101 ------- Lib/dos-8x3/test_ope.py | 22 -- Lib/dos-8x3/test_par.py | 178 ------------ Lib/dos-8x3/test_pic.py | 143 ---------- Lib/dos-8x3/test_pol.py | 172 ------------ Lib/dos-8x3/test_pop.py | 65 ----- Lib/dos-8x3/test_pos.py | 42 --- Lib/dos-8x3/test_pye.py | 152 ---------- Lib/dos-8x3/test_reg.py | 110 -------- Lib/dos-8x3/test_rfc.py | 126 --------- Lib/dos-8x3/test_rgb.py | 63 ----- Lib/dos-8x3/test_rot.py | 28 -- Lib/dos-8x3/test_sel.py | 63 ----- Lib/dos-8x3/test_sig.py | 66 ----- Lib/dos-8x3/test_soc.py | 146 ---------- Lib/dos-8x3/test_str.py | 37 --- Lib/dos-8x3/test_sun.py | 20 -- Lib/dos-8x3/test_sup.py | 73 ----- Lib/dos-8x3/test_thr.py | 113 -------- Lib/dos-8x3/test_tim.py | 39 --- Lib/dos-8x3/test_tok.py | 10 - Lib/dos-8x3/test_typ.py | 267 ------------------ Lib/dos-8x3/test_uni.py | 518 ---------------------------------- Lib/dos-8x3/test_unp.py | 144 ---------- Lib/dos-8x3/test_url.py | 32 --- Lib/dos-8x3/test_use.py | 101 ------- Lib/dos-8x3/test_wav.py | 34 --- Lib/dos-8x3/test_win.py | 147 ---------- Lib/dos-8x3/test_xml.py | 25 -- Lib/dos-8x3/test_zip.py | 26 -- Lib/dos-8x3/test_zli.py | 161 ----------- Lib/dos-8x3/threadin.py | 631 ----------------------------------------- Lib/dos-8x3/tokenize.py | 161 ----------- Lib/dos-8x3/tracebac.py | 274 ------------------ Lib/dos-8x3/userdict.py | 40 --- Lib/dos-8x3/userlist.py | 79 ------ Lib/dos-8x3/userstri.py | 171 ------------ Lib/dos-8x3/webbrows.py | 225 --------------- 113 files changed, 18934 deletions(-) delete mode 100755 Lib/dos-8x3/basehttp.py delete mode 100755 Lib/dos-8x3/bastion.py delete mode 100755 Lib/dos-8x3/cgihttps.py delete mode 100755 Lib/dos-8x3/compilea.py delete mode 100644 Lib/dos-8x3/configpa.py delete mode 100644 Lib/dos-8x3/cookie.py delete mode 100644 Lib/dos-8x3/fileinpu.py delete mode 100755 Lib/dos-8x3/formatte.py delete mode 100755 Lib/dos-8x3/gopherli.py delete mode 100755 Lib/dos-8x3/htmlenti.py delete mode 100755 Lib/dos-8x3/linecach.py delete mode 100755 Lib/dos-8x3/macurl2p.py delete mode 100755 Lib/dos-8x3/mimetool.py delete mode 100644 Lib/dos-8x3/mimetype.py delete mode 100644 Lib/dos-8x3/mimewrit.py delete mode 100755 Lib/dos-8x3/multifil.py delete mode 100755 Lib/dos-8x3/nturl2pa.py delete mode 100755 Lib/dos-8x3/posixfil.py delete mode 100755 Lib/dos-8x3/posixpat.py delete mode 100755 Lib/dos-8x3/py_compi.py delete mode 100755 Lib/dos-8x3/queue.py delete mode 100644 Lib/dos-8x3/reconver.py delete mode 100755 Lib/dos-8x3/regex_sy.py delete mode 100644 Lib/dos-8x3/regex_te.py delete mode 100644 Lib/dos-8x3/rlcomple.py delete mode 100644 Lib/dos-8x3/robotpar.py delete mode 100755 Lib/dos-8x3/simpleht.py delete mode 100755 Lib/dos-8x3/socketse.py delete mode 100644 Lib/dos-8x3/sre_comp.py delete mode 100644 Lib/dos-8x3/sre_cons.py delete mode 100644 Lib/dos-8x3/sre_pars.py delete mode 100755 Lib/dos-8x3/statcach.py delete mode 100644 Lib/dos-8x3/string_t.py delete mode 100755 Lib/dos-8x3/stringio.py delete mode 100644 Lib/dos-8x3/stringol.py delete mode 100644 Lib/dos-8x3/telnetli.py delete mode 100644 Lib/dos-8x3/test_arr.py delete mode 100644 Lib/dos-8x3/test_ate.py delete mode 100755 Lib/dos-8x3/test_aud.py delete mode 100644 Lib/dos-8x3/test_aug.py delete mode 100644 Lib/dos-8x3/test_bin.py delete mode 100644 Lib/dos-8x3/test_bsd.py delete mode 100755 Lib/dos-8x3/test_bui.py delete mode 100644 Lib/dos-8x3/test_cfg.py delete mode 100644 Lib/dos-8x3/test_cla.py delete mode 100644 Lib/dos-8x3/test_cma.py delete mode 100644 Lib/dos-8x3/test_com.py delete mode 100644 Lib/dos-8x3/test_con.py delete mode 100644 Lib/dos-8x3/test_coo.py delete mode 100644 Lib/dos-8x3/test_cop.py delete mode 100644 Lib/dos-8x3/test_cpi.py delete mode 100644 Lib/dos-8x3/test_cry.py delete mode 100644 Lib/dos-8x3/test_dos.py delete mode 100644 Lib/dos-8x3/test_err.py delete mode 100755 Lib/dos-8x3/test_exc.py delete mode 100644 Lib/dos-8x3/test_ext.py delete mode 100644 Lib/dos-8x3/test_fcn.py delete mode 100644 Lib/dos-8x3/test_fil.py delete mode 100644 Lib/dos-8x3/test_for.py delete mode 100644 Lib/dos-8x3/test_gdb.py delete mode 100644 Lib/dos-8x3/test_get.py delete mode 100755 Lib/dos-8x3/test_gra.py delete mode 100644 Lib/dos-8x3/test_gzi.py delete mode 100644 Lib/dos-8x3/test_has.py delete mode 100644 Lib/dos-8x3/test_ima.py delete mode 100644 Lib/dos-8x3/test_img.py delete mode 100644 Lib/dos-8x3/test_imp.py delete mode 100644 Lib/dos-8x3/test_lar.py delete mode 100644 Lib/dos-8x3/test_lin.py delete mode 100644 Lib/dos-8x3/test_lon.py delete mode 100644 Lib/dos-8x3/test_mat.py delete mode 100644 Lib/dos-8x3/test_mim.py delete mode 100644 Lib/dos-8x3/test_min.py delete mode 100644 Lib/dos-8x3/test_mma.py delete mode 100644 Lib/dos-8x3/test_ntp.py delete mode 100755 Lib/dos-8x3/test_opc.py delete mode 100755 Lib/dos-8x3/test_ope.py delete mode 100644 Lib/dos-8x3/test_par.py delete mode 100644 Lib/dos-8x3/test_pic.py delete mode 100644 Lib/dos-8x3/test_pol.py delete mode 100644 Lib/dos-8x3/test_pop.py delete mode 100644 Lib/dos-8x3/test_pos.py delete mode 100644 Lib/dos-8x3/test_pye.py delete mode 100644 Lib/dos-8x3/test_reg.py delete mode 100644 Lib/dos-8x3/test_rfc.py delete mode 100755 Lib/dos-8x3/test_rgb.py delete mode 100644 Lib/dos-8x3/test_rot.py delete mode 100755 Lib/dos-8x3/test_sel.py delete mode 100755 Lib/dos-8x3/test_sig.py delete mode 100644 Lib/dos-8x3/test_soc.py delete mode 100644 Lib/dos-8x3/test_str.py delete mode 100644 Lib/dos-8x3/test_sun.py delete mode 100755 Lib/dos-8x3/test_sup.py delete mode 100755 Lib/dos-8x3/test_thr.py delete mode 100644 Lib/dos-8x3/test_tim.py delete mode 100644 Lib/dos-8x3/test_tok.py delete mode 100755 Lib/dos-8x3/test_typ.py delete mode 100644 Lib/dos-8x3/test_uni.py delete mode 100644 Lib/dos-8x3/test_unp.py delete mode 100644 Lib/dos-8x3/test_url.py delete mode 100644 Lib/dos-8x3/test_use.py delete mode 100644 Lib/dos-8x3/test_wav.py delete mode 100644 Lib/dos-8x3/test_win.py delete mode 100644 Lib/dos-8x3/test_xml.py delete mode 100644 Lib/dos-8x3/test_zip.py delete mode 100644 Lib/dos-8x3/test_zli.py delete mode 100644 Lib/dos-8x3/threadin.py delete mode 100644 Lib/dos-8x3/tokenize.py delete mode 100755 Lib/dos-8x3/tracebac.py delete mode 100755 Lib/dos-8x3/userdict.py delete mode 100755 Lib/dos-8x3/userlist.py delete mode 100644 Lib/dos-8x3/userstri.py delete mode 100644 Lib/dos-8x3/webbrows.py diff --git a/Lib/dos-8x3/basehttp.py b/Lib/dos-8x3/basehttp.py deleted file mode 100755 index 49f8984..0000000 --- a/Lib/dos-8x3/basehttp.py +++ /dev/null @@ -1,482 +0,0 @@ -"""HTTP server base class. - -Note: the class in this module doesn't implement any HTTP request; see -SimpleHTTPServer for simple implementations of GET, HEAD and POST -(including CGI scripts). - -Contents: - -- BaseHTTPRequestHandler: HTTP request handler base class -- test: test function - -XXX To do: - -- send server version -- log requests even later (to capture byte count) -- log user-agent header and other interesting goodies -- send error log to separate file -- are request names really case sensitive? - -""" - - -# See also: -# -# HTTP Working Group T. Berners-Lee -# INTERNET-DRAFT R. T. Fielding -# H. Frystyk Nielsen -# Expires September 8, 1995 March 8, 1995 -# -# URL: http://www.ics.uci.edu/pub/ietf/http/draft-ietf-http-v10-spec-00.txt - - -# Log files -# --------- -# -# Here's a quote from the NCSA httpd docs about log file format. -# -# | The logfile format is as follows. Each line consists of: -# | -# | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb -# | -# | host: Either the DNS name or the IP number of the remote client -# | rfc931: Any information returned by identd for this person, -# | - otherwise. -# | authuser: If user sent a userid for authentication, the user name, -# | - otherwise. -# | DD: Day -# | Mon: Month (calendar name) -# | YYYY: Year -# | hh: hour (24-hour format, the machine's timezone) -# | mm: minutes -# | ss: seconds -# | request: The first line of the HTTP request as sent by the client. -# | ddd: the status code returned by the server, - if not available. -# | bbbb: the total number of bytes sent, -# | *not including the HTTP/1.0 header*, - if not available -# | -# | You can determine the name of the file accessed through request. -# -# (Actually, the latter is only true if you know the server configuration -# at the time the request was made!) - - -__version__ = "0.2" - - -import sys -import time -import socket # For gethostbyaddr() -import string -import mimetools -import SocketServer - -# Default error message -DEFAULT_ERROR_MESSAGE = """\ - -Error response - - -

Error response

-

Error code %(code)d. -

Message: %(message)s. -

Error code explanation: %(code)s = %(explain)s. - -""" - - -class HTTPServer(SocketServer.TCPServer): - - allow_reuse_address = 1 # Seems to make sense in testing environment - - def server_bind(self): - """Override server_bind to store the server name.""" - SocketServer.TCPServer.server_bind(self) - host, port = self.socket.getsockname() - self.server_name = socket.getfqdn(host) - self.server_port = port - - -class BaseHTTPRequestHandler(SocketServer.StreamRequestHandler): - - """HTTP request handler base class. - - The following explanation of HTTP serves to guide you through the - code as well as to expose any misunderstandings I may have about - HTTP (so you don't need to read the code to figure out I'm wrong - :-). - - HTTP (HyperText Transfer Protocol) is an extensible protocol on - top of a reliable stream transport (e.g. TCP/IP). The protocol - recognizes three parts to a request: - - 1. One line identifying the request type and path - 2. An optional set of RFC-822-style headers - 3. An optional data part - - The headers and data are separated by a blank line. - - The first line of the request has the form - - - - where is a (case-sensitive) keyword such as GET or POST, - is a string containing path information for the request, - and should be the string "HTTP/1.0". is encoded - using the URL encoding scheme (using %xx to signify the ASCII - character with hex code xx). - - The protocol is vague about whether lines are separated by LF - characters or by CRLF pairs -- for compatibility with the widest - range of clients, both should be accepted. Similarly, whitespace - in the request line should be treated sensibly (allowing multiple - spaces between components and allowing trailing whitespace). - - Similarly, for output, lines ought to be separated by CRLF pairs - but most clients grok LF characters just fine. - - If the first line of the request has the form - - - - (i.e. is left out) then this is assumed to be an HTTP - 0.9 request; this form has no optional headers and data part and - the reply consists of just the data. - - The reply form of the HTTP 1.0 protocol again has three parts: - - 1. One line giving the response code - 2. An optional set of RFC-822-style headers - 3. The data - - Again, the headers and data are separated by a blank line. - - The response code line has the form - - - - where is the protocol version (always "HTTP/1.0"), - is a 3-digit response code indicating success or - failure of the request, and is an optional - human-readable string explaining what the response code means. - - This server parses the request and the headers, and then calls a - function specific to the request type (). Specifically, - a request SPAM will be handled by a method do_SPAM(). If no - such method exists the server sends an error response to the - client. If it exists, it is called with no arguments: - - do_SPAM() - - Note that the request name is case sensitive (i.e. SPAM and spam - are different requests). - - The various request details are stored in instance variables: - - - client_address is the client IP address in the form (host, - port); - - - command, path and version are the broken-down request line; - - - headers is an instance of mimetools.Message (or a derived - class) containing the header information; - - - rfile is a file object open for reading positioned at the - start of the optional input data part; - - - wfile is a file object open for writing. - - IT IS IMPORTANT TO ADHERE TO THE PROTOCOL FOR WRITING! - - The first thing to be written must be the response line. Then - follow 0 or more header lines, then a blank line, and then the - actual data (if any). The meaning of the header lines depends on - the command executed by the server; in most cases, when data is - returned, there should be at least one header line of the form - - Content-type: / - - where and should be registered MIME types, - e.g. "text/html" or "text/plain". - - """ - - # The Python system version, truncated to its first component. - sys_version = "Python/" + string.split(sys.version)[0] - - # The server software version. You may want to override this. - # The format is multiple whitespace-separated strings, - # where each string is of the form name[/version]. - server_version = "BaseHTTP/" + __version__ - - def parse_request(self): - """Parse a request (internal). - - The request should be stored in self.raw_request; the results - are in self.command, self.path, self.request_version and - self.headers. - - Return value is 1 for success, 0 for failure; on failure, an - error is sent back. - - """ - 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 0 - elif len(words) == 2: - [command, path] = words - if command != 'GET': - self.send_error(400, - "Bad HTTP/0.9 request type (%s)" % `command`) - return 0 - else: - self.send_error(400, "Bad request syntax (%s)" % `requestline`) - return 0 - self.command, self.path, self.request_version = command, path, version - self.headers = self.MessageClass(self.rfile, 0) - return 1 - - def handle(self): - """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. - - """ - - self.raw_requestline = self.rfile.readline() - if not self.parse_request(): # An error code has been sent, just exit - return - mname = 'do_' + self.command - if not hasattr(self, mname): - self.send_error(501, "Unsupported method (%s)" % `self.command`) - return - method = getattr(self, mname) - method() - - def send_error(self, code, message=None): - """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. - - 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}) - - error_message_format = DEFAULT_ERROR_MESSAGE - - def send_response(self, code, message=None): - """Send the response header and log the response code. - - 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()) - - 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)) - - def end_headers(self): - """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. - - This is called by send_reponse(). - - """ - - self.log_message('"%s" %s %s', - self.requestline, str(code), str(size)) - - def log_error(self, *args): - """Log an error. - - 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(). - - XXX This should go to the separate error log. - - """ - - apply(self.log_message, args) - - def log_message(self, format, *args): - """Log an arbitrary message. - - 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 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)) - - def version_string(self): - """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 - - 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 - - weekdayname = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] - - monthname = [None, - 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] - - def address_string(self): - """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. - - """ - - host, port = self.client_address - return socket.getfqdn(host) - - # Essentially static class variables - - # The version of the HTTP protocol we support. - # Don't override unless you know what you're doing (hint: incoming - # requests are required to have exactly this version string). - protocol_version = "HTTP/1.0" - - # The Message-like class used to parse headers - MessageClass = mimetools.Message - - # Table mapping response codes to messages; entries have the - # 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'), - - 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'), - - 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): - """Test the HTTP request handler class. - - This runs an HTTP server on port 8000 (or the first command line - argument). - - """ - - if sys.argv[1:]: - port = string.atoi(sys.argv[1]) - else: - port = 8000 - server_address = ('', port) - - httpd = ServerClass(server_address, HandlerClass) - - print "Serving HTTP on port", port, "..." - httpd.serve_forever() - - -if __name__ == '__main__': - test() diff --git a/Lib/dos-8x3/bastion.py b/Lib/dos-8x3/bastion.py deleted file mode 100755 index a6e716b..0000000 --- a/Lib/dos-8x3/bastion.py +++ /dev/null @@ -1,174 +0,0 @@ -"""Bastionification utility. - -A bastion (for another object -- the 'original') is an object that has -the same methods as the original but does not give access to its -instance variables. Bastions have a number of uses, but the most -obvious one is to provide code executing in restricted mode with a -safe interface to an object implemented in unrestricted mode. - -The bastionification routine has an optional second argument which is -a filter function. Only those methods for which the filter method -(called with the method name as argument) returns true are accessible. -The default filter method returns true unless the method name begins -with an underscore. - -There are a number of possible implementations of bastions. We use a -'lazy' approach where the bastion's __getattr__() discipline does all -the work for a particular method the first time it is used. This is -usually fastest, especially if the user doesn't call all available -methods. The retrieved methods are stored as instance variables of -the bastion, so the overhead is only occurred on the first use of each -method. - -Detail: the bastion class has a __repr__() discipline which includes -the repr() of the original object. This is precomputed when the -bastion is created. - -""" - - -from types import MethodType - - -class BastionClass: - - """Helper class used by the Bastion() function. - - You could subclass this and pass the subclass as the bastionclass - argument to the Bastion() function, as long as the constructor has - the same signature (a get() function and a name for the object). - - """ - - def __init__(self, get, name): - """Constructor. - - Arguments: - - 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 - - def __repr__(self): - """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. - - """ - return "" % self._name_ - - def __getattr__(self, name): - """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. - - 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 - - -def Bastion(object, filter = lambda name: name[:1] != '_', - name=None, bastionclass=BastionClass): - """Create a bastion for an object, using an optional filter. - - See the Bastion module's documentation for background. - - Arguments: - - object - the original object - filter - a predicate that decides whether a function name is OK; - by default all names are OK that don't start with '_' - name - the name of the object; default repr(object) - bastionclass - class used to create the bastion; default BastionClass - - """ - - # Note: we define *two* ad-hoc functions here, get1 and get2. - # Both are intended to be called in the same way: get(name). - # It is clear that the real work (getting the attribute - # from the object and calling the filter) is done in get1. - # Why can't we pass get1 to the bastion? Because the user - # would be able to override the filter argument! With get2, - # overriding the default argument is no security loophole: - # all it does is call it. - # Also notice that we can't place the object and filter as - # instance variables on the bastion object itself, since - # 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 - - def get2(name, get1=get1): - """Internal function for Bastion(). See source comments.""" - return get1(name) - - if name is None: - 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 - o = Original() - b = Bastion(o) - testcode = """if 1: - b.add(81) - b.add(18) - print "b.total() =", b.total() - try: - print "b.sum =", b.sum, - except: - print "inaccessible" - else: - print "accessible" - try: - print "b._add =", b._add, - except: - print "inaccessible" - else: - print "accessible" - try: - print "b._get_.func_defaults =", b._get_.func_defaults, - except: - print "inaccessible" - else: - print "accessible" - \n""" - exec testcode - print '='*20, "Using rexec:", '='*20 - import rexec - r = rexec.RExec() - m = r.add_module('__main__') - m.b = b - r.r_exec(testcode) - - -if __name__ == '__main__': - _test() diff --git a/Lib/dos-8x3/cgihttps.py b/Lib/dos-8x3/cgihttps.py deleted file mode 100755 index ba1e76b..0000000 --- a/Lib/dos-8x3/cgihttps.py +++ /dev/null @@ -1,305 +0,0 @@ -"""CGI-savvy HTTP Server. - -This module builds on SimpleHTTPServer by implementing GET and POST -requests to cgi-bin scripts. - -If the os.fork() function is not present (e.g. on Windows), -os.popen2() is used as a fallback, with slightly altered semantics; if -that function is not present either (e.g. on Macintosh), only Python -scripts are supported, and they are executed by the current process. - -In all cases, the implementation is intentionally naive -- all -requests are executed sychronously. - -SECURITY WARNING: DON'T USE THIS CODE UNLESS YOU ARE INSIDE A FIREWALL --- it may execute arbitrary Python code or external programs. - -""" - - -__version__ = "0.4" - - -import os -import sys -import string -import urllib -import BaseHTTPServer -import SimpleHTTPServer - - -class CGIHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): - - """Complete HTTP server with GET, HEAD and POST commands. - - GET and HEAD also support running CGI scripts. - - The POST command is *only* implemented for CGI scripts. - - """ - - # Determine platform specifics - have_fork = hasattr(os, 'fork') - have_popen2 = hasattr(os, 'popen2') - - # Make rfile unbuffered -- we need to read one line and then pass - # the rest to a subprocess, so we can't use buffered input. - rbufsize = 0 - - def do_POST(self): - """Serve a POST request. - - 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") - - 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) - - def is_cgi(self): - """Test whether self.path corresponds to a CGI script. - - Return a tuple (dir, rest) if self.path requires running a - CGI script, None if not. Note that rest begins with a - slash if it is not empty. - - 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 - - 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 is_executable(self, path): - """Test whether argument path is an executable file.""" - return executable(path) - - def is_python(self, path): - """Test whether argument path is a Python script.""" - head, tail = os.path.splitext(path) - return tail.lower() in (".py", ".pyw") - - def run_cgi(self): - """Execute a CGI script.""" - dir, rest = self.cgi_info - 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 - ispy = self.is_python(scriptname) - if not ispy: - if not (self.have_fork or self.have_popen2): - self.send_error(403, "CGI script is not a Python script (%s)" % - `scriptname`) - return - if not self.is_executable(scriptfile): - self.send_error(403, "CGI script is not executable (%s)" % - `scriptname`) - return - - # Reference: http://hoohoo.ncsa.uiuc.edu/cgi/env.html - # XXX Much of the following could be prepared ahead of time! - env = {} - env['SERVER_SOFTWARE'] = self.version_string() - env['SERVER_NAME'] = self.server.server_name - env['GATEWAY_INTERFACE'] = 'CGI/1.1' - env['SERVER_PROTOCOL'] = self.protocol_version - env['SERVER_PORT'] = str(self.server.server_port) - env['REQUEST_METHOD'] = self.command - uqrest = urllib.unquote(rest) - env['PATH_INFO'] = uqrest - env['PATH_TRANSLATED'] = self.translate_path(uqrest) - env['SCRIPT_NAME'] = scriptname - if query: - env['QUERY_STRING'] = query - host = self.address_string() - if host != self.client_address[0]: - env['REMOTE_HOST'] = host - env['REMOTE_ADDR'] = self.client_address[0] - # XXX AUTH_TYPE - # XXX REMOTE_USER - # XXX REMOTE_IDENT - if self.headers.typeheader is None: - env['CONTENT_TYPE'] = self.headers.type - else: - env['CONTENT_TYPE'] = self.headers.typeheader - length = self.headers.getheader('content-length') - if length: - env['CONTENT_LENGTH'] = length - accept = [] - for line in self.headers.getallmatchingheaders('accept'): - if line[:1] in string.whitespace: - accept.append(string.strip(line)) - else: - accept = accept + string.split(line[7:], ',') - env['HTTP_ACCEPT'] = string.joinfields(accept, ',') - ua = self.headers.getheader('user-agent') - if ua: - env['HTTP_USER_AGENT'] = ua - co = filter(None, self.headers.getheaders('cookie')) - if co: - env['HTTP_COOKIE'] = string.join(co, ', ') - # XXX Other HTTP_* headers - if not self.have_fork: - # Since we're setting the env in the parent, provide empty - # values to override previously set values - for k in ('QUERY_STRING', 'REMOTE_HOST', 'CONTENT_LENGTH', - 'HTTP_USER_AGENT', 'HTTP_COOKIE'): - env.setdefault(k, "") - - self.send_response(200, "Script output follows") - - decoded_query = string.replace(query, '+', ' ') - - if self.have_fork: - # Unix -- fork as we should - args = [script] - if '=' not in decoded_query: - args.append(decoded_query) - nobody = nobody_uid() - self.wfile.flush() # Always flush before forking - pid = os.fork() - if pid != 0: - # Parent - pid, sts = os.waitpid(pid, 0) - if sts: - self.log_error("CGI script exit status %#x", sts) - return - # Child - try: - try: - os.setuid(nobody) - except os.error: - pass - os.dup2(self.rfile.fileno(), 0) - os.dup2(self.wfile.fileno(), 1) - os.execve(scriptfile, args, env) - except: - self.server.handle_error(self.request, self.client_address) - os._exit(127) - - elif self.have_popen2: - # Windows -- use popen2 to create a subprocess - import shutil - os.environ.update(env) - cmdline = scriptfile - if self.is_python(scriptfile): - interp = sys.executable - if interp.lower().endswith("w.exe"): - # On Windows, use python.exe, not python.exe - interp = interp[:-5] = interp[-4:] - cmdline = "%s %s" % (interp, cmdline) - if '=' not in query and '"' not in query: - cmdline = '%s "%s"' % (cmdline, query) - self.log_error("command: %s", cmdline) - try: - nbytes = int(length) - except: - nbytes = 0 - fi, fo = os.popen2(cmdline) - if self.command.lower() == "post" and nbytes > 0: - data = self.rfile.read(nbytes) - fi.write(data) - fi.close() - shutil.copyfileobj(fo, self.wfile) - sts = fo.close() - if sts: - self.log_error("CGI script exit status %#x", sts) - else: - self.log_error("CGI script exited OK") - - else: - # Other O.S. -- execute script in this process - os.environ.update(env) - save_argv = sys.argv - save_stdin = sys.stdin - save_stdout = sys.stdout - save_stderr = sys.stderr - try: - try: - sys.argv = [scriptfile] - if '=' not in decoded_query: - sys.argv.append(decoded_query) - sys.stdout = self.wfile - sys.stdin = self.rfile - execfile(scriptfile, {"__name__": "__main__"}) - finally: - sys.argv = save_argv - sys.stdin = save_stdin - sys.stdout = save_stdout - sys.stderr = save_stderr - except SystemExit, sts: - self.log_error("CGI script exit status %s", str(sts)) - else: - self.log_error("CGI script exited OK") - - -nobody = None - -def nobody_uid(): - """Internal routine to get nobody's uid""" - global nobody - if nobody: - return nobody - try: - import pwd - except ImportError: - return -1 - try: - nobody = pwd.getpwnam('nobody')[2] - except KeyError: - nobody = 1 + max(map(lambda x: x[2], pwd.getpwall())) - return nobody - - -def executable(path): - """Test for executable file.""" - try: - st = os.stat(path) - except os.error: - return 0 - return st[0] & 0111 != 0 - - -def test(HandlerClass = CGIHTTPRequestHandler, - ServerClass = BaseHTTPServer.HTTPServer): - SimpleHTTPServer.test(HandlerClass, ServerClass) - - -if __name__ == '__main__': - test() diff --git a/Lib/dos-8x3/compilea.py b/Lib/dos-8x3/compilea.py deleted file mode 100755 index e56c8b2..0000000 --- a/Lib/dos-8x3/compilea.py +++ /dev/null @@ -1,128 +0,0 @@ -"""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 stat -import sys -import py_compile - -def compile_dir(dir, maxlevels=10, ddir=None, force=0): - """Byte-compile all modules in the given directory tree. - - 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) - force: if 1, force compilation, even if timestamps are up-to-date - - """ - print 'Listing', dir, '...' - try: - names = os.listdir(dir) - except os.error: - print "Can't list", dir - names = [] - names.sort() - success = 1 - 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': - cfile = fullname + (__debug__ and 'c' or 'o') - ftime = os.stat(fullname)[stat.ST_MTIME] - try: ctime = os.stat(cfile)[stat.ST_MTIME] - except os.error: ctime = 0 - if (ctime > ftime) and not force: continue - 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 - success = 0 - 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, force) - return success - -def compile_path(skip_curdir=1, maxlevels=0, force=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) - force: as for compile_dir() (default 0) - - """ - success = 1 - for dir in sys.path: - if (not dir or dir == os.curdir) and skip_curdir: - print 'Skipping current directory' - else: - success = success and compile_dir(dir, maxlevels, None, force) - return success - -def main(): - """Script main program.""" - import getopt - try: - opts, args = getopt.getopt(sys.argv[1:], 'lfd:') - except getopt.error, msg: - print msg - print "usage: compileall [-l] [-f] [-d destdir] [directory ...]" - print "-l: don't recurse down" - print "-f: force rebuild even if timestamps are up-to-date" - print "-d destdir: purported directory name for error messages" - print "if no directory arguments, -l sys.path is assumed" - sys.exit(2) - maxlevels = 10 - ddir = None - force = 0 - for o, a in opts: - if o == '-l': maxlevels = 0 - if o == '-d': ddir = a - if o == '-f': force = 1 - if ddir: - if len(args) != 1: - print "-d destdir require exactly one directory argument" - sys.exit(2) - success = 1 - try: - if args: - for dir in args: - success = success and compile_dir(dir, maxlevels, ddir, force) - else: - success = compile_path() - except KeyboardInterrupt: - print "\n[interrupt]" - success = 0 - return success - -if __name__ == '__main__': - sys.exit(not main()) diff --git a/Lib/dos-8x3/configpa.py b/Lib/dos-8x3/configpa.py deleted file mode 100644 index 5043687..0000000 --- a/Lib/dos-8x3/configpa.py +++ /dev/null @@ -1,469 +0,0 @@ -"""Configuration file parser. - -A setup file consists of sections, lead by a "[section]" header, -and followed by "name: value" entries, with continuations and such in -the style of RFC 822. - -The option values can contain format strings which refer to other values in -the same section, or values in a special [DEFAULT] section. - -For example: - - something: %(dir)s/whatever - -would resolve the "%(dir)s" to the value of dir. All reference -expansions are done late, on demand. - -Intrinsic defaults can be specified by passing them into the -ConfigParser constructor as a dictionary. - -class: - -ConfigParser -- responsible for for parsing a list of - configuration files, and managing the parsed database. - - methods: - - __init__(defaults=None) - create the parser and specify a dictionary of intrinsic defaults. The - keys must be strings, the values must be appropriate for %()s string - interpolation. Note that `__name__' is always an intrinsic default; - it's value is the section's name. - - sections() - return all the configuration section names, sans DEFAULT - - has_section(section) - return whether the given section exists - - has_option(section, option) - return whether the given option exists in the given section - - options(section) - return list of configuration options for the named section - - has_option(section, option) - return whether the given section has the given option - - read(filenames) - read and parse the list of named configuration files, given by - name. A single filename is also allowed. Non-existing files - are ignored. - - readfp(fp, filename=None) - read and parse one configuration file, given as a file object. - The filename defaults to fp.name; it is only used in error - messages (if fp has no `name' attribute, the string `' is used). - - get(section, option, raw=0, vars=None) - 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. Additional substitutions may be - provided using the `vars' argument, which must be a dictionary whose - contents override any pre-existing defaults. - - 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) - - remove_section(section) - remove the given file section and all its options - - remove_option(section, option) - remove the given option from the given section - - set(section, option, value) - set the given option - - write(fp) - write the configuration state in .ini format -""" - -import sys -import string -import re - -DEFAULTSECT = "DEFAULT" - -MAX_INTERPOLATION_DEPTH = 10 - - - -# exception classes -class Error: - def __init__(self, msg=''): - self._msg = msg - def __repr__(self): - return self._msg - -class NoSectionError(Error): - def __init__(self, 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 - -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 - -class InterpolationError(Error): - def __init__(self, reference, option, section, rawval): - Error.__init__(self, - "Bad value substitution:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\tkey : %s\n" - "\trawval : %s\n" - % (section, option, reference, rawval)) - self.reference = reference - self.option = option - self.section = section - -class InterpolationDepthError(Error): - def __init__(self, option, section, rawval): - Error.__init__(self, - "Value interpolation too deeply recursive:\n" - "\tsection: [%s]\n" - "\toption : %s\n" - "\trawval : %s\n" - % (section, option, rawval)) - self.option = option - self.section = section - -class ParsingError(Error): - def __init__(self, filename): - Error.__init__(self, 'File contains parsing errors: %s' % filename) - self.filename = filename - self.errors = [] - - def append(self, lineno, line): - self.errors.append((lineno, line)) - self._msg = self._msg + '\n\t[line %2d]: %s' % (lineno, line) - -class MissingSectionHeaderError(ParsingError): - def __init__(self, filename, lineno, line): - Error.__init__( - self, - 'File contains no section headers.\nfile: %s, line: %d\n%s' % - (filename, lineno, line)) - self.filename = filename - self.lineno = lineno - self.line = line - - - -class ConfigParser: - def __init__(self, defaults=None): - self.__sections = {} - if defaults is None: - self.__defaults = {} - else: - self.__defaults = defaults - - def defaults(self): - 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() - - def add_section(self, section): - """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] = {} - - def has_section(self, section): - """Indicate whether the named section is present in the configuration. - - The DEFAULT section is not acknowledged. - """ - return section in self.sections() - - def options(self, section): - """Return a list of option names for the given section name.""" - try: - opts = self.__sections[section].copy() - except KeyError: - raise NoSectionError(section) - opts.update(self.__defaults) - if opts.has_key('__name__'): - del opts['__name__'] - return opts.keys() - - def has_option(self, section, option): - """Return whether the given section has the given option.""" - return option in self.options(section) - - def read(self, filenames): - """Read and parse a filename or a list of filenames. - - Files that cannot be opened are silently ignored; this is - designed so that you can specify a list of potential - configuration file locations (e.g. current directory, user's - home directory, systemwide directory), and all existing - configuration files in the list will be read. A single - filename may also be given. - """ - if type(filenames) in [type(''), type(u'')]: - filenames = [filenames] - for filename in filenames: - try: - fp = open(filename) - except IOError: - continue - self.__read(fp, filename) - fp.close() - - def readfp(self, fp, filename=None): - """Like read() but the argument must be a file-like object. - - The `fp' argument must have a `readline' method. Optional - second argument is the `filename', which if not given, is - taken from fp.name. If fp has no `name' attribute, `' is - used. - - """ - if filename is None: - try: - filename = fp.name - except AttributeError: - filename = '' - self.__read(fp, filename) - - def get(self, section, option, raw=0, vars=None): - """Get an option value for a given section. - - All % interpolations are expanded in the return values, based on the - defaults passed into the constructor, unless the optional argument - `raw' is true. Additional substitutions may be provided using the - `vars' argument, which must be a dictionary whose contents overrides - any pre-existing defaults. - - 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) - # Update with the entry specific variables - if vars: - d.update(vars) - option = self.optionxform(option) - try: - rawval = d[option] - except KeyError: - raise NoOptionError(option, section) - - if raw: - return rawval - - # do the string interpolation - value = rawval # Make it a pretty variable name - depth = 0 - while depth < 10: # Loop through this until it's done - depth = depth + 1 - if string.find(value, "%(") >= 0: - try: - value = value % d - except KeyError, key: - raise InterpolationError(key, option, section, rawval) - else: - break - if value.find("%(") >= 0: - raise InterpolationDepthError(option, section, rawval) - return value - - def __get(self, section, conv, option): - return conv(self.get(section, option)) - - def getint(self, section, option): - return self.__get(section, string.atoi, option) - - def getfloat(self, section, 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 - - def optionxform(self, optionstr): - return string.lower(optionstr) - - def has_option(self, section, option): - """Check for the existence of a given option in a given section.""" - if not section or section == "DEFAULT": - return self.__defaults.has_key(option) - elif not self.has_section(section): - return 0 - else: - return self.__sections[section].has_key(option) - - def set(self, section, option, value): - """Set an option.""" - if not section or section == "DEFAULT": - sectdict = self.__defaults - else: - try: - sectdict = self.__sections[section] - except KeyError: - raise NoSectionError(section) - sectdict[option] = value - - def write(self, fp): - """Write an .ini-format representation of the configuration state.""" - if self.__defaults: - fp.write("[DEFAULT]\n") - for (key, value) in self.__defaults.items(): - fp.write("%s = %s\n" % (key, value)) - fp.write("\n") - for section in self.sections(): - fp.write("[" + section + "]\n") - sectdict = self.__sections[section] - for (key, value) in sectdict.items(): - if key == "__name__": - continue - fp.write("%s = %s\n" % (key, value)) - fp.write("\n") - - def remove_option(self, section, option): - """Remove an option.""" - if not section or section == "DEFAULT": - sectdict = self.__defaults - else: - try: - sectdict = self.__sections[section] - except KeyError: - raise NoSectionError(section) - existed = sectdict.has_key(key) - if existed: - del sectdict[key] - return existed - - def remove_section(self, section): - """Remove a file section.""" - if self.__sections.has_key(section): - del self.__sections[section] - return 1 - else: - return 0 - - # - # Regular expressions for parsing section headers and options. Note a - # slight semantic change from the previous version, because of the use - # of \w, _ is allowed in section header names. - SECTCRE = re.compile( - r'\[' # [ - r'(?P

[-\w_.*,(){} ]+)' # a lot of stuff found by IvL - r'\]' # ] - ) - OPTCRE = re.compile( - r'(?P