From fdrake@users.sourceforge.net Sat Sep 1 03:35:26 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 31 Aug 2001 19:35:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libhttplib.tex,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23905/lib Modified Files: libhttplib.tex Log Message: Added the "Host" header to the "GET" example. This closes SF bug #457100. Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** libhttplib.tex 2001/01/22 17:42:32 1.23 --- libhttplib.tex 2001/09/01 02:35:23 1.24 *************** *** 122,125 **** --- 122,126 ---- >>> h.putheader('Accept', 'text/html') >>> h.putheader('Accept', 'text/plain') + >>> h.putheader('Host', 'www.cwi.nl') >>> h.endheaders() >>> errcode, errmsg, headers = h.getreply() From gvanrossum@users.sourceforge.net Sat Sep 1 19:29:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 11:29:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tkinter.py,1.155,1.156 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv31706 Modified Files: Tkinter.py Log Message: Add Listbox.itemconfig[ure] call. (A "recent" addition to Tk -- 8.0 doesn't have it.) This is from SF bug #457487 by anonymous. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.155 retrieving revision 1.156 diff -C2 -d -r1.155 -r1.156 *** Tkinter.py 2001/08/23 13:25:59 1.155 --- Tkinter.py 2001/09/01 18:29:55 1.156 *************** *** 4,10 **** control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, ! Checkbutton, Scale, Listbox, Scrollbar, OptionMenu. Properties of the widgets are ! specified with keyword arguments. Keyword arguments have the same ! name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack --- 4,10 ---- control of widgets. Toplevel widgets are Tk and Toplevel. Other widgets are Frame, Label, Entry, Text, Canvas, Button, Radiobutton, ! Checkbutton, Scale, Listbox, Scrollbar, OptionMenu. Properties of the ! widgets are specified with keyword arguments. Keyword arguments have ! the same name as the corresponding resource under Tk. Widgets are positioned with one of the geometry managers Place, Pack *************** *** 12,17 **** available in every Widget. ! Actions are bound to events by resources (e.g. keyword argument command) or ! with the method bind. Example (Hello, World): --- 12,17 ---- available in every Widget. ! Actions are bound to events by resources (e.g. keyword argument ! command) or with the method bind. Example (Hello, World): *************** *** 2364,2367 **** --- 2364,2388 ---- """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) + def itemconfigure(self, index, cnf=None, **kw): + """Configure resources of an item. + + The values for resources are specified as keyword arguments. + To get an overview about the allowed keyword arguments + call the method without arguments. + Valid resource names: background, bg, foreground, fg, + selectbackground, selectforeground.""" + if cnf is None and not kw: + cnf = {} + for x in self.tk.split( + self.tk.call(self._w, 'itemconfigure', index)): + cnf[x[0][1:]] = (x[0][1:],) + x[1:] + return cnf + if type(cnf) == StringType and not kw: + x = self.tk.split(self.tk.call( + self._w, 'itemconfigure', index, '-'+cnf)) + return (x[0][1:],) + x[1:] + self.tk.call((self._w, 'itemconfigure', index) + + self._options(cnf, kw)) + itemconfig = itemconfigure class Menu(Widget): From gvanrossum@users.sourceforge.net Sat Sep 1 22:56:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 14:56:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv6694 Added Files: fixdiv.py Log Message: The beginnings of a script to help finding / operators that may need to be change to //. The code is pretty gross so far, and I promise I'll work on this more, but I have to go eat now! :-) --- NEW FILE: fixdiv.py --- #! /usr/bin/env python """fixdiv - tool to fix division operators. To use this tool, first run `python -Dwarn yourscript.py 2>warnings'. This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file `warnings'. (The warnings are written to stderr, so you must use `2>' for the I/O redirect. I don't yet know how to do this on Windows.) Then run `python fixdiv.py warnings'. This first reads the warnings, looking for classic division warnings, and sorts them by file name and line number. Then, for each file that received at least one warning, it parses the file and tries to match the warnings up to the division operators found in the source code. If it is successful, it writes a recommendation to stdout in the form of a context diff. If it is not successful, it writes recommendations to stdout instead. """ import sys import getopt import re import tokenize from pprint import pprint def main(): try: opts, args = getopt.getopt(sys.argv[1:], "h") except getopt.error, msg: usage(2, msg) for o, a in opts: if o == "-h": help() if not args: usage(2, "at least one file argument is required") if args[1:]: sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0]) readwarnings(args[0]) def usage(exit, msg=None): if msg: sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) sys.stderr.write("Usage: %s warnings\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) sys.exit(exit) def help(): print __doc__ sys.exit(0) def readwarnings(warningsfile): pat = re.compile( "^(.+?):(\d+): DeprecationWarning: classic ([a-z]+) division$") try: f = open(warningsfile) except IOError, msg: sys.stderr.write("can't open: %s\n" % msg) return warnings = {} while 1: line = f.readline() if not line: break m = pat.match(line) if not m: if line.find("division") >= 0: sys.stderr.write("Warning: ignored input " + line) continue file, lineno, what = m.groups() list = warnings.get(file) if list is None: warnings[file] = list = [] list.append((int(lineno), intern(what))) f.close() files = warnings.keys() files.sort() for file in files: process(file, warnings[file]) def process(file, list): print "-"*70 if not list: sys.stderr.write("no division warnings for %s\n" % file) return try: fp = open(file) except IOError, msg: sys.stderr.write("can't open: %s\n" % msg) return print "Processing:", file f = FileContext(fp) list.sort() index = 0 # list[:index] has been processed, list[index:] is still to do orphans = [] # subset of list for which no / operator was found unknown = [] # lines with / operators for which no warnings were seen g = tokenize.generate_tokens(f.readline) while 1: startlineno, endlineno, slashes = lineinfo = scanline(g) if startlineno is None: break assert startlineno <= endlineno is not None while index < len(list) and list[index][0] < startlineno: orphans.append(list[index]) index += 1 warnings = [] while index < len(list) and list[index][0] <= endlineno: warnings.append(list[index]) index += 1 if not slashes and not warnings: pass elif slashes and not warnings: report(slashes, "Unexecuted code") elif warnings and not slashes: reportphantomwarnings(warnings, f) else: if len(slashes) > 1: report(slashes, "More than one / operator") else: (row, col), line = slashes[0] line = chop(line) if line[col:col+1] != "/": print "*** Can't find the / operator in line %d:" % row print "*", line continue intlong = [] floatcomplex = [] bad = [] for lineno, what in warnings: if what in ("int", "long"): intlong.append(what) elif what in ("float", "complex"): floatcomplex.append(what) else: bad.append(what) if bad: print "*** Bad warning for line %d:" % row, bad print "*", line elif intlong and not floatcomplex: print "%dc%d" % (row, row) print "<", line print "---" print ">", line[:col] + "/" + line[col:] elif floatcomplex and not intlong: print "True division / operator at line %d:" % row print "=", line fp.close() def reportphantomwarnings(warnings, f): blocks = [] lastrow = None lastblock = None for row, what in warnings: if row != lastrow: lastblock = [row] blocks.append(lastblock) lastblock.append(what) for block in blocks: row = block[0] whats = "/".join(block[1:]) print "*** Phantom %s warnings for line %d:" % (whats, row) f.report(row, mark="*") def report(slashes, message): lastrow = None for (row, col), line in slashes: if row != lastrow: print "*** %s on line %d:" % (message, row) print "*", chop(line) lastrow = row class FileContext: def __init__(self, fp, window=5, lineno=1): self.fp = fp self.window = 5 self.lineno = 1 self.eoflookahead = 0 self.lookahead = [] self.buffer = [] def fill(self): while len(self.lookahead) < self.window and not self.eoflookahead: line = self.fp.readline() if not line: self.eoflookahead = 1 break self.lookahead.append(line) def readline(self): self.fill() if not self.lookahead: return "" line = self.lookahead.pop(0) self.buffer.append(line) self.lineno += 1 return line def truncate(self): del self.buffer[-window:] def __getitem__(self, index): self.fill() bufstart = self.lineno - len(self.buffer) lookend = self.lineno + len(self.lookahead) if bufstart <= index < self.lineno: return self.buffer[index - bufstart] if self.lineno <= index < lookend: return self.lookahead[index - self.lineno] raise KeyError def report(self, first, last=None, mark="*"): if last is None: last = first for i in range(first, last+1): try: line = self[first] except KeyError: line = "" print mark, chop(line) def scanline(g): slashes = [] startlineno = None endlineno = None for type, token, start, end, line in g: endlineno = end[0] if startlineno is None: startlineno = endlineno if token in ("/", "/="): slashes.append((start, line)) ## if type in (tokenize.NEWLINE, tokenize.NL, tokenize.COMMENT): if type == tokenize.NEWLINE: break return startlineno, endlineno, slashes def chop(line): if line.endswith("\n"): return line[:-1] else: return line if __name__ == "__main__": main() From jackjansen@users.sourceforge.net Sat Sep 1 23:36:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts EditPythonPrefs.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv16959/Python/Mac/scripts Modified Files: EditPythonPrefs.py Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: EditPythonPrefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** EditPythonPrefs.py 2001/08/27 21:41:23 1.26 --- EditPythonPrefs.py 2001/09/01 22:36:03 1.27 *************** *** 55,58 **** --- 55,60 ---- "noargs", "delayconsole", + "divisionwarn", + "unixnewlines", ] opt_dialog_dict = {} *************** *** 62,74 **** # 1 thru 10 are the options # The GUSI creator/type and delay-console ! OD_CREATOR_ITEM = 18 ! OD_TYPE_ITEM = 19 OD_OK_ITEM = 1 OD_CANCEL_ITEM = 2 ! OD_HELP_ITEM = 20 ! OD_KEEPALWAYS_ITEM = 14 ! OD_KEEPOUTPUT_ITEM = 15 ! OD_KEEPERROR_ITEM = 16 ! OD_KEEPNEVER_ITEM = 17 def optinteract(options): --- 64,76 ---- # 1 thru 10 are the options # The GUSI creator/type and delay-console ! OD_CREATOR_ITEM = 20 ! OD_TYPE_ITEM = 21 OD_OK_ITEM = 1 OD_CANCEL_ITEM = 2 ! OD_HELP_ITEM = 22 ! OD_KEEPALWAYS_ITEM = 16 ! OD_KEEPOUTPUT_ITEM = 17 ! OD_KEEPERROR_ITEM = 18 ! OD_KEEPNEVER_ITEM = 19 def optinteract(options): From jackjansen@users.sourceforge.net Sat Sep 1 23:36:11 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Lib pythonprefs.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Lib In directory usw-pr-cvs1:/tmp/cvs-serv16990/Python/Mac/Lib Modified Files: pythonprefs.py Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: pythonprefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Lib/pythonprefs.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pythonprefs.py 2001/02/11 01:07:50 1.7 --- pythonprefs.py 2001/09/01 22:36:09 1.8 *************** *** 17,21 **** # version ! CUR_VERSION=7 preffilename = PstringLoader(AnyResLoader('STR ', resname=PREFNAME_NAME)).load() --- 17,21 ---- # version ! CUR_VERSION=8 preffilename = PstringLoader(AnyResLoader('STR ', resname=PREFNAME_NAME)).load() *************** *** 24,28 **** class PoptLoader(VersionLoader): def __init__(self, loader): ! VersionLoader.__init__(self, "bbbbbbbbbbbbbb", loader) def versioncheck(self, data): --- 24,28 ---- class PoptLoader(VersionLoader): def __init__(self, loader): ! VersionLoader.__init__(self, "bbbbbbbbbbbbbbbb", loader) def versioncheck(self, data): *************** *** 52,56 **** self.loader.save(newdata) ! popt_default_default = NullLoader(chr(CUR_VERSION) + 8*'\0') popt_default = AnyResLoader('Popt', POPT_ID, default=popt_default_default) popt_loader = ResLoader(pref_fss, 'Popt', POPT_ID, default=popt_default) --- 52,56 ---- self.loader.save(newdata) ! popt_default_default = NullLoader(chr(CUR_VERSION) + 14*'\0' + '\001') popt_default = AnyResLoader('Popt', POPT_ID, default=popt_default_default) popt_loader = ResLoader(pref_fss, 'Popt', POPT_ID, default=popt_default) *************** *** 86,90 **** dict['unbuffered'], dict['debugging'], dummy, dict['keep_console'], \ dict['nointopt'], dict['noargs'], dict['tabwarn'], \ ! dict['nosite'], dict['nonavservice'], dict['delayconsole'] = flags return dict --- 86,91 ---- dict['unbuffered'], dict['debugging'], dummy, dict['keep_console'], \ dict['nointopt'], dict['noargs'], dict['tabwarn'], \ ! dict['nosite'], dict['nonavservice'], dict['delayconsole'], \ ! dict['divisionwarn'], dict['unixnewlines'] = flags return dict *************** *** 97,101 **** dict['unbuffered'], dict['debugging'], 0, dict['keep_console'], \ dict['nointopt'], dict['noargs'], dict['tabwarn'], \ ! dict['nosite'], dict['nonavservice'], dict['delayconsole'] self.popt.save(flags) --- 98,103 ---- dict['unbuffered'], dict['debugging'], 0, dict['keep_console'], \ dict['nointopt'], dict['noargs'], dict['tabwarn'], \ ! dict['nosite'], dict['nonavservice'], dict['delayconsole'], \ ! dict['divisionwarn'], dict['unixnewlines'] self.popt.save(flags) From jackjansen@users.sourceforge.net Sat Sep 1 23:36:16 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include pythonresources.h,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv17029/Python/Mac/Include Modified Files: pythonresources.h Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: pythonresources.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/pythonresources.h,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** pythonresources.h 2001/08/03 13:31:36 1.26 --- pythonresources.h 2001/09/01 22:36:14 1.27 *************** *** 78,81 **** --- 78,84 ---- #define OPT_HELP 15 #define OPT_NONAVSERV 16 + #define OPT_VERBOSEVERBOSE 19 + #define OPT_DIVISIONWARN 20 + #define OPT_UNIXNEWLINES 21 /* Dialog for 'No preferences directory' */ *************** *** 141,145 **** #define PYTHONOPTIONSOVERRIDE_ID 229 ! #define POPT_VERSION_CURRENT 7 /* Current version number */ #define POPT_KEEPCONSOLE_NEVER 0 #define POPT_KEEPCONSOLE_OUTPUT 1 --- 144,148 ---- #define PYTHONOPTIONSOVERRIDE_ID 229 ! #define POPT_VERSION_CURRENT 8 /* Current version number */ #define POPT_KEEPCONSOLE_NEVER 0 #define POPT_KEEPCONSOLE_OUTPUT 1 *************** *** 163,166 **** --- 166,171 ---- unsigned char nonavservice; unsigned char delayconsole; + unsigned char divisionwarn; + unsigned char unixnewlines; } PyMac_PrefRecord; #endif From jackjansen@users.sourceforge.net Sat Sep 1 23:36:22 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts EditPythonPrefs.rsrc,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv17055/Python/Mac/scripts Modified Files: EditPythonPrefs.rsrc Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: EditPythonPrefs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.rsrc,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 Binary files /tmp/cvsjqSk0k and /tmp/cvsMi17Iv differ From jackjansen@users.sourceforge.net Sat Sep 1 23:36:26 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Resources pythonpath.r,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Resources In directory usw-pr-cvs1:/tmp/cvs-serv17087/Python/Mac/Resources Modified Files: pythonpath.r Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: pythonpath.r =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Resources/pythonpath.r,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** pythonpath.r 2001/08/19 22:02:56 1.13 --- pythonpath.r 2001/09/01 22:36:24 1.14 *************** *** 27,30 **** --- 27,32 ---- byte navService = 0, noNavService = 1; byte noDelayConsole = 0, delayConsole = 1; + byte noDivisionWarning = 0, divisionWarning = 1; + byte noUnixNewlines = 0, unixNewlines = 1; }; *************** *** 56,59 **** --- 58,63 ---- "No NavServices in macfs", 'DBYT', "Delay console window", 'DBYT', + "Warnings for old-style division", 'DBYT', + "Allow unix newlines on textfile input",'DBYT', } }; *************** *** 76,79 **** --- 80,85 ---- navService, noDelayConsole, + noDivisionWarning, + unixNewlines, }; From jackjansen@users.sourceforge.net Sat Sep 1 23:36:31 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:36:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Resources dialogs.rsrc,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Resources In directory usw-pr-cvs1:/tmp/cvs-serv17117/Python/Mac/Resources Modified Files: dialogs.rsrc Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Index: dialogs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Resources/dialogs.rsrc,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 Binary files /tmp/cvs7r42hp and /tmp/cvsCtLrtE differ From jackjansen@users.sourceforge.net Sat Sep 1 23:37:50 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:37:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macmain.c,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv17631/Python/Mac/Python Modified Files: macmain.c Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Also (finally) added a startup option to get -vv behaviour. Moved __convert_to_newlines to main.c because that's easier with the newline option. Index: macmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macmain.c,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** macmain.c 2001/08/03 13:31:36 1.66 --- macmain.c 2001/09/01 22:37:48 1.67 *************** *** 63,69 **** "Type \"copyright\", \"credits\" or \"license\" for more information." - - extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */ - extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */ short PyMac_AppRefNum; /* RefNum of application resource fork */ --- 63,66 ---- *************** *** 160,163 **** --- 157,161 ---- SET_OPT_ITEM(OPT_INSPECT, inspect); SET_OPT_ITEM(OPT_VERBOSE, verbose); + /* OPT_VERBOSEVERBOSE is default off */ SET_OPT_ITEM(OPT_OPTIMIZE, optimize); SET_OPT_ITEM(OPT_UNBUFFERED, unbuffered); *************** *** 174,178 **** SET_OPT_ITEM(OPT_TABWARN, tabwarn); SET_OPT_ITEM(OPT_NOSITE, nosite); ! SET_OPT_ITEM(OPT_NONAVSERV, nonavservice); /* The rest are not settable interactively */ --- 172,177 ---- SET_OPT_ITEM(OPT_TABWARN, tabwarn); SET_OPT_ITEM(OPT_NOSITE, nosite); ! SET_OPT_ITEM(OPT_DIVISIONWARN, divisionwarn); ! SET_OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines); /* The rest are not settable interactively */ *************** *** 220,223 **** --- 219,232 ---- OPT_ITEM(OPT_INSPECT, inspect); OPT_ITEM(OPT_VERBOSE, verbose); + if ( item == OPT_VERBOSEVERBOSE ) { + if ( p->verbose == 2 ) + p->verbose = 1; + else + p->verbose = 2; + GetDialogItem(dialog, OPT_VERBOSE, &type, (Handle *)&handle, &rect); + SetControlValue(handle, 1); + } + GetDialogItem(dialog, OPT_VERBOSEVERBOSE, &type, (Handle *)&handle, &rect); + SetControlValue(handle, p->verbose == 2); OPT_ITEM(OPT_OPTIMIZE, optimize); OPT_ITEM(OPT_UNBUFFERED, unbuffered); *************** *** 237,241 **** OPT_ITEM(OPT_TABWARN, tabwarn); OPT_ITEM(OPT_NOSITE, nosite); ! OPT_ITEM(OPT_NONAVSERV, nonavservice); #undef OPT_ITEM --- 246,251 ---- OPT_ITEM(OPT_TABWARN, tabwarn); OPT_ITEM(OPT_NOSITE, nosite); ! OPT_ITEM(OPT_DIVISIONWARN, divisionwarn); ! OPT_ITEM(OPT_UNIXNEWLINES, unixnewlines); #undef OPT_ITEM *************** *** 316,319 **** --- 326,330 ---- Py_NoSiteFlag = PyMac_options.nosite; Py_TabcheckFlag = PyMac_options.tabwarn; + Py_DivisionWarningFlag = PyMac_options.divisionwarn; if ( PyMac_options.noargs ) { /* don't process events at all without the scripts permission */ *************** *** 675,677 **** { return (int)PyMac_options.delayconsole; ! } \ No newline at end of file --- 686,708 ---- { return (int)PyMac_options.delayconsole; ! } ! ! #ifndef WITHOUT_UNIX_NEWLINES ! /* ! ** Experimental feature (for 2.2a2): optionally allow unix newlines ! ** as well as Mac newlines on input. We replace a lowlevel ! ** MSL routine to accomplish this. ! */ ! void ! __convert_to_newlines(unsigned char * buf, size_t * n_ptr) ! { ! unsigned char *p; ! size_t n = *n_ptr; ! ! for(p=buf; n > 0; p++, n--) ! if ( *p == '\r' ) *p = '\n'; ! else if ( *p == '\n' && !PyMac_options.unixnewlines ) ! *p = '\r'; ! } ! #endif /* WITHOUT_UNIX_NEWLINES */ ! From jackjansen@users.sourceforge.net Sat Sep 1 23:37:56 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 15:37:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macglue.c,1.103,1.104 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv17679/Python/Mac/Python Modified Files: macglue.c Log Message: Added preferences/startup options for division warning and accepting unix-style newlines on input. Also (finally) added a startup option to get -vv behaviour. Moved __convert_to_newlines to main.c because that's easier with the newline option. Index: macglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macglue.c,v retrieving revision 1.103 retrieving revision 1.104 diff -C2 -d -r1.103 -r1.104 *** macglue.c 2001/08/27 23:16:34 1.103 --- macglue.c 2001/09/01 22:37:54 1.104 *************** *** 180,200 **** int PyMac_AppearanceCompliant; - #ifndef WITHOUT_UNIX_NEWLINES - /* - ** Experimental feature (for 2.2a2): allow unix newlines - ** as well as Mac newlines on input. We replace a lowlevel - ** MSL routine to accomplish this - */ - void - __convert_to_newlines(unsigned char * buf, size_t * n_ptr) - { - unsigned char *p; - size_t n = *n_ptr; - - for(p=buf; n > 0; p++, n--) - if ( *p == '\r' ) *p = '\n'; - } - #endif /* WITHOUT_UNIX_NEWLINES */ - /* Given an FSSpec, return the FSSpec of the parent folder */ --- 180,183 ---- From jackjansen@users.sourceforge.net Sun Sep 2 00:37:03 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/CGI PythonCGISlave.rsrc,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/CGI In directory usw-pr-cvs1:/tmp/cvs-serv2305/Python/Mac/Tools/CGI Modified Files: PythonCGISlave.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: PythonCGISlave.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/CGI/PythonCGISlave.rsrc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 Binary files /tmp/cvsdiAeYz and /tmp/cvsKvp8KZ differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/CGI BuildCGIApplet.rsrc,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/CGI In directory usw-pr-cvs1:/tmp/cvs-serv2351/Python/Mac/Tools/CGI Modified Files: BuildCGIApplet.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: BuildCGIApplet.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/CGI/BuildCGIApplet.rsrc,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 Binary files /tmp/cvsFsInGC and /tmp/cvsEk9hb5 differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/IDE PythonIDE.rsrc,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/IDE In directory usw-pr-cvs1:/tmp/cvs-serv2381/Python/Mac/Tools/IDE Modified Files: PythonIDE.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: PythonIDE.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/IDE/PythonIDE.rsrc,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 Binary files /tmp/cvs3e69Nz and /tmp/cvsqXK8mZ differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:16 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts EditPythonPrefs.rsrc,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv2404/Python/Mac/scripts Modified Files: EditPythonPrefs.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: EditPythonPrefs.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/EditPythonPrefs.rsrc,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 Binary files /tmp/cvsdixSt2 and /tmp/cvsoCePAU differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts ConfigurePython.rsrc,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv2444/Python/Mac/scripts Modified Files: ConfigurePython.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: ConfigurePython.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/ConfigurePython.rsrc,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 Binary files /tmp/cvsOUwSUu and /tmp/cvsK0r1rP differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts BuildApplication.rsrc,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv2462/Python/Mac/scripts Modified Files: BuildApplication.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: BuildApplication.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplication.rsrc,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 Binary files /tmp/cvsdhGT73 and /tmp/cvswoOm2X differ From jackjansen@users.sourceforge.net Sun Sep 2 00:37:30 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/scripts BuildApplet.rsrc,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/scripts In directory usw-pr-cvs1:/tmp/cvs-serv2482/Python/Mac/scripts Modified Files: BuildApplet.rsrc Log Message: Updated the Popt resources for the applets to the newest version. Index: BuildApplet.rsrc =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/scripts/BuildApplet.rsrc,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 Binary files /tmp/cvs1dSvVt and /tmp/cvsqpr9EN differ From jackjansen@users.sourceforge.net Sun Sep 2 00:38:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:38:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte _Mltemodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv2654/Python/Mac/Modules/mlte Modified Files: _Mltemodule.c Log Message: Include Carbon/Carbon.h if we're on OSX. Index: _Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/_Mltemodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Mltemodule.c 2001/08/23 14:00:18 1.1 --- _Mltemodule.c 2001/09/01 23:38:08 1.2 *************** *** 20,24 **** #include #else ! #include #endif --- 20,24 ---- #include #else ! #include #endif From jackjansen@users.sourceforge.net Sun Sep 2 00:38:15 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:38:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte mltesupport.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv2690/Python/Mac/Modules/mlte Modified Files: mltesupport.py Log Message: Include Carbon/Carbon.h if we're on OSX. Index: mltesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/mltesupport.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** mltesupport.py 2001/08/23 13:50:07 1.5 --- mltesupport.py 2001/09/01 23:38:13 1.6 *************** *** 24,28 **** #include #else ! #include #endif --- 24,28 ---- #include #else ! #include #endif From jackjansen@users.sourceforge.net Sun Sep 2 00:38:47 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:38:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae _AEmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv2787/Python/Mac/Modules/ae Modified Files: _AEmodule.c Log Message: Don't call PyMac_HandleEvent if we're in unix-Python. Index: _AEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/_AEmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _AEmodule.c 2001/08/23 14:02:03 1.1 --- _AEmodule.c 2001/09/01 23:38:45 1.2 *************** *** 40,47 **** --- 40,49 ---- if ( PyOS_InterruptOccurred() ) return 1; + #if !TARGET_API_MAC_OSX if ( PyMac_HandleEvent(theEvent) < 0 ) { PySys_WriteStderr("Exception in user event handler during AE processing\n"); PyErr_Clear(); } + #endif return 0; } From jackjansen@users.sourceforge.net Sun Sep 2 00:38:52 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:38:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae aesupport.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv2828/Python/Mac/Modules/ae Modified Files: aesupport.py Log Message: Don't call PyMac_HandleEvent if we're in unix-Python. Index: aesupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/aesupport.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** aesupport.py 2001/08/23 13:47:45 1.23 --- aesupport.py 2001/09/01 23:38:50 1.24 *************** *** 106,113 **** --- 106,115 ---- if ( PyOS_InterruptOccurred() ) return 1; + #if !TARGET_API_MAC_OSX if ( PyMac_HandleEvent(theEvent) < 0 ) { PySys_WriteStderr("Exception in user event handler during AE processing\\n"); PyErr_Clear(); } + #endif return 0; } From jackjansen@users.sourceforge.net Sun Sep 2 00:39:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:39:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python mactoolboxglue.c,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3096/Python/Python Modified Files: mactoolboxglue.c Log Message: Added glue routine for PyMac_BuildFSSpec, PyMac_GetFSRef and PyMac_BuildFSRef. Moved the declarations to pymactoolbox.h. Index: mactoolboxglue.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/mactoolboxglue.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mactoolboxglue.c 2001/08/27 14:01:05 1.4 --- mactoolboxglue.c 2001/09/01 23:39:43 1.5 *************** *** 347,351 **** --- 347,355 ---- return (*PyMacGluePtr_##routinename)(pyobj, cobj); \ } + + GLUE_NEW(FSSpec *, PyMac_BuildFSSpec, "macfs") GLUE_CONVERT(FSSpec, PyMac_GetFSSpec, "macfs") + GLUE_NEW(FSRef *, PyMac_BuildFSRef, "macfs") + GLUE_CONVERT(FSRef, PyMac_GetFSRef, "macfs") GLUE_NEW(AppleEvent *, AEDesc_New, "Carbon.AE") /* XXXX Why by address? */ From jackjansen@users.sourceforge.net Sun Sep 2 00:39:50 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:39:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macfsmodule.c,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3122/Python/Mac/Modules Modified Files: macfsmodule.c Log Message: Added glue routine for PyMac_BuildFSSpec, PyMac_GetFSRef and PyMac_BuildFSRef. Moved the declarations to pymactoolbox.h. Index: macfsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macfsmodule.c,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** macfsmodule.c 2001/08/08 13:46:49 1.42 --- macfsmodule.c 2001/09/01 23:39:48 1.43 *************** *** 42,46 **** --- 42,52 ---- #ifdef USE_TOOLBOX_OBJECT_GLUE extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); + extern PyObject *_PyMac_BuildFSRef(FSRef *); + extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); + extern PyObject *_PyMac_BuildFSRef(FSRef *); #define PyMac_GetFSSpec _PyMac_GetFSSpec + #define PyMac_BuildFSSpec _PyMac_BuildFSSpec + #define PyMac_GetFSRef _PyMac_GetFSRef + #define PyMac_BuildFSRef _PyMac_BuildFSRef #endif static PyObject *ErrorObject; *************** *** 1208,1211 **** --- 1214,1220 ---- PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSSpec, PyMac_GetFSSpec); + PyMac_INIT_TOOLBOX_OBJECT_CONVERT(FSRef, PyMac_GetFSRef); + PyMac_INIT_TOOLBOX_OBJECT_NEW(FSSpec *, PyMac_BuildFSSpec); + PyMac_INIT_TOOLBOX_OBJECT_NEW(FSRef *, PyMac_BuildFSRef); /* Create the module and add the functions */ From jackjansen@users.sourceforge.net Sun Sep 2 00:39:55 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:39:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pymactoolbox.h,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv3158/Python/Include Modified Files: pymactoolbox.h Log Message: Added glue routine for PyMac_BuildFSSpec, PyMac_GetFSRef and PyMac_BuildFSRef. Moved the declarations to pymactoolbox.h. Index: pymactoolbox.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pymactoolbox.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pymactoolbox.h 2001/08/08 13:17:31 1.1 --- pymactoolbox.h 2001/09/01 23:39:53 1.2 *************** *** 89,93 **** /* macfs exports */ ! extern int PyMac_GetFSSpec(PyObject *, FSSpec *); /* AE exports */ --- 89,97 ---- /* macfs exports */ ! int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ ! PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ ! ! int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */ ! PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */ /* AE exports */ From jackjansen@users.sourceforge.net Sun Sep 2 00:40:21 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:40:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions dev.include,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv3369/Python/Mac/Distributions Modified Files: dev.include Log Message: xx.prj has been replaced by xx.mcp. Index: dev.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.include,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** dev.include 2001/08/03 13:31:35 1.18 --- dev.include 2001/09/01 23:40:19 1.19 *************** *** 20,23 **** --- 20,26 ---- (':Extensions:README', None) (':Extensions:README.TOO', None) + (':Extensions:example', None) + (':Extensions:example2', None) + (':Extensions:example3', None) (':Extensions:img', None) (':Extensions:midi', None) *************** *** 31,45 **** (':Lib', None) (':Mac:Build:App.carbon.mcp', None) ! (':Mac:Build:App.carbon.mcp.exp', None) ! (':Mac:Build:App.carbon.mcp.xml', None) ! (':Mac:Build:App.mcp', None) ! (':Mac:Build:App.mcp.exp', None) ! (':Mac:Build:App.mcp.xml', None) ! (':Mac:Build:Cm.carbon.mcp', None) ! (':Mac:Build:Cm.carbon.mcp.exp', None) ! (':Mac:Build:Cm.carbon.mcp.xml', None) ! (':Mac:Build:Cm.mcp', None) ! (':Mac:Build:Cm.mcp.exp', None) ! (':Mac:Build:Cm.mcp.xml', None) (':Mac:Build:ColorPicker.carbon.mcp', None) (':Mac:Build:ColorPicker.carbon.mcp.exp', None) --- 34,39 ---- (':Lib', None) (':Mac:Build:App.carbon.mcp', None) ! (':Mac:Build:CF.carbon.mcp.exp', None) ! (':Mac:Build:CF.carbon.mcp.xml', None) (':Mac:Build:ColorPicker.carbon.mcp', None) (':Mac:Build:ColorPicker.carbon.mcp.exp', None) *************** *** 48,74 **** (':Mac:Build:ColorPicker.mcp.exp', None) (':Mac:Build:ColorPicker.mcp.xml', None) ! (':Mac:Build:Fm.carbon.mcp', None) ! (':Mac:Build:Fm.carbon.mcp.exp', None) ! (':Mac:Build:Fm.carbon.mcp.xml', None) ! (':Mac:Build:Fm.mcp', None) ! (':Mac:Build:Fm.mcp.exp', None) ! (':Mac:Build:Fm.mcp.xml', None) ! (':Mac:Build:Help.mcp', None) (':Mac:Build:Help.mcp.exp', None) (':Mac:Build:Help.mcp.xml', None) (':Mac:Build:HtmlRender.prj', None) - (':Mac:Build:HtmlRender.prj.exp', None) - (':Mac:Build:Icn.carbon.mcp', None) (':Mac:Build:Icn.carbon.mcp.exp', None) (':Mac:Build:Icn.carbon.mcp.xml', None) ! (':Mac:Build:Icn.mcp', None) ! (':Mac:Build:Icn.mcp.exp', None) ! (':Mac:Build:Icn.mcp.xml', None) ! (':Mac:Build:List.carbon.mcp', None) ! (':Mac:Build:List.carbon.mcp.exp', None) ! (':Mac:Build:List.carbon.mcp.xml', None) ! (':Mac:Build:List.mcp', None) ! (':Mac:Build:List.mcp.exp', None) ! (':Mac:Build:List.mcp.xml', None) (':Mac:Build:Printing.mcp', None) (':Mac:Build:Printing.mcp.exp', None) --- 42,64 ---- (':Mac:Build:ColorPicker.mcp.exp', None) (':Mac:Build:ColorPicker.mcp.xml', None) ! (':Mac:Build:Dlg.mcp.exp', None) ! (':Mac:Build:Dlg.mcp.xml', None) ! (':Mac:Build:Drag.carbon.mcp.exp', None) ! (':Mac:Build:Drag.carbon.mcp.xml', None) ! (':Mac:Build:Drag.mcp.exp', None) ! (':Mac:Build:Drag.mcp.xml', None) (':Mac:Build:Help.mcp.exp', None) (':Mac:Build:Help.mcp.xml', None) (':Mac:Build:HtmlRender.prj', None) (':Mac:Build:Icn.carbon.mcp.exp', None) (':Mac:Build:Icn.carbon.mcp.xml', None) ! (':Mac:Build:Menu.carbon.mcp.exp', None) ! (':Mac:Build:Menu.carbon.mcp.xml', None) ! (':Mac:Build:Menu.mcp.exp', None) ! (':Mac:Build:Menu.mcp.xml', None) ! (':Mac:Build:Mlte.carbon.mcp.exp', None) ! (':Mac:Build:Mlte.carbon.mcp.xml', None) ! (':Mac:Build:Mlte.mcp.exp', None) ! (':Mac:Build:Mlte.mcp.xml', None) (':Mac:Build:Printing.mcp', None) (':Mac:Build:Printing.mcp.exp', None) *************** *** 79,123 **** (':Mac:Build:PythonInterpreter.mcp', None) (':Mac:Build:PythonStandSmall.mcp', None) (':Mac:Build:PythonStandalone.mcp', None) ! (':Mac:Build:Qdoffs.carbon.mcp', None) ! (':Mac:Build:Qdoffs.carbon.mcp.exp', None) ! (':Mac:Build:Qdoffs.carbon.mcp.xml', None) ! (':Mac:Build:Qdoffs.mcp', None) ! (':Mac:Build:Qdoffs.mcp.exp', None) ! (':Mac:Build:Qdoffs.mcp.xml', None) ! (':Mac:Build:Qt.carbon.mcp', None) (':Mac:Build:Qt.carbon.mcp.exp', None) ! (':Mac:Build:Qt.carbon.mcp.xml', None) ! (':Mac:Build:Qt.mcp', None) (':Mac:Build:Qt.mcp.exp', None) ! (':Mac:Build:Qt.mcp.xml', None) ! (':Mac:Build:Scrap.carbon.mcp', None) ! (':Mac:Build:Scrap.carbon.mcp.exp', None) ! (':Mac:Build:Scrap.carbon.mcp.xml', None) ! (':Mac:Build:Scrap.mcp', None) ! (':Mac:Build:Scrap.mcp.exp', None) ! (':Mac:Build:Scrap.mcp.xml', None) ! (':Mac:Build:Snd.carbon.mcp', None) (':Mac:Build:Snd.carbon.mcp.exp', None) (':Mac:Build:Snd.carbon.mcp.xml', None) - (':Mac:Build:Snd.mcp', None) (':Mac:Build:Snd.mcp.exp', None) (':Mac:Build:Snd.mcp.xml', None) - (':Mac:Build:Sndihooks.carbon.mcp', None) - (':Mac:Build:Sndihooks.carbon.mcp.exp', None) - (':Mac:Build:Sndihooks.carbon.mcp.xml', None) - (':Mac:Build:Sndihooks.mcp', None) - (':Mac:Build:Sndihooks.mcp.exp', None) - (':Mac:Build:Sndihooks.mcp.xml', None) - (':Mac:Build:TE.carbon.mcp', None) (':Mac:Build:TE.carbon.mcp.exp', None) (':Mac:Build:TE.carbon.mcp.xml', None) - (':Mac:Build:TE.mcp', None) (':Mac:Build:TE.mcp.exp', None) (':Mac:Build:TE.mcp.xml', None) ! (':Mac:Build:TE.mcp.xml.out', None) (':Mac:Build:_dummy_tkinter.mcp', None) (':Mac:Build:_dummy_tkinter.mcp.exp', None) - (':Mac:Build:_dummy_tkinter.old.mcp', None) (':Mac:Build:_symtable.carbon.mcp', None) (':Mac:Build:_symtable.carbon.mcp.exp', None) --- 69,227 ---- (':Mac:Build:PythonInterpreter.mcp', None) (':Mac:Build:PythonStandSmall.mcp', None) + (':Mac:Build:PythonStandSmall.mcp~0', None) + (':Mac:Build:PythonStandSmall.mcp~1', None) (':Mac:Build:PythonStandalone.mcp', None) ! (':Mac:Build:PythonStandalone.mcp~0', None) ! (':Mac:Build:PythonStandalone.mcp~1', None) (':Mac:Build:Qt.carbon.mcp.exp', None) ! (':Mac:Build:Qt.carbon.mcp.xml~0', None) (':Mac:Build:Qt.mcp.exp', None) ! (':Mac:Build:Qt.mcp.xml~0', None) (':Mac:Build:Snd.carbon.mcp.exp', None) (':Mac:Build:Snd.carbon.mcp.xml', None) (':Mac:Build:Snd.mcp.exp', None) (':Mac:Build:Snd.mcp.xml', None) (':Mac:Build:TE.carbon.mcp.exp', None) (':Mac:Build:TE.carbon.mcp.xml', None) (':Mac:Build:TE.mcp.exp', None) (':Mac:Build:TE.mcp.xml', None) ! (':Mac:Build:Win.carbon.mcp.exp', None) ! (':Mac:Build:Win.carbon.mcp.xml', None) ! (':Mac:Build:Win.mcp.exp', None) ! (':Mac:Build:Win.mcp.xml', None) ! (':Mac:Build:_AE.carbon.mcp', None) ! (':Mac:Build:_AE.carbon.mcp.exp', None) ! (':Mac:Build:_AE.carbon.mcp.xml', None) ! (':Mac:Build:_AE.mcp', None) ! (':Mac:Build:_AE.mcp.exp', None) ! (':Mac:Build:_AE.mcp.xml', None) ! (':Mac:Build:_App.carbon.mcp', None) ! (':Mac:Build:_App.carbon.mcp.exp', None) ! (':Mac:Build:_App.carbon.mcp.xml', None) ! (':Mac:Build:_App.mcp', None) ! (':Mac:Build:_App.mcp.exp', None) ! (':Mac:Build:_App.mcp.xml', None) ! (':Mac:Build:_CF.carbon.mcp', None) ! (':Mac:Build:_CF.carbon.mcp.exp', None) ! (':Mac:Build:_CF.carbon.mcp.xml', None) ! (':Mac:Build:_Cm.carbon.mcp', None) ! (':Mac:Build:_Cm.carbon.mcp.exp', None) ! (':Mac:Build:_Cm.carbon.mcp.xml', None) ! (':Mac:Build:_Cm.mcp', None) ! (':Mac:Build:_Cm.mcp.exp', None) ! (':Mac:Build:_Cm.mcp.xml', None) ! (':Mac:Build:_Ctl.carbon.mcp', None) ! (':Mac:Build:_Ctl.carbon.mcp.exp', None) ! (':Mac:Build:_Ctl.carbon.mcp.xml', None) ! (':Mac:Build:_Ctl.mcp', None) ! (':Mac:Build:_Ctl.mcp.exp', None) ! (':Mac:Build:_Ctl.mcp.xml', None) ! (':Mac:Build:_Dlg.carbon.mcp', None) ! (':Mac:Build:_Dlg.carbon.mcp.exp', None) ! (':Mac:Build:_Dlg.carbon.mcp.xml', None) ! (':Mac:Build:_Dlg.mcp', None) ! (':Mac:Build:_Dlg.mcp.exp', None) ! (':Mac:Build:_Dlg.mcp.xml', None) ! (':Mac:Build:_Drag.carbon.mcp', None) ! (':Mac:Build:_Drag.carbon.mcp.exp', None) ! (':Mac:Build:_Drag.carbon.mcp.xml', None) ! (':Mac:Build:_Drag.mcp', None) ! (':Mac:Build:_Drag.mcp.exp', None) ! (':Mac:Build:_Drag.mcp.xml', None) ! (':Mac:Build:_Evt.carbon.mcp', None) ! (':Mac:Build:_Evt.carbon.mcp.exp', None) ! (':Mac:Build:_Evt.carbon.mcp.xml', None) ! (':Mac:Build:_Evt.mcp', None) ! (':Mac:Build:_Evt.mcp.exp', None) ! (':Mac:Build:_Evt.mcp.xml', None) ! (':Mac:Build:_Fm.carbon.mcp', None) ! (':Mac:Build:_Fm.carbon.mcp.exp', None) ! (':Mac:Build:_Fm.carbon.mcp.xml', None) ! (':Mac:Build:_Fm.mcp', None) ! (':Mac:Build:_Fm.mcp.exp', None) ! (':Mac:Build:_Fm.mcp.xml', None) ! (':Mac:Build:_Help.mcp', None) ! (':Mac:Build:_Help.mcp.exp', None) ! (':Mac:Build:_Help.mcp.xml', None) ! (':Mac:Build:_Icn.carbon.mcp', None) ! (':Mac:Build:_Icn.carbon.mcp.exp', None) ! (':Mac:Build:_Icn.carbon.mcp.xml', None) ! (':Mac:Build:_Icn.mcp', None) ! (':Mac:Build:_Icn.mcp.exp', None) ! (':Mac:Build:_Icn.mcp.xml', None) ! (':Mac:Build:_List.carbon.mcp', None) ! (':Mac:Build:_List.carbon.mcp.exp', None) ! (':Mac:Build:_List.carbon.mcp.xml', None) ! (':Mac:Build:_List.mcp', None) ! (':Mac:Build:_List.mcp.exp', None) ! (':Mac:Build:_List.mcp.xml', None) ! (':Mac:Build:_Menu.carbon.mcp', None) ! (':Mac:Build:_Menu.carbon.mcp.exp', None) ! (':Mac:Build:_Menu.carbon.mcp.xml', None) ! (':Mac:Build:_Menu.mcp', None) ! (':Mac:Build:_Menu.mcp.exp', None) ! (':Mac:Build:_Menu.mcp.xml', None) ! (':Mac:Build:_Mlte.carbon.mcp', None) ! (':Mac:Build:_Mlte.carbon.mcp.exp', None) ! (':Mac:Build:_Mlte.carbon.mcp.xml', None) ! (':Mac:Build:_Mlte.mcp', None) ! (':Mac:Build:_Mlte.mcp.exp', None) ! (':Mac:Build:_Mlte.mcp.xml', None) ! (':Mac:Build:_Qd.carbon.mcp', None) ! (':Mac:Build:_Qd.carbon.mcp.exp', None) ! (':Mac:Build:_Qd.carbon.mcp.xml', None) ! (':Mac:Build:_Qd.mcp', None) ! (':Mac:Build:_Qd.mcp.exp', None) ! (':Mac:Build:_Qd.mcp.xml', None) ! (':Mac:Build:_Qdoffs.carbon.mcp', None) ! (':Mac:Build:_Qdoffs.carbon.mcp.exp', None) ! (':Mac:Build:_Qdoffs.carbon.mcp.xml', None) ! (':Mac:Build:_Qdoffs.mcp', None) ! (':Mac:Build:_Qdoffs.mcp.exp', None) ! (':Mac:Build:_Qdoffs.mcp.xml', None) ! (':Mac:Build:_Qt.carbon.mcp', None) ! (':Mac:Build:_Qt.carbon.mcp.exp', None) ! (':Mac:Build:_Qt.carbon.mcp.xml', None) ! (':Mac:Build:_Qt.mcp', None) ! (':Mac:Build:_Qt.mcp.exp', None) ! (':Mac:Build:_Qt.mcp.xml', None) ! (':Mac:Build:_Res.carbon.mcp', None) ! (':Mac:Build:_Res.carbon.mcp.exp', None) ! (':Mac:Build:_Res.carbon.mcp.xml', None) ! (':Mac:Build:_Res.mcp', None) ! (':Mac:Build:_Res.mcp.exp', None) ! (':Mac:Build:_Res.mcp.xml', None) ! (':Mac:Build:_Scrap.carbon.mcp', None) ! (':Mac:Build:_Scrap.carbon.mcp.exp', None) ! (':Mac:Build:_Scrap.carbon.mcp.xml', None) ! (':Mac:Build:_Scrap.mcp', None) ! (':Mac:Build:_Scrap.mcp.exp', None) ! (':Mac:Build:_Scrap.mcp.xml', None) ! (':Mac:Build:_Snd.carbon.mcp', None) ! (':Mac:Build:_Snd.carbon.mcp.exp', None) ! (':Mac:Build:_Snd.carbon.mcp.xml', None) ! (':Mac:Build:_Snd.mcp', None) ! (':Mac:Build:_Snd.mcp.exp', None) ! (':Mac:Build:_Snd.mcp.xml', None) ! (':Mac:Build:_Sndihooks.carbon.mcp', None) ! (':Mac:Build:_Sndihooks.carbon.mcp.exp', None) ! (':Mac:Build:_Sndihooks.carbon.mcp.xml', None) ! (':Mac:Build:_Sndihooks.mcp', None) ! (':Mac:Build:_Sndihooks.mcp.exp', None) ! (':Mac:Build:_Sndihooks.mcp.xml', None) ! (':Mac:Build:_TE.carbon.mcp', None) ! (':Mac:Build:_TE.carbon.mcp.exp', None) ! (':Mac:Build:_TE.carbon.mcp.xml', None) ! (':Mac:Build:_TE.mcp', None) ! (':Mac:Build:_TE.mcp.exp', None) ! (':Mac:Build:_TE.mcp.xml', None) ! (':Mac:Build:_Win.carbon.mcp', None) ! (':Mac:Build:_Win.carbon.mcp.exp', None) ! (':Mac:Build:_Win.carbon.mcp.xml', None) ! (':Mac:Build:_Win.mcp', None) ! (':Mac:Build:_Win.mcp.exp', None) ! (':Mac:Build:_Win.mcp.xml', None) (':Mac:Build:_dummy_tkinter.mcp', None) (':Mac:Build:_dummy_tkinter.mcp.exp', None) (':Mac:Build:_symtable.carbon.mcp', None) (':Mac:Build:_symtable.carbon.mcp.exp', None) *************** *** 175,180 **** (':Mac:Build:waste.mcp.exp', None) (':Mac:Build:waste.mcp.xml', None) ! (':Mac:Build:xx.prj', '') ! (':Mac:Build:xx.prj.exp', '') (':Mac:Build:zlib.carbon.mcp', None) (':Mac:Build:zlib.carbon.mcp.exp', None) --- 279,291 ---- (':Mac:Build:waste.mcp.exp', None) (':Mac:Build:waste.mcp.xml', None) ! (':Mac:Build:xx.carbon.mcp', '') ! (':Mac:Build:xx.carbon.mcp.exp', '') ! (':Mac:Build:xx.carbon.mcp.xml', '') ! (':Mac:Build:xxsubtype.carbon.mcp', None) ! (':Mac:Build:xxsubtype.carbon.mcp.exp', None) ! (':Mac:Build:xxsubtype.carbon.mcp.xml', None) ! (':Mac:Build:xxsubtype.mcp', None) ! (':Mac:Build:xxsubtype.mcp.exp', None) ! (':Mac:Build:xxsubtype.mcp.xml', None) (':Mac:Build:zlib.carbon.mcp', None) (':Mac:Build:zlib.carbon.mcp.exp', None) *************** *** 215,218 **** --- 326,330 ---- (':Mac:Demo:interslip', ':Mac:Demo:interslip') (':Mac:Demo:mainloops.txt', None) + (':Mac:Demo:mlte:mlted.py', None) (':Mac:Demo:mpwextensions.html', None) (':Mac:Demo:plugins.html', None) *************** *** 240,243 **** --- 352,357 ---- (':Mac:Modules', None) (':Mac:OSX:README.macosx.txt', None) + (':Mac:OSXResources', None) + (':Mac:OSXResources:', None) (':Mac:PlugIns:readme.txt', None) (':Mac:Python', None) *************** *** 266,273 **** (':Mac:mwerks:macuseshlstart.c', None) (':Mac:mwerks:malloc', None) - (':Mac:mwerks:mwerks_applet_config.h', ':Mac:mwerks:mwerks_applet_config.h') (':Mac:mwerks:mwerks_carbonNOGUSI_config.h', None) (':Mac:mwerks:mwerks_carbon_config.h', '') - (':Mac:mwerks:mwerks_carbongusi_config.h', '') (':Mac:mwerks:mwerks_carbonplugin_config.h', '') (':Mac:mwerks:mwerks_nonshared_config.h', ':Mac:mwerks:') --- 380,385 ---- *************** *** 304,307 **** --- 416,420 ---- (':Modules:_tkinter.c', None) (':Modules:_weakref.c', None) + (':Modules:addrinfo.h', None) (':Modules:almodule.c', None) (':Modules:ar_beos', None) *************** *** 333,337 **** --- 446,452 ---- (':Modules:gcmodule.c', None) (':Modules:gdbmmodule.c', None) + (':Modules:getaddrinfo.c', None) (':Modules:getbuildinfo.c', None) + (':Modules:getnameinfo.c', None) (':Modules:getpath.c', None) (':Modules:glmodule.c', None) *************** *** 388,391 **** --- 503,507 ---- (':Modules:tclNotify.c', None) (':Modules:termios.c', None) + (':Modules:testcapi_long.h', None) (':Modules:threadmodule.c', None) (':Modules:timemodule.c', None) *************** *** 401,404 **** --- 517,521 ---- (':Modules:xreadlinesmodule.c', None) (':Modules:xxmodule.c', '') + (':Modules:xxsubtype.c', None) (':Modules:yuv.h', None) (':Modules:yuvconvert.c', None) *************** *** 408,411 **** --- 525,529 ---- (':PC', None) (':PCbuild', None) + (':PLAN.txt', None) (':Parser', None) (':PlugIns', None) *************** *** 452,470 **** (':loop.py', None) (':mac2unix.shar', None) (':pystone.py', None) (':readmefiles', None) (':setup.py', None) (':site-packages', None) ! (':Extensions:example', None) ! (':Extensions:example2', None) ! (':Extensions:example3', None) ! (':Mac:Demo:mlte:mlted.py', None) ! (':Mac:Build:Mlte.mcp.xml', None) ! (':Mac:Build:Mlte.mcp.exp', None) ! (':Mac:Build:Mlte.mcp', None) ! (':Mac:Build:Mlte.carbon.mcp.xml', None) ! (':Mac:Build:Mlte.carbon.mcp.exp', None) ! (':Mac:Build:Mlte.carbon.mcp', None) ! (':Mac:Build:CF.carbon.mcp.xml', None) ! (':Mac:Build:CF.carbon.mcp.exp', None) ! (':Mac:Build:CF.carbon.mcp', None) --- 570,579 ---- (':loop.py', None) (':mac2unix.shar', None) + (':pyconfig.h.in', None) (':pystone.py', None) (':readmefiles', None) (':setup.py', None) (':site-packages', None) ! (':Mac:Build:xx.mcp', '') ! (':Mac:Build:xx.mcp.exp', '') ! (':Mac:Build:xx.mcp.xml', None) From jackjansen@users.sourceforge.net Sun Sep 2 00:40:00 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:40:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Include macglue.h,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Include In directory usw-pr-cvs1:/tmp/cvs-serv3183/Python/Mac/Include Modified Files: macglue.h Log Message: Added glue routine for PyMac_BuildFSSpec, PyMac_GetFSRef and PyMac_BuildFSRef. Moved the declarations to pymactoolbox.h. Index: macglue.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Include/macglue.h,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** macglue.h 2001/08/08 13:17:31 1.56 --- macglue.h 2001/09/01 23:39:58 1.57 *************** *** 103,113 **** #endif - /* from macfsmodule.c: */ - int PyMac_GetFSSpec(PyObject *, FSSpec *); /* argument parser for FSSpec */ - PyObject *PyMac_BuildFSSpec(FSSpec *); /* Convert FSSpec to PyObject */ - - int PyMac_GetFSRef(PyObject *, FSRef *); /* argument parser for FSRef */ - PyObject *PyMac_BuildFSRef(FSRef *); /* Convert FSRef to PyObject */ - /* From macfiletype.c: */ --- 103,106 ---- From jackjansen@users.sourceforge.net Sun Sep 2 00:41:47 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:41:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCoreCarbon.exp,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv3833/Python/Mac/Build Modified Files: PythonCoreCarbon.exp Log Message: Regenerated, mainly for new GC routines. Index: PythonCoreCarbon.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCoreCarbon.exp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PythonCoreCarbon.exp 2001/08/10 12:17:04 1.13 --- PythonCoreCarbon.exp 2001/09/01 23:41:44 1.14 *************** *** 349,352 **** --- 349,353 ---- PyDict_Size PyDict_Copy + PyDict_Merge PyDict_Update PyDict_Next *************** *** 433,436 **** --- 434,438 ---- Py_FindMethod Py_FindMethodInChain + PyCFunction_Call PyCFunction_GetFlags PyCFunction_GetSelf *************** *** 461,464 **** --- 463,467 ---- PyMem_Realloc PyMem_Malloc + _Py_ReadyTypes PyCallable_Check PyNumber_Coerce *************** *** 484,488 **** PyObject_Str PyObject_Repr - _PyGC_Dump _PyObject_Dump PyObject_Print --- 487,490 ---- *************** *** 519,522 **** --- 521,526 ---- PyString_AsDecodedObject PyString_Decode + PyString_FromFormat + PyString_FromFormatV PyString_FromString PyString_FromStringAndSize *************** *** 532,537 **** --- 536,543 ---- PyType_Type PyBaseObject_Type + PySuper_Type PyType_Ready _PyType_Lookup + call_method PyType_IsSubtype PyType_GenericNew *************** *** 643,646 **** --- 649,653 ---- SpinCursor PyMac_GetFullPath + __convert_to_newlines PyMac_AppRefNum PyMac_options *************** *** 841,844 **** --- 848,852 ---- PyExc_DeprecationWarning PyExc_SyntaxWarning + PyExc_OverflowWarning PyExc_RuntimeWarning _PyExc_Fini *************** *** 864,867 **** --- 872,876 ---- proxytype wrappertype + PyGetSet_Type PyWrapper_New PyDictProxy_New *************** *** 872,878 **** PyDescr_NewMember PyDescr_NewMethod initgc - _PyGC_Remove - _PyGC_Insert PyMac_OSErrException PyMacGluePtr_PyMac_GetFSSpec --- 881,894 ---- PyDescr_NewMember PyDescr_NewMethod + _PyGC_generation0 + _PyObject_GC_Del + _PyObject_GC_Resize + _PyObject_GC_NewVar + _PyObject_GC_New + _PyObject_GC_Malloc + _PyObject_GC_UnTrack + _PyObject_GC_Track + _PyGC_Dump initgc PyMac_OSErrException PyMacGluePtr_PyMac_GetFSSpec *************** *** 1953,1957 **** __load_buffer __prep_buffer - __convert_to_newlines __convert_from_newlines ccommand --- 1969,1972 ---- From jackjansen@users.sourceforge.net Sun Sep 2 00:42:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 16:42:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Build PythonCore.exp,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Build In directory usw-pr-cvs1:/tmp/cvs-serv4059/Python/Mac/Build Modified Files: PythonCore.exp Log Message: Regenerated, mainly for new GC routines. Index: PythonCore.exp =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Build/PythonCore.exp,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** PythonCore.exp 2001/08/10 12:16:55 1.13 --- PythonCore.exp 2001/09/01 23:42:11 1.14 *************** *** 349,352 **** --- 349,353 ---- PyDict_Size PyDict_Copy + PyDict_Merge PyDict_Update PyDict_Next *************** *** 433,436 **** --- 434,438 ---- Py_FindMethod Py_FindMethodInChain + PyCFunction_Call PyCFunction_GetFlags PyCFunction_GetSelf *************** *** 461,464 **** --- 463,467 ---- PyMem_Realloc PyMem_Malloc + _Py_ReadyTypes PyCallable_Check PyNumber_Coerce *************** *** 484,488 **** PyObject_Str PyObject_Repr - _PyGC_Dump _PyObject_Dump PyObject_Print --- 487,490 ---- *************** *** 519,522 **** --- 521,526 ---- PyString_AsDecodedObject PyString_Decode + PyString_FromFormat + PyString_FromFormatV PyString_FromString PyString_FromStringAndSize *************** *** 532,537 **** --- 536,543 ---- PyType_Type PyBaseObject_Type + PySuper_Type PyType_Ready _PyType_Lookup + call_method PyType_IsSubtype PyType_GenericNew *************** *** 649,652 **** --- 655,659 ---- SpinCursor PyMac_GetFullPath + __convert_to_newlines PyMac_AppRefNum PyMac_options *************** *** 847,850 **** --- 854,858 ---- PyExc_DeprecationWarning PyExc_SyntaxWarning + PyExc_OverflowWarning PyExc_RuntimeWarning _PyExc_Fini *************** *** 870,873 **** --- 878,882 ---- proxytype wrappertype + PyGetSet_Type PyWrapper_New PyDictProxy_New *************** *** 878,884 **** PyDescr_NewMember PyDescr_NewMethod initgc - _PyGC_Remove - _PyGC_Insert PyMac_OSErrException PyMacGluePtr_PyMac_GetFSSpec --- 887,900 ---- PyDescr_NewMember PyDescr_NewMethod + _PyGC_generation0 + _PyObject_GC_Del + _PyObject_GC_Resize + _PyObject_GC_NewVar + _PyObject_GC_New + _PyObject_GC_Malloc + _PyObject_GC_UnTrack + _PyObject_GC_Track + _PyGC_Dump initgc PyMac_OSErrException PyMacGluePtr_PyMac_GetFSSpec *************** *** 2075,2079 **** __load_buffer __prep_buffer - __convert_to_newlines __convert_from_newlines ccommand --- 2091,2094 ---- From jackjansen@users.sourceforge.net Sun Sep 2 01:08:18 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 17:08:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules Nav.c,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8279 Modified Files: Nav.c Log Message: Don't call PyMac_HandleEvent in unix-Python Index: Nav.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/Nav.c,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** Nav.c 2001/05/22 21:48:40 1.13 --- Nav.c 2001/09/02 00:08:16 1.14 *************** *** 61,64 **** --- 61,65 ---- } if ( pyfunc == Py_None ) { + #if !TARGET_API_MAC_OSX /* Special case: give update events to the Python event handling code */ if ( callBackSelector == kNavCBEvent && *************** *** 66,69 **** --- 67,71 ---- PyMac_HandleEvent(callBackParms->eventData.eventDataParms.event); /* Ignore others */ + #endif return; } From jackjansen@users.sourceforge.net Sun Sep 2 01:09:37 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sat, 01 Sep 2001 17:09:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules macfsmodule.c,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8498 Modified Files: macfsmodule.c Log Message: Silly typos. Index: macfsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/macfsmodule.c,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** macfsmodule.c 2001/09/01 23:39:48 1.43 --- macfsmodule.c 2001/09/02 00:09:35 1.44 *************** *** 42,47 **** #ifdef USE_TOOLBOX_OBJECT_GLUE extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); ! extern PyObject *_PyMac_BuildFSRef(FSRef *); ! extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); extern PyObject *_PyMac_BuildFSRef(FSRef *); #define PyMac_GetFSSpec _PyMac_GetFSSpec --- 42,47 ---- #ifdef USE_TOOLBOX_OBJECT_GLUE extern int _PyMac_GetFSSpec(PyObject *, FSSpec *); ! extern PyObject *_PyMac_BuildFSSpec(FSSpec *); ! extern int _PyMac_GetFSRef(PyObject *, FSRef *); extern PyObject *_PyMac_BuildFSRef(FSRef *); #define PyMac_GetFSSpec _PyMac_GetFSSpec From tim_one@users.sourceforge.net Sun Sep 2 04:41:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 01 Sep 2001 20:41:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.220,1.221 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv11094/python/Misc Modified Files: NEWS Log Message: Start items w/ "-" instead of "+" (consistency w/ earlier versions). Stephen Hansen reported via email that he didn't finish the port to Borland C, so remove the old item saying it worked and add a new item saying what I know; I've asked Stephen for more details. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.220 retrieving revision 1.221 diff -C2 -d -r1.220 -r1.221 *** NEWS 2001/08/31 18:31:35 1.220 --- NEWS 2001/09/02 03:40:59 1.221 *************** *** 4,8 **** Core ! + Overflowing operations on plain ints now return a long int rather than raising OverflowError. This is a partial implementation of PEP 237. You can use -Wdefault::OverflowWarning to enable a warning for --- 4,8 ---- Core ! - Overflowing operations on plain ints now return a long int rather than raising OverflowError. This is a partial implementation of PEP 237. You can use -Wdefault::OverflowWarning to enable a warning for *************** *** 10,14 **** OverflowError exception. ! + A new command line option, -D, is added to control run-time warnings for the use of classic division. (See PEP 238.) Possible values are -Dold, -Dwarn, and -Dnew. The default is -Dold, meaning --- 10,14 ---- OverflowError exception. ! - A new command line option, -D, is added to control run-time warnings for the use of classic division. (See PEP 238.) Possible values are -Dold, -Dwarn, and -Dnew. The default is -Dold, meaning *************** *** 21,25 **** division everywhere else. ! + Many built-in types can now be subclassed. This applies to int, long, float, str, unicode, and tuple. (The types complex, list and dictionary can also be subclassed; this was introduced earlier.) --- 21,25 ---- division everywhere else. ! - Many built-in types can now be subclassed. This applies to int, long, float, str, unicode, and tuple. (The types complex, list and dictionary can also be subclassed; this was introduced earlier.) *************** *** 31,39 **** once it is created. ! + A new built-in type, super, has been added. This facilitates making "cooperative super calls" in a multiple inheritance setting. For an explanation, see http://www.python.org/2.2/descrintro.html#cooperation ! + A new built-in type, getset, has been added. This enables the creation of "computed attributes". Such attributes are implemented by getter and setter functions (or only one of these for read-only --- 31,39 ---- once it is created. ! - A new built-in type, super, has been added. This facilitates making "cooperative super calls" in a multiple inheritance setting. For an explanation, see http://www.python.org/2.2/descrintro.html#cooperation ! - A new built-in type, getset, has been added. This enables the creation of "computed attributes". Such attributes are implemented by getter and setter functions (or only one of these for read-only *************** *** 41,45 **** __getattr__. See http://www.python.org/2.2/descrintro.html#getset ! + The syntax of floating-point and imaginary literals has been liberalized, to allow leading zeroes. Examples of literals now legal that were SyntaxErrors before: --- 41,45 ---- __getattr__. See http://www.python.org/2.2/descrintro.html#getset ! - The syntax of floating-point and imaginary literals has been liberalized, to allow leading zeroes. Examples of literals now legal that were SyntaxErrors before: *************** *** 47,64 **** 00.0 0e3 0100j 07.5 00000000000000000008. ! + An old tokenizer bug allowed floating point literals with an incomplete exponent, such as 1e and 3.1e-. Such literals now raise SyntaxError. Library ! + A new function, imp.lock_held(), returns 1 when the import lock is currently held. See the docs for the imp module. ! + pickle, cPickle and marshal on 32-bit platforms can now correctly read dumps containing ints written on platforms where Python ints are 8 bytes. When read on a box where Python ints are 4 bytes, such values are converted to Python longs. ! + In restricted execution mode (using the rexec module), unmarshalling code objects is no longer allowed. This plugs a security hole. --- 47,64 ---- 00.0 0e3 0100j 07.5 00000000000000000008. ! - An old tokenizer bug allowed floating point literals with an incomplete exponent, such as 1e and 3.1e-. Such literals now raise SyntaxError. Library ! - A new function, imp.lock_held(), returns 1 when the import lock is currently held. See the docs for the imp module. ! - pickle, cPickle and marshal on 32-bit platforms can now correctly read dumps containing ints written on platforms where Python ints are 8 bytes. When read on a box where Python ints are 4 bytes, such values are converted to Python longs. ! - In restricted execution mode (using the rexec module), unmarshalling code objects is no longer allowed. This plugs a security hole. *************** *** 69,73 **** API ! + The GC API has been changed. Extensions that use the old API will still compile but will not participate in GC. To upgrade an extension module: --- 69,73 ---- API ! - The GC API has been changed. Extensions that use the old API will still compile but will not participate in GC. To upgrade an extension module: *************** *** 85,89 **** - remove calls to PyObject_AS_GC and PyObject_FROM_GC ! + Two new functions: PyString_FromFormat() and PyString_FromFormatV(). These can be used safely to construct string objects from a sprintf-style format string (similar to the format string supported --- 85,89 ---- - remove calls to PyObject_AS_GC and PyObject_FROM_GC ! - Two new functions: PyString_FromFormat() and PyString_FromFormatV(). These can be used safely to construct string objects from a sprintf-style format string (similar to the format string supported *************** *** 92,100 **** New platforms Tests Windows ! + The w9xpopen hack is now used on Windows NT and 2000 too when COMPSPEC points to command.com (patch from Brian Quinlan). --- 92,104 ---- New platforms + - Patches from Stephen Hansen for the Borland C compiler (under Windows) + are reported to yield a clean compile, but a Python that doesn't yet + run correctly. Volunteers? + Tests Windows ! - The w9xpopen hack is now used on Windows NT and 2000 too when COMPSPEC points to command.com (patch from Brian Quinlan). *************** *** 436,444 **** pprint.isreadable() return sensible results. Also verifies that simple cases produce correct output. - - New platforms - - - Python should compile and run out of the box using the Borland C - compiler (under Windows), thanks to Stephen Hansen. C API --- 440,443 ---- From gvanrossum@users.sourceforge.net Sun Sep 2 04:58:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 20:58:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13534 Modified Files: regrtest.py Log Message: Whitespace normalization (tabs -> 4 spaces) in the Mac expectations. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** regrtest.py 2001/08/28 14:49:00 1.44 --- regrtest.py 2001/09/02 03:58:41 1.45 *************** *** 514,552 **** """, 'mac': ! """ ! test_al ! test_bsddb ! test_cd ! test_cl ! test_commands ! test_crypt ! test_dbm ! test_dl ! test_fcntl ! test_fork1 ! test_gl ! test_grp ! test_imgfile ! test_largefile ! test_linuxaudiodev ! test_locale ! test_mmap ! test_nis ! test_ntpath ! test_openpty ! test_poll ! test_popen2 ! test_pty ! test_pwd ! test_signal ! test_socket_ssl ! test_socketserver ! test_sunaudiodev ! test_sundry ! test_timing ! test_unicode_file ! test_winreg ! test_winsound ! """, } --- 514,552 ---- """, 'mac': ! """ ! test_al ! test_bsddb ! test_cd ! test_cl ! test_commands ! test_crypt ! test_dbm ! test_dl ! test_fcntl ! test_fork1 ! test_gl ! test_grp ! test_imgfile ! test_largefile ! test_linuxaudiodev ! test_locale ! test_mmap ! test_nis ! test_ntpath ! test_openpty ! test_poll ! test_popen2 ! test_pty ! test_pwd ! test_signal ! test_socket_ssl ! test_socketserver ! test_sunaudiodev ! test_sundry ! test_timing ! test_unicode_file ! test_winreg ! test_winsound ! """, } From gvanrossum@users.sourceforge.net Sun Sep 2 05:43:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 21:43:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts finddiv.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv18329 Added Files: finddiv.py Log Message: A grep-like tool that looks for division operators. --- NEW FILE: finddiv.py --- #! /usr/bin/env python """finddiv - a grep-like tool that looks for division operators. Usage: finddiv [-l] file_or_directory ... For directory arguments, all files in the directory whose name ends in .py are processed, and subdirectories are processed recursively. This actually tokenizes the files to avoid false hits in comments or strings literals. By default, this prints all lines containing a / or /= operator, in grep -n style. With the -l option specified, it prints the filename of files that contain at least one / or /= operator. """ import os import sys import getopt import tokenize def main(): try: opts, args = getopt.getopt(sys.argv[1:], "lh") except getopt.error, msg: usage(msg) return 2 if not args: usage("at least one file argument is required") return 2 listnames = 0 for o, a in opts: if o == "-h": print __doc__ return if o == "-l": listnames = 1 exit = None for file in args: x = process(file, listnames) exit = exit or x return exit def usage(msg): sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) sys.stderr.write("Usage: %s [-l] file ...\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) def process(file, listnames): if os.path.isdir(file): return processdir(file, listnames) try: fp = open(file) except IOError, msg: sys.stderr.write("Can't open: %s\n" % msg) return 1 g = tokenize.generate_tokens(fp.readline) lastrow = None for type, token, (row, col), end, line in g: if token in ("/", "/="): if listnames: print file break if row != lastrow: lastrow = row print "%s:%d:%s" % (file, row, line), fp.close() def processdir(dir, listnames): try: names = os.listdir(dir) except os.error, msg: sys.stderr.write("Can't list directory: %s\n" % dir) return 1 files = [] for name in names: fn = os.path.join(dir, name) if os.path.normcase(fn).endswith(".py") or os.path.isdir(fn): files.append(fn) files.sort(lambda a, b: cmp(os.path.normcase(a), os.path.normcase(b))) exit = None for fn in files: x = process(fn, listnames) exit = exit or x return exit if __name__ == "__main__": sys.exit(main()) From gvanrossum@users.sourceforge.net Sun Sep 2 05:49:38 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 21:49:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv19145 Modified Files: fixdiv.py Log Message: Added more text to the docstring, updated the way the exit status is percolated out, and some general cleanup. The output is still the same, except it now prints "Index: " instead of "Processing: ", so that the output can be used as input for patch (but only the diff-style parts of it). Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** fixdiv.py 2001/09/01 21:55:58 1.1 --- fixdiv.py 2001/09/02 04:49:36 1.2 *************** *** 6,12 **** This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file ! `warnings'. (The warnings are written to stderr, so you must use `2>' ! for the I/O redirect. I don't yet know how to do this on Windows.) Then run `python fixdiv.py warnings'. This first reads the warnings, looking for classic division warnings, and sorts them by file name and --- 6,23 ---- This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file ! `warnings'. The warnings look like this: ! ! :: DeprecationWarning: classic division ! ! The warnings are written to stderr, so you must use `2>' for the I/O ! redirect. I know of no way to redirect stderr on Windows in a DOS ! box, so you will have to modify the script to set sys.stderr to some ! kind of log file if you want to do this on Windows. + The warnings are not limited to the script; modules imported by the + script may also trigger warnings. In fact a useful technique is to + write a test script specifically intended to exercise all code in a + particular module or set of modules. + Then run `python fixdiv.py warnings'. This first reads the warnings, looking for classic division warnings, and sorts them by file name and *************** *** 15,19 **** operators found in the source code. If it is successful, it writes a recommendation to stdout in the form of a context diff. If it is not ! successful, it writes recommendations to stdout instead. """ --- 26,95 ---- operators found in the source code. If it is successful, it writes a recommendation to stdout in the form of a context diff. If it is not ! successful, it writes observations to stdout instead. ! ! There are several possible recommendations and observations: ! ! - A / operator was found that can remain unchanged. This is the ! recommendation when only float and/or complex arguments were seen. ! ! - A / operator was found that should be changed to //. This is the ! recommendation when only int and/or long arguments were seen. ! ! - A / operator was found for which int or long as well as float or ! complex arguments were seen. This is highly unlikely; if it occurs, ! you may have to restructure the code to keep the classic semantics, ! or maybe you don't care about the classic semantics. ! ! - A / operator was found for which no warnings were seen. This could ! be code that was never executed, or code that was only executed with ! with user-defined objects as arguments. You will have to ! investigate further. Note that // can be overloaded separately from ! /, using __floordiv__. True division can also be separately ! overloaded, using __truediv__. Classic division should be the same ! as either of those. (XXX should I add a warning for division on ! user-defined objects, to disambiguate this case from code that was ! never executed?) ! ! - A warning was seen for a line not containing a / operator. This is ! an anomaly that shouldn't happen; the most likely cause is a change ! to the file between the time the test script was run to collect ! warnings and the time fixdiv was run. ! ! - More than one / operator was found on one line, or in a statement ! split across multiple lines. Because the warnings framework doesn't ! (and can't) show the offset within the line, and the code generator ! doesn't always give the correct line number for operations in a ! multi-line statement, it's not clear whether both were executed. In ! practice, they usually are, so the default action is make the same ! recommendation for all / operators, based on the above criteria. ! ! Notes: ! ! - The augmented assignment operator /= is handled the same way as the ! / operator. ! ! - This tool never looks at the // operator; no warnings are ever ! generated for use of this operator. ! ! - This tool never looks at the / operator when a future division ! statement is in effect; no warnings are generated in this case, and ! because the tool only looks at files for which at least one classic ! division warning was seen, it will never look at files containing a ! future division statement. ! ! - Warnings may be issued for code not read from a file, but executed ! using an exec statement or the eval() function. These will have ! in the filename position. The fixdiv script will attempt ! and fail to open a file named "", and issue a warning about ! this failure. You're on your own to deal with this. You could make ! all recommended changes and add a future division statement to all ! affected files, and then re-run the test script; it should not issue ! any warnings. If there are any, and you have a hard time tracking ! down where they are generated, you can use the -Werror option to ! force an error instead of a first warning, generating a traceback. ! ! - The tool should be run from the same directory as that from which ! the original script was run, otherwise it won't be able to open ! files given by relative pathnames. """ *************** *** 28,55 **** opts, args = getopt.getopt(sys.argv[1:], "h") except getopt.error, msg: ! usage(2, msg) for o, a in opts: if o == "-h": ! help() if not args: ! usage(2, "at least one file argument is required") if args[1:]: sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0]) ! readwarnings(args[0]) ! def usage(exit, msg=None): ! if msg: ! sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) sys.stderr.write("Usage: %s warnings\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) - sys.exit(exit) ! def help(): ! print __doc__ ! sys.exit(0) def readwarnings(warningsfile): ! pat = re.compile( ! "^(.+?):(\d+): DeprecationWarning: classic ([a-z]+) division$") try: f = open(warningsfile) --- 104,142 ---- opts, args = getopt.getopt(sys.argv[1:], "h") except getopt.error, msg: ! usage(msg) ! return 2 for o, a in opts: if o == "-h": ! print __doc__ ! return if not args: ! usage("at least one file argument is required") ! return 2 if args[1:]: sys.stderr.write("%s: extra file arguments ignored\n", sys.argv[0]) ! warnings = readwarnings(args[0]) ! if warnings is None: ! return 1 ! files = warnings.keys() ! if not files: ! print "No classic division warnings read from", args[0] ! return ! files.sort() ! exit = None ! for file in files: ! x = process(file, warnings[file]) ! exit = exit or x ! return exit ! def usage(msg): ! sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) sys.stderr.write("Usage: %s warnings\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) ! PATTERN = ("^(.+?):(\d+): DeprecationWarning: " ! "classic (int|long|float|complex) division$") def readwarnings(warningsfile): ! prog = re.compile(PATTERN) try: f = open(warningsfile) *************** *** 62,66 **** if not line: break ! m = pat.match(line) if not m: if line.find("division") >= 0: --- 149,153 ---- if not line: break ! m = prog.match(line) if not m: if line.find("division") >= 0: *************** *** 73,97 **** list.append((int(lineno), intern(what))) f.close() ! files = warnings.keys() ! files.sort() ! for file in files: ! process(file, warnings[file]) def process(file, list): print "-"*70 ! if not list: ! sys.stderr.write("no division warnings for %s\n" % file) ! return try: fp = open(file) except IOError, msg: sys.stderr.write("can't open: %s\n" % msg) ! return ! print "Processing:", file f = FileContext(fp) list.sort() index = 0 # list[:index] has been processed, list[index:] is still to do - orphans = [] # subset of list for which no / operator was found - unknown = [] # lines with / operators for which no warnings were seen g = tokenize.generate_tokens(f.readline) while 1: --- 160,177 ---- list.append((int(lineno), intern(what))) f.close() ! return warnings def process(file, list): print "-"*70 ! assert list # if this fails, readwarnings() is broken try: fp = open(file) except IOError, msg: sys.stderr.write("can't open: %s\n" % msg) ! return 1 ! print "Index:", file f = FileContext(fp) list.sort() index = 0 # list[:index] has been processed, list[index:] is still to do g = tokenize.generate_tokens(f.readline) while 1: *************** *** 100,106 **** --- 180,189 ---- break assert startlineno <= endlineno is not None + orphans = [] while index < len(list) and list[index][0] < startlineno: orphans.append(list[index]) index += 1 + if orphans: + reportphantomwarnings(orphans, f) warnings = [] while index < len(list) and list[index][0] <= endlineno: *************** *** 110,114 **** pass elif slashes and not warnings: ! report(slashes, "Unexecuted code") elif warnings and not slashes: reportphantomwarnings(warnings, f) --- 193,197 ---- pass elif slashes and not warnings: ! report(slashes, "No conclusive evidence") elif warnings and not slashes: reportphantomwarnings(warnings, f) *************** *** 223,227 **** if token in ("/", "/="): slashes.append((start, line)) - ## if type in (tokenize.NEWLINE, tokenize.NL, tokenize.COMMENT): if type == tokenize.NEWLINE: break --- 306,309 ---- *************** *** 235,237 **** if __name__ == "__main__": ! main() --- 317,319 ---- if __name__ == "__main__": ! sys.exit(main()) From gvanrossum@users.sourceforge.net Sun Sep 2 06:07:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 01 Sep 2001 22:07:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.108,1.109 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21195 Modified Files: ACKS Log Message: An anonymous contributor reveals his name... Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.108 retrieving revision 1.109 diff -C2 -d -r1.108 -r1.109 *** ACKS 2001/08/27 06:37:48 1.108 --- ACKS 2001/09/02 05:07:17 1.109 *************** *** 447,450 **** --- 447,451 ---- Moshe Zadka Milan Zamazal + Mike Zarnstorff Siebren van der Zee Uwe Zessin From fdrake@users.sourceforge.net Sun Sep 2 07:07:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 01 Sep 2001 23:07:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib minidom-example.py,NONE,1.1 xmldomminidom.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv29330 Modified Files: xmldomminidom.tex Added Files: minidom-example.py Log Message: Move the long minidom example to a separate file; \verbatiminput does the right thing with page breaks in long examples, while the verbatim environment does not. This causes the example to wrap to the next page instead of overwriting the page footer and bottom margin. --- NEW FILE: minidom-example.py --- import xml.dom.minidom document = """\ Demo slideshow Slide title This is a demo Of a program for processing slides Another demo slide It is important To have more than one slide """ dom = xml.dom.minidom.parseString(document) space = " " def getText(nodelist): rc = "" for node in nodelist: if node.nodeType == node.TEXT_NODE: rc = rc + node.data return rc def handleSlideshow(slideshow): print "" handleSlideshowTitle(slideshow.getElementsByTagName("title")[0]) slides = slideshow.getElementsByTagName("slide") handleToc(slides) handleSlides(slides) print "" def handleSlides(slides): for slide in slides: handleSlide(slide) def handleSlide(slide): handleSlideTitle(slide.getElementsByTagName("title")[0]) handlePoints(slide.getElementsByTagName("point")) def handleSlideshowTitle(title): print "%s" % getText(title.childNodes) def handleSlideTitle(title): print "

%s

" % getText(title.childNodes) def handlePoints(points): print "
    " for point in points: handlePoint(point) print "
" def handlePoint(point): print "
  • %s
  • " % getText(point.childNodes) def handleToc(slides): for slide in slides: title = slide.getElementsByTagName("title")[0] print "

    %s

    " % getText(title.childNodes) handleSlideshow(dom) Index: xmldomminidom.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/xmldomminidom.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** xmldomminidom.tex 2001/01/22 19:06:20 1.3 --- xmldomminidom.tex 2001/09/02 06:07:36 1.4 *************** *** 144,214 **** of the flexibility of the DOM. ! \begin{verbatim} ! import xml.dom.minidom ! ! document = """\ ! ! Demo slideshow ! Slide title ! This is a demo ! Of a program for processing slides ! ! ! Another demo slide ! It is important ! To have more than ! one slide ! ! ! """ ! ! dom = xml.dom.minidom.parseString(document) ! ! space = " " ! def getText(nodelist): ! rc = "" ! for node in nodelist: ! if node.nodeType == node.TEXT_NODE: ! rc = rc + node.data ! return rc ! ! def handleSlideshow(slideshow): ! print "" ! handleSlideshowTitle(slideshow.getElementsByTagName("title")[0]) ! slides = slideshow.getElementsByTagName("slide") ! handleToc(slides) ! handleSlides(slides) ! print "" ! ! def handleSlides(slides): ! for slide in slides: ! handleSlide(slide) ! ! def handleSlide(slide): ! handleSlideTitle(slide.getElementsByTagName("title")[0]) ! handlePoints(slide.getElementsByTagName("point")) ! ! def handleSlideshowTitle(title): ! print "%s" % getText(title.childNodes) ! ! def handleSlideTitle(title): ! print "

    %s

    " % getText(title.childNodes) ! ! def handlePoints(points): ! print "
      " ! for point in points: ! handlePoint(point) ! print "
    " ! ! def handlePoint(point): ! print "
  • %s
  • " % getText(point.childNodes) ! ! def handleToc(slides): ! for slide in slides: ! title = slide.getElementsByTagName("title")[0] ! print "

    %s

    " % getText(title.childNodes) ! ! handleSlideshow(dom) ! \end{verbatim} --- 144,148 ---- of the flexibility of the DOM. ! \verbatiminput{minidom-example.py} From tim_one@users.sourceforge.net Sun Sep 2 07:29:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 01 Sep 2001 23:29:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects tupleobject.c,2.57,2.58 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv31921/python/dist/src/Objects Modified Files: tupleobject.c Log Message: Repair apparent cut'n'pasteo in tuple() docstring. Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** tupleobject.c 2001/08/30 18:31:30 2.57 --- tupleobject.c 2001/09/02 06:29:48 2.58 *************** *** 523,527 **** static char tuple_doc[] = ! "tuple(sequence) -> list\n\ \n\ Return a tuple whose items are the same as those of the argument sequence.\n\ --- 523,527 ---- static char tuple_doc[] = ! "tuple(sequence) -> tuple\n\ \n\ Return a tuple whose items are the same as those of the argument sequence.\n\ From tim_one@users.sourceforge.net Sun Sep 2 07:42:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 01 Sep 2001 23:42:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects tupleobject.c,2.58,2.59 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv693/python/dist/src/Objects Modified Files: tupleobject.c Log Message: Rewrite the tuple() docstring to parallel the list() docstring. Index: tupleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/tupleobject.c,v retrieving revision 2.58 retrieving revision 2.59 diff -C2 -d -r2.58 -r2.59 *** tupleobject.c 2001/09/02 06:29:48 2.58 --- tupleobject.c 2001/09/02 06:42:25 2.59 *************** *** 523,530 **** static char tuple_doc[] = ! "tuple(sequence) -> tuple\n\ ! \n\ ! Return a tuple whose items are the same as those of the argument sequence.\n\ ! If the argument is a tuple, the return value is the same object."; static PySequenceMethods tuple_as_sequence = { --- 523,530 ---- static char tuple_doc[] = ! "tuple() -> an empty tuple\n" ! "tuple(sequence) -> tuple initialized from sequence's items\n" ! "\n" ! "If the argument is a tuple, the return value is the same object."; static PySequenceMethods tuple_as_sequence = { From tim_one@users.sourceforge.net Sun Sep 2 09:22:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 01:22:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12216/python/dist/src/Lib/test Modified Files: test_descr.py Log Message: Make dictionary() a real constructor. Accepts at most one argument, "a mapping object", in the same sense dict.update(x) requires of x (that x has a keys() method and a getitem). Questionable: The other type constructors accept a keyword argument, so I did that here too (e.g., dictionary(mapping={1:2}) works). But type_call doesn't pass the keyword args to the tp_new slot (it passes NULL), it only passes them to the tp_init slot, so getting at them required adding a tp_init slot to dicts. Looks like that makes the normal case (i.e., no args at all) a little slower (the time it takes to call dict.tp_init and have it figure out there's nothing to do). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** test_descr.py 2001/08/31 04:35:14 1.28 --- test_descr.py 2001/09/02 08:22:48 1.29 *************** *** 1,5 **** # Test descriptor-related enhancements ! from test_support import verify, verbose from copy import deepcopy --- 1,5 ---- # Test descriptor-related enhancements ! from test_support import verify, verbose, TestFailed from copy import deepcopy *************** *** 124,127 **** --- 124,176 ---- testset2op({1:2,3:4}, 2, 3, {1:2,2:3,3:4}, "a[b]=c", "__setitem__") + def dict_constructor(): + if verbose: + print "Testing dictionary constructor ..." + d = dictionary() + verify(d == {}) + d = dictionary({}) + verify(d == {}) + d = dictionary(mapping={}) + verify(d == {}) + d = dictionary({1: 2, 'a': 'b'}) + verify(d == {1: 2, 'a': 'b'}) + for badarg in 0, 0L, 0j, "0", [0], (0,): + try: + dictionary(badarg) + except TypeError: + pass + else: + raise TestFailed("no TypeError from dictionary(%r)" % badarg) + try: + dictionary(senseless={}) + except TypeError: + pass + else: + raise TestFailed("no TypeError from dictionary(senseless={}") + + try: + dictionary({}, {}) + except TypeError: + pass + else: + raise TestFailed("no TypeError from dictionary({}, {})") + + class Mapping: + dict = {1:2, 3:4, 'a':1j} + + def __getitem__(self, i): + return self.dict[i] + + try: + dictionary(Mapping()) + except TypeError: + pass + else: + raise TestFailed("no TypeError from dictionary(incomplete mapping)") + + Mapping.keys = lambda self: self.dict.keys() + d = dictionary(mapping=Mapping()) + verify(d == Mapping.dict) + binops = { 'add': '+', *************** *** 1300,1303 **** --- 1349,1353 ---- lists() dicts() + dict_constructor() ints() longs() From tim_one@users.sourceforge.net Sun Sep 2 09:22:50 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 01:22:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.110,2.111 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12216/python/dist/src/Objects Modified Files: dictobject.c Log Message: Make dictionary() a real constructor. Accepts at most one argument, "a mapping object", in the same sense dict.update(x) requires of x (that x has a keys() method and a getitem). Questionable: The other type constructors accept a keyword argument, so I did that here too (e.g., dictionary(mapping={1:2}) works). But type_call doesn't pass the keyword args to the tp_new slot (it passes NULL), it only passes them to the tp_init slot, so getting at them required adding a tp_init slot to dicts. Looks like that makes the normal case (i.e., no args at all) a little slower (the time it takes to call dict.tp_init and have it figure out there's nothing to do). Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.110 retrieving revision 2.111 diff -C2 -d -r2.110 -r2.111 *** dictobject.c 2001/08/29 23:51:52 2.110 --- dictobject.c 2001/09/02 08:22:48 2.111 *************** *** 1693,1696 **** --- 1693,1719 ---- } + static int + dict_init(PyObject *self, PyObject *args, PyObject *kwds) + { + PyObject *arg = NULL; + static char *kwlist[] = {"mapping", 0}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:dictionary", + kwlist, &arg)) + return -1; + if (arg != NULL) { + if (PyDict_Merge(self, arg, 1) < 0) { + /* An error like "AttibuteError: keys" is too + cryptic in this context. */ + if (PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_SetString(PyExc_TypeError, + "argument must be of a mapping type"); + } + return -1; + } + } + return 0; + } + static PyObject * dict_iter(dictobject *dict) *************** *** 1699,1702 **** --- 1722,1729 ---- } + static char dictionary_doc[] = + "dictionary() -> new empty dictionary\n" + "dictionary(mapping) -> new dict initialized from mapping's key+value pairs"; + PyTypeObject PyDict_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 1722,1726 **** Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! "dictionary type", /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ (inquiry)dict_tp_clear, /* tp_clear */ --- 1749,1753 ---- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | Py_TPFLAGS_BASETYPE, /* tp_flags */ ! dictionary_doc, /* tp_doc */ (traverseproc)dict_traverse, /* tp_traverse */ (inquiry)dict_tp_clear, /* tp_clear */ *************** *** 1737,1741 **** 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! 0, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ --- 1764,1768 ---- 0, /* tp_descr_set */ 0, /* tp_dictoffset */ ! (initproc)dict_init, /* tp_init */ PyType_GenericAlloc, /* tp_alloc */ dict_new, /* tp_new */ From gvanrossum@users.sourceforge.net Sun Sep 2 14:44:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 02 Sep 2001 06:44:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.221,1.222 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv8316 Modified Files: NEWS Log Message: Add news about dictionary() constructor. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.221 retrieving revision 1.222 diff -C2 -d -r1.221 -r1.222 *** NEWS 2001/09/02 03:40:59 1.221 --- NEWS 2001/09/02 13:44:35 1.222 *************** *** 31,34 **** --- 31,38 ---- once it is created. + - The dictionary constructor now takes an optional argument, a + mapping-like object, and initializes the dictionary from its + (key, value) pairs. + - A new built-in type, super, has been added. This facilitates making "cooperative super calls" in a multiple inheritance setting. For an From gvanrossum@users.sourceforge.net Sun Sep 2 15:11:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sun, 02 Sep 2001 07:11:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv16766 Modified Files: fixdiv.py Log Message: Implement what the docstring said: multiple slashes per line are treated the same as single ones by default. Added -m option to issue a warning for this case instead. Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fixdiv.py 2001/09/02 04:49:36 1.2 --- fixdiv.py 2001/09/02 14:11:30 1.3 *************** *** 63,66 **** --- 63,67 ---- practice, they usually are, so the default action is make the same recommendation for all / operators, based on the above criteria. + The -m option issues warnings for these cases instead. Notes: *************** *** 100,106 **** from pprint import pprint def main(): try: ! opts, args = getopt.getopt(sys.argv[1:], "h") except getopt.error, msg: usage(msg) --- 101,109 ---- from pprint import pprint + multi_ok = 1 + def main(): try: ! opts, args = getopt.getopt(sys.argv[1:], "hm") except getopt.error, msg: usage(msg) *************** *** 110,113 **** --- 113,119 ---- print __doc__ return + if o == "-m": + global multi_ok + multi_ok = 0 if not args: usage("at least one file argument is required") *************** *** 131,135 **** def usage(msg): sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) ! sys.stderr.write("Usage: %s warnings\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) --- 137,141 ---- def usage(msg): sys.stderr.write("%s: %s\n" % (sys.argv[0], msg)) ! sys.stderr.write("Usage: %s [-m] warnings\n" % sys.argv[0]) sys.stderr.write("Try `%s -h' for more information.\n" % sys.argv[0]) *************** *** 198,204 **** else: if len(slashes) > 1: ! report(slashes, "More than one / operator") ! else: ! (row, col), line = slashes[0] line = chop(line) if line[col:col+1] != "/": --- 204,225 ---- else: if len(slashes) > 1: ! if not multi_ok: ! report(slashes, "More than one / operator per statement") ! continue ! intlong = [] ! floatcomplex = [] ! bad = [] ! for lineno, what in warnings: ! if what in ("int", "long"): ! intlong.append(what) ! elif what in ("float", "complex"): ! floatcomplex.append(what) ! else: ! bad.append(what) ! lastrow = None ! for (row, col), line in slashes: ! if row == lastrow: ! continue ! lastrow = row line = chop(line) if line[col:col+1] != "/": *************** *** 206,219 **** print "*", line continue - intlong = [] - floatcomplex = [] - bad = [] - for lineno, what in warnings: - if what in ("int", "long"): - intlong.append(what) - elif what in ("float", "complex"): - floatcomplex.append(what) - else: - bad.append(what) if bad: print "*** Bad warning for line %d:" % row, bad --- 227,230 ---- From jackjansen@users.sourceforge.net Sun Sep 2 15:48:35 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Sun, 02 Sep 2001 07:48:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions/(vise) Python 2.2.vct,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions/(vise) In directory usw-pr-cvs1:/tmp/cvs-serv23571/Python/Mac/Distributions/(vise) Modified Files: Python 2.2.vct Log Message: Added the last few missing files, and put everything in the right packages. Tested, too:-) Index: Python 2.2.vct =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/(vise)/Python 2.2.vct,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 Binary files /tmp/cvsz9C4Ci and /tmp/cvsGxTtBx differ From tim_one@users.sourceforge.net Sun Sep 2 19:35:56 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 11:35:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.111,2.112 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv6503 Modified Files: dictobject.c Log Message: Repair typo in comment. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.111 retrieving revision 2.112 diff -C2 -d -r2.111 -r2.112 *** dictobject.c 2001/09/02 08:22:48 2.111 --- dictobject.c 2001/09/02 18:35:54 2.112 *************** *** 1704,1708 **** if (arg != NULL) { if (PyDict_Merge(self, arg, 1) < 0) { ! /* An error like "AttibuteError: keys" is too cryptic in this context. */ if (PyErr_ExceptionMatches(PyExc_AttributeError)) { --- 1704,1708 ---- if (arg != NULL) { if (PyDict_Merge(self, arg, 1) < 0) { ! /* An error like "AttributeError: keys" is too cryptic in this context. */ if (PyErr_ExceptionMatches(PyExc_AttributeError)) { From tim_one@users.sourceforge.net Mon Sep 3 00:01:45 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 16:01:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.222,1.223 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28456/python/Misc Modified Files: NEWS Log Message: Clarify the Borland situation, based on email from Stephen. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.222 retrieving revision 1.223 diff -C2 -d -r1.222 -r1.223 *** NEWS 2001/09/02 13:44:35 1.222 --- NEWS 2001/09/02 23:01:43 1.223 *************** *** 96,102 **** New platforms ! - Patches from Stephen Hansen for the Borland C compiler (under Windows) ! are reported to yield a clean compile, but a Python that doesn't yet ! run correctly. Volunteers? Tests --- 96,104 ---- New platforms ! - Stephen Hansen contributed patches sufficient to get a clean compile ! under Borland C (Windows), but he reports problems running it and ran ! out of time to complete the port. Volunteers? Expect a MemoryError ! when importing the types module; this is probably shallow, and ! causing later failures too. Tests From tim_one@users.sourceforge.net Mon Sep 3 02:24:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 18:24:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descrtut.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv2174/python/Lib/test Added Files: test_descrtut.py Log Message: Made a doctest out of the examples in Guido's type/class tutorial. --- NEW FILE: test_descrtut.py --- # This contains most of the executable examples from Guido's descr # tutorial, once at # # http://www.python.org/2.2/descrintro.html # # A few examples left implicit in the writeup were fleshed out, a few were # skipped due to lack of interest (e.g., faking super() by hand isn't # of much interest anymore), and a few were fiddled to make the output # deterministic. from test_support import sortdict import pprint class defaultdict(dictionary): def __init__(self, default=None): dictionary.__init__(self) self.default = default def __getitem__(self, key): try: return dictionary.__getitem__(self, key) except KeyError: return self.default def get(self, key, *args): if not args: args = (self.default,) return dictionary.get(self, key, *args) def merge(self, other): for key in other: if key not in self: self[key] = other[key] test_1 = """ Here's the new type at work: >>> print defaultdict # show our type >>> print type(defaultdict) # its metatype >>> a = defaultdict(default=0.0) # create an instance >>> print a # show the instance {} >>> print type(a) # show its type >>> print a.__class__ # show its class >>> print type(a) is a.__class__ # its type is its class 1 >>> a[1] = 3.25 # modify the instance >>> print a # show the new value {1: 3.25} >>> print a[1] # show the new item 3.25 >>> print a[0] # a non-existant item 0.0 >>> a.merge({1:100, 2:200}) # use a dictionary method >>> print sortdict(a) # show the result {1: 3.25, 2: 200} >>> We can also use the new type in contexts where classic only allows "real" dictionaries, such as the locals/globals dictionaries for the exec statement or the built-in function eval(): >>> def sorted(seq): ... seq.sort() ... return seq >>> print sorted(a.keys()) [1, 2] >>> exec "x = 3; print x" in a 3 >>> print sorted(a.keys()) [1, 2, '__builtins__', 'x'] >>> print a['x'] 3 >>> However, our __getitem__() method is not used for variable access by the interpreter: >>> exec "print foo" in a Traceback (most recent call last): File "", line 1, in ? File "", line 1, in ? NameError: name 'foo' is not defined >>> Now I'll show that defaultdict instances have dynamic instance variables, just like classic classes: >>> a.default = -1 >>> print a["noway"] -1 >>> a.default = -1000 >>> print a["noway"] -1000 >>> print dir(a) ['default'] >>> a.x1 = 100 >>> a.x2 = 200 >>> print a.x1 100 >>> print dir(a) ['default', 'x1', 'x2'] >>> print a.__dict__ {'default': -1000, 'x2': 200, 'x1': 100} >>> """ class defaultdict2(dictionary): __slots__ = ['default'] def __init__(self, default=None): dictionary.__init__(self) self.default = default def __getitem__(self, key): try: return dictionary.__getitem__(self, key) except KeyError: return self.default def get(self, key, *args): if not args: args = (self.default,) return dictionary.get(self, key, *args) def merge(self, other): for key in other: if key not in self: self[key] = other[key] test_2 = """ The __slots__ declaration takes a list of instance variables, and reserves space for exactly these in the instance. When __slots__ is used, other instance variables cannot be assigned to: >>> a = defaultdict2(default=0.0) >>> a[1] 0.0 >>> a.default = -1 >>> a[1] -1 >>> a.x1 = 1 Traceback (most recent call last): File "", line 1, in ? AttributeError: 'defaultdict2' object has no attribute 'x1' >>> """ test_3 = """ Introspecting instances of built-in types For instance of built-in types, x.__class__ is now the same as type(x): >>> type([]) >>> [].__class__ >>> list >>> isinstance([], list) 1 >>> isinstance([], dictionary) 0 >>> isinstance([], object) 1 >>> Under the new proposal, the __methods__ attribute no longer exists: >>> [].__methods__ Traceback (most recent call last): File "", line 1, in ? AttributeError: 'list' object has no attribute '__methods__' >>> Instead, you can get the same information from the list type: >>> pprint.pprint(dir(list)) # like list.__dict__.keys(), but sorted ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__eq__', '__ge__', '__getattr__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__repr__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] The new introspection API gives more information than the old one: in addition to the regular methods, it also shows the methods that are normally invoked through special notations, e.g. __iadd__ (+=), __len__ (len), __ne__ (!=). You can invoke any method from this list directly: >>> a = ['tic', 'tac'] >>> list.__len__(a) # same as len(a) 2 >>> a.__len__() # ditto 2 >>> list.append(a, 'toe') # same as a.append('toe') >>> a ['tic', 'tac', 'toe'] >>> This is just like it is for user-defined classes. """ test_4 = """ Static methods and class methods The new introspection API makes it possible to add static methods and class methods. Static methods are easy to describe: they behave pretty much like static methods in C++ or Java. Here's an example: >>> class C: ... ... def foo(x, y): ... print "staticmethod", x, y ... foo = staticmethod(foo) >>> C.foo(1, 2) staticmethod 1 2 >>> c = C() >>> c.foo(1, 2) staticmethod 1 2 Class methods use a similar pattern to declare methods that receive an implicit first argument that is the *class* for which they are invoked. >>> class C: ... def foo(cls, y): ... print "classmethod", cls, y ... foo = classmethod(foo) >>> C.foo(1) classmethod test_descrtut.C 1 >>> c = C() >>> c.foo(1) classmethod test_descrtut.C 1 >>> class D(C): ... pass >>> D.foo(1) classmethod test_descrtut.D 1 >>> d = D() >>> d.foo(1) classmethod test_descrtut.D 1 This prints "classmethod __main__.D 1" both times; in other words, the class passed as the first argument of foo() is the class involved in the call, not the class involved in the definition of foo(). But notice this: >>> class E(C): ... def foo(cls, y): # override C.foo ... print "E.foo() called" ... C.foo(y) ... foo = classmethod(foo) >>> E.foo(1) E.foo() called classmethod test_descrtut.C 1 >>> e = E() >>> e.foo(1) E.foo() called classmethod test_descrtut.C 1 In this example, the call to C.foo() from E.foo() will see class C as its first argument, not class E. This is to be expected, since the call specifies the class C. But it stresses the difference between these class methods and methods defined in metaclasses (where an upcall to a metamethod would pass the target class as an explicit first argument). """ test_5 = """ Attributes defined by get/set methods >>> class getset(object): ... ... def __init__(self, get, set=None): ... self.__get = get ... self.__set = set ... ... def __get__(self, inst, type=None): ... return self.__get(inst) ... ... def __set__(self, inst, value): ... if self.__set is None: ... raise AttributeError, "this attribute is read-only" ... return self.__set(inst, value) Now let's define a class with an attribute x defined by a pair of methods, getx() and and setx(): >>> class C(object): ... ... def __init__(self): ... self.__x = 0 ... ... def getx(self): ... return self.__x ... ... def setx(self, x): ... if x < 0: x = 0 ... self.__x = x ... ... x = getset(getx, setx) Here's a small demonstration: >>> a = C() >>> a.x = 10 >>> print a.x 10 >>> a.x = -10 >>> print a.x 0 >>> Hmm -- getset is builtin now, so let's try it that way too. >>> del getset # unmask the builtin >>> getset >>> class C(object): ... def __init__(self): ... self.__x = 0 ... def getx(self): ... return self.__x ... def setx(self, x): ... if x < 0: x = 0 ... self.__x = x ... x = getset(getx, setx) >>> a = C() >>> a.x = 10 >>> print a.x 10 >>> a.x = -10 >>> print a.x 0 >>> """ test_6 = """ Method resolution order This example is implicit in the writeup. >>> class A: # classic class ... def save(self): ... print "called A.save()" >>> class B(A): ... pass >>> class C(A): ... def save(self): ... print "called C.save()" >>> class D(B, C): ... pass >>> D().save() called A.save() >>> class A(object): # new class ... def save(self): ... print "called A.save()" >>> class B(A): ... pass >>> class C(A): ... def save(self): ... print "called C.save()" >>> class D(B, C): ... pass >>> D().save() called C.save() """ class A(object): def m(self): return "A" class B(A): def m(self): return "B" + super(B, self).m() class C(A): def m(self): return "C" + super(C, self).m() class D(C, B): def m(self): return "D" + super(D, self).m() test_7 = """ Cooperative methods and "super" >>> print D().m() # "DCBA" DCBA """ test_8 = """ Backwards incompatibilities >>> class A: ... def foo(self): ... print "called A.foo()" >>> class B(A): ... pass >>> class C(A): ... def foo(self): ... B.foo(self) >>> C().foo() Traceback (most recent call last): ... TypeError: unbound method foo() must be called with B instance as first argument (got C instance instead) >>> class C(A): ... def foo(self): ... A.foo(self) >>> C().foo() called A.foo() """ __test__ = {"tut1": test_1, "tut2": test_2, "tut3": test_3, "tut4": test_4, "tut5": test_5, "tut6": test_6, "tut7": test_7, "tut8": test_8} # Magic test name that regrtest.py invokes *after* importing this module. # This worms around a bootstrap problem. # Note that doctest and regrtest both look in sys.argv for a "-v" argument, # so this works as expected in both ways of running regrtest. def test_main(): import doctest, test_descrtut if 0: # change to 1 to run forever (to check for leaks) while 1: doctest.master = None doctest.testmod(test_descrtut) print ".", else: doctest.testmod(test_descrtut) # This part isn't needed for regrtest, but for running the test directly. if __name__ == "__main__": test_main() From tim_one@users.sourceforge.net Mon Sep 3 06:47:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 22:47:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.29,1.30 test_descrtut.py,1.1,1.2 test_generators.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12547/python/Lib/test Modified Files: test_descr.py test_descrtut.py test_generators.py Log Message: Make dir() wordier (see the new docstring). The new behavior is a mixed bag. It's clearly wrong for classic classes, at heart because a classic class doesn't have a __class__ attribute, and I'm unclear on whether that's feature or bug. I'll repair this once I find out (in the meantime, dir() applied to classic classes won't find the base classes, while dir() applied to a classic-class instance *will* find the base classes but not *their* base classes). Please give the new dir() a try and see whether you love it or hate it. The new dir([]) behavior is something I could come to love. Here's something to hate: >>> class C: ... pass ... >>> c = C() >>> dir(c) ['__doc__', '__module__'] >>> The idea that an instance has a __doc__ attribute is jarring (of course it's really c.__class__.__doc__ == C.__doc__; likewise for __module__). OTOH, the code already has too many special cases, and dir(x) doesn't have a compelling or clear purpose when x isn't a module. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** test_descr.py 2001/09/02 08:22:48 1.29 --- test_descr.py 2001/09/03 05:47:38 1.30 *************** *** 173,176 **** --- 173,224 ---- verify(d == Mapping.dict) + def test_dir(): + if verbose: + print "Testing dir() ..." + junk = 12 + verify(dir() == ['junk']) + del junk + + # Just make sure these don't blow up! + for arg in 2, 2L, 2j, 2e0, [2], "2", u"2", (2,), {2:2}, type, test_dir: + dir(arg) + + # Check some details here because classic classes aren't working + # reasonably, and I want this to fail (eventually). + class C: + Cdata = 1 + def Cmethod(self): pass + + cstuff = ['Cdata', 'Cmethod', '__doc__', '__module__'] + verify(dir(C) == cstuff) + + c = C() # c.__doc__ is an odd thing to see here; ditto c.__module__. + verify(dir(c) == cstuff) + + c.cdata = 2 + c.cmethod = lambda self: 0 + verify(dir(c) == cstuff + ['cdata', 'cmethod']) + + class A(C): + Adata = 1 + def Amethod(self): pass + astuff = ['Adata', 'Amethod', '__doc__', '__module__'] + # This isn't finding C's stuff at all. + verify(dir(A) == astuff) + # But this is! It's because a.__class__ exists but A.__class__ doesn't. + a = A() + verify(dir(a) == astuff[:2] + cstuff) + + # The story for new-style classes is quite different. + class C(object): + Cdata = 1 + def Cmethod(self): pass + class A(C): + Adata = 1 + def Amethod(self): pass + d = dir(A) + for expected in 'Cdata', 'Cmethod', 'Adata', 'Amethod': + verify(expected in d) + binops = { 'add': '+', *************** *** 1350,1353 **** --- 1398,1402 ---- dicts() dict_constructor() + test_dir() ints() longs() Index: test_descrtut.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descrtut.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_descrtut.py 2001/09/03 01:24:30 1.1 --- test_descrtut.py 2001/09/03 05:47:38 1.2 *************** *** 98,109 **** >>> print a["noway"] -1000 ! >>> print dir(a) ! ['default'] >>> a.x1 = 100 >>> a.x2 = 200 >>> print a.x1 100 ! >>> print dir(a) ! ['default', 'x1', 'x2'] >>> print a.__dict__ {'default': -1000, 'x2': 200, 'x1': 100} --- 98,110 ---- >>> print a["noway"] -1000 ! >>> 'default' in dir(a) ! 1 >>> a.x1 = 100 >>> a.x2 = 200 >>> print a.x1 100 ! >>> d = dir(a) ! >>> 'default' in d and 'x1' in d and 'x2' in d ! 1 >>> print a.__dict__ {'default': -1000, 'x2': 200, 'x1': 100} Index: test_generators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_generators.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** test_generators.py 2001/08/16 08:30:10 1.27 --- test_generators.py 2001/09/03 05:47:38 1.28 *************** *** 384,395 **** >>> type(i) ! ! XXX dir(object) *generally* doesn't return useful stuff in descr-branch. ! >>> dir(i) ! [] ! ! Was hoping to see this instead: ['gi_frame', 'gi_running', 'next'] - >>> print i.next.__doc__ x.next() -> the next value, or raise StopIteration --- 384,389 ---- >>> type(i) ! >>> [s for s in dir(i) if not s.startswith('_')] ['gi_frame', 'gi_running', 'next'] >>> print i.next.__doc__ x.next() -> the next value, or raise StopIteration From tim_one@users.sourceforge.net Mon Sep 3 06:47:40 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 22:47:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.223,1.224 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv12547/python/Misc Modified Files: NEWS Log Message: Make dir() wordier (see the new docstring). The new behavior is a mixed bag. It's clearly wrong for classic classes, at heart because a classic class doesn't have a __class__ attribute, and I'm unclear on whether that's feature or bug. I'll repair this once I find out (in the meantime, dir() applied to classic classes won't find the base classes, while dir() applied to a classic-class instance *will* find the base classes but not *their* base classes). Please give the new dir() a try and see whether you love it or hate it. The new dir([]) behavior is something I could come to love. Here's something to hate: >>> class C: ... pass ... >>> c = C() >>> dir(c) ['__doc__', '__module__'] >>> The idea that an instance has a __doc__ attribute is jarring (of course it's really c.__class__.__doc__ == C.__doc__; likewise for __module__). OTOH, the code already has too many special cases, and dir(x) doesn't have a compelling or clear purpose when x isn't a module. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.223 retrieving revision 1.224 diff -C2 -d -r1.223 -r1.224 *** NEWS 2001/09/02 23:01:43 1.223 --- NEWS 2001/09/03 05:47:38 1.224 *************** *** 4,7 **** --- 4,24 ---- Core + - The builtin dir() now returns more information, and sometimes much + more, generally naming all attributes of an object, and all attributes + reachable from the object via its class, and from its class's base + classes, and so on from them too. Example: in 2.2a2, dir([]) returned + an empty list. In 2.2a3, + + >>> dir([]) + ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', + '__eq__', '__ge__', '__getattr__', '__getitem__', '__getslice__', + '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__le__', + '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__repr__', + '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', + 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', + 'reverse', 'sort'] + + dir(module) continues to return only the module's attributes, though. + - Overflowing operations on plain ints now return a long int rather than raising OverflowError. This is a partial implementation of PEP From tim_one@users.sourceforge.net Mon Sep 3 06:47:41 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 02 Sep 2001 22:47:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.231,2.232 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv12547/python/Python Modified Files: bltinmodule.c Log Message: Make dir() wordier (see the new docstring). The new behavior is a mixed bag. It's clearly wrong for classic classes, at heart because a classic class doesn't have a __class__ attribute, and I'm unclear on whether that's feature or bug. I'll repair this once I find out (in the meantime, dir() applied to classic classes won't find the base classes, while dir() applied to a classic-class instance *will* find the base classes but not *their* base classes). Please give the new dir() a try and see whether you love it or hate it. The new dir([]) behavior is something I could come to love. Here's something to hate: >>> class C: ... pass ... >>> c = C() >>> dir(c) ['__doc__', '__module__'] >>> The idea that an instance has a __doc__ attribute is jarring (of course it's really c.__class__.__doc__ == C.__doc__; likewise for __module__). OTOH, the code already has too many special cases, and dir(x) doesn't have a compelling or clear purpose when x isn't a module. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.231 retrieving revision 2.232 diff -C2 -d -r2.231 -r2.232 *** bltinmodule.c 2001/08/24 16:52:18 2.231 --- bltinmodule.c 2001/09/03 05:47:38 2.232 *************** *** 427,504 **** in addition to any features explicitly specified."; static PyObject * builtin_dir(PyObject *self, PyObject *args) { ! static char *attrlist[] = {"__members__", "__methods__", NULL}; ! PyObject *v = NULL, *l = NULL, *m = NULL; ! PyObject *d, *x; ! int i; ! char **s; ! if (!PyArg_ParseTuple(args, "|O:dir", &v)) return NULL; ! if (v == NULL) { ! x = PyEval_GetLocals(); ! if (x == NULL) goto error; ! l = PyMapping_Keys(x); ! if (l == NULL) goto error; } else { ! d = PyObject_GetAttrString(v, "__dict__"); ! if (d == NULL) PyErr_Clear(); ! else { ! l = PyMapping_Keys(d); ! if (l == NULL) ! PyErr_Clear(); ! Py_DECREF(d); } ! if (l == NULL) { ! l = PyList_New(0); ! if (l == NULL) goto error; } ! for (s = attrlist; *s != NULL; s++) { ! m = PyObject_GetAttrString(v, *s); ! if (m == NULL) { ! PyErr_Clear(); ! continue; ! } ! for (i = 0; ; i++) { ! x = PySequence_GetItem(m, i); ! if (x == NULL) { ! PyErr_Clear(); ! break; ! } ! if (PyList_Append(l, x) != 0) { ! Py_DECREF(x); ! Py_DECREF(m); ! goto error; ! } ! Py_DECREF(x); ! } ! Py_DECREF(m); } } ! if (PyList_Sort(l) != 0) goto error; ! return l; error: ! Py_XDECREF(l); ! return NULL; } static char dir_doc[] = ! "dir([object]) -> list of strings\n\ ! \n\ ! Return an alphabetized list of names comprising (some of) the attributes\n\ ! of the given object. Without an argument, the names in the current scope\n\ ! are listed. With an instance argument, only the instance attributes are\n\ ! returned. With a class argument, attributes of the base class are not\n\ ! returned. For other types or arguments, this may list members or methods."; ! static PyObject * --- 427,585 ---- in addition to any features explicitly specified."; + /* Merge the __dict__ of aclass into dict, and recursively also all + the __dict__s of aclass's base classes. The order of merging isn't + defined, as it's expected that only the final set of dict keys is + interesting. + Return 0 on success, -1 on error. + */ + + static int + merge_class_dict(PyObject* dict, PyObject* aclass) + { + PyObject *classdict; + PyObject *bases; + + assert(PyDict_Check(dict)); + /* XXX Class objects fail the PyType_Check check. Don't + XXX know of others. */ + /* assert(PyType_Check(aclass)); */ + assert(aclass); + + /* Merge in the type's dict (if any). */ + classdict = PyObject_GetAttrString(aclass, "__dict__"); + if (classdict == NULL) + PyErr_Clear(); + else { + int status = PyDict_Update(dict, classdict); + Py_DECREF(classdict); + if (status < 0) + return -1; + } + + /* Recursively merge in the base types' (if any) dicts. */ + bases = PyObject_GetAttrString(aclass, "__bases__"); + if (bases != NULL) { + int i, n; + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (merge_class_dict(dict, base) < 0) { + Py_DECREF(bases); + return -1; + } + } + Py_DECREF(bases); + } + return 0; + } static PyObject * builtin_dir(PyObject *self, PyObject *args) { ! PyObject *arg = NULL; ! /* Set exactly one of these non-NULL before the end. */ ! PyObject *result = NULL; /* result list */ ! PyObject *masterdict = NULL; /* result is masterdict.keys() */ ! if (!PyArg_ParseTuple(args, "|O:dir", &arg)) return NULL; ! ! /* If no arg, return the locals. */ ! if (arg == NULL) { ! PyObject *locals = PyEval_GetLocals(); ! if (locals == NULL) goto error; ! result = PyMapping_Keys(locals); ! if (result == NULL) goto error; } + + /* Elif this is some form of module, we only want its dict. */ + else if (PyObject_TypeCheck(arg, &PyModule_Type)) { + masterdict = PyObject_GetAttrString(arg, "__dict__"); + if (masterdict == NULL) + goto error; + } + + /* Elif some form of type, recurse. */ + else if (PyType_Check(arg)) { + masterdict = PyDict_New(); + if (masterdict == NULL) + goto error; + if (merge_class_dict(masterdict, arg) < 0) + goto error; + } + + /* Else look at its dict, and the attrs reachable from its class. */ else { ! PyObject *itsclass; ! /* Create a dict to start with. */ ! masterdict = PyObject_GetAttrString(arg, "__dict__"); ! if (masterdict == NULL) { PyErr_Clear(); ! masterdict = PyDict_New(); ! if (masterdict == NULL) ! goto error; } ! else { ! /* The object may have returned a reference to its ! dict, so copy it to avoid mutating it. */ ! PyObject *temp = PyDict_Copy(masterdict); ! if (temp == NULL) goto error; + Py_DECREF(masterdict); + masterdict = temp; } ! /* Merge in attrs reachable from its class. */ ! itsclass = PyObject_GetAttrString(arg, "__class__"); ! /* XXX Sometimes this is null! Like after "class C: pass", ! C.__class__ raises AttributeError. Don't know of other ! cases. */ ! if (itsclass == NULL) ! PyErr_Clear(); ! else { ! int status = merge_class_dict(masterdict, itsclass); ! Py_DECREF(itsclass); ! if (status < 0) ! goto error; } } ! ! assert((result == NULL) ^ (masterdict == NULL)); ! if (masterdict != NULL) { ! /* The result comes from its keys. */ ! assert(result == NULL); ! result = PyMapping_Keys(masterdict); ! if (result == NULL) ! goto error; ! } ! ! assert(result); ! if (PyList_Sort(result) != 0) goto error; ! else ! goto normal_return; ! error: ! Py_XDECREF(result); ! result = NULL; ! /* fall through */ ! normal_return: ! Py_XDECREF(masterdict); ! return result; } static char dir_doc[] = ! "dir([object]) -> list of strings\n" ! "\n" ! "Return an alphabetized list of names comprising (some of) the attributes\n" ! "of the given object, and of attributes reachable from it:\n" ! "\n" ! "No argument: the names in the current scope.\n" ! "Module object: the module attributes.\n" ! "Type object: its attributes, and recursively the attributes of its bases.\n" ! "Otherwise: its attributes, its class's attributes, and recursively the\n" ! " attributes of its class's base classes."; static PyObject * From tim_one@users.sourceforge.net Mon Sep 3 09:35:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:35:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_pow,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv12739/python/Lib/test/output Modified Files: test_pow Log Message: New restriction on pow(x, y, z): If z is not None, x and y must be of integer types, and y must be >= 0. See discussion at http://sf.net/tracker/index.php?func=detail&aid=457066&group_id=5470&atid=105470 Index: test_pow =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_pow,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_pow 1996/12/20 03:14:42 1.1 --- test_pow 2001/09/03 08:35:40 1.2 *************** *** 23,29 **** -7L -7L - 3.0 3.0 - -5.0 -5.0 - -1.0 -1.0 - -7.0 -7.0 --- 23,25 ---- From tim_one@users.sourceforge.net Mon Sep 3 09:35:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:35:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.224,1.225 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv12739/python/Misc Modified Files: NEWS Log Message: New restriction on pow(x, y, z): If z is not None, x and y must be of integer types, and y must be >= 0. See discussion at http://sf.net/tracker/index.php?func=detail&aid=457066&group_id=5470&atid=105470 Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.224 retrieving revision 1.225 diff -C2 -d -r1.224 -r1.225 *** NEWS 2001/09/03 05:47:38 1.224 --- NEWS 2001/09/03 08:35:40 1.225 *************** *** 4,7 **** --- 4,13 ---- Core + - The 3-argument builtin pow() no longer allows a third non-None argument + if either of the first two arguments is a float, or if both are of + integer types and the second argument is negative (in which latter case + the arguments are converted to float, so this is really the same + restriction). + - The builtin dir() now returns more information, and sometimes much more, generally naming all attributes of an object, and all attributes From tim_one@users.sourceforge.net Mon Sep 3 09:35:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:35:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b2.py,1.27,1.28 test_long.py,1.9,1.10 test_pow.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12739/python/Lib/test Modified Files: test_b2.py test_long.py test_pow.py Log Message: New restriction on pow(x, y, z): If z is not None, x and y must be of integer types, and y must be >= 0. See discussion at http://sf.net/tracker/index.php?func=detail&aid=457066&group_id=5470&atid=105470 Index: test_b2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b2.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** test_b2.py 2001/07/30 22:49:11 1.27 --- test_b2.py 2001/09/03 08:35:40 1.28 *************** *** 83,97 **** if fcmp(pow(2.,30), 1024.*1024.*1024.): raise TestFailed, 'pow(2.,30)' # ! # XXX These don't work -- negative float to the float power... ! #if fcmp(pow(-2.,0), 1.): raise TestFailed, 'pow(-2.,0)' ! #if fcmp(pow(-2.,1), -2.): raise TestFailed, 'pow(-2.,1)' ! #if fcmp(pow(-2.,2), 4.): raise TestFailed, 'pow(-2.,2)' ! #if fcmp(pow(-2.,3), -8.): raise TestFailed, 'pow(-2.,3)' ! # for x in 2, 2L, 2.0: for y in 10, 10L, 10.0: for z in 1000, 1000L, 1000.0: ! if fcmp(pow(x, y, z), 24.0): ! raise TestFailed, 'pow(%s, %s, %s)' % (x, y, z) print 'range' --- 83,108 ---- if fcmp(pow(2.,30), 1024.*1024.*1024.): raise TestFailed, 'pow(2.,30)' # ! if fcmp(pow(-2.,0), 1.): raise TestFailed, 'pow(-2.,0)' ! if fcmp(pow(-2.,1), -2.): raise TestFailed, 'pow(-2.,1)' ! if fcmp(pow(-2.,2), 4.): raise TestFailed, 'pow(-2.,2)' ! if fcmp(pow(-2.,3), -8.): raise TestFailed, 'pow(-2.,3)' ! ! from types import FloatType for x in 2, 2L, 2.0: for y in 10, 10L, 10.0: for z in 1000, 1000L, 1000.0: ! if isinstance(x, FloatType) or \ ! isinstance(y, FloatType) or \ ! isinstance(z, FloatType): ! try: ! pow(x, y, z) ! except TypeError: ! pass ! else: ! raise TestFailed("3-arg float pow() should have " ! "raised TypeError %r" % (x, y, z)) ! else: ! if fcmp(pow(x, y, z), 24.0): ! raise TestFailed, 'pow(%s, %s, %s)' % (x, y, z) print 'range' Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_long.py 2001/08/23 23:02:57 1.9 --- test_long.py 2001/09/03 08:35:40 1.10 *************** *** 315,322 **** for z in special: ! if z != 0: ! expected = pow(longx, longy, long(z)) ! got = pow(x, y, z) ! checkit('pow', x, y, '%', z) # ---------------------------------------------------------------- do it --- 315,331 ---- for z in special: ! if z != 0 : ! if y >= 0: ! expected = pow(longx, longy, long(z)) ! got = pow(x, y, z) ! checkit('pow', x, y, '%', z) ! else: ! try: ! pow(longx, longy, long(z)) ! except TypeError: ! pass ! else: ! raise TestFailed("pow%r should have raised " ! "TypeError" % ((longx, longy, long(z)))) # ---------------------------------------------------------------- do it Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_pow.py 2001/08/30 19:15:20 1.10 --- test_pow.py 2001/09/03 08:35:40 1.11 *************** *** 65,68 **** --- 65,77 ---- for k in range(kl, kh+1): if k != 0: + if type == float or j < 0: + try: + pow(type(i),j,k) + except TypeError: + pass + else: + raise TestFailed("expected TypeError from " + "pow%r" % ((type(i), j, k))) + continue if compare(pow(type(i),j,k), pow(type(i),j)% type(k)): raise ValueError, "pow(" +str(i)+ "," +str(j)+ \ *************** *** 97,104 **** print - print pow(3.0,3.0) % 8, pow(3.0,3.0,8) - print pow(3.0,3.0) % -8, pow(3.0,3.0,-8) - print pow(3.0,2) % -2, pow(3.0,2,-2) - print pow(5.0,2) % -8, pow(5.0,2,-8) print --- 106,109 ---- *************** *** 113,119 **** o = pow(long(i),j) % k n = pow(long(i),j,k) - if o != n: print 'Long mismatch:', i,j,k - if i >= 0 and k != 0: - o = pow(float(i),j) % k - n = pow(float(i),j,k) - if o != n: print 'Float mismatch:', i,j,k --- 118,119 ---- From tim_one@users.sourceforge.net Mon Sep 3 09:35:42 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:35:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.82,1.83 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12739/python/Doc/lib Modified Files: libfuncs.tex Log Message: New restriction on pow(x, y, z): If z is not None, x and y must be of integer types, and y must be >= 0. See discussion at http://sf.net/tracker/index.php?func=detail&aid=457066&group_id=5470&atid=105470 Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.82 retrieving revision 1.83 diff -C2 -d -r1.82 -r1.83 *** libfuncs.tex 2001/08/27 20:02:16 1.82 --- libfuncs.tex 2001/09/03 08:35:40 1.83 *************** *** 119,123 **** \end{funcdesc} ! \begin{funcdesc}{compile}{string, filename, kind\optional{, flags\optional{, dont_inherit}}} Compile the \var{string} into a code object. Code objects can be --- 119,123 ---- \end{funcdesc} ! \begin{funcdesc}{compile}{string, filename, kind\optional{, flags\optional{, dont_inherit}}} Compile the \var{string} into a code object. Code objects can be *************** *** 409,413 **** Return a dictionary representing the current local symbol table. \strong{Warning:} The contents of this dictionary should not be ! modified; changes may not affect the values of local variables used by the interpreter. \end{funcdesc} --- 409,413 ---- Return a dictionary representing the current local symbol table. \strong{Warning:} The contents of this dictionary should not be ! modified; changes may not affect the values of local variables used by the interpreter. \end{funcdesc} *************** *** 479,483 **** raised. ! If \var{mode} is omitted, it defaults to \code{'r'}. When opening a binary file, you should append \code{'b'} to the \var{mode} value for improved portability. (It's useful even on systems which don't --- 479,483 ---- raised. ! If \var{mode} is omitted, it defaults to \code{'r'}. When opening a binary file, you should append \code{'b'} to the \var{mode} value for improved portability. (It's useful even on systems which don't *************** *** 520,525 **** delivered. For example, \code{10**2} returns \code{100}, but \code{10**-2} returns \code{0.01}. (This last feature was added in ! Python 2.2. In Python 2.1 and before, a negative second argument ! would raise an exception.) \end{funcdesc} --- 520,531 ---- delivered. For example, \code{10**2} returns \code{100}, but \code{10**-2} returns \code{0.01}. (This last feature was added in ! Python 2.2. In Python 2.1 and before, if both arguments were of integer ! types and the second argument was negative, an exception was raised.) ! If the second argument is negative, the third argument must be omitted. ! If \var{z} is present, \var{x} and \var{y} must be of integer types, ! and \var{y} must be non-negative. (This restriction was added in ! Python 2.2. In Python 2.1 and before, floating 3-argument \code{pow()} ! returned platform-dependent results depending on floating-point ! rounding accidents.) \end{funcdesc} *************** *** 732,736 **** corresponding symbol table are undefined.\footnote{ In the current implementation, local variable bindings cannot ! normally be affected this way, but variables retrieved from other scopes (such as modules) can be. This may change.} \end{funcdesc} --- 738,742 ---- corresponding symbol table are undefined.\footnote{ In the current implementation, local variable bindings cannot ! normally be affected this way, but variables retrieved from other scopes (such as modules) can be. This may change.} \end{funcdesc} From tim_one@users.sourceforge.net Mon Sep 3 09:35:43 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:35:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.90,2.91 intobject.c,2.68,2.69 longobject.c,1.95,1.96 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12739/python/Objects Modified Files: floatobject.c intobject.c longobject.c Log Message: New restriction on pow(x, y, z): If z is not None, x and y must be of integer types, and y must be >= 0. See discussion at http://sf.net/tracker/index.php?func=detail&aid=457066&group_id=5470&atid=105470 Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.90 retrieving revision 2.91 diff -C2 -d -r2.90 -r2.91 *** floatobject.c 2001/08/31 17:40:15 2.90 --- floatobject.c 2001/09/03 08:35:41 2.91 *************** *** 493,501 **** { double iv, iw, ix; ! /* XXX Doesn't handle overflows if z!=None yet; it may never do so :( ! * The z parameter is really only going to be useful for integers and ! * long integers. Maybe something clever with logarithms could be done. ! * [AMK] ! */ CONVERT_TO_DOUBLE(v, iv); CONVERT_TO_DOUBLE(w, iw); --- 493,503 ---- { double iv, iw, ix; ! ! if ((PyObject *)z != Py_None) { ! PyErr_SetString(PyExc_TypeError, ! "3rd argument to floating pow() must be None"); ! return NULL; ! } ! CONVERT_TO_DOUBLE(v, iv); CONVERT_TO_DOUBLE(w, iw); *************** *** 538,551 **** PyErr_SetFromErrno(PyExc_OverflowError); return NULL; - } - if ((PyObject *)z != Py_None) { - double iz; - CONVERT_TO_DOUBLE(z, iz); - PyFPE_START_PROTECT("pow", return 0) - ix = fmod(ix, iz); /* XXX To Be Rewritten */ - if (ix != 0 && ((iv < 0 && iz > 0) || (iv > 0 && iz < 0) )) { - ix += iz; - } - PyFPE_END_PROTECT(ix) } return PyFloat_FromDouble(ix); --- 540,543 ---- Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.68 retrieving revision 2.69 diff -C2 -d -r2.68 -r2.69 *** intobject.c 2001/08/31 17:40:15 2.68 --- intobject.c 2001/09/03 08:35:41 2.69 *************** *** 576,579 **** --- 576,584 ---- CONVERT_TO_LONG(w, iw); if (iw < 0) { + if ((PyObject *)z != Py_None) { + PyErr_SetString(PyExc_TypeError, "integer pow() arg " + "3 must not be specified when arg 2 is < 0"); + return NULL; + } /* Return a float. This works because we know that this calls float_pow() which converts its Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.95 retrieving revision 1.96 diff -C2 -d -r1.95 -r1.96 *** longobject.c 2001/08/31 17:40:15 1.95 --- longobject.c 2001/09/03 08:35:41 1.96 *************** *** 1599,1608 **** size_b = b->ob_size; if (size_b < 0) { - /* Return a float. This works because we know that - this calls float_pow() which converts its - arguments to double. */ Py_DECREF(a); Py_DECREF(b); Py_DECREF(c); return PyFloat_Type.tp_as_number->nb_power(v, w, x); } --- 1599,1613 ---- size_b = b->ob_size; if (size_b < 0) { Py_DECREF(a); Py_DECREF(b); Py_DECREF(c); + if (x != Py_None) { + PyErr_SetString(PyExc_TypeError, "integer pow() arg " + "3 must not be specified when arg 2 is < 0"); + return NULL; + } + /* Return a float. This works because we know that + this calls float_pow() which converts its + arguments to double. */ return PyFloat_Type.tp_as_number->nb_power(v, w, x); } From tim_one@users.sourceforge.net Mon Sep 3 09:44:04 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 01:44:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_pow.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15483/python/Lib/test Modified Files: test_pow.py Log Message: Restore a line deleted by mistake. Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_pow.py 2001/09/03 08:35:40 1.11 --- test_pow.py 2001/09/03 08:44:02 1.12 *************** *** 118,119 **** --- 118,121 ---- o = pow(long(i),j) % k n = pow(long(i),j,k) + if o != n: print 'Integer mismatch:', i,j,k + From nascheme@users.sourceforge.net Mon Sep 3 16:44:50 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 03 Sep 2001 08:44:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include objimpl.h,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv2183/Include Modified Files: objimpl.h Log Message: Fix the names of _PyObject_GC_TRACK and _PyObject_GC_UNTRACK when the GC is disabled. Obviously everyone enables the GC. :-) Index: objimpl.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/objimpl.h,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** objimpl.h 2001/08/29 23:49:28 2.37 --- objimpl.h 2001/09/03 15:44:48 2.38 *************** *** 284,289 **** #define PyObject_GC_NewVar PyObject_NewVar #define PyObject_GC_Del PyObject_Del ! #define PyObject_GC_TRACK(op) ! #define PyObject_GC_UNTRACK(op) #define PyObject_GC_Track(op) #define PyObject_GC_UnTrack(op) --- 284,289 ---- #define PyObject_GC_NewVar PyObject_NewVar #define PyObject_GC_Del PyObject_Del ! #define _PyObject_GC_TRACK(op) ! #define _PyObject_GC_UNTRACK(op) #define PyObject_GC_Track(op) #define PyObject_GC_UnTrack(op) From nascheme@users.sourceforge.net Mon Sep 3 16:47:24 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Mon, 03 Sep 2001 08:47:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils dist.py,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv2758/Lib/distutils Modified Files: dist.py Log Message: Don't use dir() to find instance attribute names. Index: dist.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/dist.py,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** dist.py 2001/08/10 18:59:30 1.49 --- dist.py 2001/09/03 15:47:21 1.50 *************** *** 123,129 **** # object in a sneaky and underhanded (but efficient!) way. self.metadata = DistributionMetadata() ! method_basenames = dir(self.metadata) + \ ! ['fullname', 'contact', 'contact_email'] ! for basename in method_basenames: method_name = "get_" + basename setattr(self, method_name, getattr(self.metadata, method_name)) --- 123,127 ---- # object in a sneaky and underhanded (but efficient!) way. self.metadata = DistributionMetadata() ! for basename in self.metadata._METHOD_BASENAMES: method_name = "get_" + basename setattr(self, method_name, getattr(self.metadata, method_name)) *************** *** 962,965 **** --- 960,969 ---- author, and so forth. """ + + _METHOD_BASENAMES = ("name", "version", "author", "author_email", + "maintainer", "maintainer_email", "url", + "license", "description", "long_description", + "keywords", "platforms", "fullname", "contact", + "contact_email", "licence") def __init__ (self): From tim_one@users.sourceforge.net Tue Sep 4 02:20:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 18:20:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.232,2.233 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv11642/python/Python Modified Files: bltinmodule.c Log Message: builtin_dir(): Treat classic classes like types. Use PyDict_Keys instead of PyMapping_Keys because we know we have a real dict. Tolerate that objects may have an attr named "__dict__" that's not a dict (Py_None popped up during testing). test_descr.py, test_dir(): Test the new classic-class behavior; beef up the new-style class test similarly. test_pyclbr.py, checkModule(): dir(C) is no longer a synonym for C.__dict__.keys() when C is a classic class (looks like the same thing that burned distutils! -- should it be *made* a synoym again? Then it would be inconsistent with new-style class behavior.). Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.232 retrieving revision 2.233 diff -C2 -d -r2.232 -r2.233 *** bltinmodule.c 2001/09/03 05:47:38 2.232 --- bltinmodule.c 2001/09/04 01:20:04 2.233 *************** *** 441,447 **** assert(PyDict_Check(dict)); - /* XXX Class objects fail the PyType_Check check. Don't - XXX know of others. */ - /* assert(PyType_Check(aclass)); */ assert(aclass); --- 441,444 ---- *************** *** 491,495 **** if (locals == NULL) goto error; ! result = PyMapping_Keys(locals); if (result == NULL) goto error; --- 488,492 ---- if (locals == NULL) goto error; ! result = PyDict_Keys(locals); if (result == NULL) goto error; *************** *** 501,508 **** if (masterdict == NULL) goto error; } ! /* Elif some form of type, recurse. */ ! else if (PyType_Check(arg)) { masterdict = PyDict_New(); if (masterdict == NULL) --- 498,508 ---- if (masterdict == NULL) goto error; + assert(PyDict_Check(masterdict)); } ! /* Elif some form of type or class, grab its dict and its bases. ! We deliberately don't suck up its __class__, as methods belonging ! to the metaclass would probably be more confusing than helpful. */ ! else if (PyType_Check(arg) || PyClass_Check(arg)) { masterdict = PyDict_New(); if (masterdict == NULL) *************** *** 515,540 **** else { PyObject *itsclass; ! /* Create a dict to start with. */ masterdict = PyObject_GetAttrString(arg, "__dict__"); if (masterdict == NULL) { PyErr_Clear(); masterdict = PyDict_New(); - if (masterdict == NULL) - goto error; } else { /* The object may have returned a reference to its dict, so copy it to avoid mutating it. */ PyObject *temp = PyDict_Copy(masterdict); - if (temp == NULL) - goto error; Py_DECREF(masterdict); masterdict = temp; } ! /* Merge in attrs reachable from its class. */ itsclass = PyObject_GetAttrString(arg, "__class__"); - /* XXX Sometimes this is null! Like after "class C: pass", - C.__class__ raises AttributeError. Don't know of other - cases. */ if (itsclass == NULL) PyErr_Clear(); --- 515,542 ---- else { PyObject *itsclass; ! /* Create a dict to start with. CAUTION: Not everything ! responding to __dict__ returns a dict! */ masterdict = PyObject_GetAttrString(arg, "__dict__"); if (masterdict == NULL) { PyErr_Clear(); masterdict = PyDict_New(); } + else if (!PyDict_Check(masterdict)) { + Py_DECREF(masterdict); + masterdict = PyDict_New(); + } else { /* The object may have returned a reference to its dict, so copy it to avoid mutating it. */ PyObject *temp = PyDict_Copy(masterdict); Py_DECREF(masterdict); masterdict = temp; } ! if (masterdict == NULL) ! goto error; ! ! /* Merge in attrs reachable from its class. ! CAUTION: Not all objects have a __class__ attr. */ itsclass = PyObject_GetAttrString(arg, "__class__"); if (itsclass == NULL) PyErr_Clear(); *************** *** 551,555 **** /* The result comes from its keys. */ assert(result == NULL); ! result = PyMapping_Keys(masterdict); if (result == NULL) goto error; --- 553,557 ---- /* The result comes from its keys. */ assert(result == NULL); ! result = PyDict_Keys(masterdict); if (result == NULL) goto error; *************** *** 579,583 **** "No argument: the names in the current scope.\n" "Module object: the module attributes.\n" ! "Type object: its attributes, and recursively the attributes of its bases.\n" "Otherwise: its attributes, its class's attributes, and recursively the\n" " attributes of its class's base classes."; --- 581,586 ---- "No argument: the names in the current scope.\n" "Module object: the module attributes.\n" ! "Type or class object: its attributes, and recursively the attributes of\n" ! " its bases.\n" "Otherwise: its attributes, its class's attributes, and recursively the\n" " attributes of its class's base classes."; From tim_one@users.sourceforge.net Tue Sep 4 02:20:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 18:20:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.30,1.31 test_pyclbr.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11642/python/Lib/test Modified Files: test_descr.py test_pyclbr.py Log Message: builtin_dir(): Treat classic classes like types. Use PyDict_Keys instead of PyMapping_Keys because we know we have a real dict. Tolerate that objects may have an attr named "__dict__" that's not a dict (Py_None popped up during testing). test_descr.py, test_dir(): Test the new classic-class behavior; beef up the new-style class test similarly. test_pyclbr.py, checkModule(): dir(C) is no longer a synonym for C.__dict__.keys() when C is a classic class (looks like the same thing that burned distutils! -- should it be *made* a synoym again? Then it would be inconsistent with new-style class behavior.). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** test_descr.py 2001/09/03 05:47:38 1.30 --- test_descr.py 2001/09/04 01:20:04 1.31 *************** *** 184,189 **** dir(arg) ! # Check some details here because classic classes aren't working ! # reasonably, and I want this to fail (eventually). class C: Cdata = 1 --- 184,188 ---- dir(arg) ! # Try classic classes. class C: Cdata = 1 *************** *** 203,223 **** Adata = 1 def Amethod(self): pass ! astuff = ['Adata', 'Amethod', '__doc__', '__module__'] ! # This isn't finding C's stuff at all. verify(dir(A) == astuff) - # But this is! It's because a.__class__ exists but A.__class__ doesn't. a = A() ! verify(dir(a) == astuff[:2] + cstuff) ! # The story for new-style classes is quite different. class C(object): Cdata = 1 def Cmethod(self): pass class A(C): Adata = 1 def Amethod(self): pass ! d = dir(A) ! for expected in 'Cdata', 'Cmethod', 'Adata', 'Amethod': ! verify(expected in d) binops = { --- 202,244 ---- Adata = 1 def Amethod(self): pass ! ! astuff = ['Adata', 'Amethod'] + cstuff verify(dir(A) == astuff) a = A() ! verify(dir(a) == astuff) ! a.adata = 42 ! a.amethod = lambda self: 3 ! verify(dir(a) == astuff + ['adata', 'amethod']) ! # The same, but with new-style classes. Since these have object as a ! # base class, a lot more gets sucked in. ! def interesting(strings): ! return [s for s in strings if not s.startswith('_')] ! class C(object): Cdata = 1 def Cmethod(self): pass + + cstuff = ['Cdata', 'Cmethod'] + verify(interesting(dir(C)) == cstuff) + + c = C() + verify(interesting(dir(c)) == cstuff) + + c.cdata = 2 + c.cmethod = lambda self: 0 + verify(interesting(dir(c)) == cstuff + ['cdata', 'cmethod']) + class A(C): Adata = 1 def Amethod(self): pass ! ! astuff = ['Adata', 'Amethod'] + cstuff ! verify(interesting(dir(A)) == astuff) ! a = A() ! verify(interesting(dir(a)) == astuff) ! a.adata = 42 ! a.amethod = lambda self: 3 ! verify(interesting(dir(a)) == astuff + ['adata', 'amethod']) binops = { Index: test_pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyclbr.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_pyclbr.py 2001/08/13 22:25:24 1.2 --- test_pyclbr.py 2001/09/04 01:20:04 1.3 *************** *** 77,81 **** actualMethods = [] ! for m in dir(py_item): if type(getattr(py_item, m)) == MethodType: actualMethods.append(m) --- 77,81 ---- actualMethods = [] ! for m in py_item.__dict__.keys(): if type(getattr(py_item, m)) == MethodType: actualMethods.append(m) From tim_one@users.sourceforge.net Tue Sep 4 03:50:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 19:50:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include longobject.h,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv29765/python/Include Modified Files: longobject.h Log Message: Introduce new private API function _PyLong_AsScaledDouble. Not used yet, but will be the foundation for Good Things: + Speed PyLong_AsDouble. + Give PyLong_AsDouble the ability to detect overflow. + Make true division of long/long nearly as accurate as possible (no spurious infinities or NaNs). + Return non-insane results from math.log and math.log10 when passing a long that can't be approximated by a double better than HUGE_VAL. Index: longobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/longobject.h,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** longobject.h 2001/08/29 15:45:32 2.22 --- longobject.h 2001/09/04 02:50:49 2.23 *************** *** 19,22 **** --- 19,31 ---- extern DL_IMPORT(long) PyLong_AsLong(PyObject *); extern DL_IMPORT(unsigned long) PyLong_AsUnsignedLong(PyObject *); + + /* _PyLong_AsScaledDouble returns a double x and an exponent e such that + the true value is approximately equal to x * 2**(SHIFT*e). e is >= 0. + x is 0.0 if and only if the input is 0 (in which case, e and x are both + zeroes). Overflow is impossible. Note that the exponent returned must + be multiplied by SHIFT! There may not be enough room in an int to store + e*SHIFT directly. */ + extern DL_IMPORT(double) _PyLong_AsScaledDouble(PyObject *vv, int *e); + extern DL_IMPORT(double) PyLong_AsDouble(PyObject *); extern DL_IMPORT(PyObject *) PyLong_FromVoidPtr(void *); From tim_one@users.sourceforge.net Tue Sep 4 03:50:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 19:50:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.96,1.97 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv29765/python/Objects Modified Files: longobject.c Log Message: Introduce new private API function _PyLong_AsScaledDouble. Not used yet, but will be the foundation for Good Things: + Speed PyLong_AsDouble. + Give PyLong_AsDouble the ability to detect overflow. + Make true division of long/long nearly as accurate as possible (no spurious infinities or NaNs). + Return non-insane results from math.log and math.log10 when passing a long that can't be approximated by a double better than HUGE_VAL. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.96 retrieving revision 1.97 diff -C2 -d -r1.96 -r1.97 *** longobject.c 2001/09/03 08:35:41 1.96 --- longobject.c 2001/09/04 02:50:49 1.97 *************** *** 475,478 **** --- 475,530 ---- } + double + _PyLong_AsScaledDouble(PyObject *vv, int *exponent) + { + /* NBITS_WANTED should be > the number of bits in a double's precision, + but small enough so that 2**NBITS_WANTED is within the normal double + range. nbitsneeded is set to 1 less than that because the most-significant + Python digit contains at least 1 significant bit, but we don't want to + bother counting them (catering to the worst case cheaply). + + 57 is one more than VAX-D double precision; I (Tim) don't know of a double + format with more precision than that; it's 1 larger so that we add in at + least one round bit to stand in for the ignored least-significant bits. + */ + #define NBITS_WANTED 57 + PyLongObject *v; + double x; + const double multiplier = (double)(1L << SHIFT); + int i, sign; + int nbitsneeded; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return -1; + } + v = (PyLongObject *)vv; + i = v->ob_size; + sign = 1; + if (i < 0) { + sign = -1; + i = -(i); + } + else if (i == 0) { + *exponent = 0; + return 0.0; + } + --i; + x = (double)v->ob_digit[i]; + nbitsneeded = NBITS_WANTED - 1; + /* Invariant: i Python digits remain unaccounted for. */ + while (i > 0 && nbitsneeded > 0) { + --i; + x = x * multiplier + (double)v->ob_digit[i]; + nbitsneeded -= SHIFT; + } + /* There are i digits we didn't shift in. Pretending they're all + zeroes, the true value is x * 2**(i*SHIFT). */ + *exponent = i; + assert(x > 0.0); + return x * sign; + #undef NBITS_WANTED + } + /* Get a C double from a long int object. */ From gvanrossum@users.sourceforge.net Tue Sep 4 04:25:02 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:25:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3994 Modified Files: main.c Log Message: Rename the -D option to -Q, to avoid a Jython option name conflict. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** main.c 2001/08/31 18:17:13 1.58 --- main.c 2001/09/04 03:25:00 1.59 *************** *** 30,34 **** /* command line options */ ! #define BASE_OPTS "c:dD:EhiOStuUvVW:xX" #ifndef RISCOS --- 30,34 ---- /* command line options */ ! #define BASE_OPTS "c:dEhiOQ:StuUvVW:xX" #ifndef RISCOS *************** *** 51,63 **** -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\ - -D arg : division options: -Dold (default), -Dwarn, -Dnew\n\ -E : ignore environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit\n\ - "; - static char *usage_2 = "\ -i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\ and force prompts, even if stdin does not appear to be a terminal\n\ -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ --- 51,63 ---- -c cmd : program passed in as string (terminates option list)\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\ -E : ignore environment variables (such as PYTHONPATH)\n\ -h : print this help message and exit\n\ -i : inspect interactively after running script, (also PYTHONINSPECT=x)\n\ and force prompts, even if stdin does not appear to be a terminal\n\ + "; + static char *usage_2 = "\ -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ + -Q arg : division options: -Qold (default), -Qwarn, -Qnew\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ *************** *** 156,160 **** break; ! case 'D': if (strcmp(_PyOS_optarg, "old") == 0) { Py_DivisionWarningFlag = 0; --- 156,160 ---- break; ! case 'Q': if (strcmp(_PyOS_optarg, "old") == 0) { Py_DivisionWarningFlag = 0; *************** *** 171,176 **** } fprintf(stderr, ! "-D option should be " ! "`-Dold', `-Dwarn' or `-Dnew' only\n"); usage(2, argv[0]); /* NOTREACHED */ --- 171,176 ---- } fprintf(stderr, ! "-Q option should be " ! "`-Qold', `-Qwarn' or `-Qnew' only\n"); usage(2, argv[0]); /* NOTREACHED */ From gvanrossum@users.sourceforge.net Tue Sep 4 04:25:47 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:25:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.225,1.226 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4094 Modified Files: NEWS Log Message: Rename the -D option to -Q, to avoid a Jython option name conflict. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -d -r1.225 -r1.226 *** NEWS 2001/09/03 08:35:40 1.225 --- NEWS 2001/09/04 03:25:44 1.226 *************** *** 33,44 **** OverflowError exception. ! - A new command line option, -D, is added to control run-time warnings for the use of classic division. (See PEP 238.) Possible ! values are -Dold, -Dwarn, and -Dnew. The default is -Dold, meaning the / operator has its classic meaning and no warnings are issued. ! Using -Dwarn issues a run-time warning about all uses of classic ! division for int, long, float and complex arguments. Using -Dnew is questionable; it turns on new division by default, but only in the ! __main__ module. You can usefully combine -Dwarn and -Dnew: this gives the __main__ module new division, and warns about classic division everywhere else. --- 33,44 ---- OverflowError exception. ! - A new command line option, -Q, is added to control run-time warnings for the use of classic division. (See PEP 238.) Possible ! values are -Qold, -Qwarn, and -Qnew. The default is -Qold, meaning the / operator has its classic meaning and no warnings are issued. ! Using -Qwarn issues a run-time warning about all uses of classic ! division for int, long, float and complex arguments. Using -Qnew is questionable; it turns on new division by default, but only in the ! __main__ module. You can usefully combine -Qwarn and -Qnew: this gives the __main__ module new division, and warns about classic division everywhere else. From gvanrossum@users.sourceforge.net Tue Sep 4 04:26:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:26:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv4207 Modified Files: fixdiv.py Log Message: Rename the -D option to -Q, to avoid a Jython option name conflict. Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** fixdiv.py 2001/09/02 14:11:30 1.3 --- fixdiv.py 2001/09/04 03:26:15 1.4 *************** *** 3,7 **** """fixdiv - tool to fix division operators. ! To use this tool, first run `python -Dwarn yourscript.py 2>warnings'. This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file --- 3,7 ---- """fixdiv - tool to fix division operators. ! To use this tool, first run `python -Qwarn yourscript.py 2>warnings'. This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file From gvanrossum@users.sourceforge.net Tue Sep 4 04:48:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:48:50 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0238.txt,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8197 Modified Files: pep-0238.txt Log Message: Rename the -D option to -Q, to avoid a Jython option name conflict. Document the 4th value of this option (warnall). Also update some other items that are now resolved or close to being resolved. Index: pep-0238.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0238.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** pep-0238.txt 2001/08/07 15:30:11 1.16 --- pep-0238.txt 2001/09/04 03:48:48 1.17 *************** *** 252,276 **** Command Line Option ! The -D command line option takes a string argument that can take ! three values: "old", "warn", or "new". The default is "old" in ! Python 2.2 but will change to "warn" in later 2.x versions. The ! "old" value means the classic division operator acts as described. ! The "warn" value means the classic division operator issues a ! warning (a DeprecationWarning using the standard warning ! framework) when applied to ints or longs. The "new" value changes ! the default globally so that the / operator is always interpreted ! as true division. The "new" option is only intended for use in ! certain educational environments, where true division is required, ! but asking the students to include the future division statement ! in all their code would be a problem. This option will not be supported in Python 3.0; Python 3.0 will always interpret / as true division. ! (Other names have been proposed, like -Dclassic, -Dclassic-warn, ! -Dtrue, or -Dold_division etc.; these seem more verbose to me ! without much advantage. After all the term classic division is ! not used in the language at all (only in the PEP), and the term ! true division is rarely used in the language -- only in __truediv__.) --- 252,281 ---- Command Line Option ! The -Q command line option takes a string argument that can take ! four values: "old", "warn", "warnall", or "new". The default is ! "old" in Python 2.2 but will change to "warn" in later 2.x ! versions. The "old" value means the classic division operator ! acts as described. The "warn" value means the classic division ! operator issues a warning (a DeprecationWarning using the standard ! warning framework) when applied to ints or longs. The "warnall" ! value also issues warnings for classic division when applied to ! floats or complex; this is for use by the fixdiv.py conversion ! script mentioned below. The "new" value changes the default ! globally so that the / operator is always interpreted as true ! division. The "new" option is only intended for use in certain ! educational environments, where true division is required, but ! asking the students to include the future division statement in ! all their code would be a problem. This option will not be supported in Python 3.0; Python 3.0 will always interpret / as true division. ! (This option was originally proposed as -D, but that turned out to ! be an existing option for Jython, hence the Q -- mnemonic for ! Quotient. Other names have been proposed, like -Qclassic, ! -Qclassic-warn, -Qtrue, or -Qold_division etc.; these seem more ! verbose to me without much advantage. After all the term classic ! division is not used in the language at all (only in the PEP), and ! the term true division is rarely used in the language -- only in __truediv__.) *************** *** 329,333 **** If "from __future__ import division" is present in a module, or if ! -Dnew is used, the / and /= operators are translated to true division opcodes; otherwise they are translated to classic division (until Python 3.0 comes along, where they are always --- 334,338 ---- If "from __future__ import division" is present in a module, or if ! -Qnew is used, the / and /= operators are translated to true division opcodes; otherwise they are translated to classic division (until Python 3.0 comes along, where they are always *************** *** 360,365 **** default is evil. It can certainly be dangerous in the wrong hands: for example, it would be impossible to combine a 3rd ! party library package that requires -Dnew with another one that ! requires -Dold. But I believe that the VPython folks need a way to enable true division by default, and other educators might need the same. These usually have enough control over the --- 365,370 ---- default is evil. It can certainly be dangerous in the wrong hands: for example, it would be impossible to combine a 3rd ! party library package that requires -Qnew with another one that ! requires -Qold. But I believe that the VPython folks need a way to enable true division by default, and other educators might need the same. These usually have enough control over the *************** *** 371,375 **** will disappear if and when rational numbers are supported. In the interim, maybe the long-to-float conversion could be made to ! raise OverflowError if the long is out of range. - For classes to have to support all three of __div__(), --- 376,382 ---- will disappear if and when rational numbers are supported. In the interim, maybe the long-to-float conversion could be made to ! raise OverflowError if the long is out of range. Tim Peters ! will make sure that whenever an in-range float is returned, ! decent precision is guaranteed. - For classes to have to support all three of __div__(), *************** *** 427,444 **** A. They inherit the choice from the invoking module. PEP 236[4] ! lists this as a partially resolved problem. Q. What about code compiled by the codeop module? ! A. Alas, this will always use the default semantics (set by the -D ! command line option). This is a general problem with the ! future statement; PEP 236[4] lists it as an unresolved ! problem. You could have your own clone of codeop.py that ! includes a future division statement, but that's not a general ! solution. Q. Will there be conversion tools or aids? ! A. Certainly, but these are outside the scope of the PEP. Q. Why is my question not answered here? --- 434,450 ---- A. They inherit the choice from the invoking module. PEP 236[4] ! now lists this as a resolved problem, referring to PEP 264[5]. Q. What about code compiled by the codeop module? ! A. This is dealt with properly; see PEP 264[5]. Q. Will there be conversion tools or aids? ! A. Certainly. While these are outside the scope of the PEP, I ! should point out two simple tools that will be released with ! Python 2.2a3: Tools/scripts/finddiv.py finds division operators ! (slightly smarter than "grep /") and Tools/scripts/fixdiv.py ! can produce patches based on run-time analysis. Q. Why is my question not answered here? *************** *** 453,459 **** Implementation ! A very early implementation (not yet following the above spec, but ! supporting // and the future division statement) is available from ! the SourceForge patch manager[5]. --- 459,465 ---- Implementation ! Essentially everything mentioned here is implemented in CVS and ! will be released with Python 2.2a3; most of it was already ! released with Python 2.2a2. *************** *** 475,480 **** http://www.python.org/peps/pep-0236.html ! [5] Patch 443474, from __future__ import division ! http://sourceforge.net/tracker/index.php?func=detail&aid=443474&group_id=5470&atid=305470 --- 481,486 ---- http://www.python.org/peps/pep-0236.html ! [5] PEP 264, Future statements in simulated shells ! http://www.python.org/peps/pep-0236.html From gvanrossum@users.sourceforge.net Tue Sep 4 04:50:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:50:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules main.c,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv8395 Modified Files: main.c Log Message: PEP 238 documented -Qwarn as warning only for classic int or long division, and this makes sense. Add -Qwarnall to warn for all classic divisions, as required by the fixdiv.py tool. Index: main.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/main.c,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** main.c 2001/09/04 03:25:00 1.59 --- main.c 2001/09/04 03:50:04 1.60 *************** *** 59,63 **** -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ ! -Q arg : division options: -Qold (default), -Qwarn, -Qnew\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ --- 59,63 ---- -O : optimize generated bytecode (a tad; also PYTHONOPTIMIZE=x)\n\ -OO : remove doc-strings in addition to the -O optimizations\n\ ! -Q arg : division options: -Qold (default), -Qwarn, -Qwarnall, -Qnew\n\ -S : don't imply 'import site' on initialization\n\ -t : issue warnings about inconsistent tab usage (-tt: issue errors)\n\ *************** *** 162,166 **** } if (strcmp(_PyOS_optarg, "warn") == 0) { ! Py_DivisionWarningFlag++; break; } --- 162,170 ---- } if (strcmp(_PyOS_optarg, "warn") == 0) { ! Py_DivisionWarningFlag = 1; ! break; ! } ! if (strcmp(_PyOS_optarg, "warnall") == 0) { ! Py_DivisionWarningFlag = 2; break; } *************** *** 171,176 **** } fprintf(stderr, ! "-Q option should be " ! "`-Qold', `-Qwarn' or `-Qnew' only\n"); usage(2, argv[0]); /* NOTREACHED */ --- 175,180 ---- } fprintf(stderr, ! "-Q option should be `-Qold', " ! "`-Qwarn', `-Qwarnall', or `-Qnew' only\n"); usage(2, argv[0]); /* NOTREACHED */ From gvanrossum@users.sourceforge.net Tue Sep 4 04:50:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:50:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.91,2.92 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8440 Modified Files: floatobject.c Log Message: PEP 238 documented -Qwarn as warning only for classic int or long division, and this makes sense. Add -Qwarnall to warn for all classic divisions, as required by the fixdiv.py tool. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.91 retrieving revision 2.92 diff -C2 -d -r2.91 -r2.92 *** floatobject.c 2001/09/03 08:35:41 2.91 --- floatobject.c 2001/09/04 03:50:25 2.92 *************** *** 420,424 **** CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); ! if (Py_DivisionWarningFlag && PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0) return NULL; --- 420,424 ---- CONVERT_TO_DOUBLE(v, a); CONVERT_TO_DOUBLE(w, b); ! if (Py_DivisionWarningFlag >= 2 && PyErr_Warn(PyExc_DeprecationWarning, "classic float division") < 0) return NULL; From gvanrossum@users.sourceforge.net Tue Sep 4 04:50:49 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:50:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.40,2.41 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv8490 Modified Files: complexobject.c Log Message: PEP 238 documented -Qwarn as warning only for classic int or long division, and this makes sense. Add -Qwarnall to warn for all classic divisions, as required by the fixdiv.py tool. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.40 retrieving revision 2.41 diff -C2 -d -r2.40 -r2.41 *** complexobject.c 2001/08/31 17:40:15 2.40 --- complexobject.c 2001/09/04 03:50:47 2.41 *************** *** 378,382 **** Py_complex quot; ! if (Py_DivisionWarningFlag && PyErr_Warn(PyExc_DeprecationWarning, "classic complex division") < 0) --- 378,382 ---- Py_complex quot; ! if (Py_DivisionWarningFlag >= 2 && PyErr_Warn(PyExc_DeprecationWarning, "classic complex division") < 0) From gvanrossum@users.sourceforge.net Tue Sep 4 04:51:11 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 03 Sep 2001 20:51:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv8557 Modified Files: fixdiv.py Log Message: PEP 238 documented -Qwarn as warning only for classic int or long division, and this makes sense. Add -Qwarnall to warn for all classic divisions, as required by the fixdiv.py tool. Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** fixdiv.py 2001/09/04 03:26:15 1.4 --- fixdiv.py 2001/09/04 03:51:09 1.5 *************** *** 3,7 **** """fixdiv - tool to fix division operators. ! To use this tool, first run `python -Qwarn yourscript.py 2>warnings'. This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file --- 3,7 ---- """fixdiv - tool to fix division operators. ! To use this tool, first run `python -Qwarnall yourscript.py 2>warnings'. This runs the script `yourscript.py' while writing warning messages about all uses of the classic division operator to the file From tim_one@users.sourceforge.net Tue Sep 4 06:14:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 22:14:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.226,1.227 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28101/python/Misc Modified Files: NEWS Log Message: Raise OverflowError when appropriate on long->float conversion. Most of the fiddling is simply due to that no caller of PyLong_AsDouble ever checked for failure (so that's fixing old bugs). PyLong_AsDouble is much faster for big inputs now too, but that's more of a happy consequence than a design goal. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.226 retrieving revision 1.227 diff -C2 -d -r1.226 -r1.227 *** NEWS 2001/09/04 03:25:44 1.226 --- NEWS 2001/09/04 05:14:19 1.227 *************** *** 4,7 **** --- 4,10 ---- Core + - Conversion of long to float now raises OverflowError if the long is too + big to represent as a C double. + - The 3-argument builtin pow() no longer allows a third non-None argument if either of the first two arguments is a float, or if both are of *************** *** 95,98 **** --- 98,110 ---- API + + - Note that PyLong_AsDouble can fail! This has always been true, but no + callers checked for it. It's more likely to fail now, because overflow + errors are properly detected now. The proper way to check: + + double x = PyLong_AsDouble(some_long_object); + if (x == -1.0 && PyErr_Occurred()) { + /* The conversion failed. */ + } - The GC API has been changed. Extensions that use the old API will still From tim_one@users.sourceforge.net Tue Sep 4 06:14:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 22:14:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28101/python/Lib/test Modified Files: test_long.py Log Message: Raise OverflowError when appropriate on long->float conversion. Most of the fiddling is simply due to that no caller of PyLong_AsDouble ever checked for failure (so that's fixing old bugs). PyLong_AsDouble is much faster for big inputs now too, but that's more of a happy consequence than a design goal. Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_long.py 2001/09/03 08:35:40 1.10 --- test_long.py 2001/09/04 05:14:18 1.11 *************** *** 329,332 **** --- 329,368 ---- "TypeError" % ((longx, longy, long(z)))) + # ---------------------------------------- tests of long->float overflow + + def test_float_overflow(): + import math + + if verbose: + print "long->float overflow" + + for x in -2.0, -1.0, 0.0, 1.0, 2.0: + verify(float(long(x)) == x) + + huge = 1L << 30000 + mhuge = -huge + namespace = {'huge': huge, 'mhuge': mhuge, 'math': math} + for test in ["float(huge)", "float(mhuge)", + "complex(huge)", "complex(mhuge)", + "complex(huge, 1)", "complex(mhuge, 1)", + "complex(1, huge)", "complex(1, mhuge)", + "1. + huge", "huge + 1.", "1. + mhuge", "mhuge + 1.", + "1. - huge", "huge - 1.", "1. - mhuge", "mhuge - 1.", + "1. * huge", "huge * 1.", "1. * mhuge", "mhuge * 1.", + "1. // huge", "huge // 1.", "1. // mhuge", "mhuge // 1.", + "1. / huge", "huge / 1.", "1. / mhuge", "mhuge / 1.", + "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.", + "math.sin(huge)", "math.sin(mhuge)", + "math.log(huge)", "math.log(mhuge)", # should do better + "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better + "math.log10(huge)", "math.log10(mhuge)", # should do better + "math.floor(huge)", "math.floor(mhuge)"]: + + try: + eval(test, namespace) + except OverflowError: + pass + else: + raise TestFailed("expected OverflowError from %s" % test) # ---------------------------------------------------------------- do it *************** *** 336,337 **** --- 372,374 ---- test_misc() test_auto_overflow() + test_float_overflow() From tim_one@users.sourceforge.net Tue Sep 4 06:14:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 22:14:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.41,2.42 floatobject.c,2.92,2.93 longobject.c,1.97,1.98 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv28101/python/Objects Modified Files: complexobject.c floatobject.c longobject.c Log Message: Raise OverflowError when appropriate on long->float conversion. Most of the fiddling is simply due to that no caller of PyLong_AsDouble ever checked for failure (so that's fixing old bugs). PyLong_AsDouble is much faster for big inputs now too, but that's more of a happy consequence than a design goal. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.41 retrieving revision 2.42 diff -C2 -d -r2.41 -r2.42 *** complexobject.c 2001/09/04 03:50:47 2.41 --- complexobject.c 2001/09/04 05:14:19 2.42 *************** *** 523,526 **** --- 523,528 ---- else if (PyLong_Check(*pw)) { cval.real = PyLong_AsDouble(*pw); + if (cval.real == -1.0 && PyErr_Occurred()) + return -1; *pw = PyComplex_FromCComplex(cval); Py_INCREF(*pv); Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.92 retrieving revision 2.93 diff -C2 -d -r2.92 -r2.93 *** floatobject.c 2001/09/04 03:50:25 2.92 --- floatobject.c 2001/09/04 05:14:19 2.93 *************** *** 272,287 **** static int ! convert_to_double(PyObject **v, ! double *dbl) { register PyObject *obj = *v; ! if (PyInt_Check(obj)) { *dbl = (double)PyInt_AS_LONG(obj); } else if (PyLong_Check(obj)) { - PyFPE_START_PROTECT("convert_to_double", {*v=NULL;return -1;}) *dbl = PyLong_AsDouble(obj); ! PyFPE_END_PROTECT(*dbl) } else { --- 272,288 ---- static int ! convert_to_double(PyObject **v, double *dbl) { register PyObject *obj = *v; ! if (PyInt_Check(obj)) { *dbl = (double)PyInt_AS_LONG(obj); } else if (PyLong_Check(obj)) { *dbl = PyLong_AsDouble(obj); ! if (*dbl == -1.0 && PyErr_Occurred()) { ! *v = NULL; ! return -1; ! } } else { Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.97 retrieving revision 1.98 diff -C2 -d -r1.97 -r1.98 *** longobject.c 2001/09/04 02:50:49 1.97 --- longobject.c 2001/09/04 05:14:19 1.98 *************** *** 532,556 **** PyLong_AsDouble(PyObject *vv) { ! register PyLongObject *v; double x; ! double multiplier = (double) (1L << SHIFT); ! int i, sign; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return -1; } ! v = (PyLongObject *)vv; ! i = v->ob_size; ! sign = 1; ! x = 0.0; ! if (i < 0) { ! sign = -1; ! i = -(i); ! } ! while (--i >= 0) { ! x = x*multiplier + (double)v->ob_digit[i]; ! } ! return x * sign; } --- 532,557 ---- PyLong_AsDouble(PyObject *vv) { ! int e; double x; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return -1; } ! x = _PyLong_AsScaledDouble(vv, &e); ! if (x == -1.0 && PyErr_Occurred()) ! return -1.0; ! if (e > INT_MAX / SHIFT) ! goto overflow; ! errno = 0; ! x = ldexp(x, e * SHIFT); ! if (errno == ERANGE) ! goto overflow; ! return x; ! ! overflow: ! PyErr_SetString(PyExc_OverflowError, ! "long int too large to convert to float"); ! return -1.0; } *************** *** 2099,2105 **** { double result; - PyFPE_START_PROTECT("long_float", return 0) result = PyLong_AsDouble(v); ! PyFPE_END_PROTECT(result) return PyFloat_FromDouble(result); } --- 2100,2106 ---- { double result; result = PyLong_AsDouble(v); ! if (result == -1.0 && PyErr_Occurred()) ! return NULL; return PyFloat_FromDouble(result); } From tim_one@users.sourceforge.net Tue Sep 4 06:31:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 22:31:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.98,1.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2419/python/Objects Modified Files: longobject.c Log Message: Move long_true_divide next to the other division routines (for clarity!). Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.98 retrieving revision 1.99 diff -C2 -d -r1.98 -r1.99 *** longobject.c 2001/09/04 05:14:19 1.98 --- longobject.c 2001/09/04 05:31:47 1.99 *************** *** 1583,1586 **** --- 1583,1592 ---- static PyObject * + long_true_divide(PyObject *v, PyObject *w) + { + return PyFloat_Type.tp_as_number->nb_divide(v, w); + } + + static PyObject * long_mod(PyObject *v, PyObject *w) { *************** *** 2060,2069 **** Py_DECREF(b); return c; - } - - static PyObject * - long_true_divide(PyObject *v, PyObject *w) - { - return PyFloat_Type.tp_as_number->nb_divide(v, w); } --- 2066,2069 ---- From tim_one@users.sourceforge.net Tue Sep 4 06:52:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 22:52:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.69,2.70 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12934 Modified Files: intobject.c Log Message: Move int_true_divide next to the other division routines. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.69 retrieving revision 2.70 diff -C2 -d -r2.69 -r2.70 *** intobject.c 2001/09/03 08:35:41 2.69 --- intobject.c 2001/09/04 05:52:47 2.70 *************** *** 534,537 **** --- 534,543 ---- static PyObject * + int_true_divide(PyObject *v, PyObject *w) + { + return PyFloat_Type.tp_as_number->nb_true_divide(v, w); + } + + static PyObject * int_mod(PyIntObject *x, PyIntObject *y) { *************** *** 766,775 **** CONVERT_TO_LONG(w, b); return PyInt_FromLong(a | b); - } - - static PyObject * - int_true_divide(PyObject *v, PyObject *w) - { - return PyFloat_Type.tp_as_number->nb_true_divide(v, w); } --- 772,775 ---- From tim_one@users.sourceforge.net Tue Sep 4 07:17:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:17:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long_future.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19121/python/Lib/test Added Files: test_long_future.py Log Message: Change long/long true division to return as many good bits as it can; e.g., (1L << 40000)/(1L << 40001) returns 0.5, not Inf or NaN or whatever. --- NEW FILE: test_long_future.py --- from __future__ import division # When true division is the default, get rid of this and add it to # test_long.py instead. In the meantime, it's too obscure to try to # trick just part of test_long into using future division. from test_support import TestFailed, verify, verbose def test_true_division(): if verbose: print "long true division" huge = 1L << 40000 mhuge = -huge verify(huge / huge == 1.0) verify(mhuge / mhuge == 1.0) verify(huge / mhuge == -1.0) verify(mhuge / huge == -1.0) verify(1 / huge == 0.0) verify(1L / huge == 0.0) verify(1 / mhuge == 0.0) verify(1L / mhuge ==- 0.0) verify((666 * huge + (huge >> 1)) / huge == 666.5) verify((666 * mhuge + (mhuge >> 1)) / mhuge == 666.5) verify((666 * huge + (huge >> 1)) / mhuge == -666.5) verify((666 * mhuge + (mhuge >> 1)) / huge == -666.5) verify(huge / (huge << 1) == 0.5) namespace = {'huge': huge, 'mhuge': mhuge} for overflow in ["float(huge)", "float(mhuge)", "huge / 1", "huge / 2L", "huge / -1", "huge / -2L", "mhuge / 100", "mhuge / 100L"]: try: eval(overflow, namespace) except OverflowError: pass else: raise TestFailed("expected OverflowError from %r" % overflow) test_true_division() From tim_one@users.sourceforge.net Tue Sep 4 07:17:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:17:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.70,2.71 longobject.c,1.99,1.100 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19121/python/Objects Modified Files: intobject.c longobject.c Log Message: Change long/long true division to return as many good bits as it can; e.g., (1L << 40000)/(1L << 40001) returns 0.5, not Inf or NaN or whatever. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -d -r2.70 -r2.71 *** intobject.c 2001/09/04 05:52:47 2.70 --- intobject.c 2001/09/04 06:17:36 2.71 *************** *** 536,540 **** int_true_divide(PyObject *v, PyObject *w) { ! return PyFloat_Type.tp_as_number->nb_true_divide(v, w); } --- 536,547 ---- int_true_divide(PyObject *v, PyObject *w) { ! /* If they aren't both ints, give someone else a chance. In ! particular, this lets int/long get handled by longs, which ! underflows to 0 gracefully if the long is too big to convert ! to float. */ ! if (PyInt_Check(v) && PyInt_Check(w)) ! return PyFloat_Type.tp_as_number->nb_true_divide(v, w); ! Py_INCREF(Py_NotImplemented); ! return Py_NotImplemented; } Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.99 retrieving revision 1.100 diff -C2 -d -r1.99 -r1.100 *** longobject.c 2001/09/04 05:31:47 1.99 --- longobject.c 2001/09/04 06:17:36 1.100 *************** *** 1585,1589 **** long_true_divide(PyObject *v, PyObject *w) { ! return PyFloat_Type.tp_as_number->nb_divide(v, w); } --- 1585,1620 ---- long_true_divide(PyObject *v, PyObject *w) { ! PyLongObject *a, *b; ! double ad, bd; ! int aexp, bexp; ! ! CONVERT_BINOP(v, w, &a, &b); ! ad = _PyLong_AsScaledDouble((PyObject *)a, &aexp); ! bd = _PyLong_AsScaledDouble((PyObject *)b, &bexp); ! if ((ad == -1.0 || bd == -1.0) && PyErr_Occurred()) ! return NULL; ! ! if (bd == 0.0) { ! PyErr_SetString(PyExc_ZeroDivisionError, ! "long division or modulo by zero"); ! return NULL; ! } ! ! /* True value is very close to ad/bd * 2**(SHIFT*(aexp-bexp)) */ ! ad /= bd; /* overflow/underflow impossible here */ ! aexp -= bexp; ! if (aexp > INT_MAX / SHIFT) ! goto overflow; ! errno = 0; ! ad = ldexp(ad, aexp * SHIFT); ! if (ad != 0 && errno == ERANGE) /* ignore underflow to 0.0 */ ! goto overflow; ! return PyFloat_FromDouble(ad); ! ! overflow: ! PyErr_SetString(PyExc_OverflowError, ! "long/long too large for a float"); ! return NULL; ! } From tim_one@users.sourceforge.net Tue Sep 4 07:33:02 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:33:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long_future.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv23539/python/Lib/test Modified Files: test_long_future.py Log Message: Fixed a typo and added more tests. Index: test_long_future.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long_future.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_long_future.py 2001/09/04 06:17:36 1.1 --- test_long_future.py 2001/09/04 06:33:00 1.2 *************** *** 18,22 **** verify(1L / huge == 0.0) verify(1 / mhuge == 0.0) ! verify(1L / mhuge ==- 0.0) verify((666 * huge + (huge >> 1)) / huge == 666.5) verify((666 * mhuge + (mhuge >> 1)) / mhuge == 666.5) --- 18,22 ---- verify(1L / huge == 0.0) verify(1 / mhuge == 0.0) ! verify(1L / mhuge == 0.0) verify((666 * huge + (huge >> 1)) / huge == 666.5) verify((666 * mhuge + (mhuge >> 1)) / mhuge == 666.5) *************** *** 24,29 **** --- 24,31 ---- verify((666 * mhuge + (mhuge >> 1)) / huge == -666.5) verify(huge / (huge << 1) == 0.5) + verify((1000000 * huge) / huge == 1000000) namespace = {'huge': huge, 'mhuge': mhuge} + for overflow in ["float(huge)", "float(mhuge)", "huge / 1", "huge / 2L", "huge / -1", "huge / -2L", *************** *** 35,38 **** --- 37,49 ---- else: raise TestFailed("expected OverflowError from %r" % overflow) + + for zero in ["huge / 0", "huge / 0L", + "mhuge / 0", "mhuge / 0L"]: + try: + eval(zero, namespace) + except ZeroDivisionError: + pass + else: + raise TestFailed("expected ZeroDivisionError from %r" % zero) test_true_division() From tim_one@users.sourceforge.net Tue Sep 4 07:37:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib rfc822.py,1.61,1.62 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24638/python/Lib Modified Files: rfc822.py Log Message: Whitespace normalization. Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -d -r1.61 -r1.62 *** rfc822.py 2001/08/27 20:16:53 1.61 --- rfc822.py 2001/09/04 06:37:28 1.62 *************** *** 968,972 **** ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][timeval[1]-1], ! timeval[0], timeval[3], timeval[4], timeval[5]) --- 968,972 ---- ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][timeval[1]-1], ! timeval[0], timeval[3], timeval[4], timeval[5]) From tim_one@users.sourceforge.net Tue Sep 4 07:37:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv24638/python/Tools/scripts Modified Files: fixdiv.py Log Message: Whitespace normalization. Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** fixdiv.py 2001/09/04 03:51:09 1.5 --- fixdiv.py 2001/09/04 06:37:28 1.6 *************** *** 231,238 **** print "*", line elif intlong and not floatcomplex: ! print "%dc%d" % (row, row) ! print "<", line ! print "---" ! print ">", line[:col] + "/" + line[col:] elif floatcomplex and not intlong: print "True division / operator at line %d:" % row --- 231,238 ---- print "*", line elif intlong and not floatcomplex: ! print "%dc%d" % (row, row) ! print "<", line ! print "---" ! print ">", line[:col] + "/" + line[col:] elif floatcomplex and not intlong: print "True division / operator at line %d:" % row From tim_one@users.sourceforge.net Tue Sep 4 07:37:30 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 03 Sep 2001 23:37:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long.py,1.11,1.12 test_pow.py,1.12,1.13 test_urllib2.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24638/python/Lib/test Modified Files: test_long.py test_pow.py test_urllib2.py Log Message: Whitespace normalization. Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_long.py 2001/09/04 05:14:18 1.11 --- test_long.py 2001/09/04 06:37:28 1.12 *************** *** 358,362 **** "math.log10(huge)", "math.log10(mhuge)", # should do better "math.floor(huge)", "math.floor(mhuge)"]: ! try: eval(test, namespace) --- 358,362 ---- "math.log10(huge)", "math.log10(mhuge)", # should do better "math.floor(huge)", "math.floor(mhuge)"]: ! try: eval(test, namespace) Index: test_pow.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pow.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_pow.py 2001/09/03 08:44:02 1.12 --- test_pow.py 2001/09/04 06:37:28 1.13 *************** *** 119,121 **** n = pow(long(i),j,k) if o != n: print 'Integer mismatch:', i,j,k - --- 119,120 ---- Index: test_urllib2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urllib2.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_urllib2.py 2001/08/27 22:31:58 1.4 --- test_urllib2.py 2001/09/04 06:37:28 1.5 *************** *** 19,23 **** # urllib.pathname2url works, unfortunately... if os.name == 'mac': ! fname = '/' + fname.replace(':', '/') file_url = "file://%s" % fname f = urllib2.urlopen(file_url) --- 19,23 ---- # urllib.pathname2url works, unfortunately... if os.name == 'mac': ! fname = '/' + fname.replace(':', '/') file_url = "file://%s" % fname f = urllib2.urlopen(file_url) From jackjansen@users.sourceforge.net Tue Sep 4 10:05:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 02:05:14 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv28489 Modified Files: setup.py Log Message: Disabled _curses modules on MacOSX. The curses version is a 1994 BSD curses, far too old for _cursesmodule.c. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** setup.py 2001/08/22 19:24:42 1.52 --- setup.py 2001/09/04 09:05:11 1.53 *************** *** 452,456 **** exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) ! elif (self.compiler.find_library_file(lib_dirs, 'curses')): if (self.compiler.find_library_file(lib_dirs, 'terminfo')): curses_libs = ['curses', 'terminfo'] --- 452,457 ---- exts.append( Extension('_curses', ['_cursesmodule.c'], libraries = curses_libs) ) ! elif (self.compiler.find_library_file(lib_dirs, 'curses')) and platform != 'darwin1': ! # OSX has an old Berkeley curses, not good enough for the _curses module. if (self.compiler.find_library_file(lib_dirs, 'terminfo')): curses_libs = ['curses', 'terminfo'] From jackjansen@users.sourceforge.net Tue Sep 4 13:01:51 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 05:01:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils sysconfig.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv1543 Modified Files: sysconfig.py Log Message: On the mac some library paths returned were outdated, some were outright funny. Fixed. Index: sysconfig.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** sysconfig.py 2001/08/23 20:53:27 1.41 --- sysconfig.py 2001/09/04 12:01:49 1.42 *************** *** 103,116 **** if plat_specific: if standard_lib: ! return os.path.join(prefix, "Mac", "Plugins") else: ! raise DistutilsPlatformError( ! "OK, where DO site-specific extensions go on the Mac?") else: if standard_lib: return os.path.join(prefix, "Lib") else: ! raise DistutilsPlatformError( ! "OK, where DO site-specific modules go on the Mac?") else: raise DistutilsPlatformError( --- 103,114 ---- if plat_specific: if standard_lib: ! return os.path.join(prefix, "Lib", "lib-dynload") else: ! return os.path.join(prefix, "Lib", "site-packages") else: if standard_lib: return os.path.join(prefix, "Lib") else: ! return os.path.join(prefix, "Lib", "site-packages") else: raise DistutilsPlatformError( From fdrake@users.sourceforge.net Tue Sep 4 16:10:18 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 08:10:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib HTMLParser.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25450 Modified Files: HTMLParser.py Log Message: Added reasonable parsing of the DOCTYPE declaration, fixed edge cases regarding bare ampersands in content. Index: HTMLParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/HTMLParser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** HTMLParser.py 2001/08/20 21:24:19 1.5 --- HTMLParser.py 2001/09/04 15:10:16 1.6 *************** *** 16,21 **** interesting_normal = re.compile('[&<]') interesting_cdata = re.compile(r'<(/|\Z)') ! incomplete = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*' ! '|#([0-9]*|[xX][0-9a-fA-F]*))?') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') --- 16,20 ---- interesting_normal = re.compile('[&<]') interesting_cdata = re.compile(r'<(/|\Z)') ! incomplete = re.compile('&[a-zA-Z#]') entityref = re.compile('&([a-zA-Z][-.a-zA-Z0-9]*)[^a-zA-Z0-9]') *************** *** 186,192 **** elif declopen.match(rawdata, i): # ' n = len(rawdata) while j < n: c = rawdata[j] if c == ">": # end of declaration syntax ! self.handle_decl(rawdata[i+2:j]) return j + 1 if c in "\"'": --- 270,284 ---- # in practice, this should look like: ((name|stringlit) S*)+ '>' n = len(rawdata) + decltype = None + extrachars = "" while j < n: c = rawdata[j] if c == ">": # end of declaration syntax ! data = rawdata[i+2:j] ! if decltype == "doctype": ! self.handle_decl(data) ! else: ! self.unknown_decl(data) return j + 1 if c in "\"'": *************** *** 274,282 **** --- 292,530 ---- return -1 # incomplete j = m.end() + if decltype is None: + decltype = m.group(0).rstrip().lower() + if decltype != "doctype": + extrachars = "=" + elif c == "[" and decltype == "doctype": + j = self.parse_doctype_subset(j + 1, i) + if j < 0: + return j + elif c in extrachars: + j = j + 1 + while j < n and rawdata[j] in string.whitespace: + j = j + 1 + if j == n: + # end of buffer while in declaration + return -1 else: raise HTMLParseError( "unexpected char in declaration: %s" % `rawdata[j]`, self.getpos()) + decltype = decltype or '' return -1 # incomplete + + # Internal -- scan past the internal subset in a n: + # end of buffer; incomplete + return -1 + if rawdata[j:j+4] == " ]""" --- 140,150 ---- ! ! ! ! ! %paramEntity; ]""" *************** *** 200,203 **** --- 201,212 ---- self._run_check("""""", [ ("starttag", "a", [("a.b", "v"), ("c:d", "v"), ("e-f", "v")]), + ]) + + def test_illegal_declarations(self): + s = 'abcdef' + self._run_check(s, [ + ("data", "abc"), + ("unknown decl", 'spacer type="block" height="25"'), + ("data", "def"), ]) From gvanrossum@users.sourceforge.net Tue Sep 4 16:18:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 08:18:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib reconvert.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27855 Modified Files: reconvert.py Log Message: Suppress the warning about regex here. Index: reconvert.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/reconvert.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** reconvert.py 2001/02/15 22:15:13 1.5 --- reconvert.py 2001/09/04 15:18:54 1.6 *************** *** 61,64 **** --- 61,68 ---- + import warnings + warnings.filterwarnings("ignore", ".* regex .*", DeprecationWarning, __name__, + append=1) + import regex from regex_syntax import * # RE_* From gvanrossum@users.sourceforge.net Tue Sep 4 16:22:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 08:22:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test___all__.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28838 Modified Files: test___all__.py Log Message: Suppressing all DeprecationWarning messages was a bit of a problem for the -Qwarnall option, so I've changed this to only filter out the one warning that's a problem in practice. Index: test___all__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test___all__.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test___all__.py 2001/08/09 21:40:30 1.19 --- test___all__.py 2001/09/04 15:22:02 1.20 *************** *** 3,9 **** def check_all(modname): - import warnings - warnings.filterwarnings("ignore", "", DeprecationWarning, modname) - names = {} try: --- 3,6 ---- *************** *** 123,126 **** --- 120,126 ---- check_all("re") check_all("reconvert") + import warnings + warnings.filterwarnings("ignore", ".* regsub .*", DeprecationWarning, "regsub", + append=1) check_all("regsub") check_all("repr") From gvanrossum@users.sourceforge.net Tue Sep 4 17:22:04 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 09:22:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts fixdiv.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv15846 Modified Files: fixdiv.py Log Message: - Reverse the meaning of the -m option: warnings about multiple / operators per line or statement are now on by default, and -m turns these warnings off. - Change the way multiple / operators are reported; a regular recommendation is always emitted after the warning. - Report ambiguous warnings (both int|long and float|complex used for the same operator). - Update the doc string again to clarify all this and describe the possible messages more precisely. Index: fixdiv.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/fixdiv.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** fixdiv.py 2001/09/04 06:37:28 1.6 --- fixdiv.py 2001/09/04 16:22:01 1.7 *************** *** 24,45 **** line number. Then, for each file that received at least one warning, it parses the file and tries to match the warnings up to the division ! operators found in the source code. If it is successful, it writes a ! recommendation to stdout in the form of a context diff. If it is not ! successful, it writes observations to stdout instead. ! There are several possible recommendations and observations: ! - A / operator was found that can remain unchanged. This is the ! recommendation when only float and/or complex arguments were seen. ! - A / operator was found that should be changed to //. This is the recommendation when only int and/or long arguments were seen. ! - A / operator was found for which int or long as well as float or complex arguments were seen. This is highly unlikely; if it occurs, you may have to restructure the code to keep the classic semantics, or maybe you don't care about the classic semantics. ! - A / operator was found for which no warnings were seen. This could be code that was never executed, or code that was only executed with with user-defined objects as arguments. You will have to --- 24,60 ---- line number. Then, for each file that received at least one warning, it parses the file and tries to match the warnings up to the division ! operators found in the source code. If it is successful, it writes ! its findings to stdout, preceded by a line of dashes and a line of the ! form: ! Index: ! If the only findings found are suggestions to change a / operator into ! a // operator, the output is acceptable input for the Unix 'patch' ! program. ! Here are the possible messages on stdout (N stands for a line number): ! ! - A plain-diff-style change ('NcN', a line marked by '<', a line ! containing '---', and a line marked by '>'): ! ! A / operator was found that should be changed to //. This is the recommendation when only int and/or long arguments were seen. ! - 'True division / operator at line N' and a line marked by '=': ! ! A / operator was found that can remain unchanged. This is the ! recommendation when only float and/or complex arguments were seen. ! ! - 'Ambiguous / operator (..., ...) at line N', line marked by '?': ! ! A / operator was found for which int or long as well as float or complex arguments were seen. This is highly unlikely; if it occurs, you may have to restructure the code to keep the classic semantics, or maybe you don't care about the classic semantics. ! - 'No conclusive evidence on line N', line marked by '*': ! ! A / operator was found for which no warnings were seen. This could be code that was never executed, or code that was only executed with with user-defined objects as arguments. You will have to *************** *** 51,67 **** never executed?) ! - A warning was seen for a line not containing a / operator. This is ! an anomaly that shouldn't happen; the most likely cause is a change ! to the file between the time the test script was run to collect ! warnings and the time fixdiv was run. ! - More than one / operator was found on one line, or in a statement ! split across multiple lines. Because the warnings framework doesn't ! (and can't) show the offset within the line, and the code generator ! doesn't always give the correct line number for operations in a ! multi-line statement, it's not clear whether both were executed. In ! practice, they usually are, so the default action is make the same ! recommendation for all / operators, based on the above criteria. ! The -m option issues warnings for these cases instead. Notes: --- 66,101 ---- never executed?) ! - 'Phantom ... warnings for line N', line marked by '*': ! A warning was seen for a line not containing a / operator. The most ! likely cause is a warning about code executed by 'exec' or eval() ! (see note below), or an indirect invocation of the / operator, for ! example via the div() function in the operator module. It could ! also be caused by a change to the file between the time the test ! script was run to collect warnings and the time fixdiv was run. ! ! - 'More than one / operator in line N'; or ! 'More than one / operator per statement in lines N-N': ! ! The scanner found more than one / operator on a single line, or in a ! statement split across multiple lines. Because the warnings ! framework doesn't (and can't) show the offset within the line, and ! the code generator doesn't always give the correct line number for ! operations in a multi-line statement, we can't be sure whether all ! operators in the statement were executed. To be on the safe side, ! by default a warning is issued about this case. In practice, these ! cases are usually safe, and the -m option suppresses these warning. ! ! - 'Can't find the / operator in line N', line marked by '*': ! ! This really shouldn't happen. It means that the tokenize module ! reported a '/' operator but the line it returns didn't contain a '/' ! character at the indicated position. ! ! - 'Bad warning for line N: XYZ', line marked by '*': ! ! This really shouldn't happen. It means that a 'classic XYZ ! division' warning was read with XYZ being something other than ! 'int', 'long', 'float', or 'complex'. Notes: *************** *** 80,92 **** - Warnings may be issued for code not read from a file, but executed ! using an exec statement or the eval() function. These will have ! in the filename position. The fixdiv script will attempt ! and fail to open a file named "", and issue a warning about ! this failure. You're on your own to deal with this. You could make ! all recommended changes and add a future division statement to all ! affected files, and then re-run the test script; it should not issue ! any warnings. If there are any, and you have a hard time tracking ! down where they are generated, you can use the -Werror option to ! force an error instead of a first warning, generating a traceback. - The tool should be run from the same directory as that from which --- 114,128 ---- - Warnings may be issued for code not read from a file, but executed ! using an exec statement or the eval() function. These may have ! in the filename position, in which case the fixdiv script ! will attempt and fail to open a file named '' and issue a ! warning about this failure; or these may be reported as 'Phantom' ! warnings (see above). You're on your own to deal with these. You ! could make all recommended changes and add a future division ! statement to all affected files, and then re-run the test script; it ! should not issue any warnings. If there are any, and you have a ! hard time tracking down where they are generated, you can use the ! -Werror option to force an error instead of a first warning, ! generating a traceback. - The tool should be run from the same directory as that from which *************** *** 99,105 **** import re import tokenize - from pprint import pprint ! multi_ok = 1 def main(): --- 135,140 ---- import re import tokenize ! multi_ok = 0 def main(): *************** *** 115,119 **** if o == "-m": global multi_ok ! multi_ok = 0 if not args: usage("at least one file argument is required") --- 150,154 ---- if o == "-m": global multi_ok ! multi_ok = 1 if not args: usage("at least one file argument is required") *************** *** 205,210 **** if len(slashes) > 1: if not multi_ok: ! report(slashes, "More than one / operator per statement") ! continue intlong = [] floatcomplex = [] --- 240,256 ---- if len(slashes) > 1: if not multi_ok: ! rows = [] ! lastrow = None ! for (row, col), line in slashes: ! if row == lastrow: ! continue ! rows.append(row) ! lastrow = row ! assert rows ! if len(rows) == 1: ! print "*** More than one / operator in line", rows[0] ! else: ! print "*** More than one / operator per statement", ! print "in lines %d-%d" % (rows[0], rows[-1]) intlong = [] floatcomplex = [] *************** *** 238,241 **** --- 284,291 ---- print "True division / operator at line %d:" % row print "=", line + elif intlong and floatcomplex: + print "*** Ambiguous / operator (%s, %s) at line %d:" % ( + "|".join(intlong), "|".join(floatcomplex), row) + print "?", line fp.close() From fdrake@users.sourceforge.net Tue Sep 4 17:26:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 09:26:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_htmlparser.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17166/test Modified Files: test_htmlparser.py Log Message: HTMLParser is allowed to be more strict than sgmllib, so let's not change their basic behavior: When parsing something that cannot possibly be valid in either HTML or XHTML, raise an exception. Index: test_htmlparser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_htmlparser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_htmlparser.py 2001/09/04 15:13:04 1.5 --- test_htmlparser.py 2001/09/04 16:26:03 1.6 *************** *** 204,213 **** def test_illegal_declarations(self): ! s = 'abcdef' ! self._run_check(s, [ ! ("data", "abc"), ! ("unknown decl", 'spacer type="block" height="25"'), ! ("data", "def"), ! ]) def test_starttag_end_boundary(self): --- 204,208 ---- def test_illegal_declarations(self): ! self._parse_error('') def test_starttag_end_boundary(self): From fdrake@users.sourceforge.net Tue Sep 4 17:26:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 09:26:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib HTMLParser.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv17166 Modified Files: HTMLParser.py Log Message: HTMLParser is allowed to be more strict than sgmllib, so let's not change their basic behavior: When parsing something that cannot possibly be valid in either HTML or XHTML, raise an exception. Index: HTMLParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/HTMLParser.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** HTMLParser.py 2001/09/04 15:10:16 1.6 --- HTMLParser.py 2001/09/04 16:26:03 1.7 *************** *** 270,275 **** # in practice, this should look like: ((name|stringlit) S*)+ '>' n = len(rawdata) ! decltype = None ! extrachars = "" while j < n: c = rawdata[j] --- 270,279 ---- # in practice, this should look like: ((name|stringlit) S*)+ '>' n = len(rawdata) ! decltype, j = self.scan_name(j, i) ! if j < 0: ! return j ! if decltype.lower() != "doctype": ! raise HTMLParseError("unknown declaration: '%s'" % decltype, ! self.getpos()) while j < n: c = rawdata[j] *************** *** 277,284 **** # end of declaration syntax data = rawdata[i+2:j] ! if decltype == "doctype": ! self.handle_decl(data) ! else: ! self.unknown_decl(data) return j + 1 if c in "\"'": --- 281,285 ---- # end of declaration syntax data = rawdata[i+2:j] ! self.handle_decl(data) return j + 1 if c in "\"'": *************** *** 288,315 **** j = m.end() elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": ! m = declname.match(rawdata, j) ! if not m: ! return -1 # incomplete ! j = m.end() ! if decltype is None: ! decltype = m.group(0).rstrip().lower() ! if decltype != "doctype": ! extrachars = "=" elif c == "[" and decltype == "doctype": j = self.parse_doctype_subset(j + 1, i) - if j < 0: - return j - elif c in extrachars: - j = j + 1 - while j < n and rawdata[j] in string.whitespace: - j = j + 1 - if j == n: - # end of buffer while in declaration - return -1 else: raise HTMLParseError( "unexpected char in declaration: %s" % `rawdata[j]`, self.getpos()) ! decltype = decltype or '' return -1 # incomplete --- 289,301 ---- j = m.end() elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": ! name, j = self.scan_name(j, i) elif c == "[" and decltype == "doctype": j = self.parse_doctype_subset(j + 1, i) else: raise HTMLParseError( "unexpected char in declaration: %s" % `rawdata[j]`, self.getpos()) ! if j < 0: ! return j return -1 # incomplete *************** *** 360,368 **** # end of buffer; incomplete return -1 ! m = declname.match(rawdata, j + 1) ! s = m.group() ! if s == rawdata[j+1:]: ! return -1 ! j = j + 1 + len(s.rstrip()) if rawdata[j] == ";": j = j + 1 --- 346,352 ---- # end of buffer; incomplete return -1 ! s, j = self.scan_name(j + 1, declstartpos) ! if j < 0: ! return j if rawdata[j] == ";": j = j + 1 *************** *** 384,389 **** else: self.updatepos(declstartpos, j) ! raise HTMLParseError("unexpected char in internal subset", ! self.getpos()) # end of buffer reached return -1 --- 368,374 ---- else: self.updatepos(declstartpos, j) ! raise HTMLParseError( ! "unexpected char %s in internal subset" % `c`, ! self.getpos()) # end of buffer reached return -1 From fdrake@users.sourceforge.net Tue Sep 4 19:18:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 11:18:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsys.tex,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv16527/lib Modified Files: libsys.tex Log Message: Added documentation for sys.maxunicode and sys.warnoptions. Fixed a markup error which caused an em dash to be presented as a minus sign. This closes SF bug #458350. Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** libsys.tex 2001/07/26 13:41:05 1.51 --- libsys.tex 2001/09/04 18:18:36 1.52 *************** *** 257,264 **** The largest positive integer supported by Python's regular integer type. This is at least 2**31-1. The largest negative integer is ! \code{-maxint-1} -- the asymmetry results from the use of 2's complement binary arithmetic. \end{datadesc} \begin{datadesc}{modules} This is a dictionary that maps module names to modules which have --- 257,271 ---- The largest positive integer supported by Python's regular integer type. This is at least 2**31-1. The largest negative integer is ! \code{-maxint-1} --- the asymmetry results from the use of 2's complement binary arithmetic. \end{datadesc} + \begin{datadesc}{maxunicode} + An integer giving the largest supported code point for a Unicode + character. The value of this depends on the configuration option + that specifies whether Unicode characters are stored as UCS-2 or + UCS-4. + \end{datadesc} + \begin{datadesc}{modules} This is a dictionary that maps module names to modules which have *************** *** 449,452 **** --- 456,465 ---- 'final', 0)}. \versionadded{2.0} + \end{datadesc} + + \begin{datadesc}{warnoptions} + This is an implementation detail of the warnings framework; do not + modify this value. Refer to the \refmodule{warnings} module for + more information on the warnings framework. \end{datadesc} From fdrake@users.sourceforge.net Tue Sep 4 19:26:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 11:26:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libshutil.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv18232/lib Modified Files: libshutil.tex Log Message: Add more detail to the descriptions of the shutil functions. This closes SF bug #458223. Index: libshutil.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libshutil.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** libshutil.tex 2001/03/02 16:46:42 1.7 --- libshutil.tex 2001/09/04 18:26:27 1.8 *************** *** 22,26 **** Copy the contents of the file named \var{src} to a file named \var{dst}. If \var{dst} exists, it will be replaced, otherwise it ! will be created. \end{funcdesc} --- 22,28 ---- Copy the contents of the file named \var{src} to a file named \var{dst}. If \var{dst} exists, it will be replaced, otherwise it ! will be created. Special files such as character or block devices ! and pipes cannot not be copied with this function. \var{src} and ! \var{dst} are path names given as strings. \end{funcdesc} *************** *** 36,40 **** \begin{funcdesc}{copymode}{src, dst} Copy the permission bits from \var{src} to \var{dst}. The file ! contents, owner, and group are unaffected. \end{funcdesc} --- 38,43 ---- \begin{funcdesc}{copymode}{src, dst} Copy the permission bits from \var{src} to \var{dst}. The file ! contents, owner, and group are unaffected. \var{src} and \var{dst} ! are path names given as strings. \end{funcdesc} *************** *** 42,46 **** Copy the permission bits, last access time, and last modification time from \var{src} to \var{dst}. The file contents, owner, and ! group are unaffected. \end{funcdesc} --- 45,50 ---- Copy the permission bits, last access time, and last modification time from \var{src} to \var{dst}. The file contents, owner, and ! group are unaffected. \var{src} and \var{dst} are path names given ! as strings. \end{funcdesc} *************** *** 49,53 **** \var{dst} is a directory, a file with the same basename as \var{src} is created (or overwritten) in the directory specified. Permission ! bits are copied. \end{funcdesc} --- 53,58 ---- \var{dst} is a directory, a file with the same basename as \var{src} is created (or overwritten) in the directory specified. Permission ! bits are copied. \var{src} and \var{dst} are path names given as ! strings. \end{funcdesc} From fdrake@users.sourceforge.net Tue Sep 4 19:39:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 11:39:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib imputil.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21330 Modified Files: imputil.py Log Message: Added docstring by Neal Norwitz. This closes SF bug #450979. Index: imputil.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imputil.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** imputil.py 2001/07/28 20:33:41 1.21 --- imputil.py 2001/09/04 18:39:45 1.22 *************** *** 1,7 **** ! # ! # imputil.py: import utilities ! # ! ### docco needed here and in Docs/ ... # note: avoid importing non-builtin modules --- 1,13 ---- ! """ ! Import utilities ! Exported classes: ! ImportManager Manage the import process ! ! Importer Base class for replacing standard import functions ! BuiltinImporter Emulate the import mechanism for builtin and frozen modules ! ! DynLoadSuffixImporter ! """ # note: avoid importing non-builtin modules From fdrake@users.sourceforge.net Tue Sep 4 19:55:05 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 11:55:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25002 Modified Files: xmlrpclib.py Log Message: Added docstring by Neal Norwitz. This closes SF bug #450981. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** xmlrpclib.py 2001/08/23 20:13:08 1.4 --- xmlrpclib.py 2001/09/04 18:55:03 1.5 *************** *** 3,17 **** # $Id$ # - # an XML-RPC client interface for Python. - # - # the marshalling and response parser code can also be used to - # implement XML-RPC servers. - # - # Notes: - # this version is designed to work with Python 1.5.2 or newer. - # unicode encoding support requires at least Python 1.6. - # experimental HTTPS requires Python 2.0 built with SSL sockets. - # expat parser support requires Python 2.0 with pyexpat support. - # # History: # 1999-01-14 fl Created --- 3,6 ---- *************** *** 88,91 **** --- 77,135 ---- # TODO: memo problem (see HP's mail) + """ + An XML-RPC client interface for Python. + + The marshalling and response parser code can also be used to + implement XML-RPC servers. + + Notes: + This version is designed to work with Python 1.5.2 or newer. + Unicode encoding support requires at least Python 1.6. + Experimental HTTPS requires Python 2.0 built with SSL sockets. + Expat parser support requires Python 2.0 with pyexpat support. + + Exported exceptions: + + Error Base class for client errors + ProtocolError Indicates an HTTP protocol error + ResponseError Indicates a broken response package + Fault Indicates a XML-RPC fault package + + Exported classes: + + Boolean boolean wrapper to generate a "boolean" XML-RPC value + DateTime dateTime wrapper for an ISO 8601 string or time tuple or + localtime integer value to generate a "dateTime.iso8601" + XML-RPC value + Binary binary data wrapper + + SlowParser Slow but safe standard parser + Marshaller Generate an XML-RPC params chunk from a Python data structure + Unmarshaller Unmarshal an XML-RPC response from incoming XML event message + + Transport Handles an HTTP transaction to an XML-RPC server + SafeTransport Handles an HTTPS transaction to an XML-RPC server + ServerProxy Connect to a server through a proxy + Server Same as ServerProxy + + Exported constants: + + True + False + + Exported functions: + + boolean Convert any Python value to an XML-RPC boolean + datetime Convert value to an XML-RPC datetime + binary Convert value to an XML-RPC binary value + getparser Create instance of the fastest available parser & attach + to an unmarshalling object + dumps Convert an argument tuple or a Fault instance to an XML-RPC + request (or response, if the methodresponse option is used). + loads Convert an XML-RPC packet to unmarshalled data plus a method + name (None if not present). + + """ + import re, string, time, operator import urllib, xmllib *************** *** 121,129 **** class Error(Exception): ! # base class for client errors pass class ProtocolError(Error): ! # indicates an HTTP protocol error def __init__(self, url, errcode, errmsg, headers): self.url = url --- 165,173 ---- class Error(Exception): ! """Base class for client errors.""" pass class ProtocolError(Error): ! """Indicates an HTTP protocol error.""" def __init__(self, url, errcode, errmsg, headers): self.url = url *************** *** 138,146 **** class ResponseError(Error): ! # indicates a broken response package pass class Fault(Error): ! # indicates a XML-RPC fault package def __init__(self, faultCode, faultString, **extra): self.faultCode = faultCode --- 182,190 ---- class ResponseError(Error): ! """Indicates a broken response package""" pass class Fault(Error): ! """indicates a XML-RPC fault package""" def __init__(self, faultCode, faultString, **extra): self.faultCode = faultCode *************** *** 155,162 **** # Special values - # boolean wrapper - # use True or False to generate a "boolean" XML-RPC value class Boolean: def __init__(self, value = 0): --- 199,208 ---- # Special values class Boolean: + """Boolean-value wrapper. + + Use True or False to generate a "boolean" XML-RPC value. + """ def __init__(self, value = 0): *************** *** 186,190 **** def boolean(value, truefalse=(False, True)): ! # convert any Python value to XML-RPC boolean return truefalse[operator.truth(value)] --- 232,236 ---- def boolean(value, truefalse=(False, True)): ! """Convert any Python value to XML-RPC boolean.""" return truefalse[operator.truth(value)] *************** *** 195,198 **** --- 241,247 ---- class DateTime: + """DataTime wrapper for an ISO 8601 string or time tuple or + localtime integer value to generate a 'dateTime.iso8601' XML-RPC + value.""" def __init__(self, value=0): *************** *** 226,233 **** return value - # - # binary data wrapper class Binary: def __init__(self, data=None): --- 275,281 ---- return value class Binary: + """Wrapper for binary data.""" def __init__(self, data=None): *************** *** 345,351 **** class SlowParser(xmllib.XMLParser): ! # slow but safe standard parser, based on the XML parser in ! # Python's standard library. this is about 10 times slower ! # than sgmlop, on roundtrip testing. def __init__(self, target): self.handle_xml = target.xml --- 393,401 ---- class SlowParser(xmllib.XMLParser): ! """XML parser using xmllib.XMLParser. ! ! This is about 10 times slower than sgmlop on roundtrip testing. ! """ ! def __init__(self, target): self.handle_xml = target.xml *************** *** 360,370 **** class Marshaller: ! """Generate an XML-RPC params chunk from a Python data structure""" ! # USAGE: create a marshaller instance for each set of parameters, ! # and use "dumps" to convert your data (represented as a tuple) to ! # a XML-RPC params chunk. to write a fault response, pass a Fault ! # instance instead. you may prefer to use the "dumps" convenience ! # function for this purpose (see below). # by the way, if you don't understand what's going on in here, --- 410,421 ---- class Marshaller: ! """Generate an XML-RPC params chunk from a Python data structure. ! Create a marshaller instance for each set of parameters, and use ! "dumps" method to convert your data (represented as a tuple) to a ! XML-RPC params chunk. to write a fault response, pass a Fault ! instance instead. You may prefer to use the "dumps" convenience ! function for this purpose (see below). ! """ # by the way, if you don't understand what's going on in here, *************** *** 470,480 **** class Unmarshaller: ! ! # unmarshal an XML-RPC response, based on incoming XML event ! # messages (start, data, end). call close to get the resulting ! # data structure ! # note that this reader is fairly tolerant, and gladly accepts ! # bogus XML-RPC data without complaining (but not bogus XML). # and again, if you don't understand what's going on in here, --- 521,531 ---- class Unmarshaller: ! """Unmarshal an XML-RPC response, based on incoming XML event ! messages (start, data, end). Call close() to get the resulting ! data structure. ! Note that this reader is fairly tolerant, and gladly accepts ! bogus XML-RPC data without complaining (but not bogus XML). ! """ # and again, if you don't understand what's going on in here, From nascheme@users.sourceforge.net Tue Sep 4 20:03:38 2001 From: nascheme@users.sourceforge.net (Neil Schemenauer) Date: Tue, 04 Sep 2001 12:03:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.272,2.273 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27436/Python Modified Files: ceval.c Log Message: Move call_trace(..., PyTrace_CALL, ...) call to top of eval_frame. That way it's called each time a generator is resumed. The tracing of normal functions should be unaffected by this change. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.272 retrieving revision 2.273 diff -C2 -d -r2.272 -r2.273 *** ceval.c 2001/08/30 16:06:23 2.272 --- ceval.c 2001/09/04 19:03:35 2.273 *************** *** 589,592 **** --- 589,627 ---- f->f_stacktop = NULL; + if (tstate->use_tracing) { + if (tstate->c_tracefunc != NULL) { + /* tstate->c_tracefunc, if defined, is a + function that will be called on *every* entry + to a code block. Its return value, if not + None, is a function that will be called at + the start of each executed line of code. + (Actually, the function must return itself + in order to continue tracing.) The trace + functions are called with three arguments: + a pointer to the current frame, a string + indicating why the function is called, and + an argument which depends on the situation. + The global trace function is also called + whenever an exception is detected. */ + if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, + f, PyTrace_CALL, Py_None)) { + /* XXX Need way to compute arguments?? */ + /* Trace function raised an error */ + return NULL; + } + } + if (tstate->c_profilefunc != NULL) { + /* Similar for c_profilefunc, except it needn't + return itself and isn't called for "line" events */ + if (call_trace(tstate->c_profilefunc, + tstate->c_profileobj, + f, PyTrace_CALL, Py_None)) { + /* XXX Need way to compute arguments?? */ + /* Profile function raised an error */ + return NULL; + } + } + } + #ifdef LLTRACE lltrace = PyDict_GetItemString(f->f_globals,"__lltrace__") != NULL; *************** *** 2494,2532 **** Py_INCREF(o); freevars[f->f_ncells + i] = o; - } - } - - if (tstate->use_tracing) { - if (tstate->c_tracefunc != NULL) { - /* tstate->c_tracefunc, if defined, is a - function that will be called on *every* entry - to a code block. Its return value, if not - None, is a function that will be called at - the start of each executed line of code. - (Actually, the function must return itself - in order to continue tracing.) The trace - functions are called with three arguments: - a pointer to the current frame, a string - indicating why the function is called, and - an argument which depends on the situation. - The global trace function is also called - whenever an exception is detected. */ - if (call_trace(tstate->c_tracefunc, tstate->c_traceobj, - f, PyTrace_CALL, Py_None)) { - /* XXX Need way to compute arguments?? */ - /* Trace function raised an error */ - goto fail; - } - } - if (tstate->c_profilefunc != NULL) { - /* Similar for c_profilefunc, except it needn't - return itself and isn't called for "line" events */ - if (call_trace(tstate->c_profilefunc, - tstate->c_profileobj, - f, PyTrace_CALL, Py_None)) { - /* XXX Need way to compute arguments?? */ - /* Profile function raised an error */ - goto fail; - } } } --- 2529,2532 ---- From fdrake@users.sourceforge.net Tue Sep 4 20:10:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 12:10:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib re.py,1.40,1.41 sre.py,1.34,1.35 sre_compile.py,1.40,1.41 sre_constants.py,1.29,1.30 sre_parse.py,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29424 Modified Files: re.py sre.py sre_compile.py sre_constants.py sre_parse.py Log Message: Added docstrings by Neal Norwitz. This closes SF bug #450980. Index: re.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/re.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** re.py 2001/02/15 22:15:13 1.40 --- re.py 2001/09/04 19:10:20 1.41 *************** *** 1,5 **** ! # ! # Minimal "re" compatibility wrapper ! # # If your regexps don't work well under 2.0b1, you can switch # to the old engine ("pre") down below. --- 1,4 ---- ! """Minimal "re" compatibility wrapper""" ! # If your regexps don't work well under 2.0b1, you can switch # to the old engine ("pre") down below. Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** sre.py 2001/08/10 14:56:54 1.34 --- sre.py 2001/09/04 19:10:20 1.35 *************** *** 15,18 **** --- 15,99 ---- # + """Support for regular expressions (RE). + + This module provides regular expression matching operations similar to + those found in Perl. It's 8-bit clean: the strings being processed may + contain both null bytes and characters whose high bit is set. Regular + expression pattern strings may not contain null bytes, but can specify + the null byte using the \\number notation. Characters with the high + bit set may be included. + + Regular expressions can contain both special and ordinary + characters. Most ordinary characters, like "A", "a", or "0", are the + simplest regular expressions; they simply match themselves. You can + concatenate ordinary characters, so last matches the string 'last'. + + The special characters are: + "." Matches any character except a newline. + "^" Matches the start of the string. + "$" Matches the end of the string. + "*" Matches 0 or more (greedy) repetitions of the preceding RE. + Greedy means that it will match as many repetitions as possible. + "+" Matches 1 or more (greedy) repetitions of the preceding RE. + "?" Matches 0 or 1 (greedy) of the preceding RE. + *?,+?,?? Non-greedy versions of the previous three special characters. + {m,n} Matches from m to n repetitions of the preceding RE. + {m,n}? Non-greedy version of the above. + "\\" Either escapes special characters or signals a special sequence. + [] Indicates a set of characters. + A "^" as the first character indicates a complementing set. + "|" A|B, creates an RE that will match either A or B. + (...) Matches the RE inside the parentheses. + The contents can be retrieved or matched later in the string. + (?iLmsx) Set the I, L, M, S, or X flag for the RE. + (?:...) Non-grouping version of regular parentheses. + (?P...) The substring matched by the group is accessible by name. + (?P=name) Matches the text matched earlier by the group named name. + (?#...) A comment; ignored. + (?=...) Matches if ... matches next, but doesn't consume the string. + (?!...) Matches if ... doesn't match next. + + The special sequences consist of "\\" and a character from the list + below. If the ordinary character is not on the list, then the + resulting RE will match the second character. + \\number Matches the contents of the group of the same number. + \\A Matches only at the start of the string. + \\Z Matches only at the end of the string. + \\b Matches the empty string, but only at the start or end of a word. + \\B Matches the empty string, but not at the start or end of a word. + \\d Matches any decimal digit; equivalent to the set [0-9]. + \\D Matches any non-digit character; equivalent to the set [^0-9]. + \\s Matches any whitespace character; equivalent to [ \\t\\n\\r\\f\\v]. + \\S Matches any non-whitespace character; equiv. to [^ \\t\\n\\r\\f\\v]. + \\w Matches any alphanumeric character; equivalent to [a-zA-Z0-9_]. + With LOCALE, it will match the set [0-9_] plus characters defined + as letters for the current locale. + \\W Matches the complement of \\w. + \\\\ Matches a literal backslash. + + This module exports the following functions: + match Match a regular expression pattern to the beginning of a string. + search Search a string for the presence of a pattern. + sub Substitute occurrences of a pattern found in a string. + subn Same as sub, but also return the number of substitutions made. + split Split a string by the occurrences of a pattern. + findall Find all occurrences of a pattern in a string. + compile Compile a pattern into a RegexObject. + purge Clear the regular expression cache. + template Compile a template pattern, returning a pattern object. + escape Backslash all non-alphanumerics in a string. + + Some of the functions in this module takes flags as optional parameters: + I IGNORECASE Perform case-insensitive matching. + L LOCALE Make \w, \W, \b, \B, dependent on the current locale. + M MULTILINE "^" matches the beginning of lines as well as the string. + "$" matches the end of lines as well as the string. + S DOTALL "." matches any character at all, including the newline. + X VERBOSE Ignore whitespace and comments for nicer looking RE's. + U UNICODE Use unicode locale. + + This module also defines an exception 'error'. + + """ import sre_compile import sre_parse Index: sre_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** sre_compile.py 2001/07/21 01:41:30 1.40 --- sre_compile.py 2001/09/04 19:10:20 1.41 *************** *** 9,12 **** --- 9,14 ---- # + """Internal support module for sre""" + import _sre,sys Index: sre_constants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_constants.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** sre_constants.py 2001/07/02 16:58:38 1.29 --- sre_constants.py 2001/09/04 19:10:20 1.30 *************** *** 10,13 **** --- 10,15 ---- # + """Internal support module for sre""" + # update when constants are added or removed Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** sre_parse.py 2001/03/22 15:50:10 1.46 --- sre_parse.py 2001/09/04 19:10:20 1.47 *************** *** 9,12 **** --- 9,14 ---- # + """Internal support module for sre""" + # XXX: show string offset and offending character for all errors From gvanrossum@users.sourceforge.net Tue Sep 4 20:14:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 12:14:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib base64.py,1.12,1.13 binhex.py,1.21,1.22 bisect.py,1.7,1.8 dumbdbm.py,1.12,1.13 inspect.py,1.19,1.20 quopri.py,1.14,1.15 repr.py,1.11,1.12 rfc822.py,1.62,1.63 wave.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30102 Modified Files: base64.py binhex.py bisect.py dumbdbm.py inspect.py quopri.py repr.py rfc822.py wave.py Log Message: The first batch of changes recommended by the fixdiv tool. These are mostly changes of / operators into //. Once or twice I did more or less than recommended. Index: base64.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/base64.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** base64.py 2001/06/07 18:56:13 1.12 --- base64.py 2001/09/04 19:14:13 1.13 *************** *** 10,14 **** MAXLINESIZE = 76 # Excluding the CRLF ! MAXBINSIZE = (MAXLINESIZE/4)*3 def encode(input, output): --- 10,14 ---- MAXLINESIZE = 76 # Excluding the CRLF ! MAXBINSIZE = (MAXLINESIZE//4)*3 def encode(input, output): Index: binhex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/binhex.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** binhex.py 2001/08/01 18:17:23 1.21 --- binhex.py 2001/09/04 19:14:13 1.22 *************** *** 129,133 **** self.data = self.data + data datalen = len(self.data) ! todo = (datalen/3)*3 data = self.data[:todo] self.data = self.data[todo:] --- 129,133 ---- self.data = self.data + data datalen = len(self.data) ! todo = (datalen//3)*3 data = self.data[:todo] self.data = self.data[todo:] *************** *** 293,297 **** while wtd > 0: if self.eof: return decdata ! wtd = ((wtd+2)/3)*4 data = self.ifp.read(wtd) # --- 293,297 ---- while wtd > 0: if self.eof: return decdata ! wtd = ((wtd+2)//3)*4 data = self.ifp.read(wtd) # Index: bisect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bisect.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** bisect.py 2001/02/18 03:30:53 1.7 --- bisect.py 2001/09/04 19:14:13 1.8 *************** *** 13,17 **** hi = len(a) while lo < hi: ! mid = (lo+hi)/2 if x < a[mid]: hi = mid else: lo = mid+1 --- 13,17 ---- hi = len(a) while lo < hi: ! mid = (lo+hi)//2 if x < a[mid]: hi = mid else: lo = mid+1 *************** *** 34,38 **** hi = len(a) while lo < hi: ! mid = (lo+hi)/2 if x < a[mid]: hi = mid else: lo = mid+1 --- 34,38 ---- hi = len(a) while lo < hi: ! mid = (lo+hi)//2 if x < a[mid]: hi = mid else: lo = mid+1 *************** *** 53,57 **** hi = len(a) while lo < hi: ! mid = (lo+hi)/2 if a[mid] < x: lo = mid+1 else: hi = mid --- 53,57 ---- hi = len(a) while lo < hi: ! mid = (lo+hi)//2 if a[mid] < x: lo = mid+1 else: hi = mid *************** *** 73,77 **** hi = len(a) while lo < hi: ! mid = (lo+hi)/2 if a[mid] < x: lo = mid+1 else: hi = mid --- 73,77 ---- hi = len(a) while lo < hi: ! mid = (lo+hi)//2 if a[mid] < x: lo = mid+1 else: hi = mid Index: dumbdbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** dumbdbm.py 2001/07/19 10:06:39 1.12 --- dumbdbm.py 2001/09/04 19:14:13 1.13 *************** *** 88,92 **** ## pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ## f.seek(pos) ! npos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE f.write('\0'*(npos-pos)) pos = npos --- 88,92 ---- ## pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ## f.seek(pos) ! npos = ((pos + _BLOCKSIZE - 1) // _BLOCKSIZE) * _BLOCKSIZE f.write('\0'*(npos-pos)) pos = npos Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** inspect.py 2001/07/15 21:08:29 1.19 --- inspect.py 2001/09/04 19:14:13 1.20 *************** *** 591,595 **** lineno = getlineno(frame) if context > 0: ! start = lineno - 1 - context/2 try: lines, lnum = findsource(frame) --- 591,595 ---- lineno = getlineno(frame) if context > 0: ! start = lineno - 1 - context//2 try: lines, lnum = findsource(frame) Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** quopri.py 2001/07/02 04:57:30 1.14 --- quopri.py 2001/09/04 19:14:14 1.15 *************** *** 28,32 **** """Quote a single character.""" i = ord(c) ! return ESCAPE + HEX[i/16] + HEX[i%16] --- 28,32 ---- """Quote a single character.""" i = ord(c) ! return ESCAPE + HEX[i//16] + HEX[i%16] Index: repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/repr.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** repr.py 2001/08/09 18:56:27 1.11 --- repr.py 2001/09/04 19:14:14 1.12 *************** *** 66,70 **** s = `x[:self.maxstring]` if len(s) > self.maxstring: ! i = max(0, (self.maxstring-3)/2) j = max(0, self.maxstring-3-i) s = `x[:i] + x[len(x)-j:]` --- 66,70 ---- s = `x[:self.maxstring]` if len(s) > self.maxstring: ! i = max(0, (self.maxstring-3)//2) j = max(0, self.maxstring-3-i) s = `x[:i] + x[len(x)-j:]` *************** *** 74,78 **** s = `x` # XXX Hope this isn't too slow... if len(s) > self.maxlong: ! i = max(0, (self.maxlong-3)/2) j = max(0, self.maxlong-3-i) s = s[:i] + '...' + s[len(s)-j:] --- 74,78 ---- s = `x` # XXX Hope this isn't too slow... if len(s) > self.maxlong: ! i = max(0, (self.maxlong-3)//2) j = max(0, self.maxlong-3-i) s = s[:i] + '...' + s[len(s)-j:] *************** *** 87,91 **** hex(id(x))[2:] + '>' if len(s) > self.maxstring: ! i = max(0, (self.maxstring-3)/2) j = max(0, self.maxstring-3-i) s = s[:i] + '...' + s[len(s)-j:] --- 87,91 ---- hex(id(x))[2:] + '>' if len(s) > self.maxstring: ! i = max(0, (self.maxstring-3)//2) j = max(0, self.maxstring-3-i) s = s[:i] + '...' + s[len(s)-j:] Index: rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/rfc822.py,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -d -r1.62 -r1.63 *** rfc822.py 2001/09/04 06:37:28 1.62 --- rfc822.py 2001/09/04 19:14:14 1.63 *************** *** 928,932 **** else: tzsign = 1 ! tzoffset = tzsign * ( (tzoffset/100)*3600 + (tzoffset % 100)*60) tuple = (yy, mm, dd, thh, tmm, tss, 0, 0, 0, tzoffset) return tuple --- 928,932 ---- else: tzsign = 1 ! tzoffset = tzsign * ( (tzoffset//100)*3600 + (tzoffset % 100)*60) tuple = (yy, mm, dd, thh, tmm, tss, 0, 0, 0, tzoffset) return tuple Index: wave.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/wave.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** wave.py 2001/03/01 04:27:19 1.15 --- wave.py 2001/09/04 19:14:14 1.16 *************** *** 147,151 **** raise Error, 'data chunk before fmt chunk' self._data_chunk = chunk ! self._nframes = chunk.chunksize / self._framesize self._data_seek_needed = 0 break --- 147,151 ---- raise Error, 'data chunk before fmt chunk' self._data_chunk = chunk ! self._nframes = chunk.chunksize // self._framesize self._data_seek_needed = 0 break *************** *** 249,253 **** if self._convert and data: data = self._convert(data) ! self._soundpos = self._soundpos + len(data) / (self._nchannels * self._sampwidth) return data --- 249,253 ---- if self._convert and data: data = self._convert(data) ! self._soundpos = self._soundpos + len(data) // (self._nchannels * self._sampwidth) return data *************** *** 260,264 **** if wFormatTag == WAVE_FORMAT_PCM: sampwidth = struct.unpack(' Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30102/test Modified Files: test_audioop.py test_augassign.py test_b1.py test_binascii.py test_binop.py test_compare.py test_long.py test_operator.py test_pty.py test_strftime.py Log Message: The first batch of changes recommended by the fixdiv tool. These are mostly changes of / operators into //. Once or twice I did more or less than recommended. Index: test_audioop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_audioop.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_audioop.py 2001/01/17 21:51:35 1.9 --- test_audioop.py 2001/09/04 19:14:14 1.10 *************** *** 117,122 **** 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 --- 117,122 ---- 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 Index: test_augassign.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_augassign.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_augassign.py 2001/08/29 17:50:22 1.3 --- test_augassign.py 2001/09/04 19:14:14 1.4 *************** *** 6,10 **** x **= 2 x -= 8 ! x /= 2 x //= 1 x %= 12 --- 6,10 ---- x **= 2 x -= 8 ! x //= 2 x //= 1 x %= 12 *************** *** 20,25 **** x[0] **= 2 x[0] -= 8 - x[0] /= 2 x[0] //= 2 x[0] %= 12 x[0] &= 2 --- 20,25 ---- x[0] **= 2 x[0] -= 8 x[0] //= 2 + x[0] //= 2 x[0] %= 12 x[0] &= 2 *************** *** 34,38 **** x[0] **= 2 x[0] -= 8 ! x[0] /= 2 x[0] //= 1 x[0] %= 12 --- 34,38 ---- x[0] **= 2 x[0] -= 8 ! x[0] //= 2 x[0] //= 1 x[0] %= 12 Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** test_b1.py 2001/08/17 22:08:34 1.39 --- test_b1.py 2001/09/04 19:14:14 1.40 *************** *** 414,418 **** # Failed in all Linux builds. x = -1-sys.maxint ! if x >> 1 != x/2: raise TestFailed("x >> 1 != x/2 when x == -1-sys.maxint") --- 414,418 ---- # Failed in all Linux builds. x = -1-sys.maxint ! if x >> 1 != x//2: raise TestFailed("x >> 1 != x/2 when x == -1-sys.maxint") Index: test_binascii.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binascii.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_binascii.py 2001/01/17 19:11:13 1.8 --- test_binascii.py 2001/09/04 19:14:14 1.9 *************** *** 55,62 **** def addnoise(line): noise = fillers ! ratio = len(line) / len(noise) res = "" while line and noise: ! if len(line) / len(noise) > ratio: c, line = line[0], line[1:] else: --- 55,62 ---- def addnoise(line): noise = fillers ! ratio = len(line) // len(noise) res = "" while line and noise: ! if len(line) // len(noise) > ratio: c, line = line[0], line[1:] else: Index: test_binop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binop.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_binop.py 2001/08/24 18:52:50 1.3 --- test_binop.py 2001/09/04 19:14:14 1.4 *************** *** 43,48 **** raise ZeroDivisionError, "zero denominator" g = gcd(den, num) ! self.__num = long(num/g) ! self.__den = long(den/g) def _get_num(self): --- 43,48 ---- raise ZeroDivisionError, "zero denominator" g = gcd(den, num) ! self.__num = long(num//g) ! self.__den = long(den//g) def _get_num(self): Index: test_compare.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compare.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_compare.py 2001/08/16 16:56:16 1.5 --- test_compare.py 2001/09/04 19:14:14 1.6 *************** *** 48,52 **** L = [] for i in range(10): ! L.insert(len(L)/2, Empty()) for a in L: for b in L: --- 48,52 ---- L = [] for i in range(10): ! L.insert(len(L)//2, Empty()) for a in L: for b in L: Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_long.py 2001/09/04 06:37:28 1.12 --- test_long.py 2001/09/04 19:14:14 1.13 *************** *** 77,81 **** def test_division_2(x, y): q, r = divmod(x, y) ! q2, r2 = x/y, x%y pab, pba = x*y, y*x check(pab == pba, "multiplication does not commute for", x, y) --- 77,81 ---- def test_division_2(x, y): q, r = divmod(x, y) ! q2, r2 = x//y, x%y pab, pba = x*y, y*x check(pab == pba, "multiplication does not commute for", x, y) *************** *** 118,122 **** p2 = 2L ** n check(x << n >> n == x, "x << n >> n != x for", x, n) ! check(x / p2 == x >> n, "x / p2 != x >> n for x n p2", x, n, p2) check(x * p2 == x << n, "x * p2 != x << n for x n p2", x, n, p2) check(x & -p2 == x >> n << n == x & ~(p2 - 1), --- 118,122 ---- p2 = 2L ** n check(x << n >> n == x, "x << n >> n != x for", x, n) ! check(x // p2 == x >> n, "x // p2 != x >> n for x n p2", x, n, p2) check(x * p2 == x << n, "x * p2 != x << n for x n p2", x, n, p2) check(x & -p2 == x >> n << n == x & ~(p2 - 1), *************** *** 162,166 **** y = getran(leny) test_bitop_identities_2(x, y) ! test_bitop_identities_3(x, y, getran((lenx + leny)/2)) # ------------------------------------------------- hex oct repr str atol --- 162,166 ---- y = getran(leny) test_bitop_identities_2(x, y) ! test_bitop_identities_3(x, y, getran((lenx + leny)//2)) # ------------------------------------------------- hex oct repr str atol *************** *** 297,302 **** if y: ! expected = longx / longy ! got = x / y checkit(x, '/', y) --- 297,302 ---- if y: ! expected = longx // longy ! got = x // y checkit(x, '/', y) Index: test_operator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_operator.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_operator.py 2001/08/11 03:21:35 1.6 --- test_operator.py 2001/09/04 19:14:14 1.7 *************** *** 83,87 **** def test_div(self): ! self.failUnless(operator.div(5, 2) == 2) def test_floordiv(self): --- 83,87 ---- def test_div(self): ! self.failUnless(operator.floordiv(5, 2) == 2) def test_floordiv(self): Index: test_pty.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pty.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_pty.py 2001/03/29 04:36:09 1.12 --- test_pty.py 2001/09/04 19:14:14 1.13 *************** *** 87,91 **** debug("Waiting for child (%d) to finish."%pid) (pid, status) = os.waitpid(pid, 0) ! res = status / 256 debug("Child (%d) exited with status %d (%d)."%(pid, res, status)) if res == 1: --- 87,91 ---- debug("Waiting for child (%d) to finish."%pid) (pid, status) = os.waitpid(pid, 0) ! res = status >> 8 debug("Child (%d) exited with status %d (%d)."%(pid, res, status)) if res == 1: Index: test_strftime.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strftime.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** test_strftime.py 2001/03/23 20:24:07 1.25 --- test_strftime.py 2001/09/04 19:14:14 1.26 *************** *** 65,72 **** ('%p', ampm, 'AM or PM as appropriate'), ('%S', '%02d' % now[5], 'seconds of current time (00-60)'), ! ('%U', '%02d' % ((now[7] + jan1[6])/7), 'week number of the year (Sun 1st)'), ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'), ! ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)/7), 'week number of the year (Mon 1st)'), # %x see below --- 65,72 ---- ('%p', ampm, 'AM or PM as appropriate'), ('%S', '%02d' % now[5], 'seconds of current time (00-60)'), ! ('%U', '%02d' % ((now[7] + jan1[6])//7), 'week number of the year (Sun 1st)'), ('%w', '0?%d' % ((1+now[6]) % 7), 'weekday as a number (Sun 1st)'), ! ('%W', '%02d' % ((now[7] + (jan1[6] - 1)%7)//7), 'week number of the year (Mon 1st)'), # %x see below From fdrake@users.sourceforge.net Tue Sep 4 20:20:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 12:20:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32197 Modified Files: sre.py Log Message: Convert docstring to "raw" string. Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** sre.py 2001/09/04 19:10:20 1.35 --- sre.py 2001/09/04 19:20:06 1.36 *************** *** 15,19 **** # ! """Support for regular expressions (RE). This module provides regular expression matching operations similar to --- 15,19 ---- # ! r"""Support for regular expressions (RE). This module provides regular expression matching operations similar to *************** *** 57,74 **** below. If the ordinary character is not on the list, then the resulting RE will match the second character. ! \\number Matches the contents of the group of the same number. ! \\A Matches only at the start of the string. ! \\Z Matches only at the end of the string. ! \\b Matches the empty string, but only at the start or end of a word. ! \\B Matches the empty string, but not at the start or end of a word. ! \\d Matches any decimal digit; equivalent to the set [0-9]. ! \\D Matches any non-digit character; equivalent to the set [^0-9]. ! \\s Matches any whitespace character; equivalent to [ \\t\\n\\r\\f\\v]. ! \\S Matches any non-whitespace character; equiv. to [^ \\t\\n\\r\\f\\v]. ! \\w Matches any alphanumeric character; equivalent to [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus characters defined as letters for the current locale. ! \\W Matches the complement of \\w. ! \\\\ Matches a literal backslash. This module exports the following functions: --- 57,74 ---- below. If the ordinary character is not on the list, then the resulting RE will match the second character. ! \number Matches the contents of the group of the same number. ! \A Matches only at the start of the string. ! \Z Matches only at the end of the string. ! \b Matches the empty string, but only at the start or end of a word. ! \B Matches the empty string, but not at the start or end of a word. ! \d Matches any decimal digit; equivalent to the set [0-9]. ! \D Matches any non-digit character; equivalent to the set [^0-9]. ! \s Matches any whitespace character; equivalent to [ \t\n\r\f\v]. ! \S Matches any non-whitespace character; equiv. to [^ \t\n\r\f\v]. ! \w Matches any alphanumeric character; equivalent to [a-zA-Z0-9_]. With LOCALE, it will match the set [0-9_] plus characters defined as letters for the current locale. ! \W Matches the complement of \w. ! \\ Matches a literal backslash. This module exports the following functions: From akuchling@users.sourceforge.net Tue Sep 4 20:34:39 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 04 Sep 2001 12:34:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _cursesmodule.c,2.54,2.55 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv3995 Modified Files: _cursesmodule.c Log Message: [Bug #457654] bkgd() used a hard-coded A_NORMAL attribute, when it should have used the attribute argument provided as a parameter Index: _cursesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_cursesmodule.c,v retrieving revision 2.54 retrieving revision 2.55 diff -C2 -d -r2.54 -r2.55 *** _cursesmodule.c 2001/07/19 20:48:32 2.54 --- _cursesmodule.c 2001/09/04 19:34:32 2.55 *************** *** 525,529 **** } ! return PyCursesCheckERR(wbkgd(self->win, bkgd | A_NORMAL), "bkgd"); } --- 525,529 ---- } ! return PyCursesCheckERR(wbkgd(self->win, bkgd | attr), "bkgd"); } From fdrake@users.sourceforge.net Tue Sep 4 20:43:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 04 Sep 2001 12:43:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pprint.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv6780 Modified Files: pprint.py Log Message: Make pprint more locale-friendly; patch contributed by Denis S. Otkidach. This closes SF patch #451538. Index: pprint.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pprint.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** pprint.py 2001/05/14 18:39:41 1.14 --- pprint.py 2001/09/04 19:43:26 1.15 *************** *** 35,39 **** """ ! from types import DictType, ListType, TupleType try: --- 35,40 ---- """ ! from types import DictType, ListType, TupleType, StringType ! import sys try: *************** *** 96,100 **** self.__stream = stream else: - import sys self.__stream = sys.stdout --- 97,100 ---- *************** *** 188,197 **** # Return triple (repr_string, isreadable, isrecursive). def _safe_repr(object, context, maxlevels=None, level=0): level += 1 typ = type(object) ! if not (typ in (DictType, ListType, TupleType) and object): rep = `object` return rep, (rep and (rep[0] != '<')), 0 if context.has_key(id(object)): --- 188,215 ---- # Return triple (repr_string, isreadable, isrecursive). + _have_module = sys.modules.has_key + def _safe_repr(object, context, maxlevels=None, level=0): level += 1 typ = type(object) ! if not (typ in (DictType, ListType, TupleType, StringType) and object): rep = `object` return rep, (rep and (rep[0] != '<')), 0 + elif typ is StringType: + if not _have_module('locale'): + return `object`, 1, 0 + if "'" in object and '"' not in object: + closure = '"' + quotes = {'"': '\\"'} + else: + closure = "'" + quotes = {"'": "\\'"} + sio = StringIO() + for char in object: + if char.isalpha(): + sio.write(char) + else: + sio.write(quotes.get(char, `char`[1:-1])) + return closure + sio.getvalue() + closure, 1, 0 if context.has_key(id(object)): From tim_one@users.sourceforge.net Tue Sep 4 20:48:03 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 12:48:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7479/python/Lib/test Modified Files: test_long.py Log Message: Revert one of the "division fixes" in test_long. It intends to try both "/" and "//", and doesn't really care what they *mean*, just that both are tried (and that, whatever they mean, they act similarly for int and long arguments). Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_long.py 2001/09/04 19:14:14 1.13 --- test_long.py 2001/09/04 19:48:01 1.14 *************** *** 297,302 **** if y: ! expected = longx // longy ! got = x // y checkit(x, '/', y) --- 297,302 ---- if y: ! expected = longx / longy ! got = x / y checkit(x, '/', y) From akuchling@users.sourceforge.net Tue Sep 4 21:06:45 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 04 Sep 2001 13:06:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils/command install.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv13203 Modified Files: install.py Log Message: [Bug #436732] install.py does not record a created *.pth file in the INSTALLED_FILES output. Modified version of a patch from Jon Nelson (jnelson) Index: install.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/install.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** install.py 2001/08/23 20:53:27 1.58 --- install.py 2001/09/04 20:06:43 1.59 *************** *** 538,543 **** def get_outputs (self): ! # This command doesn't have any outputs of its own, so just ! # get the outputs of all its sub-commands. outputs = [] for cmd_name in self.get_sub_commands(): --- 538,542 ---- def get_outputs (self): ! # Assemble the outputs of all the sub-commands. outputs = [] for cmd_name in self.get_sub_commands(): *************** *** 549,552 **** --- 548,555 ---- outputs.append(filename) + if self.path_file and self.install_path_file: + outputs.append(os.path.join(self.install_libbase, + self.path_file + ".pth")) + return outputs From akuchling@users.sourceforge.net Tue Sep 4 21:42:10 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Tue, 04 Sep 2001 13:42:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils/command install_data.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv22233 Modified Files: install_data.py Log Message: [Bug #444589] Record empty directories in the install_data command Slightly modified version of patch from Jon Nelson (jnelson). Index: install_data.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/install_data.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** install_data.py 2001/02/05 17:43:11 1.18 --- install_data.py 2001/09/04 20:42:08 1.19 *************** *** 64,71 **** dir = change_root(self.root, dir) self.mkpath(dir) ! for data in f[1]: ! data = convert_path(data) ! (out, _) = self.copy_file(data, dir) ! self.outfiles.append(out) def get_inputs (self): --- 64,79 ---- dir = change_root(self.root, dir) self.mkpath(dir) ! ! if f[1] == []: ! # If there are no files listed, the user must be ! # trying to create an empty directory, so add the ! # directory to the list of output files. ! self.outfiles.append(dir) ! else: ! # Copy files, adding them to the list of output files. ! for data in f[1]: ! data = convert_path(data) ! (out, _) = self.copy_file(data, dir) ! self.outfiles.append(out) def get_inputs (self): From jackjansen@users.sourceforge.net Tue Sep 4 22:24:01 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:24:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/iconsrc - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/iconsrc In directory usw-pr-cvs1:/tmp/cvs-serv1135/iconsrc Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/iconsrc added to the repository From jackjansen@users.sourceforge.net Tue Sep 4 22:25:38 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:25:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/iconsrc PythonCompiled.psd,NONE,1.1 PythonIcon.psd,NONE,1.1 PythonSource.psd,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/iconsrc In directory usw-pr-cvs1:/tmp/cvs-serv1252 Added Files: PythonCompiled.psd PythonIcon.psd PythonSource.psd Log Message: Photoshop sources for icon files. Not pretty, but hey! I'm not an artist (and a certain artist didn't jump in, yet). --- NEW FILE: PythonCompiled.psd --- 8BPS         ÿÀ   ßúùÚî­¶VíÌw%3I$’R’I$”ÿ uqø&R¯é|“”‰$’JÿÕõTÉÒILô‡Àÿ –gRm 'UbòàÍ3Ö›d†4””Õê_Zìa-d¬ƒõ¯/tÉUò:?Q±ÄúeöPÿ Blank page Ù üþþýüþüþÿÿþèÿþÿþÿþ×ÿ ÊÈÆÁ¿¾¹¶±¥rÝÿÿàáþà ÿæäååææääãâþà ÌÉĽ´©‘—óýþÿúôíåÝÓʹóÿýæèèçæäâãäãâáààßÞÞÝÝüÜûÚüÙÿØÿ×ÿÖÿÕÔÓÒÑÐÏüÎ ÍÌÉŽ´ªž”òþýÿúôíåÝÓʹôÿþèçéèæäãääãâáààßÞÞÝÝÜÜþÛûÚüÙþØÿ×ÿÖÕÔÔÓÒÑÐþÏþÎ ÌÊžµ« š¤ìþüÿúôíåÝÓʹõÿÿççþèäãþäãâáàßÞÞÝÝþÜþÛûÚüÙÿØÿ×ÿÖÿÕÔÓÒÑÐÐýÏ ÎÍÊÆ¿¶¬¡«äúþþýÿúôíåÝÓʹöÿýéþèçæþåãâáàßßÞþÝþÜýÛúÚþÙþØÿ×ÿÖÕÔÔÓÒÑÐÐþÏÎÍÊÆ¿¶­£ ©ÊàçîòùûþþúôíåÝÓʹ÷ÿÿéýè çææåäâááàßÞÞÝÝýÜýÛúÚþÙþØÿ×'ÖÕÕÔÓÒÑÑÐÐÏÏÎÌÊÅ¿·®¤ž¢ž”ŠŒ‡ƒ‚Š¢¯¿ÑãÝÓʺøÿÿêèþéÿè æåäãâáàßßÞÞÝÝýÜýÛúÚþÙÿØÿ×ÿÖ&ÕÔÔÓÒÑÑÐÏÎÍËÈþ·¯¦•…{tlifeehimpt’¬Éʺùÿÿëèþéÿè æåäãâáààßÞÞþÝýÜüÛûÚþÙÿØÿ×ÿÖ&ÕÔÓÒÑÑÐÏÍËÉƽ¸°¨Ÿ–‚zvpmkjklnqsvzƒŸ¾µúÿÿìýé èçæåäããâáàßßÞÞþÝýÜüÛûÚþÙÿØÿ×ÖÕÕÔÓÒÑÐÎÌÊÈÅÁ½¸²ª¢™ˆ€{wussþt vy|~„‰¤­ûÿþêéêêéèæåääããâáààßßÞÞþÝýÜüÛûÚþÙÿØÿ×ÖÕÔÓÒÑÐÎÌÊÈž¹´®¦Ÿ—‰„ý}ÿ €‚„‡‰Œ‘«üÿ ÿêéêêéèæååããþâáààßþÞþÝýÜüÛûÚþÙÿØ×ÖÖÕÔÓÒÑÏÍËÉÇÄÀ¼¸³¬¥ž˜“Ž‹Š‰ˆü‰ ŠŒŽ‘”——¢ ýÿÿìêëëéçýåÿäãâááàßßþÞþÝüÜúÛþÚþÙÿØ×ÖÖÕÔÓÒÐÏÎÌÊÇÄÁ½¹³¬¦¡œ˜–ý•ÿ–þ•–˜——››­ýÿÿîêëëéæäýåäãââáààßßþÞýÝùÜþÛýÚÿÙÿØ×ÖÕÕÔÓÒÒÑÏÍËÈžº´¯ª§£¢ý¡þ¢ÿ¡ÿ ¡  ¡¡¢£þÿþìêëëéäãåþæ åäãâááààßßþÞýÝùÜýÛþÚÿÙÿØ×ÖÕÕþÔ!ÓÑÐÎÌÉÇÄÀ¼¸´±¯®­­®¯®®¯¬¬«ª¨©§§¨¦¦´þÿþíëìëéåäåççæåäããâááààþßþÞýÝÿÜÿÝýÜýÛÿÚþÙØ×ÖÖþÕ$ÔÓÒÐÏÍËÉÆÃÀ½»º¹¸¸¹¹ºº¹¸¶µ³²°¯®¬¬«®WÿÿÿíëëìéçåæèçææåäããâááààþßýÞýÝ ïîíììëêêéèèþçÿæþåûäíãúâãåæýçÿæÿå äããââáàßßÞÞÝÜÛþÚþÿÿòòúñ ïîîíììëêêééèèþçþæüåïä÷ãäæçýèÿçÿæåääããâáààßßÞÝÜÛÛÜþÿ ñðïïîîíììëëþêþéýèûçèæçéýêþéÿèÿçÿæÿå äããâááàßÞÝÞÿÿ ëêèæåéìîðÿÿÿöøýùþøÿ÷þöþõþôüóúòùñûðüïýîûíðìþí ìéèéìíîïÿÿÿõüùþøÿ÷þöþõþôüóøòøñûðüïüîûí÷ìýíþîíìîïïîðÿÿÿõüùþøÿ÷þöþõýôûóöòùñûðüïûîóíþîÿïðïþðÿïýÿÿôüùþøÿ÷þöþõýôúóóòúñûðûïðîþïÿðþñðïðýÿÿóüùþøÿ÷þöþõüôõóõòúñûðùïùîüïÿðñòòññðïýÿÿòüùÿøþ÷þöþõüôíóùòúñùðõïýð ÿñùúúùùøø÷÷þöþõðôôõõôõóûòüóûôÿóÿÿÿñùúúùùøþ÷ÿöýõóôìõóôóóþôõôõþôóÿÿ ÿñøúúùøø÷÷þöþõóôøõüöòõóôþóûôýõýôÿÿ ÿñûúúù÷õö÷ööýõôôúõõöðõòôþõ æåäãâáààßààüßýàþßÞÝÜÛýÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸæÿÿääååþæåãâààßþÞüÝÞßýà%ßÞÞÝÜÜÛÚÛÚÚÙÙØ××ÖÕÕÔÓÒÑÐÎÊÇĽ¸±ª¢œ™ÃÊžçÿÿåäþå æääãâáààßÞÞüÝÿÞüßþÞ"ÝÜÜÛÛÚÚÙÙØØ××ÖÕÔÔÓÒÑÏÌÉÅÁº²¬¤›•ªÓÊžèÿÿæäåææþäÿâÿáàßßÞßýÞ ÌËÈü³¨›‘–ûþÿúôíåÝÓÊòÿ çåäãâáààßÞÞþÝýÜýÛúÚþÙÿØÿ×ÿÖ&ÕÔÓÒÑÐÏÎÍËÉƽ·°¨Ÿ–Œ„ztomjjklnqsvzƒŸ¾µúÿÿêüé èæåäããâáàßßÞÞþÝýÜüÛûÚþÙÿØÿ×ÖÕÕÔÓÒÑÏÎÌÊÇÄÀ¼·²ª¢š‘ˆ{wtþsÿt vy|~„‰¤­ûÿþëéêêéèçåäããââáààßßÞÞþÝýÜüÛÿÚ éèææåääãââáþàþßýÞÿÝ ëêçæåèìîñÿÿÿöøýùÿøþ÷þöþõþôüóúòùñûðüïýîüíøìÿëúìþí ìêçèëîîðÿÿÿõüùÿøþ÷þöþõþôüóøòøñüðüïüîúí÷ìýíþîíìîïðîïÿÿÿõüùÿøþ÷þöþõþôûóöòøñüðüïûîòíþîþï æåäãâáààßßàþßûàþßÞÝÜÛýÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸæÿÿääþåæåääâáàßýÞÿÝÿÞþßþà%ßÞÞÝÜÜÛÚÛÚÚÙÙØ××ÖÕÕÔÓÒÑÐÎÊÇĽ¸±ª¢œ™ÃÊžçÿÿääåææååäãâáàßßþÞþÝþÞüßþÞ"ÝÜÜÛÛÚÚÙÙØØ××ÖÕÔÔÓÒÑÏÌÉÅÁº²¬¤›•ªÓÊžèÿÿæäåææåãäãâááàßàþßúÞÿß'ÞßÞÞÝÝÜÜÛÛÚÚÙÙØ××ÖÕÔÔÓÒÑÐÍËÇþ¶¬¤”“ÝÓÊžéÿÿæäåæåääþãâáàáààþßüÞÿÝüÞ æåäãâáàßßÞÞþÝþÜ ÍËÅ¿·¬ ˜¥ìýüÿúôíåÝÓʹõÿþéçèèçäãþäãâáàßÞÞÝÝþÜþÛûÚÿÙÚÙÙØØ××ÖÖÕÕÔÓÒÑÐüÏ ÎÍÊÆ¿¸­¡œªàùûÿúôíåÝÓʹöÿ ÿêéêééèçæåäþâáàßßÞÞþÝýÜüÛûÚþÙÿØÿ×ÖÕÕÔÓÒÑÏÎÌÊÇÄÁ¼·±ª¢™‘‡‚{xuþsÿt vy|~„‰¤­ûÿÿìéêêéèæåäããââáààßßÞÞþÝýÜüÛûÚþÙÿØÿ×ÖÕÔÓÒÑÐÎÌÉÇÄÁ½¹´®§Ÿ—Ž‰…~|þ}ÿ €‚„‡‰Œ‘«üÿýééþêçæåäþãÿâáàßßþÞþÝýÜûÛÚÛþÚþÙÿØ×ÖÖÕÔÓÒÑÏÍËÉÆÃÀ¼¸³­¦Ÿ˜’ŒŠ‰ˆü‰ ŠŒŽ‘”——¢ ýÿÿëêëëéçýåÿäãâáààßßþÞþÝüÜúÛþÚþÙÿØ×ÖÕÔÔÓÒÐÏÍËÉÇÄÁ½¹´­§¡œ˜–þ•þ–þ•–˜——››­ýÿüìêëëéæüåäãââáààßßþÞýÝùÜþÛþÚþÙØ××ÖÕÔÔÓÒÑÐÏÍËÈÆÿºµ°«§¤¢þ¡ý¢ÿ¡ÿ ¡  ¡¡¢£þÿüíþëéäãåþæ åäãâááààßßþÞüÝúÜýÛþÚÿÙÿØ(×ÖÕÕÔÔÓÒÑÐÎÌÊÇÄÁ½¸´±°®­­®¯®¯¯¬¬«ª¨©§§¨¦¦´þÿþìëìëéæãåççæåäããâááààßßýÞüÝÜÝÝýÜþÛþÚþÙ+Ø××ÖÕÕÔÓÒÑÐÏÍËÉÇÄÀ½»º¹¸¸¹¹ºº¹¸¶µ³²°¯®¬¬«®WÿÿÿììëìêçåæççææåäãââááààþßýÞýÝ ïîíììëêêéèèþçÿæþåûäîãùâãåæýçÿæÿåäããââáààßÞÞÝÜÛÚÙÚýÿÿòòúñ ïîîíììëêêééèèþçþæüåñäõãäæçýèÿçÿæåääããâááàßßÞÝÜÛÛÜýÿ óòòñððïïîííüìúëõê÷éüèÿé ëêçäåêìîòÿÿÿöøýùþøÿ÷þöþõþôýóúòøñûðüïýîüíùìüëüìþí ìêçéìíîðÿÿÿõüùþøÿ÷þöþõþôüóùò÷ñüðüïüîúíöìþíþîþíþîñÿÿÿõüùþøÿ÷þöþõýôüóöòøñüðüïûîñíÿîþïýðïðýÿÿôüùþøÿ÷þöþõýôúóóòúñüðûïøîüíüîÿïÿðþñðïïýÿÿóüùÿøþ÷þöþõüôöóôòûñûðùï÷îýïÿðÿñòññðïþÿÿòüùÿøþ÷þöþõüôîóøòûñùðóïþðÿñþòÿñòýÿÿòúýùÿøþ÷ÿöýõúôëóùòúñïðþñüòÿñÿÿÿòþúÿùÿøÿ÷þöýõùôüóøôõóúòöñúðýñÿòþóþòñÿÿ ÿñùúúùùøø÷÷þöýõäô÷óøòôñþòÿóÿôÿóÿòÿÿÿñþúÿùÿøÿ÷þöýõßôöóïòÿóýôÿóòÿÿþñþúÿùÿøÿ÷ÿöýõñôôõõôõóùòýóûôÿóÿÿÿñùúúùøøþ÷ÿöýõóôíõóôòóþôõôõþôóÿÿþñþúùøþ÷þöþõóô÷õþöóõóôûóüôýõýôÿÿþñþúùöõö÷ööýõôôúõööðõñôúõþôÿÿ ÿòûûúùöôö÷ööþõóôûõñöîõùôüõöõöþõôÿÿþðþúùöôýöÿõòôûõëöèõÿöõöýõÿÿÿðùúúù÷ôþöþõýôüóûôûõåöðõúöþõÿÿ ÿðûúúùù÷÷ööõõþô÷óýôüõáööõüö 0 0 0 0 0 0 0 Ô6 ÞN ìo máìÿ ü±.mͪ™ê 8íçÿ¡ !)28>CFFEA<5/& å ì í ñ ò ž ž ž ž ž ÷ÿ™çÿÑÿ›ÿÿ•—þÿžœ”ýÿ 2,)ÿÿ˜š˜š™™êÿýÿÿ 23,ÿÿ™™›ž—šêÿþÿþ 210ÿÿ™™šœ˜šêÿþÿþ 211ÿ›˜›š™™êÿþÿþ šã(43¨Ýà¡CùR¬Ð7(í•)434+êÿ GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý ù GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý fgÿffÿÿ š™šð™ š™š› ÿefeeffêÿÿÿý GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý ÊÈÆÁ¿¾¹¶±¥rÌÿíÿàáþà ÌÊžµ« š¤ìþüÿúôíåÝÓʹäÿþÿ âáâßáÞÞßÜÜßþÛÚÞÚÚÞÚÙÝþÙÿØÿ×ÿÖÿÕÔÓÒÑÐÐýÏ ÎÍÊÆ¿¶¬¡«äúþþýÿúôíåÝÓʹåÿÿÿùõûÿþùõüÿüùùþÿûùùÿéþè ãââáâàßáÞÞáþÝ ÞßáâÞÝÞáßÞÝýÜýÛÿÚþÙØ×ÖÖþÕ"ÔÓÒÐÏÍËÉÆÃÀ½»º¹¸¸¹¹ºº¹¸¶µ³²°¯®¬¬«®WîÿíÿíëëìéçåæèçææåäããâááààþßýÞýÝ ÒÏÍÌÉÇÄÁ¾º¸îÿíÿÿíûìë¯èç¬æåäªãââ©áàà¨ßߧ¦ÞÞ¦Þ¦ÞݦÝݦýÝ¥ÜÜ¥ÛÛ¤ÚÚÙ¢Ø×Ö ÖÖ×ØÙÚÛÛÚÚþÙþØÿ× ÖÕÓÑÐÍËÈÅ¿»îÿÿÿ øöÿÿþöùÿÿûóþÿ ùõÿÿïììîííþì¾Úè­æåæ¬ããâ«ãâà©ãÓµµÓã¦Þ¦ÞÞ¦ÞÞ¦ÞþݦÝݳÎÜ¥ÛÛÚ£ÙØØ¡×ØÙÚÜÝÞÞÝÝþÜÛÚÚÙÙØ×ÖÕÓÑÎÌÉÆÂÀîÿþÿ äããäåãáâäãáñàüßþÞþÝÞßáãüäãââáààßÞÞÝÜÛÚÚÙ×ÕÒÐÐîÿíÿýðýïîíìëêêéèççææååääþãýâñáùàûßàâäüåäãââáààßßÞÝÜÛÛÚÙ×ÕÒÓîÿíÿûðþïÿí ìëêêéèèçææþåÿäýãöâóáûàáãäûåäããâááàßÞÞÝÜÜÛÚÙ×ÕÕîÿíÿøðìëÛ’¯èè¼sææ嬀þ䜎ããÕªªÆâÆ©©Ôâ©þâÿ© ·âÔ©áá·pááâäåýæþåäããâááàßßÞÝÝÜÛÚÙ×Øîÿíÿøð-ïî²ììëê¯éèè­ççææ¬ååää«ää«ããªãªããªããªãã¸Õâ©ââá¨þà¨ááâäæýçÿæÿå äããââáàßßÞÞÝÜÛþÚîÿíÿÿòúñ ïî²íììë¯êéé®èþç'¬ææåå¬åå«ää«ä«ää«ää«ääªããªâáâ©ááâ©áââåæçþèÿçÿæåääããâáààßßÞÝÜÛÛÜîÿÿÿ,øöÿÿþùùüÿüùùþÿûùùÿòïîòòðïïððî°îíìë¯êêé¯éèèç­çþæ­æå¬åå¬å¬åå«ää«ää¹Öã«þã äããâááàßÞÝÞîÿþÿ#ùÿÿùÿÿùÿùÿÿùÿùÿþûôôñôôñôôðòñîïïîîìíìþëþêýéúèþçâßþçâßûæÿäþãþäçèéêþëþêäàþèÿçæååäþãâáàßßîÿÿÿ)ùõûÿþùùüÿüùùþÿûùùÿôñïòôóññóòñíîïïîëìíìëëêëüêúéþèãÞþèàØæýçæÕüÓÒÞèéêüëÿêâØèéþèçææþåäãââáàîÿíÿÿõúôóòòñþðïîîíýìúë 粨»ÏÊ®¨ÍêêüëþêÞÓèþéþèýçÿæÿåÿãîÿíÿÿõþöýõ4ô§˜óòãµµÒïв²ÞîÁ²²îîîß²²ÅêÀ‡ íì±æì°°¿ç“q¢ªSÀêêûëÿêÂœäýéûèÿçæåääîÿíÿ ÑçèèéÕ¾æèàáþéÿêýëêéèëîÿ ÿùÿÿùÿùÿÿùÿÿùþþÿùÿÿóøøôøø÷óööóôòþôòñóïòòïññðîððïíýï îšÑî¼ííìáÌ´ý² ¯nhQTObdŽ²þ°¯Ãçþè Ѻæè×Øééêêþëÿìëêêíîÿ ÿûþÿùÿùÿÿùÿÿøþþÿùÿÿô÷øôøø÷ó÷öòòïõôóòóóññòïþñ QÂçé麙âéÏÒþêÿëüìëìïîÿöÿþþûÿÿø šÖﵜïîîÕ†4û3433234û3 J±åé鸙áèÁÆêêþëûìíñîÿöÿÿþ óðóóðòòïòòïþòÿñ™ÎñàÑñØ\ë3 23¢áßÌëꢩþíþîíìîïïîðîÿÿûþÿùþÿ ñûúúù÷õö÷ööýõôôúõþö#Úv25Øÿ¯*í”?D23žÜ'05/+43."!'240?ºëüôþõ ñúûúùöôö÷ööþõóôûõýö#Íj23[è­=Äw1535¥õüÈG|çÆ!†ÜáÜB#/<¨çþôýõÿöõöþõ šã(43¨Ýà¡CùR¬Ð7(í•)45‡Üûöÿ÷ö÷þö ðüûúùø÷öõõôþóþòúñþòýóüôêI2ü4-43'6þ454,455#341!4430544Ÿüöü÷þö 6788654;95£ýöú÷ÿö æåäãâáààßààüßýàþßÞÝÜÛýÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸÕÿíÿÿäÿåþæåãâààßþÞüÝÞßýà%ßÞÞÝÜÜÛÚÛÚÚÙÙØ××ÖÕÕÔÓÒÑÐÎÊÇĽ¸±ª¢œ™ÃÊžÖÿíÿåäþå æääãâáààßÞÞüÝÿÞüßþÞ"ÝÜÜÛÛÚÚÙÙØØ××ÖÕÔÔÓÒÑÏÌÉÅÁº²¬¤›•ªÓÊž×ÿÿÿÿùûÿþöùÿÿûóþÿûùùÿæåþæäæåþâãâàßáãþÞÿáÿÞ*ßâáÞÞßáàÞÝÜÛÛÚÚÙÙØ××ÖÕÔÔÓÒÑÐÍËÇþ¶¬¤”“ÝÓÊžØÿÿûþÿùþÿ ™ËÈ’¼³~›‘–ûþÿúôíåÝÓÊáÿÿÿøöÿÿþöùÿÿüùùþÿûùùÿüç;åæåä¸Õã©àßà¨àÝܨáÜÛ¥àбÚÛ¦ÝÚÙØ¢ØסÖÖ ÔÔžÒÑÐÏšÍÌÌÍšËÈ“½´’–öýÿúôíåÝÓʹâÿþÿ âáâßáÞÞßÜÜßþÛÚÞÚÚÞÚÙÝÚÙÙØØ××ÖÖÕÕÔÓÒÑÐüÏÎÍÉž¶¬¢œ®âúûýþþÿúôíåÝÓʹåÿÿÿùõûÿþùõüÿüùùþÿûùùÿýè ãââáâàßáÞÞáþÝ ¾½»¸¶µ²±¯±™îÿíÿüìëêééèçæåäããâááàþßþÞýÝ ÒÏÎÌÉÇÄÁ¾º¸îÿíÿïííüìë¯èç¬æåäªãââ©áàà¨ßߧ¦ÞÞ¦Þ¦ÞÞ¦ÝݦýݦÜÜ¥ÛÛ¤ÚÚÙ¢Ø×Ö ÖÖ×ØÚþÛþÚþÙ øöÿÿþöùÿÿûóþÿ ùõÿÿïììîííþì6¾Úè­æåæ¬ããâ«ãâà©ãÓµµÓã¦Þ¦ÞÞ¦ÞÞ¦ÞÞÝݦÝݳÎÜ¥ÛÛÚ£ÙØØ¡×ØÙÛÝþÞþÝÿÜÿÛÚÙÙØ×ÖÕÓÑÎÌÉÆÂÀîÿþÿ 棚¯ÈÀŸ˜Äêêûëÿêɤæþéþèýçÿæåäããîÿíÿÿõþöýõ4ô§˜óóãµµÒïв²ßîÁ²²ïîïß²²ªåÀ=íì±6 Ùì°°¿å}\n•›h;´êêûëÿêv Ûééèéûèÿçæåäãîÿíÿ Ù¯êê¯Ü Üèèéé¸äéÎÐýéüêéèçèîÿ ÿûþÿùÿùÿÿùÿÿùþþÿ?ùÿÿôöøóø÷÷óöö¸ˆÄô嵶ÒòÒµµàñô²ðï³…Âîß²²;ÇÏW?ÝìÀlnº¼š´+$ F´þº ¹Êçèèé¯lãèÎÐþéÿêýëêéèéîÿ ÿùÿÿùÿùÿÿùÿÿùþþÿùÿÿóøøôøø÷óööóôòþô òñóïòòïññðîþð '¸æéé_ ªïLïîîÎjï ´ð¼1ì óðóóðòòïòòïþòÿñ óðóóðóòïòòïüò ç å ñûúúù÷õö÷ööþõóôùõÿö ÑU ÁE æåäãâáààßßàþßûàþßÞÝÜÛýÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸÕÿíÿÿäþåæåääâáàßýÞÿÝÿÞþßþà%ßÞÞÝÜÜÛÚÛÚÚÙÙØ××ÖÕÕÔÓÒÑÐÎÊÇĽ¸±ª¢œ™ÃÊžÖÿíÿÿä åææååäãâáàßßþÞþÝþÞüßþÞ"ÝÜÜÛÛÚÚÙÙØØ××ÖÕÔÔÓÒÑÏÌÉÅÁº²¬¤›•ªÓÊž×ÿÿÿÿùûÿþöùÿÿûóþÿûùùÿæåþæþå:ãââãâààáãßÞÞáâÞÞßâáÞßßáàÞÜÜÛÛÚÚÙÙØ××ÖÕÔÔÓÒÑÐÍËÇþ¶¬¤”“ÝÓÊžØÿÿûþÿùþÿ ¥ÜÜÛ¤Ú̱ÙÙ£þØ(ס×סÖÕ ÔÓÑÑÐÏšËÊÉË™ËÈ’¼²}™Ž”ýÿÿúôíåÝÓÊàÿíÿ šÌÈ“½´’•÷ýÿúôíåÝÓʹâÿþÿ ÍËÅ¿·¬ ˜¥ìýüÿúôíåÝÓʹäÿþÿ âáâßáÞÞßÜÜßþÛÚÞÚÚÞÚÙÝÚÙÙØØ××ÖÖÕÕÔÓÒÑÐüÏ ÎÍÊÆ¿¸­¡œªàùûÿúôíåÝÓʹåÿÿÿùõûÿþùõüÿüùùþÿûùùÿýè ãââáâàßáÞÞáþÝ ÒÏÎÌÉÇÄÁ¾º¸îÿíÿïííüìë¯èç¬ååäªãââ©áàà¨ßߧ¦ÞÞ¦Þ¦ÞݦÝݦýݦÜÜ¥ÛÛ¤ÚÚÙ¢Ø×Ö þÖØÙÚÛÛþÚþÙÿØÿ× ÖÕÔÒÐÍËÈÅ¿»îÿÿÿ øöÿÿþöùÿÿûóþÿùõÿÿïììþíþì9¾Úè­æåæ¬ããâ«ãâà©ãÓµµÓã¦Þ¦ÞÞ¦ÞÞ¦ÞÞÝݦÝݳÎÜ¥ÛÛÚ£ÙØØ¡××ØÚÜÝÞÞþÝÿÜÿÛÚÙÙØ×ÖÖÓÒÎÌÉÆÂÀîÿþÿ ßÞßßÞßÞãèéêûë êÝÍèéèèççææþåäãââáßîÿíÿÿõôõüô óòòñððïïîííüìúëýêÞçêâÙþêÓÀçýé èÙÙÐÈÊÕ×àéêûëÿêÚÈèééþèÿçþæåäããââîÿíÿûõýôÿóÿòÿñðïîííìøíÿìÿí ìÖèìßÓììë̵èýê éÑÑĵ¹ÍÏÜêûëþê×Âçééýèýçÿæåäãâîÿíÿÿõþöýõ3ô§˜óòãµµÒïв²ßîÁ²²îîîß²²¾èÀnsíí±rláë°°¿é¿¨š›®«ˆ×êûëÿêé¨láþéüèçèççæåäâîÿíÿ ¹¸Èõ晸ôôÆzþôŶ¶óó§˜óó䶶eÄÕ¶´Ëžç™´àððív‚þðþñüòÿñøÿ š™š³ëñð·½ññþòÿóÿôÿóÿòøÿ òûûúùöôö÷ööþõóôûõýö#â´™™{>‘,eš«˜™—D*Šºb,¦ªZŽ¥œœÐñþôüõöõöþõ ðùúúùùø÷öõõþôõóüôýõöõÙ£þ™ ›)<„ˆÂL¡˜™A¬ªGÀŒ>#–¢ P ™™Áêûöÿ÷ö÷ööõôøÿ ðûûúùø÷öõõôþóþòúñþòýóüôð¤ü™˜™™¡®–ý˜–­œ——–¯¤˜˜™¦™™§˜œþ™ P` --- NEW FILE: PythonIcon.psd --- 8BPS         ÿÀ   -¥å‡x I‹7/ cœD@$oO¬Œ'ýUÊ Á– ?¬<Ê°ò~§t±˜òÖE$Ûu_¯zÿ ŒAÓõ‡ò{„’ISk©$’IOÿÒõT’I%<Öÿ Ø^îñ?¬ýQ™ýiù5£wòJDíàßøn3<¼U~رýîŽu¸Y5cW”öÅWïEÁèùÙì}˜ÌmH“ s9ÿ òhþ‹“î îå/OúƒÕªÎé-©²D1ÓäH1—ˆcçgc>g$Y‰ïÃ8L~þ<ž‰½JI$šå©$’IOÿÔõB1N’œŸ­ÿ ooí^ïkM¡çÈn[=[+¬SÕ1în@.uMЈô–åŸR¾­·ü6Oùìÿ ÷õ–d2ë.Ýú¨ú@¿ù_ÉT¯ËÇÕ꨿®çº¾àºªþ£ýZø|ŸóÙÿ è0+µ±+}½¹>¦ñùR mÐæp™´µ¼) )t’I%?ÿÙ /B, ‡½ ÷ ,•ôÿÿÓm÷ú &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& &¶ÿ¬& %±ù¨% &zÎÅÿ¯Yý 452)!$,45þ3îÿü™ûÿûÿý™üÿü™÷ÿþ3 42/+**-034þ3îÿü™ûÿþ™õÿý™ 0*9]}‹rO0+þ3îÿü™ûÿþ™õÿþ™ÿ˜÷ÿÿ3 ,A–ãÿÿÈv+!233îÿü™ûÿþ™õÿþ™›÷ÿÿ3 ,B™èÿÿÌw+ 233ãÿþ™õÿ™˜™¢©÷ÿÿ3 0(:fŽ¤Ÿ€V/)233ãÿÿ™ýÿý™íÿü31/..02ü3ãÿþ™þÿý™íÿÿ3 451("+45þ3ãÿþ™þÿý™íÿü3 ),ÿÿ¨¤™˜™ÿÿý™þ™÷ÿ+/Ó3-/øÿý™þ™÷ÿ02Ó3ÿ1øÿý™þ™÷ÿ › ”yaTVi„›Ÿþ™îÿüfûÿþfõÿýf œ¡“rUDH_œ þ™ãÿÿfýÿýfíÿü™›œœ›šü™ãÿþfþÿýfíÿÿ™ ˜—š¢¨¬«¦Ÿ˜—þ™ãÿþfþÿýfíÿü™ ý ÿ ýã ý þæ !#&(*+,ý-,+*(%#  þë "&),03579;ý<;9752/,(%" þ #&*.37:>BEHJLýMKJGEA=962-)%! þ  $).4:?FLRX^djpuzƒ†‰‹ýŒ"Šˆ…}ysnhb\VPJC>82-(# þõ #(.4:@GMT[bhov{‚‡Œ”—šœžž›™–“Š…€zsmf`YRKE>82,'" þô  &,2:AIQYbks{ƒ‹’š §¬±µº½ÀÂÄþÅ&Äÿ¼¹µ°ª¤ž—ˆ€xph_WNF?70*$ þö ÷ û þ !'.5?GQ\gr}‰”Ÿ©´¾ÆÏÕÜâçìðóöøúûüýþþùÿÿþÿý(üûù÷õñïêæàÚÔ̹°¦›„yncXND<3+% þÿ  &,4=FOZdoz†‘œ§±»ÃËÓÚáæëïòõøùûüüýþþùÿÿþÿýÿü'úù÷ôñíéäßØÑÈÀ¸®£—Œvk`VLB91)" ýù #*2:DNXbmx‚Ž˜£®·ÁÉÑÙßåéíñôöøùûüüýýõþÿý*üûúù÷õóðìèãÝÖÏǾµ« •Šti^RH?7/'! þù  %-4=FOZdoz…›¥¯¹ÁÉÐ×Ýâæêíðòóôõö÷÷ñøÿ÷+öõôóñïìéåàÛÕÎƾµ¬¢—Œvk`VLB:1*# ù $+2:BLU_it~ˆ’œ¥®¶½ÄÊÏÔ×ÛÞàâãååææíçÿæ)åäãâßÝÚÖÒÎÈÁ»³«¢™…zpf[RH?7/(" ù $+2:BKU^hq{…Ž—Ÿ§®µ»ÀÅÉÌÏÒÔÕ×ØØÙÙíÚÿÙ)Ø×ÖÕÓÑÎËÈÄ¿¹³¬¤”‹xnd[QH?7/(" ù #)08?GOXajr{ƒ‹“™Ÿ¦ª¯³¶¹»½¿ÀÁÁÂÂíÃÄÃþÂ'À¿¾½º¸µ²­©£—ˆxpg^UME=5.'! ù !&,3:AIPX`hov}„‰”˜œŸ¢¤¦¨©ª««þ¬í­þ¬(«ªª¨§¥£¡ž›—’‡‚{tme^VNF?81*$ ù ù ù ýù  !#$%&''((Þ)þ(ÿ'ÿ&%$#"! þÿ þ HLIJKKJKJKLþKþLMLMþL O;CHMDHMKHHþJHJIIKJþKJMMþL ILKJHH>O7Q+ý DKJLJFGIKMJþKÿJMKLKLLþKLKþLÿKLKLMLèMLKþL LJLKMLLKKLLéKÿLMKýLKLMKMýLKLMMþKJKLNMLMLJCDB5KOþ þ HLIJKKJKJKLþKþLMLMþL O;CHMDHMKHHþJHJIIKJþKJMMþL ILKJHH>O7Q+ý DKJLJFGIKMJþKÿJMKLKLLþKLKþLÿKLKLMLèMLKþL LJLKMLLKKLLéKÿLMKýLKLMKMýLKLMMþKJKLNMLMLJCDB5KOþ þ HLIJKKJKJKLþKþLMLMþL O;CHMDHMKHHþJHJIIKJþKJMMþL ILKJHH>O7Q+ý DKJLJFGIKMJþKÿJMKLKLLþKLKþLÿKLKLMLèMLKþL LJLKMLLKKLLéKÿLMKýLKLMKMýLKLMMþKJKLNMLMLJCDB5KOþ ü Ô û ö î /A, û 1D. û 1D. û 1D. û 1D. û 1D. û 1D. û ;S8 FbB 5gws{›¸¼¼®tuxV#ù  ú QqL [€V f` j”d j”d j”d j”d m™g 5S> ¥Kþ v¥o €´y ‹Ãƒ –ÒŽ !¡á˜! ÌÊÑèüÿÿõßÌËöÍÎͧxM#ü $«ð¢$ ÛÙÞïýÿÿøèÛÚöÜÝܶ‡[-þ $®ô¤$ êèìöþÿÿûòêéöëìëÅ–j<  1E/   K{¤Ö÷üØÿþûðÄ”k9  *Mx¨ÊëÔÿûß¾˜fDü Lz¥ÕìøÔÿþôèÅ“q: 8XBBDþ  =k—ÄòùýÏÿ ü÷鲇Y, ÿÿ&Lz¥ÑüþÍÿ þôÀ–h; •œš›• –—™š– —˜™™— —˜™™— 2.6FPUUM@1.ö32343ú —˜™™— ›˜™™› ™—™š™ —™™š— ž˜™šž ›˜™™› œš™™œ œš™˜œ š¤ —™™¢ –˜œ£ 06.™š˜˜™ 157ª˜˜• 231Ÿ—˜Ÿ 2435+ 2436@ 24323 2433+ 2433- 213443 ÿŸ™ÿªÿ jhedj iefhi heffh šœ–Œƒ€…šœö™š™—Ÿú heffh heffh dgffd hffgh ceffc ceegc š›™˜—”• Ÿöÿñçóà¬nEÿÿ`×ûÿiÖÿíÏáæ¢KýÿVˆÔþâžZÿÿu¼½rly¡Å£Jÿ¡úå™jh}¨Æ¡Vÿÿ hÚúÿfÒÿÿûÿÿÆtúÿ8¯ýÈV ÿ¦üÖ_ÿ ÿ¦üÖ^ÿ ðÿÿØ}ÿ "kÐþÿ­JD²øÈ_þÿ¡öÖgÿÿPŒžqÿ:}·ÐÀ‡Cúÿkš¼ÀeÿH’ÃÏ´xÿÿzŸ…KþÿožŒPþÿDHûÿKOLC÷ÿGMMFüÿDLOJûÿ †óÿíâðؘJÿÿ TÿÿqL39o¨À³üÿ ŒoF Jƒ‚q}ûÿ{< þ H uÿE&wþÿDqÿÿqQÿu, Q…Y%"Züÿ;^þÿX(b‡}L1ÿC&wþÿDqÿÿqJÿÿwQ8%!5Ln†üÿC J ð¯Åðÿÿþûøúáÿíÿ¥¤ÍþÿñÝÙêüÿô´™«à÷ý™D.$=oŠ–•‚^-&2\À÷ý öÙÌÛöÿÿý÷òõáÿíÿ¤¢Ëþÿï×Óèüÿõ¼£²ßööù÷”C.$=k‚Š‰{\-&2[»ù÷ö÷úýúÿ øÞÒáøÿÿþõðóáÿíÿ¾½ÜþÿíÒÍäüÿùѾÆàêêùëŽA1+8Tckj_K0+3W³ùëêëòûúÿ øÛÌÝøÿÿýõïóáÿíÿÊÉæþÿêÍÆàüÿüäÖÕÜÞÞù߈A207DOTSJ>403U«ùßÞßëùúÿ ÷ÖÆÙ÷ÿÿýõïóáÿíÿ¸¶Ùþÿß¹´ÑüÿüçÚÓÓÒÒùÓ•]OSRINSQKJTPPn®ùÓÒÓãöúÿ öÔÄ×öÿÿýõïóáÿíÿ¢ ÆþÿÒ¥ ÀüÿýëàÓËÆÆùÇ vjofPQTTOVmoi…±ùÇÆÇÛôúÿ öÔÄ×öÿÿýôîòáÿíÿž›ÂþÿΟ›¼üÿýïæÔúºù»œvkkfQPTTNVljkƒ©ù»º»Ôòúÿ òɹÌòÿÿùàÑÛáÿíÿšÂþÿÍŸ›ºüÿýòëÓ»®®ù¯•ukkePPUUNUkjk ù¯®¯Ìïúÿ ì´¤¸ìÿÿòÀ¤·áÿíÿšÂþÿËžš¹üÿþôìɦ••ù—ƒmgjaLLPOIQgjetŒù—•—·äûýüÿ è©™­èÿÿ𸛮áÿíÿ›ÂþÿËžš¸üÿýòç©qXZù^WMLMIABDCAALMKRYú^]Y\†Éñùüÿ 稙­çÿÿõ͸ÅáÿíÿšÁþÿÊ›¶üÿýîàŽI33ô5 6787754456ø5ÿ3_±çôüÿ 槙«æÿÿúâÓÞáÿíÿœ›ÁþÿÇœš¶üÿüé؆Eñ3211224232ö3Y§Þðüÿ 楙ªæÿÿúâÓÞáÿíÿš¿þÿÆœš³üÿûãÍ~Cö3 楙¨æÿÿúâÓÞáÿíÿ¡ ÆþÿÆšš³üÿúÜÀvAô3 壙§åÿÿ÷×ÆÓáÿíÿ¬«ÔþÿÅ›™³üÿùÖµn>ô3 䤙¥äÿÿò­»áÿíÿ±¯ÙþÿÆ›šµþÿþüòÌ¥a;Ý3EyµÚúüþÿ 䣙¤äÿÿï´™ªáÿíÿ¨§ÏþÿÇ››¸þÿüôà lD5Ý38Q~¶ðöþÿÿ䤙¦äÿÿï³™©áÿíÿœ›¿þÿÉš»þÿøëÏs<22Û3JŽåðüÿÿ奙§åÿÿï³™ªáÿíÿÿ› ìÒÏæÿõé¯]72Ø3ÿ2AuÐíù÷ÛËÛöÿÿ챜©áÿíÿš™ºþÿñÞÚíÿñÞ¢PÖ3ÿ27iÄåöùã×äùÿÿë­™¥áÿíÿš™ºþÿ óâàðÿìÔ™M4×3ÿ27e¹ÝôûèÝèúÿÿë­™¥áÿíÿš™ºþÿ õçåóÿçÉ‘J2Õ36`­Ôñûìãìûÿÿì­™¥áÿíÿš™ºþÿøíëõÿ⿇FÔ35Z£Ëîüðéðüÿÿ묙£áÿíÿÿš >„ÛìúÿÿúåÕàáÿûÿÿþõÿßÞïþÿñݯ_2Ë3 <}ÏåùÿÿûéÛåáÿûÿÿþõÿåäóþÿîÔ¤Y22Ì3 ;vÃÞ÷ÿÿüíâéáÿüÿþþõÿêéõþÿêËšT2Ë3 2o·×õÿÿüðèîáÿüÿÿþ 2h«Ïñþÿýôîòáÿüÿÿþ 27L„Ìïøÿüúûáÿýÿÿþÿýõÿÿþÿþðá—M30þ3ƒäù¡3þ3V¡äÿÿÛ†ý3A³ýË^ç313g»æõÿþþáÿýÿÿþÿýòÿþêÕK2.3d¤áÿóš3 <…¿¼ ¥`ý3 /«ýÅN ü3ù3û3/3b±Ýòîÿ 3¦üÖ_3 3¦üÖ^2 ,32& € Úe8lÚÿÿýôîòáÿíÿƒþÿÜ©ŸËüÿãE,³÷ý  éŸ~¤éÿÿûëßçáÿíÿ~þÿל‘ÄüÿæYA·ôôùõ z ³îÿÿûæØááÿíÿ\Y©þÿÒ‚¼üÿïŽ\vÁååùæ r 줩ìÿÿúæ×ááÿíÿzwÁþÿË€q²üÿ÷½˜£ÈÖÖù×k ê™pŸêÿÿúæ×ááÿíÿMI þÿ®QCŒüÿ÷Ä¢¥¾ÇÇùÈ{6#+&!'-,# *($J™ùÈÇÈÜôúÿ é•k›éÿÿúæ×ááÿíÿqþÿŽbüÿùͱ«µ¸¸ù¹‰UFP?&'-,$,JNEfù¹¸¹Òñúÿ é•k›éÿÿúäÔßáÿíÿ gþÿ…Vüÿú×À±­©©ùªƒTGJ@&&-,$+IIFd”ùª©ªÉïúÿ àzO€àÿÿð³¦áÿíÿ gþÿ‚Rüÿûàζ¤ššù›zRGJ?%&-,$+HIF_ˆù›š›¿ëúÿ ÏFNÏÿÿßaJáÿíÿ gþÿ~OüÿüçׯŒ{{ù}eHBI9 !&&'CH?Qoù}{}¦Ýúýüÿ Å* Ä' Â$ À! ¿ ½ º Ý º Fþÿ÷çÃQ Ù jüÿóÌ£H Ï 5n¶ðøýÿÿÝb(Máÿúÿ eÒçùÿÿ󾘲áÿûÿÿþõÿ¯­ÙþÿîÔ›:Ê \ÃÞ÷ÿÿõǧ½áÿûÿÿþõÿ½»àþÿêÉŽ3Ê S´Öõÿÿ÷ѶÈáÿüÿþþõÿÊÉæþÿå¾-É é£ˆ¦éÿÿþøõ÷áÿíÿwuµþÿêËÅàüÿîg€Ò÷þÌ¡œ¤‘mXOO]yž£š®à÷þøÿ òűÈòÿÿüóìðáÿíÿvt²þÿçĽÜüÿð›vÕûúùûÊ¡œ¥‘o^XXb{ž¢š­Ý÷ûýþúÿ õλÒõÿÿýðèíáÿíÿž›Ëþÿä¼´×üÿõ»­ÝõôùõÇ ›Ÿ•€uopw‡›ŸšªÙ÷õøýúÿ óɲÌóÿÿüðçíáÿíÿ¯­Úþÿ೪Ñüÿú×ÁÊäïîùïÄ¡š›˜…‡’››š©Õ÷ïõüúÿ ò©Æòÿÿüðçíáÿíÿ”’ÆþÿΗŽºüÿúÜÇÍáéèùé˯§¬¥“…‚‚‰š««¨¶×÷éñúúÿ ò¿¦Ãòÿÿüðçíáÿíÿÿp ò¿¦Ãòÿÿüïåìáÿíÿlj¤þÿ¶qišüÿüçÙÖÜÝÜùÝͺ¶¹¯”ƒ€‡·¸µÁÔ÷Ýéùúÿ í¯•³íÿÿöÒ»Êáÿíÿki¤þÿ´pi˜üÿüìáÚÙ×Öù×ʺ¶¹¯“ƒ€‡·¸µ¿Ï÷×æ÷úÿ âw•âÿÿì w’áÿíÿÿk Ü€fƒÜÿÿé•j†áÿíÿkj¤þÿ¯nh’üÿýôìÏ·¬¬ù¯¬§§©£–ŽŒš¦¨¥¨­ú¯®­­Âäøýüÿ Ü}fƒÜÿÿñµ”©áÿíÿji¤þÿ­miüÿþõíÅ£š˜øšþ›™˜–•––˜ýš Û|fÛÿÿ÷Ô¼Ìáÿíÿkj¢þÿ¬jgŽüÿýôë㚘ù™þš˜™üšó™š™¬Óïøüÿ Ù{fÙÿÿ÷Ô¼Íáÿíÿij þÿªjgŒüÿýñæ¿¢š˜ù™˜™š˜™üšó™š™ªÎê÷üÿ Øxf|Øÿÿ÷Ô¼Íáÿíÿsqªþÿ©jgŠüÿýî໡š˜ø™š™™šü™š™™š˜ø™š™¨Éåôüÿ ×ufz×ÿÿóĨ»áÿíÿƒ€¿þÿ©jfŠüÿüëÚ· ™˜ß™¦Åáñüÿ ÕsfxÕÿÿ즃˜áÿíÿ‰†ÈþÿªjgŠýÿýøæÒ±ž™˜ß™£¼Ûîýþþÿ ÕseyÕÿÿæŽg€áÿíÿ}z·þÿ«lgŒþÿþúðѶ¢›™˜ô™ ÖtfyÖÿÿæŽgáÿíÿkj¡þÿ­lgþÿüö纞™™šî™ Ε¶ÿýùçɯŸØ™›¤¸Ôñúýç Š§éÿÿë }”áÿíÿhgšþÿ ã½µÔÿúôÙ±›Ö™š ¾éöüòƲÉóÿÿåŠk}áÿíÿgh™þÿ ëÍÆßÿøïÒ©š×™š™›¶âòúöÔÄ×öÿÿã„fwáÿíÿÿg ôÿþþòßÈ«™˜šÌ™ ³Õçøÿÿüïåìáÿüÿÿþ š›™²ÝòúÿþýþáÿýÿÿþÿýñÿõêÈ¥™™tD T™™qL39o¨À³ü™'ŒoF Jƒ‚q}û™{< þ u™E&wþ™ Dq™Ÿ™š™ »Üíþñÿÿþòÿÿÿÿþþý J ü Ô Û ö î /A, Û 1D. Û 1D. Û 1D. Û %šÇ“% `[ …ëõÿÍUù  ú QqL [€V f` j”d j”d …° 0¹ã±0 :ÕÿÎ: ;ØÿÐ; =ÛÿÓ= ?Þÿ×? @áÿÚ@ BäÿÝB EçÿáE EèÿáE  1E/  *M­óÏÿá‰Dü &`¥ÝûÏÿ õÊ‘I ðš- ò£BEHJLýMKJGEA=962-)%! þ  $).4:?FLRX^djpuzƒ†‰‹ýŒ"Šˆ…}ysnhb\VPJC>82-(# þõ #(.4:@GMT[bhov{‚‡Œ”—šœžž›™–“Š…€zsmf`YRKE>82,'" þå  &,2:AIQYbks{ƒ‹’š §¬±µº½ÀÂÄþÅ&Äÿ¼¹µ°ª¤ž—ˆ€xph_WNF?70*$ þç è ì ï !'.5?GQ\gr}‰”Ÿ©´¾ÆÏÕÜâçìðóöøúûüýþþùÿÿþÿý(üûù÷õñïêæàÚÔ̹°¦›„yncXND<3+% þð  &,4=FOZdoz†‘œ§±»ÃËÓÚáæëïòõøùûüüýþþùÿÿþÿýÿü'úù÷ôñíéäßØÑÈÀ¸®£—Œvk`VLB91)" ýò #*2:DNXbmx‚Ž˜£®·ÁÉÑÙßåéíñôöøùûüüýýõþÿý*üûúù÷õóðìèãÝÖÏǾµ« •Šti^RH?7/'! þò  %-4=FOZdoz…›¥¯¹ÁÉÐ×Ýâæêíðòóôõö÷÷ñøÿ÷+öõôóñïìéåàÛÕÎƾµ¬¢—Œvk`VLB:1*# ò $+2:BLU_it~ˆ’œ¥®¶½ÄÊÏÔ×ÛÞàâãååææíçÿæ)åäãâßÝÚÖÒÎÈÁ»³«¢™…zpf[RH?7/(" ò $+2:BKU^hq{…Ž—Ÿ§®µ»ÀÅÉÌÏÒÔÕ×ØØÙÙíÚÿÙ)Ø×ÖÕÓÑÎËÈÄ¿¹³¬¤”‹xnd[QH?7/(" ò #)08?GOXajr{ƒ‹“™Ÿ¦ª¯³¶¹»½¿ÀÁÁÂÂíÃÄÃþÂ'À¿¾½º¸µ²­©£—ˆxpg^UME=5.'! ò !&,3:AIPX`hov}„‰”˜œŸ¢¤¦¨©ª««þ¬í­þ¬(«ªª¨§¥£¡ž›—’‡‚{tme^VNF?81*$ ò ò ò ýò  !#$%&''((Þ)þ(ÿ'ÿ&%$#"! þð --- NEW FILE: PythonSource.psd --- 8BPS         ÿÀ   ÷Ù³éHßñ†ÿ £T’÷ÝçR{˜ÿ ’äºoÖª…Ÿ¤©ÔµßM îoõöírꪶ»«mµ8>·‰k‚Jf’I$§ÿÑõT’I% Éüßš§è‡ºÁkæ6è5v»wý6ÿ ·ìvx.ˆÖÍa%<ûº`gl}\²Ú­³‰¨´Ø kk>Žßw¨×~ÿ -s\\’Ãò0ÿ žÛ ¶#­5þ” õ¿²­¤’šÕ³(Ø¡‚“P¬&Eƒéìt3ô{QM5n.,ÓÂòH‰$¤^?èÛ÷½ Ñ·î©$¤^?¸ß¸$+¬pÐ>A$”Ž Ù ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓÊìÿûãÿÇôãýâ –˜——››­ÿÿûêÿÍ÷êìéÿèþçÿæþåäããâáßÝÚÕÑÍÆ¿¹³­©¦¢¢ý¡þ¢ÿ¡ÿ ¡  ¡¡¢£ÿûê ÒÏÎÌÉÇÄÁ¾º¸ÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜòóöòüñÿÓüñðññúðüï í²ýýüóü½ÑÕûþúýüóü½ÑÕûüúþùûüõú÷ùøø ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓÊìÿûãÿÇôãýâ –˜——››­ÿÿûêÿÍ÷êìéÿèþçþæÿåäããâáßÝÚÖÑÍÆ¿º³­©¦£¢ý¡þ¢ÿ¡ÿ ¡  ¡¡¢£ÿûê ÒÏÎÌÉÇÄÁ¾º¸ÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜôòüñÿÓýñýð óùûùùúùùúúùõøý÷ í²ýýüóü½ÑÕûþúýüóü½ÑÕûüúþùûüõú÷ùøø ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓÊìÿûãÿÇôãýâ –˜——››­ÿÿûêÿÍùêéêìéÿèþçþæÿåÿäãâáßÝÚÖÑÍÆ¿¹³­©¦¢¢ý¡þ¢ÿ¡ÿ ¡  ¡¡¢£ÿ ÒÏÎÌÉÇÄÁ¾º¸ÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜþòóòóòòóüòýñÿÓ òññòððñððñüðûï í²ýýüóü½ÑÕûþúýüóü½ÑÕûüúþùûüõú÷ùøø Ô6 ÞN ìo máìÿ ü±.mͪ™ê 8íçÿ¡ !)28>CFFEA<5/& å ì í ñ ò ž ž ž ž ž ÷ÿ™çÿÑÿ›ÿÿ•—þÿžœ”ýÿ 2,)ÿÿ˜š˜š™™êÿýÿÿ 23,ÿÿ™™›ž—šêÿþÿþ 210ÿÿ™™šœ˜šêÿþÿþ 211ÿ›˜›š™™êÿþÿþ šã(43¨Ýà¡CùR¬Ð7(í•)434+êÿ GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý ù GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý fgÿffÿÿ š™šð™ š™š› ÿefeeffêÿÿÿý GEAJILIKLKKþLMLLMLýMþLÿMLKKMþLÿJI?: 3FHIFLJJIKLKöLÿM÷LÿK JKKMKHJ<4/ïÿúÿý ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓØÙÿíÿûãÿÇôãýâ ÒÏÎÌÉÇÄÁ¾º¸îÿíÿÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜîÿíÿòóöòüñÿÓüñðññúðýï èßðññðñðÞÛÜþÛÚæïýîÿíþìãØéêéèèçææåääãâááàßîÿíÿÿõñôÿÕ÷óûòêðòìæþñáÖðñþò ðÌÅÏÚÖÈÃÛðïýî ™Ôõ·›ôõõä5ù301432ü3 RÊðòò½™èðÓ×ïþîíìëëêþé šÚõ·œõõôÛŠ5û3433234û3 K·îòò»™èïÄÉðïþîíììëêþéîÿöÿÿþ õ¢ãõ¶œõõòËnî3 @žæñò»˜éð¦­ðïïþî 4nÏòÕ©íç½òýñïѯÐîíììîÿ÷ÿÿþÿýûÿ 23†Öíäòñ ©óþòýñÿðïîîîÿøÿÿþýþýûÿ šã(43¨Ýà¡CùR¬Ð7(í•)45‡Üüöùõ ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓØÙÿíÿûãÿÇôãýâ ÒÏÎÌÉÇÄÁ¾º¸îÿíÿÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜîÿíÿôòüñÿÓýñýð ð»ÆÕѽ¸×ððýî Þëþê éèèçææåääããáîÿíÿóõýô£“£º“qÕô¢øó¯åòͨóóôe àóêïïà3, nüðþïîívÞëéèêééèèçææåääããîÿíÿñö÷õÿÖùô ·óÈžôóód Þððïïá ®õNõõôÔnï JÇò‹0åÂAaòýñïѯÐîíììîÿ÷ÿÿþÿýûÿ ç ÁF ÜÛÛÚÙÙØØ×ÖÖþÕÓÒÑÍÉüµ¬£›”×ÝÓØÙÿíÿûãÿÇôãýâ ÒÏÎÌÉÇÄÁ¾º¸îÿíÿÿíðìýë¬Îëë¿üëûêÛœÛÛêýëþìÿëÿê èæåäâáàßÞÝÝÜþÛ ãââáààßÞÝÝÜîÿíÿþòóòóòòóüòýñÿÓ òññòððñððñüðýïîíðïïîíûï ñààØÏÑÜÝçððýî fÁõ˜jÖ´³¤™šð™š™ ÈÓ±œfäÃvˆðáïïßßЮþìëêîÿ÷ÿþþ šµäó²‚êÃ…žòýñðѯÐîíììîÿ÷ÿÿþÿýûÿ š™š³îôó¹¿ôôúóÿòÿñøÿ From jackjansen@users.sourceforge.net Tue Sep 4 22:26:23 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:26:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app/Resources - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources In directory usw-pr-cvs1:/tmp/cvs-serv1902/Resources Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources added to the repository From jackjansen@users.sourceforge.net Tue Sep 4 22:26:43 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:26:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app/Resources/English.lproj - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj In directory usw-pr-cvs1:/tmp/cvs-serv1984/English.lproj Log Message: Directory /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj added to the repository From jackjansen@users.sourceforge.net Tue Sep 4 22:28:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:28:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app Info.plist,NONE,1.1 PkgInfo,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app In directory usw-pr-cvs1:/tmp/cvs-serv2267 Added Files: Info.plist PkgInfo Log Message: Template for an OSX PythonInterpreter application. --- NEW FILE: Info.plist --- CFBundleDevelopmentRegion English CFBundleDocumentTypes CFBundleTypeExtensions .py CFBundleTypeIconFile PythonSource.icns CFBundleTypeName Python Module CFBundleTypeOSTypes TEXT CFBundleTypeRole Viewer CFBundleTypeExtensions .pyc CFBundleTypeIconFile PythonCompiled.icns CFBundleTypeName Python Compiled Module CFBundleTypeOSTypes PYC CFBundleTypeRole Viewer CFBundleExecutable python CFBundleGetInfoString Python Interpreter version 2.2a3, (c) 2001 Python Software Foundation. CFBundleIconFile PythonInterpreter.icns CFBundleIdentifier org.python.interpreter CFBundleInfoDictionaryVersion 6.0 CFBundleName PythonInterpreter CFBundlePackageType APPL CFBundleShortVersionString Python Interpreter version 2.2a3 CFBundleSignature PytX CFBundleVersion 2.2a3 CSResourcesFileMapped --- NEW FILE: PkgInfo --- APPLPytX From jackjansen@users.sourceforge.net Tue Sep 4 22:28:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:28:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app/Resources PythonCompiled.icns,NONE,1.1 PythonInterpreter.icns,NONE,1.1 PythonSource.icns,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources In directory usw-pr-cvs1:/tmp/cvs-serv2267/Resources Added Files: PythonCompiled.icns PythonInterpreter.icns PythonSource.icns Log Message: Template for an OSX PythonInterpreter application. --- NEW FILE: PythonCompiled.icns --- icns "räáßÞÙÔ¿Ô„ sæÞÛÚØÒË™vÄ€ uðÍçååÇâçæáÜ "rãàßÞÙÔ¿Ô„ sæÞÛÚ×ÒÊšvÄ€ uðÍçååÇâçæáÜ "räáßÞÙÔ¿Ô„ sæÞÛÚ×ÒʘuÄ€ uðÍçååÇâçæáÛ âàÞÛØÖÓÐƸ§Ž  ÷öæðìßÏËßØäƒ3ßËíìî‡ úøØõôôñÖÕÒ4ƒ3Jâòóó‡ 3íîìèæäãâàà€ßÞÝàãâßÝÙÒ‡  ÷öæðìßÏË߻₠úøØõôôñÖÕɃ 3íîìèæäãâàà€ßÞÝßãâßÝÙÒ‡  ÷öæðìßÏËßÏ郙Ô·íìí‡ ùøØõôôñÖÕÏšƒ™£Ùñóó‡ uèèåâàÞÝÜÛÛ€ÚØ×ÖÔÒÐÏÊ¿¥™‡xuŒ¬ÄZ " ÜÛÚÙ×ÖÔÒÐÍÌ€ÊǾ·²‹ çêêéçæåãáßÞ‹ xøø÷öõôôòòñ€ðÓ©î3342433¹é½Èêëììî‹ " VYb{›¼Ýîöùò‹ Ž’Ÿ±Èáðõùó‹ sèèåâàÞÝÜÛÛ€ÚØ×ÖÔÒÐÏʾ¦š…ywŒ¬ÄZ " ÜÛÚÙØÖÓÒÐÏÌ€ÊǾ·²‹ çêêéåæåãâßÞ‹ " VYb{›¼Ýîöùò‹ Ž’Ÿ±Èáðõùó‹ sèèåâàÞÝÜÛÛ€ÚØ×ÖÔÒÐÏÊ¿¦™ˆyuŒ¬ÄZ " zìêéçäâàßÞÞÝ ÜÛÚÙ×ÕÔÒÐÏÌ€ÊǾ·²‹ çêêéçæåãáßÞ‹ xøø÷öõôóòòñ€ðÃ~˜šš™šÔ颳êëììï‹ " VYb{›¼Ýîöùò‹ Ž’Ÿ±Èáðõùó‹ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ óóô ××ÖÖÕÔÔÓÒÑЀπΠÌÊžµ« š¤ìþ‚ÿúôíåÝÓʹ âáâßáÞÞßÜÜ߀ÛÚÞÚÚÞÚÙÝ€Ù ØØ××ÖÖÕÕÔÓÒÑÐÐÏ ÎÍÊÆ¿¶¬¡«äúþþÿúôíåÝÓʹ› óóô ãââáâàßáÞÞá€Ý ÞßáâÞÝÞáßÞÝÜÛÚÚ€ÙØ×ÖÖ€Õ"ÔÓÒÐÏÍËÉÆÃÀ½»º¹¸¸¹¹ºº¹¸¶µ³²°¯®¬¬«®W¤ ÒÏÍÌÉÇÄÁ¾º¸¤ òñ äããäåãáâäãáà‚߀ހÝÞßáã‚äãââáààßÞÞÝÜÛÚÚÙ×ÕÒÐÐÿ£ 粨»ÏÊ®¨Íêê‚ë€êÞÓè€é€èçææååããÿ£ óóô ÑçèèéÕ¾æèàá€éêêëêéèëÿÿ QÂçé麙âéÏÒ€êëë‚ìëìï¤ šÖﵜïîîÕ†4ƒ3433234ƒ3 J±åé鸙áèÁÆêê€ëƒìíñ¤ óóô óðóóðòòïòòï€ò ññ™ÎñàÑñØ\“3 23¢áßÌëꢩ€í€îíìîïïîð‘ 554332EÍðòó‚ôõôœ ñúûúùöôö÷öö€õ‹ôƒõö#Íj23[è­=Äw1535¥õüÈG|çÆ!†ÜáÜB#/<¨ç€ôõööõö€õ šã(43¨Ýà¡CùR¬Ð7(í•)45‡Üƒö÷÷ö÷€ö æåäãâáààßàà‚ßà€ßÞÝÜÛÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸ½ æääãâáààßÞÞ‚ÝÞނ߀Þ"ÝÜÜÛÛÚÚÙÙØØ××ÖÕÔÔÓÒÑÏÌÉÅÁº²¬¤›•ªÓÊž© óóô ™ËÈ’¼³~›‘–û€ÿúôíåÝÓÊŸ âáâßáÞÞßÜÜ߀ÛÚÞÚÚÞÚÙÝÚÙÙØØ××ÖÖÕÕÔÓÒÑЂÏÎÍÉž¶¬¢œ®âúûýþ€ÿúôíåÝÓʹ› ××ÖÖÕÔÓÓÒÑÐÏÎÍÉƾ·­¤Ÿ¨ÌßæíôûûþþúôíåÝÓʹ« óóô ãââáâàßáÞÞá€Ý ÒÏÎÌÉÇÄÁ¾º¸¤ òñ 棚¯ÈÀŸ˜Äêêƒëêêɤæ€é€èçææåäããÿ£ Ûééèéƒèççæåä㤠ٯêê¯Ü óóô Üèèéé¸äéÎÐé‚êéèçèÿ F´€º ¹Êçèèé¯lãèÎЀéêêëêéèéÿÿ òñóïòòïññðî€ð '¸æéé_ ªïLïîîÎj óóô ´ð¼1’ óðóóðòòïòòï€ò ññ óðóóðóòïòòï‚ò — ™ ÁE æåäãâáààßßà€ßƒà€ßÞÝÜÛÚÙØØ××ÖÖÕÔÔÓÑÏÏËÈÿº³®§¢¬ÈŸ½ óóô ¥ÜÜÛ¤Ú̱ÙÙ£€Ø(ס×סÖÕ ÔÓÑÑÐÏšËÊÉË™ËÈ’¼²}™Ž”ýÿÿúôíåÝÓʲ šÌÈ“½´’•÷ÿúôíåÝÓʹŸ ÍËÅ¿·¬ ˜¥ìý‚ÿúôíåÝÓʹ âáâßáÞÞßÜÜ߀ÛÚÞÚÚÞÚÙÝÚÙÙØØ××ÖÖÕÕÔÓÒÑÐ‚Ï ÎÍÊÆ¿¸­¡œªàùƒÿúôíåÝÓʹ› ××ÖÖÕÔÓÓÒÑÐÏÎÌÊÅ¿·­¤ž¨Éáçð÷üüþÿùôíåÝÓʹ« óóô ãââáâàßáÞÞá€Ý òñ ßÞßßÞßÞãèéêƒë êÝÍèéèèççææ€åäãââáߤ óòòñððïïîíí‚ì„ëêÞçêâÙ€êÓÀçé èÙÙÐÈÊÕ×àéêƒëêêÚÈèéé€èçç€æåäããââÿ£ óóô óóô š™š³ëñð·½ññ€òóóôôóóòòœ òûûúùöôö÷öö€õ‹ôƒõö#â´™™{>‘,eš«˜™—D*Šºb,¦ªZŽ¥œœÐñ€ô‚õöõö€õ ðùúúùùø÷öõõ€ô‰ó‚ôõöõÙ£€™ ›)<„ˆÂL¡˜™A¬ªGÀŒ>#–¢ P ™™Áêƒö÷÷ö÷ööõô --- NEW FILE: PythonInterpreter.icns --- icns "     äÿÿÿÿÿÿÿÿÿÿÿÿÿÍB  *Ej‘¶ÒäîòðêÛáyS2  Iœžq”    #4Oi†§¿ÓæñøüþþÿÿÿýüùñçØÀ¨ŒkQ9"   ÜÑÇÔÜ ðÖÍÚð ÖÔÇÕÖ ÚÒÂÑÚ ÜοÑÜ ÜοÑÜ ÞõÆÞ ß° ´ß Û¦™©Û Ü¥™ªÜ ݤ™§Ý Ú¡™§Ú Û¢™¤Û ÜŸ™¥Ü Ú¡™¢Ú Ú ™ Ú á ™£á ÞÌÉÝ ;ÌÔª 8xÌП 8r»ÍÌ 2k¯Ì¿ 2fªÌð 24H€ÃÌŸÿŸÄ̱ 3¦üÖ_3 3¦üÖ^2 ªª?ªŸª¹ÈÔÎÔ€ÓÎÌǼ¸°ª£œ•‘ˆ{vojfb^ZXVUQPONN‚M)NNOOQRTVX[^cgmqv~‡‹‘™Ÿª­µ»ÀÅÌ×ÐÕ××ÐÔ‘ÌÌ£ z y ЗxœÐ t ᪇«á n g Ðg™Ð ÍtKzÍ ¿BJ¿ ¸' ¹$ · ¶ ³ ± ± ± ´ ƒW ¢K=„ `Ìɪ W»ÈŸ NªÇÌ … !w‘¥ ªª?ªŸª¹ÈÔÎÔ€ÓÎÌǼ¸°ª£œ•‘ˆ{vojfb^ZXVUQPONN‚M)NNOOQRTVX[^cgmqv~‡‹‘™Ÿª­µ»ÀÅÌ×ÐÕ××ÐÔ‘ÌÌ£ àØÞ×Óʾ»»ÄÍ€×ÜÖ Ð¿«ÁÐ ðÆ´Éð ÖÁ­ÃÖ Î¾¤¿Î й¡¼Ð й¡¼Ð Õª®Õ Ô‹s‘Ô Ó|fÓ ÏyfÏ Ñyf}Ñ Îxf|Î ÏwfyÏ ÌrfxÌ ËpfwË ËpewË T™™qL39o¨À³‚™'ŒoF Jƒ‚q}ƒ™{< € u™E&w€™ Dq™Ÿ™š™¶ÓÝ¥ J ªª?ªŸª¹ÈÔÎÔ€ÓÎÌǼ¸°ª£œ•‘ˆ{vojfb^ZXVUQPONN‚M)NNOOQRTVX[^cgmqv~‡‹‘™Ÿª­µ»ÀÅÌ×ÐÕ××ÐÔ‘ÌÌ£     /A, 1D. 1D. 1D. …ëÿÿÿÿÿÿÿÿÿÿÿÿÍU   1E/  *M­óÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá‰D &`¥ÝûÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿõÊ‘I 8XB "&),03579;<<<<;9752/,(%"  #&*.37:>BEHJLMMMMKJGEA=962-)%!   $).4:?FLRX^djpuzƒ†‰‹ŒŒŒŒŠˆ…}ysnhb\VPJC>82-(#  #(.4:@GMT[bhov{‚‡Œ”—šœžž›™–“Š…€zsmf`YRKE>82,'"   &,2:AIQYbks{ƒ‹’š §¬±µº½ÀÂÄÅÅÅÄÿ¼¹µ°ª¤ž—ˆ€xph_WNF?70*$     !'.5?GQ\gr}‰”Ÿ©´¾ÆÏÕÜâçìðóöøúûüýþþþÿÿÿÿÿÿÿÿþþýýüûù÷õñïêæàÚÔ̹°¦›„yncXND<3+%   &,4=FOZdoz†‘œ§±»ÃËÓÚáæëïòõøùûüüýþþþÿÿÿÿÿÿÿÿþþýýüüúù÷ôñíéäßØÑÈÀ¸®£—Œvk`VLB91)"  #*2:DNXbmx‚Ž˜£®·ÁÉÑÙßåéíñôöøùûüüýýþþþþþþþþþþþþýýüûúù÷õóðìèãÝÖÏǾµ« •Šti^RH?7/'!   %-4=FOZdoz…›¥¯¹ÁÉÐ×Ýâæêíðòóôõö÷÷øøøøøøøøøøøøøøøø÷÷öõôóñïìéåàÛÕÎƾµ¬¢—Œvk`VLB:1*#  $+2:BLU_it~ˆ’œ¥®¶½ÄÊÏÔ×ÛÞàâãååææççççççççççççççççççççææåäãâßÝÚÖÒÎÈÁ»³«¢™…zpf[RH?7/("  $+2:BKU^hq{…Ž—Ÿ§®µ»ÀÅÉÌÏÒÔÕ×ØØÙÙÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÚÙÙØ×ÖÕÓÑÎËÈÄ¿¹³¬¤”‹xnd[QH?7/("  #)08?GOXajr{ƒ‹“™Ÿ¦ª¯³¶¹»½¿ÀÁÁÂÂÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÃÄÃÂÂÂÀ¿¾½º¸µ²­©£—ˆxpg^UME=5.'!  !&,3:AIPX`hov}„‰”˜œŸ¢¤¦¨©ª««¬¬¬­­­­­­­­­­­­­­­­­­­­¬¬¬«ªª¨§¥£¡ž›—’‡‚{tme^VNF?81*$      !#$%&''(()))))))))))))))))))))))))))))))))))(((''&&%$#"!  --- NEW FILE: PythonSource.icns --- icns àÞÜÚØÖÓÐƸ§Ž 45"5#2435 €öõô‹ ¨˜˜¥—¤˜™˜™Í€öõô‹ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ãââáààßÞÝÝܤ èßðññðñðÞÛÜ€ÛÚæïîíí€ìãØéêéèèçææåääãâááàߤ ðÌÅÏÚÖÈÃÛðïî ™Ôõ·›ôõõä5…301432‚3 RÊðòò½™èðÓ×ï€îíìëëê€é šÚõ·œõõôÛŠ5ƒ3433234ƒ3 K·îòò»™èïÄÉðï€îíììëê€é¤ õ¢ãõ¶œõõòËn3 @žæñò»˜éð¦­ðïï€î 4nÏòÕ©íç½òñïѯÐîíìì 23†Öíäòñ ©ó€òñððïîî šã(43¨Ýà¡CùR¬Ð7(í•)45‡Ü‚ö…õ ãââáààßÞÝÝܤ ð»ÆÕѽ¸×ððî Þë€ê éèèçææåääããᤠÞððïïá ®õNõõôÔn JÇò‹0åÂAaòñïѯÐîíìì — ÜÜÝÜÛÛÚØÙÙ×€ÖÕÕÔ€ÒÑÐÐÎÍÉÆÄÀ¾¼¹µ²¯«vÄ ãââáààßÞÝÝܤ ñààØÏÑÜÝçððî fÁõ˜jÖ´³¤™šŽ™š™ ÈÓ±œfäÃvˆðáïïßßЮ€ìëê¤ šµäó²‚êÃ…žòñðѯÐîíìì š™š³îôó¹¿ôô„óòòññœ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ From jackjansen@users.sourceforge.net Tue Sep 4 22:28:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:28:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app/Resources/English.lproj InfoPlist.strings,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app/Resources/English.lproj In directory usw-pr-cvs1:/tmp/cvs-serv2267/Resources/English.lproj Added Files: InfoPlist.strings Log Message: Template for an OSX PythonInterpreter application. --- NEW FILE: InfoPlist.strings --- þÿ From jackjansen@users.sourceforge.net Tue Sep 4 22:33:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 14:33:14 -0700 Subject: [Python-checkins] CVS: python/dist/src setup.py,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv3846 Modified Files: setup.py Log Message: On MacOSX built the toolbox extension modules iff we're building with --enable-framework. Some modules that are also useful outside a fullblown application are always built. Index: setup.py =================================================================== RCS file: /cvsroot/python/python/dist/src/setup.py,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** setup.py 2001/09/04 09:05:11 1.53 --- setup.py 2001/09/04 21:33:12 1.54 *************** *** 559,591 **** # already generally useful, some (the GUI ones) really need to # be used from a framework. exts.append( Extension('gestalt', ['gestaltmodule.c']) ) exts.append( Extension('MacOS', ['macosmodule.c']) ) exts.append( Extension('icglue', ['icgluemodule.c']) ) exts.append( Extension('macfs', ['macfsmodule.c', '../Python/getapplbycreator.c']) ) ! ## exts.append( Extension('Nav', ['Nav.c']) ) ! ## exts.append( Extension('AE', ['ae/AEmodule.c']) ) ! ## exts.append( Extension('App', ['app/Appmodule.c']) ) ! ## exts.append( Extension('CF', ['cf/CFmodule.c'], ! ## extra_link_args=['-framework', 'CoreFoundation']) ) ! ## exts.append( Extension('Cm', ['cm/Cmmodule.c']) ) ! ## exts.append( Extension('Ctl', ['ctl/Ctlmodule.c']) ) ! ## exts.append( Extension('Dlg', ['dlg/Dlgmodule.c']) ) ! ## exts.append( Extension('Drag', ['drag/Dragmodule.c']) ) ! ## exts.append( Extension('Evt', ['evt/Evtmodule.c']) ) ! ## exts.append( Extension('Fm', ['fm/Fmmodule.c']) ) ! ## exts.append( Extension('Icn', ['icn/Icnmodule.c']) ) ! ## exts.append( Extension('List', ['list/Listmodule.c']) ) ! ## exts.append( Extension('Menu', ['menu/Menumodule.c']) ) ! ## exts.append( Extension('Mlte', ['mlte/Mltemodule.c']) ) ! ## exts.append( Extension('Qd', ['qd/Qdmodule.c']) ) ! ## exts.append( Extension('Qdoffs', ['qdoffs/Qdoffsmodule.c']) ) ! ## exts.append( Extension('Qt', ['qt/Qtmodule.c'], ! ## extra_link_args=['-framework', 'QuickTime']) ) ! ## exts.append( Extension('Res', ['res/Resmodule.c'] ) ) ! #### exts.append( Extension('Scrap', ['scrap/Scrapmodule.c']) ) ! ## exts.append( Extension('Snd', ['snd/Sndmodule.c']) ) ! ## exts.append( Extension('TE', ['te/TEmodule.c']) ) ! #### exts.append( Extension('waste', ['waste/wastemodule.c']) ) ! ## exts.append( Extension('Win', ['win/Winmodule.c']) ) self.extensions.extend(exts) --- 559,597 ---- # already generally useful, some (the GUI ones) really need to # be used from a framework. + # + # I would like to trigger on WITH_NEXT_FRAMEWORK but that isn't + # available here. This Makefile variable is also what the install + # procedure triggers on. + frameworkdir = sysconfig.get_config_var('PYTHONFRAMEWORKDIR') exts.append( Extension('gestalt', ['gestaltmodule.c']) ) exts.append( Extension('MacOS', ['macosmodule.c']) ) exts.append( Extension('icglue', ['icgluemodule.c']) ) exts.append( Extension('macfs', ['macfsmodule.c', '../Python/getapplbycreator.c']) ) ! exts.append( Extension('_CF', ['cf/_CFmodule.c'], ! extra_link_args=['-framework', 'CoreFoundation']) ) ! exts.append( Extension('_Res', ['res/_Resmodule.c'] ) ) ! exts.append( Extension('_Snd', ['snd/_Sndmodule.c']) ) ! if frameworkdir: ! exts.append( Extension('Nav', ['Nav.c']) ) ! exts.append( Extension('_AE', ['ae/_AEmodule.c']) ) ! exts.append( Extension('_App', ['app/_Appmodule.c']) ) ! exts.append( Extension('_Cm', ['cm/_Cmmodule.c']) ) ! exts.append( Extension('_Ctl', ['ctl/_Ctlmodule.c']) ) ! exts.append( Extension('_Dlg', ['dlg/_Dlgmodule.c']) ) ! exts.append( Extension('_Drag', ['drag/_Dragmodule.c']) ) ! exts.append( Extension('_Evt', ['evt/_Evtmodule.c']) ) ! exts.append( Extension('_Fm', ['fm/_Fmmodule.c']) ) ! exts.append( Extension('_Icn', ['icn/_Icnmodule.c']) ) ! exts.append( Extension('_List', ['list/_Listmodule.c']) ) ! exts.append( Extension('_Menu', ['menu/_Menumodule.c']) ) ! exts.append( Extension('_Mlte', ['mlte/_Mltemodule.c']) ) ! exts.append( Extension('_Qd', ['qd/_Qdmodule.c']) ) ! exts.append( Extension('_Qdoffs', ['qdoffs/_Qdoffsmodule.c']) ) ! exts.append( Extension('_Qt', ['qt/_Qtmodule.c'], ! extra_link_args=['-framework', 'QuickTime']) ) ! ## exts.append( Extension('_Scrap', ['scrap/_Scrapmodule.c']) ) ! exts.append( Extension('_TE', ['te/_TEmodule.c']) ) ! ## exts.append( Extension('waste', ['waste/wastemodule.c']) ) ! exts.append( Extension('_Win', ['win/_Winmodule.c']) ) self.extensions.extend(exts) From tim_one@users.sourceforge.net Tue Sep 4 23:08:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 15:08:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.143,1.144 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Doc/api Modified Files: api.tex Log Message: At Guido's suggestion, here's a new C API function, PyObject_Dir(), like __builtin__.dir(). Moved the guts from bltinmodule.c to object.c. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.143 retrieving revision 1.144 diff -C2 -d -r1.143 -r1.144 *** api.tex 2001/08/30 15:24:17 1.143 --- api.tex 2001/09/04 22:08:55 1.144 *************** *** 1721,1724 **** --- 1721,1734 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyObject_Dir}{PyObject *o} + This is equivalent to the Python expression \samp{dir(\var{o})}, + returning a (possibly empty) list of strings appropriate for the + object argument, or \NULL{} in case of error. + If the argument is \NULL{}, this is like the Python \samp{dir()}, + returning the names of the current locals; in this case, if no + execution frame is active then \NULL{} is returned but + \cfunction{PyErr_Occurred()} will return false. + \end{cfuncdesc} + \section{Number Protocol \label{number}} From tim_one@users.sourceforge.net Tue Sep 4 23:08:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 15:08:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.227,1.228 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Misc Modified Files: NEWS Log Message: At Guido's suggestion, here's a new C API function, PyObject_Dir(), like __builtin__.dir(). Moved the guts from bltinmodule.c to object.c. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.227 retrieving revision 1.228 diff -C2 -d -r1.227 -r1.228 *** NEWS 2001/09/04 05:14:19 1.227 --- NEWS 2001/09/04 22:08:56 1.228 *************** *** 97,101 **** Build ! API - Note that PyLong_AsDouble can fail! This has always been true, but no --- 97,103 ---- Build ! C API ! ! - New function PyObject_Dir(obj), like Python __builtin__.dir(obj). - Note that PyLong_AsDouble can fail! This has always been true, but no From tim_one@users.sourceforge.net Tue Sep 4 23:08:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 15:08:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.88,2.89 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Include Modified Files: object.h Log Message: At Guido's suggestion, here's a new C API function, PyObject_Dir(), like __builtin__.dir(). Moved the guts from bltinmodule.c to object.c. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.88 retrieving revision 2.89 diff -C2 -d -r2.88 -r2.89 *** object.h 2001/08/29 23:46:35 2.88 --- object.h 2001/09/04 22:08:56 2.89 *************** *** 347,350 **** --- 347,358 ---- extern DL_IMPORT(void) (*PyObject_ClearWeakRefs)(PyObject *); + /* PyObject_Dir(obj) acts like Python __builtin__.dir(obj), returning a + list of strings. PyObject_Dir(NULL) is like __builtin__.dir(), + returning the names of the current locals. In this case, if there are + no current locals, NULL is returned, and PyErr_Occurred() is false. + */ + extern DL_IMPORT(PyObject *) PyObject_Dir(PyObject *); + + /* Helpers for printing recursive container types */ extern DL_IMPORT(int) Py_ReprEnter(PyObject *); From tim_one@users.sourceforge.net Tue Sep 4 23:08:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 15:08:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.233,2.234 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Python Modified Files: bltinmodule.c Log Message: At Guido's suggestion, here's a new C API function, PyObject_Dir(), like __builtin__.dir(). Moved the guts from bltinmodule.c to object.c. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.233 retrieving revision 2.234 diff -C2 -d -r2.233 -r2.234 *** bltinmodule.c 2001/09/04 01:20:04 2.233 --- bltinmodule.c 2001/09/04 22:08:56 2.234 *************** *** 427,574 **** in addition to any features explicitly specified."; - /* Merge the __dict__ of aclass into dict, and recursively also all - the __dict__s of aclass's base classes. The order of merging isn't - defined, as it's expected that only the final set of dict keys is - interesting. - Return 0 on success, -1 on error. - */ - - static int - merge_class_dict(PyObject* dict, PyObject* aclass) - { - PyObject *classdict; - PyObject *bases; - - assert(PyDict_Check(dict)); - assert(aclass); - - /* Merge in the type's dict (if any). */ - classdict = PyObject_GetAttrString(aclass, "__dict__"); - if (classdict == NULL) - PyErr_Clear(); - else { - int status = PyDict_Update(dict, classdict); - Py_DECREF(classdict); - if (status < 0) - return -1; - } - - /* Recursively merge in the base types' (if any) dicts. */ - bases = PyObject_GetAttrString(aclass, "__bases__"); - if (bases != NULL) { - int i, n; - assert(PyTuple_Check(bases)); - n = PyTuple_GET_SIZE(bases); - for (i = 0; i < n; i++) { - PyObject *base = PyTuple_GET_ITEM(bases, i); - if (merge_class_dict(dict, base) < 0) { - Py_DECREF(bases); - return -1; - } - } - Py_DECREF(bases); - } - return 0; - } - static PyObject * builtin_dir(PyObject *self, PyObject *args) { PyObject *arg = NULL; - /* Set exactly one of these non-NULL before the end. */ - PyObject *result = NULL; /* result list */ - PyObject *masterdict = NULL; /* result is masterdict.keys() */ if (!PyArg_ParseTuple(args, "|O:dir", &arg)) return NULL; ! ! /* If no arg, return the locals. */ ! if (arg == NULL) { ! PyObject *locals = PyEval_GetLocals(); ! if (locals == NULL) ! goto error; ! result = PyDict_Keys(locals); ! if (result == NULL) ! goto error; ! } ! ! /* Elif this is some form of module, we only want its dict. */ ! else if (PyObject_TypeCheck(arg, &PyModule_Type)) { ! masterdict = PyObject_GetAttrString(arg, "__dict__"); ! if (masterdict == NULL) ! goto error; ! assert(PyDict_Check(masterdict)); ! } ! ! /* Elif some form of type or class, grab its dict and its bases. ! We deliberately don't suck up its __class__, as methods belonging ! to the metaclass would probably be more confusing than helpful. */ ! else if (PyType_Check(arg) || PyClass_Check(arg)) { ! masterdict = PyDict_New(); ! if (masterdict == NULL) ! goto error; ! if (merge_class_dict(masterdict, arg) < 0) ! goto error; ! } ! ! /* Else look at its dict, and the attrs reachable from its class. */ ! else { ! PyObject *itsclass; ! /* Create a dict to start with. CAUTION: Not everything ! responding to __dict__ returns a dict! */ ! masterdict = PyObject_GetAttrString(arg, "__dict__"); ! if (masterdict == NULL) { ! PyErr_Clear(); ! masterdict = PyDict_New(); ! } ! else if (!PyDict_Check(masterdict)) { ! Py_DECREF(masterdict); ! masterdict = PyDict_New(); ! } ! else { ! /* The object may have returned a reference to its ! dict, so copy it to avoid mutating it. */ ! PyObject *temp = PyDict_Copy(masterdict); ! Py_DECREF(masterdict); ! masterdict = temp; ! } ! if (masterdict == NULL) ! goto error; ! ! /* Merge in attrs reachable from its class. ! CAUTION: Not all objects have a __class__ attr. */ ! itsclass = PyObject_GetAttrString(arg, "__class__"); ! if (itsclass == NULL) ! PyErr_Clear(); ! else { ! int status = merge_class_dict(masterdict, itsclass); ! Py_DECREF(itsclass); ! if (status < 0) ! goto error; ! } ! } ! ! assert((result == NULL) ^ (masterdict == NULL)); ! if (masterdict != NULL) { ! /* The result comes from its keys. */ ! assert(result == NULL); ! result = PyDict_Keys(masterdict); ! if (result == NULL) ! goto error; ! } ! ! assert(result); ! if (PyList_Sort(result) != 0) ! goto error; ! else ! goto normal_return; ! ! error: ! Py_XDECREF(result); ! result = NULL; ! /* fall through */ ! normal_return: ! Py_XDECREF(masterdict); ! return result; } --- 427,438 ---- in addition to any features explicitly specified."; static PyObject * builtin_dir(PyObject *self, PyObject *args) { PyObject *arg = NULL; if (!PyArg_ParseTuple(args, "|O:dir", &arg)) return NULL; ! return PyObject_Dir(arg); } From tim_one@users.sourceforge.net Tue Sep 4 23:08:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 15:08:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.143,2.144 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv11322/python/Objects Modified Files: object.c Log Message: At Guido's suggestion, here's a new C API function, PyObject_Dir(), like __builtin__.dir(). Moved the guts from bltinmodule.c to object.c. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.143 retrieving revision 2.144 diff -C2 -d -r2.143 -r2.144 *** object.c 2001/08/31 17:40:15 2.143 --- object.c 2001/09/04 22:08:56 2.144 *************** *** 1358,1361 **** --- 1358,1506 ---- } + /* Helper for PyObject_Dir. + Merge the __dict__ of aclass into dict, and recursively also all + the __dict__s of aclass's base classes. The order of merging isn't + defined, as it's expected that only the final set of dict keys is + interesting. + Return 0 on success, -1 on error. + */ + + static int + merge_class_dict(PyObject* dict, PyObject* aclass) + { + PyObject *classdict; + PyObject *bases; + + assert(PyDict_Check(dict)); + assert(aclass); + + /* Merge in the type's dict (if any). */ + classdict = PyObject_GetAttrString(aclass, "__dict__"); + if (classdict == NULL) + PyErr_Clear(); + else { + int status = PyDict_Update(dict, classdict); + Py_DECREF(classdict); + if (status < 0) + return -1; + } + + /* Recursively merge in the base types' (if any) dicts. */ + bases = PyObject_GetAttrString(aclass, "__bases__"); + if (bases != NULL) { + int i, n; + assert(PyTuple_Check(bases)); + n = PyTuple_GET_SIZE(bases); + for (i = 0; i < n; i++) { + PyObject *base = PyTuple_GET_ITEM(bases, i); + if (merge_class_dict(dict, base) < 0) { + Py_DECREF(bases); + return -1; + } + } + Py_DECREF(bases); + } + return 0; + } + + /* Like __builtin__.dir(arg). See bltinmodule.c's builtin_dir for the + docstring, which should be kept in synch with this implementation. */ + + PyObject * + PyObject_Dir(PyObject *arg) + { + /* Set exactly one of these non-NULL before the end. */ + PyObject *result = NULL; /* result list */ + PyObject *masterdict = NULL; /* result is masterdict.keys() */ + + /* If NULL arg, return the locals. */ + if (arg == NULL) { + PyObject *locals = PyEval_GetLocals(); + if (locals == NULL) + goto error; + result = PyDict_Keys(locals); + if (result == NULL) + goto error; + } + + /* Elif this is some form of module, we only want its dict. */ + else if (PyObject_TypeCheck(arg, &PyModule_Type)) { + masterdict = PyObject_GetAttrString(arg, "__dict__"); + if (masterdict == NULL) + goto error; + assert(PyDict_Check(masterdict)); + } + + /* Elif some form of type or class, grab its dict and its bases. + We deliberately don't suck up its __class__, as methods belonging + to the metaclass would probably be more confusing than helpful. */ + else if (PyType_Check(arg) || PyClass_Check(arg)) { + masterdict = PyDict_New(); + if (masterdict == NULL) + goto error; + if (merge_class_dict(masterdict, arg) < 0) + goto error; + } + + /* Else look at its dict, and the attrs reachable from its class. */ + else { + PyObject *itsclass; + /* Create a dict to start with. CAUTION: Not everything + responding to __dict__ returns a dict! */ + masterdict = PyObject_GetAttrString(arg, "__dict__"); + if (masterdict == NULL) { + PyErr_Clear(); + masterdict = PyDict_New(); + } + else if (!PyDict_Check(masterdict)) { + Py_DECREF(masterdict); + masterdict = PyDict_New(); + } + else { + /* The object may have returned a reference to its + dict, so copy it to avoid mutating it. */ + PyObject *temp = PyDict_Copy(masterdict); + Py_DECREF(masterdict); + masterdict = temp; + } + if (masterdict == NULL) + goto error; + + /* Merge in attrs reachable from its class. + CAUTION: Not all objects have a __class__ attr. */ + itsclass = PyObject_GetAttrString(arg, "__class__"); + if (itsclass == NULL) + PyErr_Clear(); + else { + int status = merge_class_dict(masterdict, itsclass); + Py_DECREF(itsclass); + if (status < 0) + goto error; + } + } + + assert((result == NULL) ^ (masterdict == NULL)); + if (masterdict != NULL) { + /* The result comes from its keys. */ + assert(result == NULL); + result = PyDict_Keys(masterdict); + if (result == NULL) + goto error; + } + + assert(result); + if (PyList_Sort(result) != 0) + goto error; + else + goto normal_return; + + error: + Py_XDECREF(result); + result = NULL; + /* fall through */ + normal_return: + Py_XDECREF(masterdict); + return result; + } /* From jackjansen@users.sourceforge.net Tue Sep 4 23:15:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:15:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Distributions dev.include,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Distributions In directory usw-pr-cvs1:/tmp/cvs-serv13511/Python/Mac/Distributions Modified Files: dev.include Log Message: Added pythonpath.r to the developer distribution. It's useful to people extending Python. Suggested by Alexandre Parenteau. Index: dev.include =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Distributions/dev.include,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** dev.include 2001/09/01 23:40:19 1.19 --- dev.include 2001/09/04 22:15:05 1.20 *************** *** 282,285 **** --- 282,288 ---- (':Mac:Build:xx.carbon.mcp.exp', '') (':Mac:Build:xx.carbon.mcp.xml', '') + (':Mac:Build:xx.mcp', '') + (':Mac:Build:xx.mcp.exp', '') + (':Mac:Build:xx.mcp.xml', None) (':Mac:Build:xxsubtype.carbon.mcp', None) (':Mac:Build:xxsubtype.carbon.mcp.exp', None) *************** *** 362,366 **** (':Mac:Relnotes', None) (':Mac:Relnotes-source', None) - (':Mac:Resources', None) (':Mac:TODO', None) (':Mac:Tools:BBPy', None) --- 365,368 ---- *************** *** 575,579 **** (':setup.py', None) (':site-packages', None) ! (':Mac:Build:xx.mcp', '') ! (':Mac:Build:xx.mcp.exp', '') ! (':Mac:Build:xx.mcp.xml', None) --- 577,587 ---- (':setup.py', None) (':site-packages', None) ! (':Mac:Resources:pythonpath.r', '') ! (':Mac:Resources:version.r', None) ! (':Mac:Resources:tkpython.rsrc', None) ! (':Mac:Resources:gusiprefs.rsrc', None) ! (':Mac:Resources:errors.rsrc', None) ! (':Mac:Resources:dialogs.rsrc', None) ! (':Mac:Resources:Carbon.r', None) ! (':Mac:Resources:bundle.rsrc', None) ! (':Mac:Resources:balloons.bh', None) From jackjansen@users.sourceforge.net Tue Sep 4 23:16:35 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:16:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen bgenObjectDefinition.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv13891/Python/Tools/bgen/bgen Modified Files: bgenObjectDefinition.py Log Message: Don't use a default "int" return type, gcc gives a warning about it. Index: bgenObjectDefinition.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenObjectDefinition.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** bgenObjectDefinition.py 2001/08/27 14:30:55 1.12 --- bgenObjectDefinition.py 2001/09/04 22:16:33 1.13 *************** *** 99,103 **** def outputConvert(self): ! Output("%s%s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype) OutLbrace() --- 99,103 ---- def outputConvert(self): ! Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype) OutLbrace() From jackjansen@users.sourceforge.net Tue Sep 4 23:17:01 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/win _Winmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/win In directory usw-pr-cvs1:/tmp/cvs-serv13959/Python/Mac/Modules/win Modified Files: _Winmodule.c Log Message: Regenerated without default int return types. Index: _Winmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/_Winmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Winmodule.c 2001/08/23 13:58:48 1.1 --- _Winmodule.c 2001/09/04 22:16:59 1.2 *************** *** 83,87 **** return (PyObject *)it; } ! WinObj_Convert(PyObject *v, WindowPtr *p_itself) { --- 83,87 ---- return (PyObject *)it; } ! int WinObj_Convert(PyObject *v, WindowPtr *p_itself) { From jackjansen@users.sourceforge.net Tue Sep 4 23:17:05 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/te _TEmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/te In directory usw-pr-cvs1:/tmp/cvs-serv14031/Python/Mac/Modules/te Modified Files: _TEmodule.c Log Message: Regenerated without default int return types. Index: _TEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/te/_TEmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _TEmodule.c 2001/08/23 13:58:53 1.1 --- _TEmodule.c 2001/09/04 22:17:03 1.2 *************** *** 83,87 **** return (PyObject *)it; } ! TEObj_Convert(PyObject *v, TEHandle *p_itself) { if (!TEObj_Check(v)) --- 83,87 ---- return (PyObject *)it; } ! int TEObj_Convert(PyObject *v, TEHandle *p_itself) { if (!TEObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:17:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/snd _Sndmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/snd In directory usw-pr-cvs1:/tmp/cvs-serv14057/Python/Mac/Modules/snd Modified Files: _Sndmodule.c Log Message: Regenerated without default int return types. Index: _Sndmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/snd/_Sndmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Sndmodule.c 2001/08/23 13:58:59 1.1 --- _Sndmodule.c 2001/09/04 22:17:10 1.2 *************** *** 81,85 **** return (PyObject *)it; } ! static SndCh_Convert(PyObject *v, SndChannelPtr *p_itself) { if (!SndCh_Check(v)) --- 81,85 ---- return (PyObject *)it; } ! static int SndCh_Convert(PyObject *v, SndChannelPtr *p_itself) { if (!SndCh_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:17:18 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res _Resmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv14076/Python/Mac/Modules/res Modified Files: _Resmodule.c Log Message: Regenerated without default int return types. Index: _Resmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/_Resmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Resmodule.c 2001/08/23 13:59:14 1.1 --- _Resmodule.c 2001/09/04 22:17:16 1.2 *************** *** 66,70 **** return (PyObject *)it; } ! ResObj_Convert(PyObject *v, Handle *p_itself) { if (!ResObj_Check(v)) --- 66,70 ---- return (PyObject *)it; } ! int ResObj_Convert(PyObject *v, Handle *p_itself) { if (!ResObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:17:39 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qt _Qtmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qt In directory usw-pr-cvs1:/tmp/cvs-serv14104/Python/Mac/Modules/qt Modified Files: _Qtmodule.c Log Message: Regenerated without default int return types. Index: _Qtmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qt/_Qtmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Qtmodule.c 2001/08/23 13:59:45 1.1 --- _Qtmodule.c 2001/09/04 22:17:37 1.2 *************** *** 113,117 **** return (PyObject *)it; } ! MovieCtlObj_Convert(PyObject *v, MovieController *p_itself) { if (!MovieCtlObj_Check(v)) --- 113,117 ---- return (PyObject *)it; } ! int MovieCtlObj_Convert(PyObject *v, MovieController *p_itself) { if (!MovieCtlObj_Check(v)) *************** *** 975,979 **** return (PyObject *)it; } ! TimeBaseObj_Convert(PyObject *v, TimeBase *p_itself) { if (!TimeBaseObj_Check(v)) --- 975,979 ---- return (PyObject *)it; } ! int TimeBaseObj_Convert(PyObject *v, TimeBase *p_itself) { if (!TimeBaseObj_Check(v)) *************** *** 1369,1373 **** return (PyObject *)it; } ! UserDataObj_Convert(PyObject *v, UserData *p_itself) { if (!UserDataObj_Check(v)) --- 1369,1373 ---- return (PyObject *)it; } ! int UserDataObj_Convert(PyObject *v, UserData *p_itself) { if (!UserDataObj_Check(v)) *************** *** 1646,1650 **** return (PyObject *)it; } ! MediaObj_Convert(PyObject *v, Media *p_itself) { if (!MediaObj_Check(v)) --- 1646,1650 ---- return (PyObject *)it; } ! int MediaObj_Convert(PyObject *v, Media *p_itself) { if (!MediaObj_Check(v)) *************** *** 2680,2684 **** return (PyObject *)it; } ! TrackObj_Convert(PyObject *v, Track *p_itself) { if (!TrackObj_Check(v)) --- 2680,2684 ---- return (PyObject *)it; } ! int TrackObj_Convert(PyObject *v, Track *p_itself) { if (!TrackObj_Check(v)) *************** *** 3767,3771 **** return (PyObject *)it; } ! MovieObj_Convert(PyObject *v, Movie *p_itself) { if (!MovieObj_Check(v)) --- 3767,3771 ---- return (PyObject *)it; } ! int MovieObj_Convert(PyObject *v, Movie *p_itself) { if (!MovieObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:17:43 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qdoffs _Qdoffsmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qdoffs In directory usw-pr-cvs1:/tmp/cvs-serv14165/Python/Mac/Modules/qdoffs Modified Files: _Qdoffsmodule.c Log Message: Regenerated without default int return types. Index: _Qdoffsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qdoffs/_Qdoffsmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Qdoffsmodule.c 2001/08/23 13:59:51 1.1 --- _Qdoffsmodule.c 2001/09/04 22:17:41 1.2 *************** *** 56,60 **** return (PyObject *)it; } ! GWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) { if (!GWorldObj_Check(v)) --- 56,60 ---- return (PyObject *)it; } ! int GWorldObj_Convert(PyObject *v, GWorldPtr *p_itself) { if (!GWorldObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:17:58 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:17:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd _Qdmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv14197/Python/Mac/Modules/qd Modified Files: _Qdmodule.c Log Message: Regenerated without default int return types. Index: _Qdmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/_Qdmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Qdmodule.c 2001/08/23 14:00:12 1.1 --- _Qdmodule.c 2001/09/04 22:17:56 1.2 *************** *** 164,168 **** return (PyObject *)it; } ! GrafObj_Convert(PyObject *v, GrafPtr *p_itself) { #if 1 --- 164,168 ---- return (PyObject *)it; } ! int GrafObj_Convert(PyObject *v, GrafPtr *p_itself) { #if 1 *************** *** 415,419 **** return (PyObject *)it; } ! BMObj_Convert(PyObject *v, BitMapPtr *p_itself) { if (!BMObj_Check(v)) --- 415,419 ---- return (PyObject *)it; } ! int BMObj_Convert(PyObject *v, BitMapPtr *p_itself) { if (!BMObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:03 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte _Mltemodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv14264/Python/Mac/Modules/mlte Modified Files: _Mltemodule.c Log Message: Regenerated without default int return types. Index: _Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/_Mltemodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Mltemodule.c 2001/09/01 23:38:08 1.2 --- _Mltemodule.c 2001/09/04 22:18:01 1.3 *************** *** 108,112 **** return (PyObject *)it; } ! TXNObj_Convert(PyObject *v, TXNObject *p_itself) { if (!TXNObj_Check(v)) --- 108,112 ---- return (PyObject *)it; } ! int TXNObj_Convert(PyObject *v, TXNObject *p_itself) { if (!TXNObj_Check(v)) *************** *** 1095,1099 **** return (PyObject *)it; } ! TXNFontMenuObj_Convert(PyObject *v, TXNFontMenuObject *p_itself) { if (!TXNFontMenuObj_Check(v)) --- 1095,1099 ---- return (PyObject *)it; } ! int TXNFontMenuObj_Convert(PyObject *v, TXNFontMenuObject *p_itself) { if (!TXNFontMenuObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:14 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/menu _Menumodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/menu In directory usw-pr-cvs1:/tmp/cvs-serv14326/Python/Mac/Modules/menu Modified Files: _Menumodule.c Log Message: Regenerated without default int return types. Index: _Menumodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/menu/_Menumodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Menumodule.c 2001/08/23 14:00:27 1.1 --- _Menumodule.c 2001/09/04 22:18:12 1.2 *************** *** 68,72 **** return (PyObject *)it; } ! MenuObj_Convert(PyObject *v, MenuHandle *p_itself) { if (!MenuObj_Check(v)) --- 68,72 ---- return (PyObject *)it; } ! int MenuObj_Convert(PyObject *v, MenuHandle *p_itself) { if (!MenuObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:19 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/list _Listmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/list In directory usw-pr-cvs1:/tmp/cvs-serv14362/Python/Mac/Modules/list Modified Files: _Listmodule.c Log Message: Regenerated without default int return types. Index: _Listmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/list/_Listmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Listmodule.c 2001/08/23 14:00:32 1.1 --- _Listmodule.c 2001/09/04 22:18:17 1.2 *************** *** 86,90 **** return (PyObject *)it; } ! ListObj_Convert(PyObject *v, ListHandle *p_itself) { if (!ListObj_Check(v)) --- 86,90 ---- return (PyObject *)it; } ! int ListObj_Convert(PyObject *v, ListHandle *p_itself) { if (!ListObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:33 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/drag _Dragmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/drag In directory usw-pr-cvs1:/tmp/cvs-serv14401/Python/Mac/Modules/drag Modified Files: _Dragmodule.c Log Message: Regenerated without default int return types. Index: _Dragmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/drag/_Dragmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Dragmodule.c 2001/08/23 14:01:11 1.1 --- _Dragmodule.c 2001/09/04 22:18:31 1.2 *************** *** 67,71 **** return (PyObject *)it; } ! DragObj_Convert(PyObject *v, DragRef *p_itself) { if (!DragObj_Check(v)) --- 67,71 ---- return (PyObject *)it; } ! int DragObj_Convert(PyObject *v, DragRef *p_itself) { if (!DragObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:43 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/dlg _Dlgmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/dlg In directory usw-pr-cvs1:/tmp/cvs-serv14452/Python/Mac/Modules/dlg Modified Files: _Dlgmodule.c Log Message: Regenerated without default int return types. Index: _Dlgmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/dlg/_Dlgmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Dlgmodule.c 2001/08/23 14:01:18 1.1 --- _Dlgmodule.c 2001/09/04 22:18:41 1.2 *************** *** 159,163 **** return (PyObject *)it; } ! DlgObj_Convert(PyObject *v, DialogPtr *p_itself) { if (v == Py_None) { *p_itself = NULL; return 1; } --- 159,163 ---- return (PyObject *)it; } ! int DlgObj_Convert(PyObject *v, DialogPtr *p_itself) { if (v == Py_None) { *p_itself = NULL; return 1; } From jackjansen@users.sourceforge.net Tue Sep 4 23:18:52 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl _Ctlmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv14513/Python/Mac/Modules/ctl Modified Files: _Ctlmodule.c Log Message: Regenerated without default int return types. Index: _Ctlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/_Ctlmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Ctlmodule.c 2001/08/23 14:01:29 1.1 --- _Ctlmodule.c 2001/09/04 22:18:50 1.2 *************** *** 119,123 **** return (PyObject *)it; } ! CtlObj_Convert(PyObject *v, ControlHandle *p_itself) { if (!CtlObj_Check(v)) --- 119,123 ---- return (PyObject *)it; } ! int CtlObj_Convert(PyObject *v, ControlHandle *p_itself) { if (!CtlObj_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:18:56 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:18:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cm _Cmmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cm In directory usw-pr-cvs1:/tmp/cvs-serv14556/Python/Mac/Modules/cm Modified Files: _Cmmodule.c Log Message: Regenerated without default int return types. Index: _Cmmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cm/_Cmmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Cmmodule.c 2001/08/23 14:01:33 1.1 --- _Cmmodule.c 2001/09/04 22:18:54 1.2 *************** *** 85,89 **** return (PyObject *)it; } ! CmpInstObj_Convert(PyObject *v, ComponentInstance *p_itself) { if (!CmpInstObj_Check(v)) --- 85,89 ---- return (PyObject *)it; } ! int CmpInstObj_Convert(PyObject *v, ComponentInstance *p_itself) { if (!CmpInstObj_Check(v)) *************** *** 333,337 **** return (PyObject *)it; } ! CmpObj_Convert(PyObject *v, Component *p_itself) { if ( v == Py_None ) { --- 333,337 ---- return (PyObject *)it; } ! int CmpObj_Convert(PyObject *v, Component *p_itself) { if ( v == Py_None ) { From jackjansen@users.sourceforge.net Tue Sep 4 23:19:07 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:19:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf _CFmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv14582/Python/Mac/Modules/cf Modified Files: _CFmodule.c Log Message: Regenerated without default int return types. Index: _CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/_CFmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _CFmodule.c 2001/08/23 14:01:45 1.1 --- _CFmodule.c 2001/09/04 22:19:05 1.2 *************** *** 56,59 **** --- 56,60 ---- } + int CFRange_Convert(PyObject *v, CFRange *p_itself) { *************** *** 103,107 **** return (PyObject *)it; } ! CFTypeRefObj_Convert(PyObject *v, CFTypeRef *p_itself) { --- 104,108 ---- return (PyObject *)it; } ! int CFTypeRefObj_Convert(PyObject *v, CFTypeRef *p_itself) { *************** *** 326,330 **** return (PyObject *)it; } ! CFArrayRefObj_Convert(PyObject *v, CFArrayRef *p_itself) { --- 327,331 ---- return (PyObject *)it; } ! int CFArrayRefObj_Convert(PyObject *v, CFArrayRef *p_itself) { *************** *** 476,480 **** return (PyObject *)it; } ! CFMutableArrayRefObj_Convert(PyObject *v, CFMutableArrayRef *p_itself) { --- 477,481 ---- return (PyObject *)it; } ! int CFMutableArrayRefObj_Convert(PyObject *v, CFMutableArrayRef *p_itself) { *************** *** 629,633 **** return (PyObject *)it; } ! CFDictionaryRefObj_Convert(PyObject *v, CFDictionaryRef *p_itself) { --- 630,634 ---- return (PyObject *)it; } ! int CFDictionaryRefObj_Convert(PyObject *v, CFDictionaryRef *p_itself) { *************** *** 761,765 **** return (PyObject *)it; } ! CFMutableDictionaryRefObj_Convert(PyObject *v, CFMutableDictionaryRef *p_itself) { --- 762,766 ---- return (PyObject *)it; } ! int CFMutableDictionaryRefObj_Convert(PyObject *v, CFMutableDictionaryRef *p_itself) { *************** *** 877,881 **** return (PyObject *)it; } ! CFDataRefObj_Convert(PyObject *v, CFDataRef *p_itself) { --- 878,882 ---- return (PyObject *)it; } ! int CFDataRefObj_Convert(PyObject *v, CFDataRef *p_itself) { *************** *** 1027,1031 **** return (PyObject *)it; } ! CFMutableDataRefObj_Convert(PyObject *v, CFMutableDataRef *p_itself) { --- 1028,1032 ---- return (PyObject *)it; } ! int CFMutableDataRefObj_Convert(PyObject *v, CFMutableDataRef *p_itself) { *************** *** 1225,1229 **** return (PyObject *)it; } ! CFStringRefObj_Convert(PyObject *v, CFStringRef *p_itself) { --- 1226,1230 ---- return (PyObject *)it; } ! int CFStringRefObj_Convert(PyObject *v, CFStringRef *p_itself) { *************** *** 1828,1832 **** return (PyObject *)it; } ! CFMutableStringRefObj_Convert(PyObject *v, CFMutableStringRef *p_itself) { --- 1829,1833 ---- return (PyObject *)it; } ! int CFMutableStringRefObj_Convert(PyObject *v, CFMutableStringRef *p_itself) { *************** *** 2115,2119 **** return (PyObject *)it; } ! CFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself) { --- 2116,2120 ---- return (PyObject *)it; } ! int CFURLRefObj_Convert(PyObject *v, CFURLRef *p_itself) { From jackjansen@users.sourceforge.net Tue Sep 4 23:19:16 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:19:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae _AEmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv14660/Python/Mac/Modules/ae Modified Files: _AEmodule.c Log Message: Regenerated without default int return types. Index: _AEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/_AEmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _AEmodule.c 2001/09/01 23:38:45 1.2 --- _AEmodule.c 2001/09/04 22:19:14 1.3 *************** *** 72,76 **** return (PyObject *)it; } ! AEDesc_Convert(PyObject *v, AEDesc *p_itself) { if (!AEDesc_Check(v)) --- 72,76 ---- return (PyObject *)it; } ! int AEDesc_Convert(PyObject *v, AEDesc *p_itself) { if (!AEDesc_Check(v)) From jackjansen@users.sourceforge.net Tue Sep 4 23:19:20 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:19:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv14678/Python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: Regenerated without default int return types. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** cfsupport.py 2001/08/23 13:47:57 1.8 --- cfsupport.py 2001/09/04 22:19:18 1.9 *************** *** 82,85 **** --- 82,86 ---- } + int CFRange_Convert(PyObject *v, CFRange *p_itself) { From jackjansen@users.sourceforge.net Tue Sep 4 23:20:41 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:20:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules Nav.c,1.14,1.15 icgluemodule.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14791 Modified Files: Nav.c icgluemodule.c Log Message: Added prototypes to silence gcc strict-prototype warnings. Fixed a few missing return values. Index: Nav.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/Nav.c,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** Nav.c 2001/09/02 00:08:16 1.14 --- Nav.c 2001/09/04 22:20:39 1.15 *************** *** 89,96 **** Boolean c_rv = false; ! if (!dict) return; if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) { PyErr_Clear(); ! return; } rv = PyObject_CallFunction(pyfunc, "s#", (void *)callBackParms, sizeof(NavCBRec)); --- 89,96 ---- Boolean c_rv = false; ! if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "previewProc")) == NULL ) { PyErr_Clear(); ! return false; } rv = PyObject_CallFunction(pyfunc, "s#", (void *)callBackParms, sizeof(NavCBRec)); *************** *** 115,122 **** Boolean c_rv = false; ! if (!dict) return; if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) { PyErr_Clear(); ! return; } rv = PyObject_CallFunction(pyfunc, "O&s#h", --- 115,122 ---- Boolean c_rv = false; ! if (!dict) return false; if ( (pyfunc = PyDict_GetItemString(dict, "filterProc")) == NULL ) { PyErr_Clear(); ! return false; } rv = PyObject_CallFunction(pyfunc, "O&s#h", *************** *** 245,251 **** static PyObject * ! nav_NavTranslateFile(self, args) ! navrrobject *self; ! PyObject *args; { NavTranslationOptions howToTranslate; --- 245,249 ---- static PyObject * ! nav_NavTranslateFile(navrrobject *self, PyObject *args) { NavTranslationOptions howToTranslate; *************** *** 268,274 **** static PyObject * ! nav_NavCompleteSave(self, args) ! navrrobject *self; ! PyObject *args; { NavTranslationOptions howToTranslate; --- 266,270 ---- static PyObject * ! nav_NavCompleteSave(navrrobject *self, PyObject *args) { NavTranslationOptions howToTranslate; *************** *** 311,316 **** static void ! navrr_dealloc(self) ! navrrobject *self; { NavDisposeReply(&self->itself); --- 307,311 ---- static void ! navrr_dealloc(navrrobject *self) { NavDisposeReply(&self->itself); *************** *** 319,325 **** static PyObject * ! navrr_getattr(self, name) ! navrrobject *self; ! char *name; { FSSpec fss; --- 314,318 ---- static PyObject * ! navrr_getattr(navrrobject *self, char *name) { FSSpec fss; *************** *** 380,387 **** static int ! navrr_setattr(self, name, v) ! navrrobject *self; ! char *name; ! PyObject *v; { /* Set attribute 'name' to value 'v'. v==NULL means delete */ --- 373,377 ---- static int ! navrr_setattr(navrrobject *self, char *name, PyObject *v) { /* Set attribute 'name' to value 'v'. v==NULL means delete */ *************** *** 429,436 **** static PyObject * ! nav_NavGetFile(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 419,423 ---- static PyObject * ! nav_NavGetFile(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 467,474 **** static PyObject * ! nav_NavPutFile(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 454,458 ---- static PyObject * ! nav_NavPutFile(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 505,512 **** static PyObject * ! nav_NavAskSaveChanges(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 489,493 ---- static PyObject * ! nav_NavAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 538,545 **** static PyObject * ! nav_NavCustomAskSaveChanges(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 519,523 ---- static PyObject * ! nav_NavCustomAskSaveChanges(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 570,577 **** static PyObject * ! nav_NavAskDiscardChanges(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 548,552 ---- static PyObject * ! nav_NavAskDiscardChanges(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 602,609 **** static PyObject * ! nav_NavChooseFile(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 577,581 ---- static PyObject * ! nav_NavChooseFile(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 640,647 **** static PyObject * ! nav_NavChooseFolder(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 612,616 ---- static PyObject * ! nav_NavChooseFolder(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 676,683 **** static PyObject * ! nav_NavChooseVolume(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 645,649 ---- static PyObject * ! nav_NavChooseVolume(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 712,719 **** static PyObject * ! nav_NavChooseObject(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 678,682 ---- static PyObject * ! nav_NavChooseObject(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 748,755 **** static PyObject * ! nav_NavNewFolder(self, args, kw) ! PyObject *self; /* Not used */ ! PyObject *args; ! PyObject *kw; { PyObject *dict; --- 711,715 ---- static PyObject * ! nav_NavNewFolder(PyObject *self, PyObject *args, PyObject *kw) { PyObject *dict; *************** *** 785,791 **** static PyObject * ! nav_NavCustomControl(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { --- 745,749 ---- static PyObject * ! nav_NavCustomControl(PyObject *self, PyObject *args) { *************** *** 802,808 **** static PyObject * ! nav_NavServicesCanRun(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { Boolean rv; --- 760,764 ---- static PyObject * ! nav_NavServicesCanRun(PyObject *self, PyObject *args) { Boolean rv; *************** *** 818,824 **** static PyObject * ! nav_NavServicesAvailable(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { Boolean rv; --- 774,778 ---- static PyObject * ! nav_NavServicesAvailable(PyObject *self, PyObject *args) { Boolean rv; *************** *** 835,841 **** static PyObject * ! nav_NavLoad(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { --- 789,793 ---- static PyObject * ! nav_NavLoad(PyObject *self, PyObject *args) { *************** *** 852,858 **** static PyObject * ! nav_NavUnload(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { --- 804,808 ---- static PyObject * ! nav_NavUnload(PyObject *self, PyObject *args) { *************** *** 869,875 **** static PyObject * ! nav_NavLibraryVersion(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { UInt32 rv; --- 819,823 ---- static PyObject * ! nav_NavLibraryVersion(PyObject *self, PyObject *args) { UInt32 rv; *************** *** 886,892 **** static PyObject * ! nav_NavGetDefaultDialogOptions(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { NavDialogOptions dialogOptions; --- 834,838 ---- static PyObject * ! nav_NavGetDefaultDialogOptions(PyObject *self, PyObject *args) { NavDialogOptions dialogOptions; *************** *** 950,954 **** void ! initNav() { PyObject *m, *d; --- 896,900 ---- void ! initNav(void) { PyObject *m, *d; Index: icgluemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/icgluemodule.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** icgluemodule.c 2001/05/19 12:34:59 1.5 --- icgluemodule.c 2001/09/04 22:20:39 1.6 *************** *** 89,95 **** static PyObject * ! ici_ICFindConfigFile(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 89,93 ---- static PyObject * ! ici_ICFindConfigFile(iciobject *self, PyObject *args) { ICError err; *************** *** 109,115 **** static PyObject * ! ici_ICFindUserConfigFile(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 107,111 ---- static PyObject * ! ici_ICFindUserConfigFile(iciobject *self, PyObject *args) { ICError err; *************** *** 130,136 **** static PyObject * ! ici_ICChooseConfig(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 126,130 ---- static PyObject * ! ici_ICChooseConfig(iciobject *self, PyObject *args) { ICError err; *************** *** 149,155 **** static PyObject * ! ici_ICChooseNewConfig(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 143,147 ---- static PyObject * ! ici_ICChooseNewConfig(iciobject *self, PyObject *args) { ICError err; *************** *** 170,176 **** static PyObject * ! ici_ICGetSeed(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 162,166 ---- static PyObject * ! ici_ICGetSeed(iciobject *self, PyObject *args) { ICError err; *************** *** 190,196 **** static PyObject * ! ici_ICBegin(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 180,184 ---- static PyObject * ! ici_ICBegin(iciobject *self, PyObject *args) { ICError err; *************** *** 211,217 **** static PyObject * ! ici_ICFindPrefHandle(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 199,203 ---- static PyObject * ! ici_ICFindPrefHandle(iciobject *self, PyObject *args) { ICError err; *************** *** 233,239 **** static PyObject * ! ici_ICSetPref(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 219,223 ---- static PyObject * ! ici_ICSetPref(iciobject *self, PyObject *args) { ICError err; *************** *** 259,265 **** static PyObject * ! ici_ICCountPref(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 243,247 ---- static PyObject * ! ici_ICCountPref(iciobject *self, PyObject *args) { ICError err; *************** *** 279,285 **** static PyObject * ! ici_ICGetIndPref(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 261,265 ---- static PyObject * ! ici_ICGetIndPref(iciobject *self, PyObject *args) { ICError err; *************** *** 300,306 **** static PyObject * ! ici_ICDeletePref(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 280,284 ---- static PyObject * ! ici_ICDeletePref(iciobject *self, PyObject *args) { ICError err; *************** *** 321,327 **** static PyObject * ! ici_ICEnd(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 299,303 ---- static PyObject * ! ici_ICEnd(iciobject *self, PyObject *args) { ICError err; *************** *** 341,347 **** static PyObject * ! ici_ICEditPreferences(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 317,321 ---- static PyObject * ! ici_ICEditPreferences(iciobject *self, PyObject *args) { ICError err; *************** *** 362,368 **** static PyObject * ! ici_ICParseURL(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 336,340 ---- static PyObject * ! ici_ICParseURL(iciobject *self, PyObject *args) { ICError err; *************** *** 388,394 **** static PyObject * ! ici_ICLaunchURL(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 360,364 ---- static PyObject * ! ici_ICLaunchURL(iciobject *self, PyObject *args) { ICError err; *************** *** 413,419 **** static PyObject * ! ici_ICMapFilename(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 383,387 ---- static PyObject * ! ici_ICMapFilename(iciobject *self, PyObject *args) { ICError err; *************** *** 443,449 **** static PyObject * ! ici_ICMapTypeCreator(self, args) ! iciobject *self; ! PyObject *args; { ICError err; --- 411,415 ---- static PyObject * ! ici_ICMapTypeCreator(iciobject *self, PyObject *args) { ICError err; *************** *** 518,523 **** static void ! ici_dealloc(self) ! iciobject *self; { (void)ICStop(self->inst); --- 484,488 ---- static void ! ici_dealloc(iciobject *self) { (void)ICStop(self->inst); *************** *** 526,532 **** static PyObject * ! ici_getattr(self, name) ! iciobject *self; ! char *name; { return Py_FindMethod(ici_methods, (PyObject *)self, name); --- 491,495 ---- static PyObject * ! ici_getattr(iciobject *self, char *name) { return Py_FindMethod(ici_methods, (PyObject *)self, name); *************** *** 571,577 **** static PyObject * ! ic_ICStart(self, args) ! PyObject *self; /* Not used */ ! PyObject *args; { OSType creator; --- 534,538 ---- static PyObject * ! ic_ICStart(PyObject *self, PyObject *args) { OSType creator; *************** *** 598,602 **** void ! initicglue() { PyObject *m, *d; --- 559,563 ---- void ! initicglue(void) { PyObject *m, *d; From jackjansen@users.sourceforge.net Tue Sep 4 23:25:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:25:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf _CFmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv16005/Python/Mac/Modules/cf Modified Files: _CFmodule.c Log Message: Shut up a few more gcc warnings. Index: _CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/_CFmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _CFmodule.c 2001/09/04 22:19:05 1.2 --- _CFmodule.c 2001/09/04 22:25:43 1.3 *************** *** 273,277 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself); return PyString_FromString(buf); } --- 273,277 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned long)self, (unsigned long)self->ob_itself); return PyString_FromString(buf); } From jackjansen@users.sourceforge.net Tue Sep 4 23:25:49 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:25:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv16045/Python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: Shut up a few more gcc warnings. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** cfsupport.py 2001/09/04 22:19:18 1.9 --- cfsupport.py 2001/09/04 22:25:47 1.10 *************** *** 191,195 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 191,195 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned long)self, (unsigned long)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() From jackjansen@users.sourceforge.net Tue Sep 4 23:29:33 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 04 Sep 2001 15:29:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules gestaltmodule.c,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16694 Modified Files: gestaltmodule.c Log Message: Added prototypes to shut gcc -Wstrict-prototypes up. Index: gestaltmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/gestaltmodule.c,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** gestaltmodule.c 2001/05/12 22:46:35 1.7 --- gestaltmodule.c 2001/09/04 22:29:31 1.8 *************** *** 36,42 **** static PyObject * ! gestalt_gestalt(self, args) ! PyObject *self; ! PyObject *args; { OSErr iErr; --- 36,40 ---- static PyObject * ! gestalt_gestalt(PyObject *self, PyObject *args) { OSErr iErr; *************** *** 64,68 **** void ! initgestalt() { Py_InitModule("gestalt", gestalt_methods); --- 62,66 ---- void ! initgestalt(void) { Py_InitModule("gestalt", gestalt_methods); From gvanrossum@users.sourceforge.net Tue Sep 4 23:38:17 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 15:38:17 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0251.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv18117 Modified Files: pep-0251.txt Log Message: Insert a3 between a2 and a4. Index: pep-0251.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0251.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0251.txt 2001/08/14 16:59:58 1.4 --- pep-0251.txt 2001/09/04 22:38:15 1.5 *************** *** 31,35 **** 14-Nov-2001: 2.2b2 10-Oct-2001: 2.2b1 ! 19-Sep-2001: 2.2a3 (new! a third alpha) 22-Aug-2001: 2.2a2 18-Jul-2001: 2.2a1 --- 31,36 ---- 14-Nov-2001: 2.2b2 10-Oct-2001: 2.2b1 ! 19-Sep-2001: 2.2a4 ! 7-Sep-1001: 2.2a3 (new! an extra alpha to release more new stuff) 22-Aug-2001: 2.2a2 18-Jul-2001: 2.2a1 From tim_one@users.sourceforge.net Wed Sep 5 00:17:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 16:17:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mathmodule.c,2.60,2.61 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv26643/python/Modules Modified Files: mathmodule.c Log Message: Mechanical fiddling to make this easier to work with in my editor. Repaired the ldexp docstring (said the name of the func was "ldexp_doc"). Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.60 retrieving revision 2.61 diff -C2 -d -r2.60 -r2.61 *** mathmodule.c 2001/08/07 22:10:00 2.60 --- mathmodule.c 2001/09/04 23:17:42 2.61 *************** *** 159,163 **** "tanh(x)\n\nReturn the hyperbolic tangent of x.") - static PyObject * math_frexp(PyObject *self, PyObject *args) --- 159,162 ---- *************** *** 177,186 **** static char math_frexp_doc [] = ! "frexp(x)\n\ ! \n\ ! Return the mantissa and exponent of x, as pair (m, e).\n\ ! m is a float and e is an int, such that x = m * 2.**e.\n\ ! If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."; ! static PyObject * --- 176,184 ---- static char math_frexp_doc [] = ! "frexp(x)\n" ! "\n" ! "Return the mantissa and exponent of x, as pair (m, e).\n" ! "m is a float and e is an int, such that x = m * 2.**e.\n" ! "If x is 0, m and e are both 0. Else 0.5 <= abs(m) < 1.0."; static PyObject * *************** *** 203,210 **** static char math_ldexp_doc [] = ! "ldexp_doc(x, i)\n\ ! \n\ ! Return x * (2**i)."; ! static PyObject * --- 201,205 ---- static char math_ldexp_doc [] = ! "ldexp(x, i) -> x * (2**i)"; static PyObject * *************** *** 232,240 **** static char math_modf_doc [] = ! "modf(x)\n\ ! \n\ ! Return the fractional and integer parts of x. Both results carry the sign\n\ ! of x. The integer part is returned as a real."; ! static PyMethodDef math_methods[] = { --- 227,234 ---- static char math_modf_doc [] = ! "modf(x)\n" ! "\n" ! "Return the fractional and integer parts of x. Both results carry the sign\n" ! "of x. The integer part is returned as a real."; static PyMethodDef math_methods[] = { *************** *** 267,272 **** static char module_doc [] = ! "This module is always available. It provides access to the\n\ ! mathematical functions defined by the C standard."; DL_EXPORT(void) --- 261,266 ---- static char module_doc [] = ! "This module is always available. It provides access to the\n" ! "mathematical functions defined by the C standard."; DL_EXPORT(void) From tim_one@users.sourceforge.net Wed Sep 5 01:53:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 17:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.228,1.229 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17117/python/Misc Modified Files: NEWS Log Message: Return reasonable results for math.log(long) and math.log10(long) (we were getting Infs, NaNs, or nonsense in 2.1 and before; in yesterday's CVS we were getting OverflowError; but these functions always make good sense for positive arguments, no matter how large). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.228 retrieving revision 1.229 diff -C2 -d -r1.228 -r1.229 *** NEWS 2001/09/04 22:08:56 1.228 --- NEWS 2001/09/05 00:53:45 1.229 *************** *** 82,85 **** --- 82,88 ---- Library + - math.log and math.log10 now return sensible results for even huge + long arguments. For example, math.log10(10 ** 10000) ~= 10000.0. + - A new function, imp.lock_held(), returns 1 when the import lock is currently held. See the docs for the imp module. From tim_one@users.sourceforge.net Wed Sep 5 01:53:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 17:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_long.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17117/python/Lib/test Modified Files: test_long.py Log Message: Return reasonable results for math.log(long) and math.log10(long) (we were getting Infs, NaNs, or nonsense in 2.1 and before; in yesterday's CVS we were getting OverflowError; but these functions always make good sense for positive arguments, no matter how large). Index: test_long.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_long.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_long.py 2001/09/04 19:48:01 1.14 --- test_long.py 2001/09/05 00:53:44 1.15 *************** *** 1,3 **** ! from test_support import verify, verbose, TestFailed from string import join from random import random, randint --- 1,3 ---- ! from test_support import verify, verbose, TestFailed, fcmp from string import join from random import random, randint *************** *** 354,360 **** "1. ** huge", "huge ** 1.", "1. ** mhuge", "mhuge ** 1.", "math.sin(huge)", "math.sin(mhuge)", - "math.log(huge)", "math.log(mhuge)", # should do better "math.sqrt(huge)", "math.sqrt(mhuge)", # should do better - "math.log10(huge)", "math.log10(mhuge)", # should do better "math.floor(huge)", "math.floor(mhuge)"]: --- 354,358 ---- *************** *** 365,368 **** --- 363,401 ---- else: raise TestFailed("expected OverflowError from %s" % test) + + # ---------------------------------------------- test huge log and log10 + + def test_logs(): + import math + + if verbose: + print "log and log10" + + LOG10E = math.log10(math.e) + + for exp in range(10) + [100, 1000, 10000]: + value = 10 ** exp + log10 = math.log10(value) + verify(fcmp(log10, exp) == 0) + + # log10(value) == exp, so log(value) == log10(value)/log10(e) == + # exp/LOG10E + expected = exp / LOG10E + log = math.log(value) + verify(fcmp(log, expected) == 0) + + for bad in -(1L << 10000), -2L, 0L: + try: + math.log(bad) + raise TestFailed("expected ValueError from log(<= 0)") + except ValueError: + pass + + try: + math.log10(bad) + raise TestFailed("expected ValueError from log10(<= 0)") + except ValueError: + pass + # ---------------------------------------------------------------- do it *************** *** 373,374 **** --- 406,408 ---- test_auto_overflow() test_float_overflow() + test_logs() From tim_one@users.sourceforge.net Wed Sep 5 01:53:47 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 17:53:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mathmodule.c,2.61,2.62 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17117/python/Modules Modified Files: mathmodule.c Log Message: Return reasonable results for math.log(long) and math.log10(long) (we were getting Infs, NaNs, or nonsense in 2.1 and before; in yesterday's CVS we were getting OverflowError; but these functions always make good sense for positive arguments, no matter how large). Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.61 retrieving revision 2.62 diff -C2 -d -r2.61 -r2.62 *** mathmodule.c 2001/09/04 23:17:42 2.61 --- mathmodule.c 2001/09/05 00:53:45 2.62 *************** *** 2,5 **** --- 2,6 ---- #include "Python.h" + #include "longintrepr.h" #ifndef _MSC_VER *************** *** 137,144 **** FUNC2(hypot, hypot, "hypot(x,y)\n\nReturn the Euclidean distance, sqrt(x*x + y*y).") - FUNC1(log, log, - "log(x)\n\nReturn the natural logarithm of x.") - FUNC1(log10, log10, - "log10(x)\n\nReturn the base-10 logarithm of x.") #ifdef MPW_3_1 /* This hack is needed for MPW 3.1 but not for 3.2 ... */ FUNC2(pow, power, --- 138,141 ---- *************** *** 231,234 **** --- 228,294 ---- "Return the fractional and integer parts of x. Both results carry the sign\n" "of x. The integer part is returned as a real."; + + /* A decent logarithm is easy to compute even for huge longs, but libm can't + do that by itself -- loghelper can. func is log or log10, and name is + "log" or "log10". Note that overflow isn't possible: a long can contain + no more than INT_MAX * SHIFT bits, so has value certainly less than + 2**(2**64 * 2**16) == 2**2**80, and log2 of that is 2**80, which is + small enough to fit in an IEEE single. log and log10 are even smaller. + */ + + static PyObject* + loghelper(PyObject* args, double (*func)(double), char *name) + { + PyObject *arg; + char format[16]; + + /* See whether this is a long. */ + format[0] = 'O'; + format[1] = ':'; + strcpy(format + 2, name); + if (! PyArg_ParseTuple(args, format, &arg)) + return NULL; + + /* If it is long, do it ourselves. */ + if (PyLong_Check(arg)) { + double x; + int e; + x = _PyLong_AsScaledDouble(arg, &e); + if (x <= 0.0) { + PyErr_SetString(PyExc_ValueError, + "math domain error"); + return NULL; + } + /* Value is ~= x * 2**(e*SHIFT), so the log ~= + log(x) + log(2) * e * SHIFT. + CAUTION: e*SHIFT may overflow using int arithmetic, + so force use of double. */ + x = func(x) + func(2.0) * (double)e * (double)SHIFT; + return PyFloat_FromDouble(x); + } + + /* Else let libm handle it by itself. */ + format[0] = 'd'; + return math_1(args, func, format); + } + + static PyObject * + math_log(PyObject *self, PyObject *args) + { + return loghelper(args, log, "log"); + } + + static char math_log_doc[] = + "log(x) -> the natural logarithm (base e) of x."; + + static PyObject * + math_log10(PyObject *self, PyObject *args) + { + return loghelper(args, log10, "log10"); + } + + static char math_log10_doc[] = + "log10(x) -> the base 10 logarithm of x."; + static PyMethodDef math_methods[] = { From gvanrossum@users.sourceforge.net Wed Sep 5 03:26:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 19:26:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_repr.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3574 Modified Files: test_repr.py Log Message: Add a test for the final branch in repr.Repr.repr1(), which deals with a default repr() that's longer than 20 characters. Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_repr.py 2001/08/24 18:37:32 1.3 --- test_repr.py 2001/09/05 02:26:26 1.4 *************** *** 79,82 **** --- 79,87 ---- eq(r(i3), (""%id(i3))) + s = r(ClassWithFailingRepr) + self.failUnless(s.startswith("")) + self.failUnless(s.find("...") == 8) + def test_file(self): fp = open(unittest.__file__) From gvanrossum@users.sourceforge.net Wed Sep 5 03:27:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 04 Sep 2001 19:27:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib repr.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3714 Modified Files: repr.py Log Message: Another / that should be a // (previously not caught because of incomplete coverage of the test suite). Index: repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/repr.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** repr.py 2001/09/04 19:14:14 1.12 --- repr.py 2001/09/05 02:27:04 1.13 *************** *** 24,28 **** s = `x` if len(s) > self.maxother: ! i = max(0, (self.maxother-3)/2) j = max(0, self.maxother-3-i) s = s[:i] + '...' + s[len(s)-j:] --- 24,28 ---- s = `x` if len(s) > self.maxother: ! i = max(0, (self.maxother-3)//2) j = max(0, self.maxother-3-i) s = s[:i] + '...' + s[len(s)-j:] From tim_one@users.sourceforge.net Wed Sep 5 05:33:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 21:33:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules mathmodule.c,2.62,2.63 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28828/python/Modules Modified Files: mathmodule.c Log Message: loghelper(): Try to nudge the compiler into doing mults in an order that minimizes roundoff error. Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.62 retrieving revision 2.63 diff -C2 -d -r2.62 -r2.63 *** mathmodule.c 2001/09/05 00:53:45 2.62 --- mathmodule.c 2001/09/05 04:33:11 2.63 *************** *** 264,268 **** CAUTION: e*SHIFT may overflow using int arithmetic, so force use of double. */ ! x = func(x) + func(2.0) * (double)e * (double)SHIFT; return PyFloat_FromDouble(x); } --- 264,268 ---- CAUTION: e*SHIFT may overflow using int arithmetic, so force use of double. */ ! x = func(x) + (e * (double)SHIFT) * func(2.0); return PyFloat_FromDouble(x); } From tim_one@users.sourceforge.net Wed Sep 5 06:38:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 22:38:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv7743/python/Include Modified Files: pyport.h Log Message: Try to recover from that glibc's ldexp apparently doesn't set errno on overflow. Needs testing on Linux (test_long.py and test_long_future.py especially). Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -d -r2.33 -r2.34 *** pyport.h 2001/08/29 21:37:09 2.33 --- pyport.h 2001/09/05 05:38:10 2.34 *************** *** 231,234 **** --- 231,254 ---- #define Py_IS_INFINITY(X) ((X) && (X)*0.5 == (X)) + /* Py_OVERFLOWED(X) + * Return 1 iff a libm function overflowed. Set errno to 0 before calling + * a libm function, and invoke this macro after, passing the function + * result. + * Caution: + * This isn't reliable. C99 no longer requires libm to set errno under + * any exceptional condition, but does require +- HUGE_VAL return + * values on overflow. A 754 box *probably* maps HUGE_VAL to a + * double infinity, and we're cool if that's so, unless the input + * was an infinity and an infinity is the expected result. A C89 + * system sets errno to ERANGE, so we check for that too. We're + * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or + * if the returned result is a NaN, or if a C89 box returns HUGE_VAL + * in non-overflow cases. + * X is evaluated more than once. + */ + #define Py_OVERFLOWED(X) ((X) != 0.0 && (errno == ERANGE || \ + (X) == HUGE_VAL || \ + (X) == -HUGE_VAL)) + /************************************************************************** Prototypes that are missing from the standard include files on some systems From tim_one@users.sourceforge.net Wed Sep 5 06:38:12 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 22:38:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.100,1.101 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7743/python/Objects Modified Files: longobject.c Log Message: Try to recover from that glibc's ldexp apparently doesn't set errno on overflow. Needs testing on Linux (test_long.py and test_long_future.py especially). Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -d -r1.100 -r1.101 *** longobject.c 2001/09/04 06:17:36 1.100 --- longobject.c 2001/09/05 05:38:10 1.101 *************** *** 546,550 **** errno = 0; x = ldexp(x, e * SHIFT); ! if (errno == ERANGE) goto overflow; return x; --- 546,550 ---- errno = 0; x = ldexp(x, e * SHIFT); ! if (Py_OVERFLOWED(x)) goto overflow; return x; *************** *** 1608,1612 **** errno = 0; ad = ldexp(ad, aexp * SHIFT); ! if (ad != 0 && errno == ERANGE) /* ignore underflow to 0.0 */ goto overflow; return PyFloat_FromDouble(ad); --- 1608,1612 ---- errno = 0; ad = ldexp(ad, aexp * SHIFT); ! if (Py_OVERFLOWED(ad)) /* ignore underflow to 0.0 */ goto overflow; return PyFloat_FromDouble(ad); From tim_one@users.sourceforge.net Wed Sep 5 07:24:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 23:24:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.34,2.35 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17904/python/Include Modified Files: pyport.h Log Message: Repair indentation. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -d -r2.34 -r2.35 *** pyport.h 2001/09/05 05:38:10 2.34 --- pyport.h 2001/09/05 06:24:24 2.35 *************** *** 237,245 **** * Caution: * This isn't reliable. C99 no longer requires libm to set errno under ! * any exceptional condition, but does require +- HUGE_VAL return ! * values on overflow. A 754 box *probably* maps HUGE_VAL to a ! * double infinity, and we're cool if that's so, unless the input ! * was an infinity and an infinity is the expected result. A C89 ! * system sets errno to ERANGE, so we check for that too. We're * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or * if the returned result is a NaN, or if a C89 box returns HUGE_VAL --- 237,245 ---- * Caution: * This isn't reliable. C99 no longer requires libm to set errno under ! * any exceptional condition, but does require +- HUGE_VAL return ! * values on overflow. A 754 box *probably* maps HUGE_VAL to a ! * double infinity, and we're cool if that's so, unless the input ! * was an infinity and an infinity is the expected result. A C89 ! * system sets errno to ERANGE, so we check for that too. We're * out of luck if a C99 754 box doesn't map HUGE_VAL to +Inf, or * if the returned result is a NaN, or if a C89 box returns HUGE_VAL From tim_one@users.sourceforge.net Wed Sep 5 07:25:00 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 04 Sep 2001 23:25:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.93,2.94 intobject.c,2.71,2.72 longobject.c,1.101,1.102 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17986/python/Objects Modified Files: floatobject.c intobject.c longobject.c Log Message: Make the error msgs in our pow() implementations consistent. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.93 retrieving revision 2.94 diff -C2 -d -r2.93 -r2.94 *** floatobject.c 2001/09/04 05:14:19 2.93 --- floatobject.c 2001/09/05 06:24:58 2.94 *************** *** 496,501 **** if ((PyObject *)z != Py_None) { ! PyErr_SetString(PyExc_TypeError, ! "3rd argument to floating pow() must be None"); return NULL; } --- 496,501 ---- if ((PyObject *)z != Py_None) { ! PyErr_SetString(PyExc_TypeError, "pow() 3rd argument not " ! "allowed unless all other arguments are integers"); return NULL; } Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -d -r2.71 -r2.72 *** intobject.c 2001/09/04 06:17:36 2.71 --- intobject.c 2001/09/05 06:24:58 2.72 *************** *** 590,595 **** if (iw < 0) { if ((PyObject *)z != Py_None) { ! PyErr_SetString(PyExc_TypeError, "integer pow() arg " ! "3 must not be specified when arg 2 is < 0"); return NULL; } --- 590,595 ---- if (iw < 0) { if ((PyObject *)z != Py_None) { ! PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " ! "cannot be negative when 3rd argument specified"); return NULL; } *************** *** 604,608 **** if (iz == 0) { PyErr_SetString(PyExc_ValueError, ! "pow() arg 3 cannot be 0"); return NULL; } --- 604,608 ---- if (iz == 0) { PyErr_SetString(PyExc_ValueError, ! "pow() 3rd argument cannot be 0"); return NULL; } Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.101 retrieving revision 1.102 diff -C2 -d -r1.101 -r1.102 *** longobject.c 2001/09/05 05:38:10 1.101 --- longobject.c 2001/09/05 06:24:58 1.102 *************** *** 1686,1690 **** return Py_NotImplemented; } ! size_b = b->ob_size; if (size_b < 0) { --- 1686,1697 ---- return Py_NotImplemented; } ! ! if (c != Py_None && ((PyLongObject *)c)->ob_size == 0) { ! PyErr_SetString(PyExc_ValueError, ! "pow() 3rd argument cannot be 0"); ! z = NULL; ! goto error; ! } ! size_b = b->ob_size; if (size_b < 0) { *************** *** 1693,1698 **** Py_DECREF(c); if (x != Py_None) { ! PyErr_SetString(PyExc_TypeError, "integer pow() arg " ! "3 must not be specified when arg 2 is < 0"); return NULL; } --- 1700,1705 ---- Py_DECREF(c); if (x != Py_None) { ! PyErr_SetString(PyExc_TypeError, "pow() 2nd argument " ! "cannot be negative when 3rd argument specified"); return NULL; } From loewis@users.sourceforge.net Wed Sep 5 09:22:36 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 01:22:36 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.249,1.250 configure,1.241,1.242 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv13709 Modified Files: configure.in configure Log Message: Check for RFC 2553 API. Fixes bug #454493. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.249 retrieving revision 1.250 diff -C2 -d -r1.249 -r1.250 *** configure.in 2001/08/29 23:44:38 1.249 --- configure.in 2001/09/05 08:22:34 1.250 *************** *** 969,973 **** # Check for enable-ipv6 ! AC_MSG_CHECKING([whether to enable ipv6]) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Enable ipv6 (with ipv4) support --- 969,973 ---- # Check for enable-ipv6 ! AC_MSG_CHECKING([if --enable-ipv6 is specified]) AC_ARG_ENABLE(ipv6, [ --enable-ipv6 Enable ipv6 (with ipv4) support *************** *** 984,987 **** --- 984,989 ---- esac ], + [ + dnl the check does not work on cross compilation case... AC_TRY_RUN([ /* AF_INET6 available check */ #include *************** *** 996,1000 **** ], AC_MSG_RESULT(yes) - AC_DEFINE(ENABLE_IPV6) ipv6=yes, AC_MSG_RESULT(no) --- 998,1001 ---- *************** *** 1002,1006 **** AC_MSG_RESULT(no) ipv6=no ! )) ipv6type=unknown --- 1003,1024 ---- AC_MSG_RESULT(no) ipv6=no ! ) ! ! if test "$ipv6" = "yes"; then ! AC_MSG_CHECKING(if RFC2553 API is available) ! AC_TRY_COMPILE([#include ! #include ], ! [struct sockaddr_in6 x; ! x.sin6_scope_id;], ! AC_MSG_RESULT(yes) ! ipv6=yes, ! AC_MSG_RESULT(no, IPv6 disabled) ! ipv6=no) ! fi ! ! if test "$ipv6" = "yes"; then ! AC_DEFINE(ENABLE_IPV6) ! fi ! ]) ipv6type=unknown Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.241 retrieving revision 1.242 diff -C2 -d -r1.241 -r1.242 *** configure 2001/08/29 23:58:47 1.241 --- configure 2001/09/05 08:22:34 1.242 *************** *** 2306,2310 **** #include "confdefs.h" #include - #include main() { --- 2306,2309 ---- *************** *** 2315,2319 **** } EOF [...3633 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 7072,7076 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7075: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7093,7097 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7096: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then From loewis@users.sourceforge.net Wed Sep 5 09:36:54 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 01:36:54 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.250,1.251 configure,1.242,1.243 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17326 Modified Files: configure.in configure Log Message: Use -fPIC instead of -fpic for gcc on HP/UX. Fixes bug #433234. Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.250 retrieving revision 1.251 diff -C2 -d -r1.250 -r1.251 *** configure.in 2001/09/05 08:22:34 1.250 --- configure.in 2001/09/05 08:36:51 1.251 *************** *** 712,716 **** fi;; hp*|HP*) if test "$GCC" = yes; ! then CCSHARED="-fpic"; else CCSHARED="+z"; fi;; --- 712,716 ---- fi;; hp*|HP*) if test "$GCC" = yes; ! then CCSHARED="-fPIC"; else CCSHARED="+z"; fi;; Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.242 retrieving revision 1.243 diff -C2 -d -r1.242 -r1.243 *** configure 2001/09/05 08:22:34 1.242 --- configure 2001/09/05 08:36:52 1.243 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.249 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.250 # Guess values for system-dependent variables and create Makefiles. *************** *** 3088,3092 **** fi;; hp*|HP*) if test "$GCC" = yes; ! then CCSHARED="-fpic"; else CCSHARED="+z"; fi;; --- 3088,3092 ---- fi;; hp*|HP*) if test "$GCC" = yes; ! then CCSHARED="-fPIC"; else CCSHARED="+z"; fi;; From jackjansen@users.sourceforge.net Wed Sep 5 11:27:50 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:27:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen bgenBuffer.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv10847/python/Tools/bgen/bgen Modified Files: bgenBuffer.py Log Message: Only output the buffer size error label if it is used. Shuts up another couple of gcc warnings. Index: bgenBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenBuffer.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** bgenBuffer.py 1999/09/30 14:15:14 1.5 --- bgenBuffer.py 2001/09/05 10:27:48 1.6 *************** *** 37,40 **** --- 37,41 ---- self.sizetype = sizetype self.sizeformat = sizeformat or type2format[sizetype] + self.label_needed = 0 def declare(self, name): *************** *** 68,71 **** --- 69,73 ---- self.size) Output("goto %s__error__;", name) + self.label_needed = 1 OutRbrace() self.transferSize(name) *************** *** 84,90 **** def cleanup(self, name): ! DedentLevel() ! Output(" %s__error__: ;", name) ! IndentLevel() --- 86,93 ---- def cleanup(self, name): ! if self.label_needed: ! DedentLevel() ! Output(" %s__error__: ;", name) ! IndentLevel() From jackjansen@users.sourceforge.net Wed Sep 5 11:27:55 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:27:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/bgen/bgen bgenHeapBuffer.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/bgen/bgen In directory usw-pr-cvs1:/tmp/cvs-serv10865/python/Tools/bgen/bgen Modified Files: bgenHeapBuffer.py Log Message: Only output the buffer size error label if it is used. Shuts up another couple of gcc warnings. Index: bgenHeapBuffer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/bgen/bgen/bgenHeapBuffer.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** bgenHeapBuffer.py 1995/03/10 14:37:52 1.2 --- bgenHeapBuffer.py 2001/09/05 10:27:53 1.3 *************** *** 25,28 **** --- 25,29 ---- Output('PyErr_NoMemory();') Output("goto %s__error__;", name) + self.label_needed = 1 OutRbrace() Output("%s__len__ = %s__in_len__;", name, name) From jackjansen@users.sourceforge.net Wed Sep 5 11:28:51 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:28:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/snd _Sndmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/snd In directory usw-pr-cvs1:/tmp/cvs-serv11081/python/Mac/Modules/snd Modified Files: _Sndmodule.c Log Message: Shut up many more gcc warnings. Index: _Sndmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/snd/_Sndmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Sndmodule.c 2001/09/04 22:17:10 1.2 --- _Sndmodule.c 2001/09/05 10:28:49 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 23,28 **** #include #endif - /* Create a SndCommand object (an (int, int, int) tuple) */ static PyObject * --- 27,32 ---- #include #endif + #if !TARGET_API_MAC_CARBON /* Create a SndCommand object (an (int, int, int) tuple) */ static PyObject * *************** *** 31,34 **** --- 35,39 ---- return Py_BuildValue("hhl", pc->cmd, pc->param1, pc->param2); } + #endif /* Convert a SndCommand argument */ *************** *** 81,94 **** return (PyObject *)it; } - static int SndCh_Convert(PyObject *v, SndChannelPtr *p_itself) - { - if (!SndCh_Check(v)) - { - PyErr_SetString(PyExc_TypeError, "SndChannel required"); - return 0; - } - *p_itself = ((SndChannelObject *)v)->ob_itself; - return 1; - } static void SndCh_dealloc(SndChannelObject *self) --- 86,89 ---- *************** *** 234,238 **** _res = Py_BuildValue("s#", (char *)&theStatus__out__, (int)sizeof(SCStatus)); - theStatus__error__: ; return _res; } --- 229,232 ---- *************** *** 373,377 **** return (PyObject *)it; } ! static SPBObj_Convert(PyObject *v, SPBPtr *p_itself) { if (!SPBObj_Check(v)) --- 367,371 ---- return (PyObject *)it; } ! static int SPBObj_Convert(PyObject *v, SPBPtr *p_itself) { if (!SPBObj_Check(v)) *************** *** 475,479 **** { PyObject *_res = NULL; ! return SPBObj_New(); } --- 469,473 ---- { PyObject *_res = NULL; ! _res = SPBObj_New(); return _res; } *************** *** 573,577 **** _res = Py_BuildValue("s#", (char *)&theStatus__out__, (int)sizeof(SMStatus)); - theStatus__error__: ; return _res; } --- 567,570 ---- *************** *** 897,901 **** _res = Py_BuildValue("s#", (char *)&cp__out__, (int)sizeof(CompressionInfo)); - cp__error__: ; return _res; } --- 890,893 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:28:55 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:28:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/snd sndsupport.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/snd In directory usw-pr-cvs1:/tmp/cvs-serv11111/python/Mac/Modules/snd Modified Files: sndsupport.py Log Message: Shut up many more gcc warnings. Index: sndsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/snd/sndsupport.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** sndsupport.py 2001/08/23 13:51:17 1.17 --- sndsupport.py 2001/09/05 10:28:53 1.18 *************** *** 96,100 **** includestuff = includestuff + """ ! /* Create a SndCommand object (an (int, int, int) tuple) */ static PyObject * --- 96,100 ---- includestuff = includestuff + """ ! #if !TARGET_API_MAC_CARBON /* Create a SndCommand object (an (int, int, int) tuple) */ static PyObject * *************** *** 103,106 **** --- 103,107 ---- return Py_BuildValue("hhl", pc->cmd, pc->param1, pc->param2); } + #endif /* Convert a SndCommand argument */ *************** *** 231,234 **** --- 232,238 ---- Output("SndDisposeChannel(%s, 1);", itselfname) + def outputConvert(self): + pass # Not needed + # *************** *** 271,275 **** def outputConvert(self): ! Output("%s%s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype) OutLbrace() self.outputCheckConvertArg() --- 275,279 ---- def outputConvert(self): ! Output("%sint %s_Convert(PyObject *v, %s *p_itself)", self.static, self.prefix, self.itselftype) OutLbrace() self.outputCheckConvertArg() *************** *** 334,338 **** sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr') spbobject = SpbObjectDefinition('SPB', 'SPBObj', 'SPBPtr') ! spbgenerator = ManualGenerator("SPB", "return SPBObj_New();") module = MacModule('_Snd', 'Snd', includestuff, finalstuff, initstuff) module.addobject(sndobject) --- 338,342 ---- sndobject = SndObjectDefinition('SndChannel', 'SndCh', 'SndChannelPtr') spbobject = SpbObjectDefinition('SPB', 'SPBObj', 'SPBPtr') ! spbgenerator = ManualGenerator("SPB", "_res = SPBObj_New(); return _res;") module = MacModule('_Snd', 'Snd', includestuff, finalstuff, initstuff) module.addobject(sndobject) From jackjansen@users.sourceforge.net Wed Sep 5 11:29:04 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd _Qdmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv11133/python/Mac/Modules/qd Modified Files: _Qdmodule.c Log Message: Shut up many more gcc warnings. Index: _Qdmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/_Qdmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Qdmodule.c 2001/09/04 22:17:56 1.2 --- _Qdmodule.c 2001/09/05 10:29:02 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 443,447 **** return NULL; cp = _self->ob_itself->baseAddr+from; ! return PyString_FromStringAndSize(cp, length); } --- 447,452 ---- return NULL; cp = _self->ob_itself->baseAddr+from; ! _res = PyString_FromStringAndSize(cp, length); ! return _res; } *************** *** 459,463 **** memcpy(cp, icp, length); Py_INCREF(Py_None); ! return Py_None; } --- 464,469 ---- memcpy(cp, icp, length); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } *************** *** 913,917 **** _res = Py_BuildValue("s#", (char *)&pnState__out__, (int)sizeof(PenState)); - pnState__error__: ; return _res; } --- 919,922 ---- *************** *** 3471,3475 **** _res = Py_BuildValue("s#", (char *)&thePat__out__, (int)sizeof(Pattern)); - thePat__error__: ; return _res; } --- 3476,3479 ---- *************** *** 4117,4121 **** _res = Py_BuildValue("s#", (char *)&arrow__out__, (int)sizeof(Cursor)); - arrow__error__: ; return _res; } --- 4121,4124 ---- *************** *** 4130,4134 **** _res = Py_BuildValue("s#", (char *)&dkGray__out__, (int)sizeof(Pattern)); - dkGray__error__: ; return _res; } --- 4133,4136 ---- *************** *** 4143,4147 **** _res = Py_BuildValue("s#", (char *)<Gray__out__, (int)sizeof(Pattern)); - ltGray__error__: ; return _res; } --- 4145,4148 ---- *************** *** 4156,4160 **** _res = Py_BuildValue("s#", (char *)&gray__out__, (int)sizeof(Pattern)); - gray__error__: ; return _res; } --- 4157,4160 ---- *************** *** 4169,4173 **** _res = Py_BuildValue("s#", (char *)&black__out__, (int)sizeof(Pattern)); - black__error__: ; return _res; } --- 4169,4172 ---- *************** *** 4182,4186 **** _res = Py_BuildValue("s#", (char *)&white__out__, (int)sizeof(Pattern)); - white__error__: ; return _res; } --- 4181,4184 ---- *************** *** 4449,4453 **** PyObject *_res = NULL; char *textBuf__in__; - int textBuf__len__; int textBuf__in_len__; short firstByte; --- 4447,4450 ---- *************** *** 4458,4461 **** --- 4455,4460 ---- &byteCount)) return NULL; + /* Fool compiler warnings */ + textBuf__in_len__ = textBuf__in_len__; MacDrawText(textBuf__in__, firstByte, *************** *** 4463,4467 **** Py_INCREF(Py_None); _res = Py_None; - textBuf__error__: ; return _res; } --- 4462,4465 ---- *************** *** 4500,4504 **** short _rv; char *textBuf__in__; - int textBuf__len__; int textBuf__in_len__; short firstByte; --- 4498,4501 ---- *************** *** 4509,4512 **** --- 4506,4511 ---- &byteCount)) return NULL; + /* Fool compiler warnings */ + textBuf__in_len__ = textBuf__in_len__; _rv = TextWidth(textBuf__in__, firstByte, *************** *** 4514,4518 **** _res = Py_BuildValue("h", _rv); - textBuf__error__: ; return _res; } --- 4513,4516 ---- *************** *** 4978,4982 **** PyObject *_res = NULL; char *textBuf__in__; - int textBuf__len__; int textBuf__in_len__; short firstByte; --- 4976,4979 ---- *************** *** 4987,4990 **** --- 4984,4989 ---- &byteCount)) return NULL; + /* Fool compiler warnings */ + textBuf__in_len__ = textBuf__in_len__; DrawText(textBuf__in__, firstByte, *************** *** 4992,4996 **** Py_INCREF(Py_None); _res = Py_None; - textBuf__error__: ; return _res; } --- 4991,4994 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:29:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd qdsupport.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv11192/python/Mac/Modules/qd Modified Files: qdsupport.py Log Message: Shut up many more gcc warnings. Index: qdsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/qdsupport.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** qdsupport.py 2001/08/23 13:50:22 1.34 --- qdsupport.py 2001/09/05 10:29:07 1.35 *************** *** 25,29 **** class TextThingieClass(FixedInputBufferType): def getargsCheck(self, name): ! pass TextThingie = TextThingieClass(None) --- 25,33 ---- class TextThingieClass(FixedInputBufferType): def getargsCheck(self, name): ! Output("/* Fool compiler warnings */") ! Output("%s__in_len__ = %s__in_len__;", name, name) ! ! def declareSize(self, name): ! Output("int %s__in_len__;", name) TextThingie = TextThingieClass(None) *************** *** 567,571 **** return NULL; cp = _self->ob_itself->baseAddr+from; ! return PyString_FromStringAndSize(cp, length); """ f = ManualGenerator("getdata", getdata_body) --- 571,576 ---- return NULL; cp = _self->ob_itself->baseAddr+from; ! _res = PyString_FromStringAndSize(cp, length); ! return _res; """ f = ManualGenerator("getdata", getdata_body) *************** *** 583,587 **** memcpy(cp, icp, length); Py_INCREF(Py_None); ! return Py_None; """ f = ManualGenerator("putdata", putdata_body) --- 588,593 ---- memcpy(cp, icp, length); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ f = ManualGenerator("putdata", putdata_body) From jackjansen@users.sourceforge.net Wed Sep 5 11:29:18 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/win _Winmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/win In directory usw-pr-cvs1:/tmp/cvs-serv11219/python/Mac/Modules/win Modified Files: _Winmodule.c Log Message: Shut up many more gcc warnings. Index: _Winmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/_Winmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Winmodule.c 2001/09/04 22:16:59 1.2 --- _Winmodule.c 2001/09/05 10:29:15 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 2126,2130 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 2130,2134 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 2644,2648 **** if ( !PyArg_ParseTuple(_args, "i", &ptr) ) return NULL; ! return WinObj_WhichWindow((WindowPtr)ptr); } --- 2648,2653 ---- if ( !PyArg_ParseTuple(_args, "i", &ptr) ) return NULL; ! _res = WinObj_WhichWindow((WindowPtr)ptr); ! return _res; } From jackjansen@users.sourceforge.net Wed Sep 5 11:29:23 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/te _TEmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/te In directory usw-pr-cvs1:/tmp/cvs-serv11247/python/Mac/Modules/te Modified Files: _TEmodule.c Log Message: Shut up many more gcc warnings. Index: _TEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/te/_TEmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _TEmodule.c 2001/09/04 22:17:03 1.2 --- _TEmodule.c 2001/09/05 10:29:21 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 114,118 **** Py_INCREF(Py_None); _res = Py_None; - text__error__: ; return _res; } --- 118,121 ---- *************** *** 252,256 **** Py_INCREF(Py_None); _res = Py_None; - text__error__: ; return _res; } --- 255,258 ---- *************** *** 532,536 **** Py_INCREF(Py_None); _res = Py_None; - text__error__: ; return _res; } --- 534,537 ---- *************** *** 874,878 **** Py_INCREF(Py_None); _res = Py_None; - text__error__: ; return _res; } --- 875,878 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:29:29 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res _Resmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv11277/python/Mac/Modules/res Modified Files: _Resmodule.c Log Message: Shut up many more gcc warnings. Index: _Resmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/_Resmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Resmodule.c 2001/09/04 22:17:16 1.2 --- _Resmodule.c 2001/09/05 10:29:27 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 395,399 **** PyObject *_res = NULL; ! return CtlObj_New((ControlHandle)_self->ob_itself); } --- 399,404 ---- PyObject *_res = NULL; ! _res = CtlObj_New((ControlHandle)_self->ob_itself); ! return _res; } *************** *** 403,407 **** PyObject *_res = NULL; ! return MenuObj_New((MenuHandle)_self->ob_itself); } --- 408,413 ---- PyObject *_res = NULL; ! _res = MenuObj_New((MenuHandle)_self->ob_itself); ! return _res; } *************** *** 1534,1538 **** } ! OptResObj_Convert(PyObject *v, Handle *p_itself) { PyObject *tmp; --- 1540,1544 ---- } ! int OptResObj_Convert(PyObject *v, Handle *p_itself) { PyObject *tmp; From jackjansen@users.sourceforge.net Wed Sep 5 11:29:40 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qt _Qtmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qt In directory usw-pr-cvs1:/tmp/cvs-serv11313/python/Mac/Modules/qt Modified Files: _Qtmodule.c Log Message: Shut up many more gcc warnings. Index: _Qtmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qt/_Qtmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Qtmodule.c 2001/09/04 22:17:37 1.2 --- _Qtmodule.c 2001/09/05 10:29:38 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:29:45 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qdoffs _Qdoffsmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qdoffs In directory usw-pr-cvs1:/tmp/cvs-serv11357/python/Mac/Modules/qdoffs Modified Files: _Qdoffsmodule.c Log Message: Shut up many more gcc warnings. Index: _Qdoffsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qdoffs/_Qdoffsmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Qdoffsmodule.c 2001/09/04 22:17:41 1.2 --- _Qdoffsmodule.c 2001/09/05 10:29:43 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 504,508 **** return NULL; cp = GetPixBaseAddr(pm)+from; ! return PyString_FromStringAndSize(cp, length); } --- 508,513 ---- return NULL; cp = GetPixBaseAddr(pm)+from; ! _res = PyString_FromStringAndSize(cp, length); ! return _res; } *************** *** 521,525 **** memcpy(cp, icp, length); Py_INCREF(Py_None); ! return Py_None; } --- 526,531 ---- memcpy(cp, icp, length); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } From jackjansen@users.sourceforge.net Wed Sep 5 11:29:51 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/mlte _Mltemodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/mlte In directory usw-pr-cvs1:/tmp/cvs-serv11384/python/Mac/Modules/mlte Modified Files: _Mltemodule.c Log Message: Shut up many more gcc warnings. Index: _Mltemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/mlte/_Mltemodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _Mltemodule.c 2001/09/04 22:18:01 1.3 --- _Mltemodule.c 2001/09/05 10:29:49 1.4 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 684,688 **** Py_INCREF(Py_None); _res = Py_None; - iDataPtr__error__: ; return _res; } --- 688,691 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:29:59 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:29:59 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/menu _Menumodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/menu In directory usw-pr-cvs1:/tmp/cvs-serv11414/python/Mac/Modules/menu Modified Files: _Menumodule.c Log Message: Shut up many more gcc warnings. Index: _Menumodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/menu/_Menumodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Menumodule.c 2001/09/04 22:18:12 1.2 --- _Menumodule.c 2001/09/05 10:29:57 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:30:04 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/list _Listmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/list In directory usw-pr-cvs1:/tmp/cvs-serv11456/python/Mac/Modules/list Modified Files: _Listmodule.c Log Message: Shut up many more gcc warnings. Index: _Listmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/list/_Listmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Listmodule.c 2001/09/04 22:18:17 1.2 --- _Listmodule.c 2001/09/05 10:30:02 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 362,366 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 366,369 ---- *************** *** 440,444 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 443,446 ---- *************** *** 930,934 **** l = (ListObject *)ListObj_New(as_List(h)); l->ob_must_be_disposed = 0; ! return Py_BuildValue("O", l); } --- 932,937 ---- l = (ListObject *)ListObj_New(as_List(h)); l->ob_must_be_disposed = 0; ! _res = Py_BuildValue("O", l); ! return _res; } From jackjansen@users.sourceforge.net Wed Sep 5 11:30:11 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/icn _Icnmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/icn In directory usw-pr-cvs1:/tmp/cvs-serv11551/python/Mac/Modules/icn Modified Files: _Icnmodule.c Log Message: Shut up many more gcc warnings. Index: _Icnmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/icn/_Icnmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Icnmodule.c 2001/08/23 14:00:41 1.1 --- _Icnmodule.c 2001/09/05 10:30:09 1.2 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:30:15 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/help _Helpmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/help In directory usw-pr-cvs1:/tmp/cvs-serv11592/python/Mac/Modules/help Modified Files: _Helpmodule.c Log Message: Shut up many more gcc warnings. Index: _Helpmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/help/_Helpmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Helpmodule.c 2001/08/23 14:00:46 1.1 --- _Helpmodule.c 2001/09/05 10:30:13 1.2 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:30:22 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/evt _Evtmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/evt In directory usw-pr-cvs1:/tmp/cvs-serv11609/python/Mac/Modules/evt Modified Files: _Evtmodule.c Log Message: Shut up many more gcc warnings. Index: _Evtmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/evt/_Evtmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Evtmodule.c 2001/08/23 14:01:03 1.1 --- _Evtmodule.c 2001/09/05 10:30:20 1.2 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 107,111 **** _res = Py_BuildValue("s#", (char *)&theKeys__out__, (int)sizeof(KeyMap)); - theKeys__error__: ; return _res; } --- 111,114 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:30:27 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/fm _Fmmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/fm In directory usw-pr-cvs1:/tmp/cvs-serv11668/python/Mac/Modules/fm Modified Files: _Fmmodule.c Log Message: Shut up many more gcc warnings. Index: _Fmmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/fm/_Fmmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Fmmodule.c 2001/08/23 14:00:56 1.1 --- _Fmmodule.c 2001/09/05 10:30:25 1.2 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:30:34 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/dlg _Dlgmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/dlg In directory usw-pr-cvs1:/tmp/cvs-serv11691/python/Mac/Modules/dlg Modified Files: _Dlgmodule.c Log Message: Shut up many more gcc warnings. Index: _Dlgmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/dlg/_Dlgmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Dlgmodule.c 2001/09/04 22:18:41 1.2 --- _Dlgmodule.c 2001/09/05 10:30:32 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:30:42 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/drag _Dragmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/drag In directory usw-pr-cvs1:/tmp/cvs-serv11740/python/Mac/Modules/drag Modified Files: _Dragmodule.c Log Message: Shut up many more gcc warnings. Index: _Dragmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/drag/_Dragmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Dragmodule.c 2001/09/04 22:18:31 1.2 --- _Dragmodule.c 2001/09/05 10:30:39 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 122,126 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 126,129 ---- *************** *** 151,155 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 154,157 ---- *************** *** 802,806 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; } --- 804,809 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } *************** *** 820,824 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; } --- 823,828 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } *************** *** 836,840 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; } --- 840,845 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } *************** *** 852,856 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; } --- 857,862 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; } From jackjansen@users.sourceforge.net Wed Sep 5 11:30:50 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl _Ctlmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv11785/python/Mac/Modules/ctl Modified Files: _Ctlmodule.c Log Message: Shut up many more gcc warnings. Index: _Ctlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/_Ctlmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Ctlmodule.c 2001/09/04 22:18:50 1.2 --- _Ctlmodule.c 2001/09/05 10:30:48 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 1677,1681 **** return PyMac_Error(_err); } ! return Py_BuildValue("O&", OptResObj_New, hdl); } --- 1681,1686 ---- return PyMac_Error(_err); } ! _res = Py_BuildValue("O&", OptResObj_New, hdl); ! return _res; } *************** *** 2527,2530 **** --- 2532,2536 ---- tracker = obj; Py_INCREF(tracker); + return 1; } *************** *** 2576,2580 **** return -1; /* And store the Python callback */ ! sprintf(keybuf, "%x", which); if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) return -1; --- 2582,2586 ---- return -1; /* And store the Python callback */ ! sprintf(keybuf, "%x", (unsigned)which); if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) return -1; *************** *** 2588,2592 **** PyObject *func, *rv; ! sprintf(keybuf, "%x", which); if ( self->ob_callbackdict == NULL || (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { --- 2594,2598 ---- PyObject *func, *rv; ! sprintf(keybuf, "%x", (unsigned)which); if ( self->ob_callbackdict == NULL || (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { From jackjansen@users.sourceforge.net Wed Sep 5 11:30:55 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:30:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cm _Cmmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cm In directory usw-pr-cvs1:/tmp/cvs-serv11820/python/Mac/Modules/cm Modified Files: _Cmmodule.c Log Message: Shut up many more gcc warnings. Index: _Cmmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cm/_Cmmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** _Cmmodule.c 2001/09/04 22:18:54 1.2 --- _Cmmodule.c 2001/09/05 10:30:53 1.3 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:31:03 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf _CFmodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv11851/python/Mac/Modules/cf Modified Files: _CFmodule.c Log Message: Shut up many more gcc warnings. Index: _CFmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/_CFmodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _CFmodule.c 2001/09/04 22:25:43 1.3 --- _CFmodule.c 2001/09/05 10:31:01 1.4 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 273,277 **** { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned long)self, (unsigned long)self->ob_itself); return PyString_FromString(buf); } --- 277,281 ---- { char buf[100]; ! sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 423,427 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 427,431 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 576,580 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 580,584 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 708,712 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 712,716 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 824,828 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 828,832 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 974,978 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 978,982 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 1097,1101 **** Py_INCREF(Py_None); _res = Py_None; - bytes__error__: ; return _res; } --- 1101,1104 ---- *************** *** 1119,1123 **** Py_INCREF(Py_None); _res = Py_None; - newBytes__error__: ; return _res; } --- 1122,1125 ---- *************** *** 1172,1176 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 1174,1178 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 1775,1779 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 1777,1781 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 2062,2066 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 2064,2068 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 2434,2438 **** { char buf[100]; ! sprintf(buf, "", self, self->ob_itself); return PyString_FromString(buf); } --- 2436,2440 ---- { char buf[100]; ! sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself); return PyString_FromString(buf); } *************** *** 2591,2595 **** _res = Py_BuildValue("O&", CFDataRefObj_New, _rv); - bytes__error__: ; return _res; } --- 2593,2596 ---- *************** *** 2612,2616 **** _res = Py_BuildValue("O&", CFDataRefObj_New, _rv); - bytes__error__: ; return _res; } --- 2613,2616 ---- *************** *** 2849,2853 **** _res = Py_BuildValue("O&", CFStringRefObj_New, _rv); - bytes__error__: ; return _res; } --- 2849,2852 ---- *************** *** 3039,3043 **** _res = Py_BuildValue("O&", CFURLRefObj_New, _rv); - URLBytes__error__: ; return _res; } --- 3038,3041 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:31:09 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/app _Appmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/app In directory usw-pr-cvs1:/tmp/cvs-serv11905/python/Mac/Modules/app Modified Files: _Appmodule.c Log Message: Shut up many more gcc warnings. Index: _Appmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/app/_Appmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** _Appmodule.c 2001/08/23 14:01:51 1.1 --- _Appmodule.c 2001/09/05 10:31:07 1.2 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ From jackjansen@users.sourceforge.net Wed Sep 5 11:31:15 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ae _AEmodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ae In directory usw-pr-cvs1:/tmp/cvs-serv11929/python/Mac/Modules/ae Modified Files: _AEmodule.c Log Message: Shut up many more gcc warnings. Index: _AEmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ae/_AEmodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _AEmodule.c 2001/09/04 22:19:14 1.3 --- _AEmodule.c 2001/09/05 10:31:13 1.4 *************** *** 6,11 **** --- 6,15 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif /* Macro to test whether a weak-loaded CFM function exists */ *************** *** 159,163 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 163,166 ---- *************** *** 303,307 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 306,309 ---- *************** *** 518,522 **** Py_INCREF(Py_None); _res = Py_None; - dataPtr__error__: ; return _res; } --- 520,523 ---- *************** *** 828,832 **** _res = Py_BuildValue("O&", AEDesc_New, &result); - dataPtr__error__: ; return _res; } --- 829,832 ---- *************** *** 852,856 **** _res = Py_BuildValue("O&", AEDesc_New, &result); - dataPtr__error__: ; return _res; } --- 852,855 ---- *************** *** 876,880 **** _res = Py_BuildValue("O&", AEDesc_New, &resultList); - factoringPtr__error__: ; return _res; } --- 875,878 ---- *************** *** 931,935 **** _res = Py_BuildValue("O&", AEDesc_New, &theAEDesc); - dataPtr__error__: ; return _res; } --- 929,932 ---- From jackjansen@users.sourceforge.net Wed Sep 5 11:31:20 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/win winsupport.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/win In directory usw-pr-cvs1:/tmp/cvs-serv11964/python/Mac/Modules/win Modified Files: winsupport.py Log Message: Shut up many more gcc warnings. Index: winsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/win/winsupport.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -d -r1.26 -r1.27 *** winsupport.py 2001/08/23 13:51:46 1.26 --- winsupport.py 2001/09/05 10:31:18 1.27 *************** *** 180,184 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 180,184 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 209,213 **** if ( !PyArg_ParseTuple(_args, "i", &ptr) ) return NULL; ! return WinObj_WhichWindow((WindowPtr)ptr); """ --- 209,214 ---- if ( !PyArg_ParseTuple(_args, "i", &ptr) ) return NULL; ! _res = WinObj_WhichWindow((WindowPtr)ptr); ! return _res; """ From jackjansen@users.sourceforge.net Wed Sep 5 11:31:25 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qdoffs qdoffssupport.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qdoffs In directory usw-pr-cvs1:/tmp/cvs-serv11988/python/Mac/Modules/qdoffs Modified Files: qdoffssupport.py Log Message: Shut up many more gcc warnings. Index: qdoffssupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qdoffs/qdoffssupport.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** qdoffssupport.py 2001/08/23 13:50:16 1.6 --- qdoffssupport.py 2001/09/05 10:31:22 1.7 *************** *** 106,110 **** return NULL; cp = GetPixBaseAddr(pm)+from; ! return PyString_FromStringAndSize(cp, length); """ f = ManualGenerator("GetPixMapBytes", pixmapgetbytes_body) --- 106,111 ---- return NULL; cp = GetPixBaseAddr(pm)+from; ! _res = PyString_FromStringAndSize(cp, length); ! return _res; """ f = ManualGenerator("GetPixMapBytes", pixmapgetbytes_body) *************** *** 123,127 **** memcpy(cp, icp, length); Py_INCREF(Py_None); ! return Py_None; """ f = ManualGenerator("PutPixMapBytes", pixmapputbytes_body) --- 124,129 ---- memcpy(cp, icp, length); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ f = ManualGenerator("PutPixMapBytes", pixmapputbytes_body) From jackjansen@users.sourceforge.net Wed Sep 5 11:31:30 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/list listsupport.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/list In directory usw-pr-cvs1:/tmp/cvs-serv12010/python/Mac/Modules/list Modified Files: listsupport.py Log Message: Shut up many more gcc warnings. Index: listsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/list/listsupport.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** listsupport.py 2001/08/23 13:49:41 1.10 --- listsupport.py 2001/09/05 10:31:28 1.11 *************** *** 177,181 **** l = (ListObject *)ListObj_New(as_List(h)); l->ob_must_be_disposed = 0; ! return Py_BuildValue("O", l); """ f = ManualGenerator("as_List", as_List_body) --- 177,182 ---- l = (ListObject *)ListObj_New(as_List(h)); l->ob_must_be_disposed = 0; ! _res = Py_BuildValue("O", l); ! return _res; """ f = ManualGenerator("as_List", as_List_body) From jackjansen@users.sourceforge.net Wed Sep 5 11:31:34 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/drag dragsupport.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/drag In directory usw-pr-cvs1:/tmp/cvs-serv12040/python/Mac/Modules/drag Modified Files: dragsupport.py Log Message: Shut up many more gcc warnings. Index: dragsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/drag/dragsupport.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** dragsupport.py 2001/08/23 13:48:25 1.7 --- dragsupport.py 2001/09/05 10:31:32 1.8 *************** *** 237,241 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; """ installtracking = ManualGenerator("InstallTrackingHandler", installtracking_body) --- 237,242 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ installtracking = ManualGenerator("InstallTrackingHandler", installtracking_body) *************** *** 253,257 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; """ installreceive = ManualGenerator("InstallReceiveHandler", installreceive_body) --- 254,259 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ installreceive = ManualGenerator("InstallReceiveHandler", installreceive_body) *************** *** 267,271 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; """ removetracking = ManualGenerator("RemoveTrackingHandler", removetracking_body) --- 269,274 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ removetracking = ManualGenerator("RemoveTrackingHandler", removetracking_body) *************** *** 281,285 **** if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! return Py_None; """ removereceive = ManualGenerator("RemoveReceiveHandler", removereceive_body) --- 284,289 ---- if (_err != noErr) return PyMac_Error(_err); Py_INCREF(Py_None); ! _res = Py_None; ! return _res; """ removereceive = ManualGenerator("RemoveReceiveHandler", removereceive_body) From jackjansen@users.sourceforge.net Wed Sep 5 11:31:39 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/cf cfsupport.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/cf In directory usw-pr-cvs1:/tmp/cvs-serv12076/python/Mac/Modules/cf Modified Files: cfsupport.py Log Message: Shut up many more gcc warnings. Index: cfsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/cf/cfsupport.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** cfsupport.py 2001/09/04 22:25:47 1.10 --- cfsupport.py 2001/09/05 10:31:37 1.11 *************** *** 191,195 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned long)self, (unsigned long)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 191,195 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", CFGetTypeID(self->ob_itself), (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 206,210 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 206,210 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 218,222 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 218,222 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 230,234 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 230,234 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 242,246 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 242,246 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 254,258 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 254,258 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 266,270 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 266,270 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 297,301 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 297,301 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 313,317 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 313,317 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() *************** *** 325,329 **** OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", self, self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() --- 325,329 ---- OutLbrace() Output("char buf[100];") ! Output("""sprintf(buf, "", (unsigned)self, (unsigned)self->ob_itself);""") Output("return PyString_FromString(buf);") OutRbrace() From jackjansen@users.sourceforge.net Wed Sep 5 11:31:44 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/ctl ctlsupport.py,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/ctl In directory usw-pr-cvs1:/tmp/cvs-serv12105/python/Mac/Modules/ctl Modified Files: ctlsupport.py Log Message: Shut up many more gcc warnings. Index: ctlsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/ctl/ctlsupport.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -d -r1.41 -r1.42 *** ctlsupport.py 2001/08/23 13:48:09 1.41 --- ctlsupport.py 2001/09/05 10:31:42 1.42 *************** *** 170,173 **** --- 170,174 ---- tracker = obj; Py_INCREF(tracker); + return 1; } *************** *** 219,223 **** return -1; /* And store the Python callback */ ! sprintf(keybuf, "%x", which); if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) return -1; --- 220,224 ---- return -1; /* And store the Python callback */ ! sprintf(keybuf, "%x", (unsigned)which); if (PyDict_SetItemString(self->ob_callbackdict, keybuf, callback) < 0) return -1; *************** *** 231,235 **** PyObject *func, *rv; ! sprintf(keybuf, "%x", which); if ( self->ob_callbackdict == NULL || (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { --- 232,236 ---- PyObject *func, *rv; ! sprintf(keybuf, "%x", (unsigned)which); if ( self->ob_callbackdict == NULL || (func = PyDict_GetItemString(self->ob_callbackdict, keybuf)) == NULL ) { *************** *** 555,559 **** return PyMac_Error(_err); } ! return Py_BuildValue("O&", OptResObj_New, hdl); """ --- 556,561 ---- return PyMac_Error(_err); } ! _res = Py_BuildValue("O&", OptResObj_New, hdl); ! return _res; """ From jackjansen@users.sourceforge.net Wed Sep 5 11:31:49 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res ressupport.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv12128/python/Mac/Modules/res Modified Files: ressupport.py Log Message: Shut up many more gcc warnings. Index: ressupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/ressupport.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** ressupport.py 2001/08/23 13:50:42 1.16 --- ressupport.py 2001/09/05 10:31:47 1.17 *************** *** 62,66 **** } ! OptResObj_Convert(PyObject *v, Handle *p_itself) { PyObject *tmp; --- 62,66 ---- } ! int OptResObj_Convert(PyObject *v, Handle *p_itself) { PyObject *tmp; From jackjansen@users.sourceforge.net Wed Sep 5 11:31:54 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 03:31:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res resedit.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv12151/python/Mac/Modules/res Modified Files: resedit.py Log Message: Shut up many more gcc warnings. Index: resedit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/resedit.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** resedit.py 2000/03/08 16:58:15 1.4 --- resedit.py 2001/09/05 10:31:52 1.5 *************** *** 59,63 **** as_xxx_body = """ ! return %sObj_New((%sHandle)_self->ob_itself); """ --- 59,64 ---- as_xxx_body = """ ! _res = %sObj_New((%sHandle)_self->ob_itself); ! return _res; """ From akuchling@users.sourceforge.net Wed Sep 5 13:03:01 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Wed, 05 Sep 2001 05:03:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils sysconfig.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv32579 Modified Files: sysconfig.py Log Message: [Bug #404274] Restore some special-case code for AIX and BeOS under 1.5.2. This will have to stay until we decide to drop 1.5.2 compatibility completely. Index: sysconfig.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** sysconfig.py 2001/09/04 12:01:49 1.42 --- sysconfig.py 2001/09/05 12:02:59 1.43 *************** *** 319,323 **** --- 319,350 ---- if python_build: g['LDSHARED'] = g['BLDSHARED'] + + elif sys.version < '2.1': + # The following two branches are for 1.5.2 compatibility. + if sys.platform == 'aix4': # what about AIX 3.x ? + # Linker script is in the config directory, not in Modules as the + # Makefile says. + python_lib = get_python_lib(standard_lib=1) + ld_so_aix = os.path.join(python_lib, 'config', 'ld_so_aix') + python_exp = os.path.join(python_lib, 'config', 'python.exp') + + g['LDSHARED'] = "%s %s -bI:%s" % (ld_so_aix, g['CC'], python_exp) + elif sys.platform == 'beos': + # Linker script is in the config directory. In the Makefile it is + # relative to the srcdir, which after installation no longer makes + # sense. + python_lib = get_python_lib(standard_lib=1) + linkerscript_name = os.path.basename(string.split(g['LDSHARED'])[0]) + linkerscript = os.path.join(python_lib, 'config', linkerscript_name) + + # XXX this isn't the right place to do this: adding the Python + # library to the link, if needed, should be in the "build_ext" + # command. (It's also needed for non-MS compilers on Windows, and + # it's taken care of for them by the 'build_ext.get_libraries()' + # method.) + g['LDSHARED'] = ("%s -L%s/lib -lpython%s" % + (linkerscript, PREFIX, sys.version[0:3])) + global _config_vars _config_vars = g From theller@users.sourceforge.net Wed Sep 5 13:55:56 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Wed, 05 Sep 2001 05:55:56 -0700 Subject: [Python-checkins] CVS: distutils/misc archive.h,1.4,1.5 extract.c,1.5,1.6 install.c,1.11,1.12 wininst.exe,1.9,1.10 Message-ID: Update of /cvsroot/python/distutils/misc In directory usw-pr-cvs1:/tmp/cvs-serv13479 Modified Files: archive.h extract.c install.c wininst.exe Log Message: Implement PEP250 for bdist_wininst: Use Lib/site-packages under windows (but only for version 2.2 and up). The scheme has to be determined at runtime. Index: archive.h =================================================================== RCS file: /cvsroot/python/distutils/misc/archive.h,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** archive.h 2001/02/19 09:19:07 1.4 --- archive.h 2001/09/05 12:55:53 1.5 *************** *** 59,68 **** #pragma pack() typedef int (*NOTIFYPROC)(int code, LPSTR text, ...); extern BOOL extract_file (char *dst, char *src, int method, int comp_size, int uncomp_size, NOTIFYPROC notify); ! extern BOOL unzip_archive (char *dirname, char *data, DWORD size, ! NOTIFYPROC callback); extern char *map_new_file (DWORD flags, char *filename, char *pathname_part, int size, --- 59,75 ---- #pragma pack() + /* installation scheme */ + + typedef struct tagSCHEME { + char *name; + char *prefix; + } SCHEME; + typedef int (*NOTIFYPROC)(int code, LPSTR text, ...); extern BOOL extract_file (char *dst, char *src, int method, int comp_size, int uncomp_size, NOTIFYPROC notify); ! extern BOOL unzip_archive (SCHEME *scheme, char *dirname, char *data, ! DWORD size, NOTIFYPROC notify); extern char *map_new_file (DWORD flags, char *filename, char *pathname_part, int size, *************** *** 79,80 **** --- 86,88 ---- #define NUM_FILES 6 #define FILE_OVERWRITTEN 7 + Index: extract.c =================================================================== RCS file: /cvsroot/python/distutils/misc/extract.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** extract.c 2001/02/19 09:19:07 1.5 --- extract.c 2001/09/05 12:55:53 1.6 *************** *** 10,14 **** /* Convert unix-path to dos-path */ ! static void fixpath (char *path) { while (path && *path) { --- 10,14 ---- /* Convert unix-path to dos-path */ ! static void normpath (char *path) { while (path && *path) { *************** *** 186,190 **** */ BOOL ! unzip_archive (char *dirname, char *data, DWORD size, NOTIFYPROC notify) { int n; --- 186,191 ---- */ BOOL ! unzip_archive (SCHEME *scheme, char *dirname, char *data, DWORD size, ! NOTIFYPROC notify) { int n; *************** *** 208,211 **** --- 209,213 ---- /* Loop through the central directory, reading all entries */ for (n = 0; n < pe->nTotalCDir; ++n) { + int i; char *fname; char *pcomp; *************** *** 230,238 **** + pfhdr->extra_length]; strcpy (pathname, dirname); ! strcat (pathname, "\\"); new_part = &pathname[lstrlen (pathname)]; strncat (pathname, fname, pfhdr->fname_length); ! fixpath (pathname); if (pathname[strlen(pathname)-1] != '\\') { /* --- 232,276 ---- + pfhdr->extra_length]; + /* dirname is the Python home directory (prefix) */ strcpy (pathname, dirname); ! if (pathname[strlen(pathname)-1] != '\\') ! strcat (pathname, "\\"); new_part = &pathname[lstrlen (pathname)]; + /* we must now match the first part of the pathname + * in the archive to a component in the installation + * scheme (PURELIB, PLATLIB, HEADERS, SCRIPTS, or DATA) + * and replace this part by the one in the scheme to use + */ + for (i = 0; *scheme[i].name; ++i) { + if (0 == strnicmp(scheme[i].name, fname, strlen(scheme[i].name))) { + char *rest; + int len; + int namelen = strlen(scheme[i].name); /* length of the replaced part */ + + strcat(pathname, scheme[i].prefix); + + rest = fname + namelen; + len = pfhdr->fname_length - namelen; + + if ((pathname[strlen(pathname)-1] != '\\') + && (pathname[strlen(pathname)-1] != '/')) + strcat(pathname, "\\"); + /* Now that pathname ends with a separator, + * we must make sure rest does not start with + * an additional one. + */ + if ((rest[0] == '\\') || (rest[0] == '/')) { + ++rest; + --len; + } + + strncat(pathname, rest, len); + goto Done; + } + } + /* no prefix to replace found, go unchanged */ strncat (pathname, fname, pfhdr->fname_length); ! Done: ! normpath (pathname); if (pathname[strlen(pathname)-1] != '\\') { /* Index: install.c =================================================================== RCS file: /cvsroot/python/distutils/misc/install.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** install.c 2001/04/09 18:03:11 1.11 --- install.c 2001/09/05 12:55:53 1.12 *************** *** 865,868 **** --- 865,887 ---- } + /* Note: If scheme.prefix is nonempty, it must end with a '\'! */ + SCHEME old_scheme[] = { + { "PURELIB", "" }, + { "PLATLIB", "" }, + { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ + { "SCRIPTS", "Scripts\\" }, + { "DATA", "" }, + { NULL, NULL }, + }; + + SCHEME new_scheme[] = { + { "PURELIB", "Lib\\site-packages\\" }, + { "PLATLIB", "Lib\\site-packages\\" }, + { "HEADERS", "" }, /* 'Include/dist_name' part already in archive */ + { "SCRIPTS", "Scripts\\" }, + { "DATA", "" }, + { NULL, NULL }, + }; + BOOL CALLBACK InstallFilesDlgProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) *************** *** 870,873 **** --- 889,893 ---- LPNMHDR lpnm; char Buffer[4096]; + SCHEME *scheme; switch (msg) { *************** *** 922,930 **** OpenLogfile(install_dir); /* Extract all files from the archive */ SetDlgItemText (hwnd, IDC_TITLE, "Installing files..."); ! success = unzip_archive (install_dir, arc_data, ! arc_size, notify); /* Compile the py-files */ if (pyc_compile) { --- 942,975 ---- OpenLogfile(install_dir); + /* + * The scheme we have to use depends on the Python version... + if sys.version < "2.2": + WINDOWS_SCHEME = { + 'purelib': '$base', + 'platlib': '$base', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } + else: + WINDOWS_SCHEME = { + 'purelib': '$base/Lib/site-packages', + 'platlib': '$base/Lib/site-packages', + 'headers': '$base/Include/$dist_name', + 'scripts': '$base/Scripts', + 'data' : '$base', + } + */ + scheme = old_scheme; + if (py_major > 2) + scheme = new_scheme; + else if((py_major == 2) && (py_minor >= 2)) + scheme = new_scheme; /* Extract all files from the archive */ SetDlgItemText (hwnd, IDC_TITLE, "Installing files..."); ! success = unzip_archive (scheme, ! install_dir, arc_data, ! arc_size, notify); /* Compile the py-files */ if (pyc_compile) { Index: wininst.exe =================================================================== RCS file: /cvsroot/python/distutils/misc/wininst.exe,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 Binary files /tmp/cvsPhHaDh and /tmp/cvs07uEOo differ From theller@users.sourceforge.net Wed Sep 5 14:00:43 2001 From: theller@users.sourceforge.net (Thomas Heller) Date: Wed, 05 Sep 2001 06:00:43 -0700 Subject: [Python-checkins] CVS: distutils/distutils/command bdist_wininst.py,1.22,1.23 Message-ID: Update of /cvsroot/python/distutils/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv14593 Modified Files: bdist_wininst.py Log Message: Implement PEP250: Use Lib/site-packages under windows. bdist_wininst doesn't use the NT SCHEME any more, instead a custom SCHEME is used, which is exchanged at installation time, depending on the python version used. Avoid a bogus warning frpom install_lib about installing into a directory not on sys.path. Index: bdist_wininst.py =================================================================== RCS file: /cvsroot/python/distutils/distutils/command/bdist_wininst.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** bdist_wininst.py 2001/07/04 16:52:02 1.22 --- bdist_wininst.py 2001/09/05 13:00:40 1.23 *************** *** 84,93 **** install = self.reinitialize_command('install') install.root = self.bdist_dir - if os.name != 'nt': - # Must force install to use the 'nt' scheme; we set the - # prefix too just because it looks silly to put stuff - # in (eg.) ".../usr/Scripts", "usr/Include", etc. - install.prefix = "Python" - install.select_scheme('nt') install_lib = self.reinitialize_command('install_lib') --- 84,87 ---- *************** *** 96,105 **** install_lib.optimize = 0 ! install_lib.ensure_finalized() self.announce("installing to %s" % self.bdist_dir) install.ensure_finalized() install.run() # And make an archive relative to the root of the # pseudo-installation tree. --- 90,114 ---- install_lib.optimize = 0 ! # Use a custom scheme for the zip-file, because we have to decide ! # at installation time which scheme to use. ! for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): ! value = string.upper(key) ! if key == 'headers': ! value = value + '/Include/$dist_name' ! setattr(install, ! 'install_' + key, ! value) self.announce("installing to %s" % self.bdist_dir) install.ensure_finalized() + + # avoid warning of 'install_lib' about installing + # into a directory not in sys.path + sys.path.insert(0, os.path.join(self.bdist_dir, 'PURELIB')) + install.run() + del sys.path[0] + # And make an archive relative to the root of the # pseudo-installation tree. *************** *** 108,127 **** "%s.win32" % fullname) - # Our archive MUST be relative to sys.prefix, which is the - # same as install_purelib in the 'nt' scheme. - root_dir = os.path.normpath(install.install_purelib) - - # Sanity check: Make sure everything is included - for key in ('purelib', 'platlib', 'headers', 'scripts', 'data'): - attrname = 'install_' + key - install_x = getattr(install, attrname) - # (Use normpath so that we can string.find to look for - # subdirectories) - install_x = os.path.normpath(install_x) - if string.find(install_x, root_dir) != 0: - raise DistutilsInternalError \ - ("'%s' not included in install_lib" % key) arcname = self.make_archive(archive_basename, "zip", ! root_dir=root_dir) self.create_exe(arcname, fullname, self.bitmap) --- 117,122 ---- "%s.win32" % fullname) arcname = self.make_archive(archive_basename, "zip", ! root_dir=self.bdist_dir) self.create_exe(arcname, fullname, self.bitmap) *************** *** 234,247 **** EXEDATA = """\ TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAA4AAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v ! ZGUuDQ0KJAAAAAAAAABwv7aMNN7Y3zTe2N803tjfT8LU3zXe2N+3wtbfNt7Y39zB3N823tjfVsHL ! 3zze2N803tnfSN7Y3zTe2N853tjf3MHS3zne2N+M2N7fNd7Y31JpY2g03tjfAAAAAAAAAABQRQAA ! TAEDABAF0joAAAAAAAAAAOAADwELAQYAAEAAAAAQAAAAoAAA8OwAAACwAAAA8AAAAABAAAAQAAAA ! AgAABAAAAAAAAAAEAAAAAAAAAAAAAQAABAAAAAAAAAIAAAAAABAAABAAAAAAEAAAEAAAAAAAABAA ! AAAAAAAAAAAAADDxAABsAQAAAPAAADABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAFVQWDAAAAAAAKAAAAAQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAIAAAOBV ! UFgxAAAAAABAAAAAsAAAAEAAAAAEAAAAAAAAAAAAAAAAAABAAADgLnJzcmMAAAAAEAAAAPAAAAAE ! AAAARAAAAAAAAAAAAAAAAAAAQAAAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- 229,242 ---- EXEDATA = """\ TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAA8AAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1v ! ZGUuDQ0KJAAAAAAAAAA/SHa+eykY7XspGO17KRjtADUU7XkpGO0UNhLtcCkY7fg1Fu15KRjtFDYc ! 7XkpGO0ZNgvtcykY7XspGe0GKRjteykY7XYpGO19ChLteSkY7bwvHu16KRjtUmljaHspGO0AAAAA ! AAAAAAAAAAAAAAAAUEUAAEwBAwCMCZY7AAAAAAAAAADgAA8BCwEGAABAAAAAEAAAAKAAAADuAAAA ! sAAAAPAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAAAEAAAQAAAAAAAACAAAAAAAQAAAQ ! AAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAw8QAAbAEAAADwAAAwAQAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABVUFgwAAAAAACgAAAAEAAAAAAAAAAEAAAA ! AAAAAAAAAAAAAACAAADgVVBYMQAAAAAAQAAAALAAAABAAAAABAAAAAAAAAAAAAAAAAAAQAAA4C5y ! c3JjAAAAABAAAADwAAAABAAAAEQAAAAAAAAAAAAAAAAAAEAAAMAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA *************** *** 250,254 **** IHBhY2tlZCB3aXRoIHRoZSBVUFggZXhlY3V0YWJsZSBwYWNrZXIgaHR0cDovL3VweC50c3gub3Jn ICQKACRJZDogVVBYIDEuMDEgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgdGhlIFVQWCBUZWFtLiBB ! bGwgUmlnaHRzIFJlc2VydmVkLiAkCgBVUFghDAkCCtCN63fHS7mJS8gAAOo8AAAAsAAAJgEAbP/b //9TVVaLdCQUhfZXdH2LbCQci3wMgD4AdHBqXFb/5vZv/xU0YUAAi/BZHVl0X4AmAFcRvGD9v/n+ 2IP7/3Unag+4hcB1E4XtdA9XaBBw/d/+vw1qBf/Vg8QM6wdXagEJWVn2wxB1HGi3ABOyna0ALbQp --- 245,249 ---- IHBhY2tlZCB3aXRoIHRoZSBVUFggZXhlY3V0YWJsZSBwYWNrZXIgaHR0cDovL3VweC50c3gub3Jn ICQKACRJZDogVVBYIDEuMDEgQ29weXJpZ2h0IChDKSAxOTk2LTIwMDAgdGhlIFVQWCBUZWFtLiBB ! bGwgUmlnaHRzIFJlc2VydmVkLiAkCgBVUFghDAkCCmxXYH6y1WEpVsgAAP49AAAAsAAAJgEAJv/b //9TVVaLdCQUhfZXdH2LbCQci3wMgD4AdHBqXFb/5vZv/xU0YUAAi/BZHVl0X4AmAFcRvGD9v/n+ 2IP7/3Unag+4hcB1E4XtdA9XaBBw/d/+vw1qBf/Vg8QM6wdXagEJWVn2wxB1HGi3ABOyna0ALbQp *************** *** 256,539 **** bxFWVlMFDP/Xg/j/iUX8D4WIY26+vZnUEQN1GyEg/3UQ6Bf/b7s31wBopw+EA0HrsR9QdAmPbduz UI/rL1wgGOpTDGoCrM2W7f9VIPDALmcQZronYy91JS67aFTH6Xbf891TAes7B1kO8yR0Cq3QHvkT ! A41F9G4GAgx7n4UYQqh9/BIDvO7NNEjMNBR1CQvIlgbTfTN/DlZqBFYQxBD7GlyEyHyJfg9hOIKz 3drmPOsmpSsCUyqs+b5tW1OnCCWLBDvGdRcnEMKGNuEoco4KM8BsC+3/5FvJOIN9EAhTi10IaUOS ! druwffI4k8jdUOjISeJFsnzb3AwvUMgIFEBqAcz+c7ftGF4G2CVoqFEq8VCJXdS/sLDtLSCM1xw7 ! dGn/dChQaO72+b6QmBlLBCGsjnQTGnOd+5YNfIsEyYr2IR8byFn3IDw6Lh9kQ+2w0VoDxUUSPsgP ! 3ea+U5fcGY1e8NAUxtHd8GHOgewY4YtNENAM/3/D30RUC/qNRAvquCtIDCvKg+kWA9GBOFBLBeP/ ! 3fYGiU307mUsg2UMAGaDeAoAD45OHdv//+0GPfSLVRCLRBoqjTQajTwIA/uBPjEBY7lttgIuNoE/ ! CwMEKou23Zq/D79OIIPCLokwA9ME8BHNW7f7Vh4DygUcAxHRCE8cicG/3LYvVxoD0BP0jRoe7I2F ! 6P7dsxEalGL0C2iw81BmC7Z82+4QH96Uzb1t742EBQ02+EZHGlAbJexkZvcDtXXwHkRhSwRoV9y9 ! 1AboRsq8BecPXHRG4WDdd0xmi0YMUAQOQfd2TlB2hZIJ6S0AjbtrOPe6Hie0Pht2FFENbTTbb+xL ! AfodGDkqFO5Nd2wbGBNAUItyv0AKUEJf69zGagZVFLQS/xoVOcbh5HYGjLR51ppw/3934ev3USQE ! RBGKCITJdAuA+S91A8YAXLlbOeNAde+HQDR0F4AjNRkmtlUWYV8F19gbrVkRJsBXUBTUlt9sBcfY ! jOIM0GoKmVn39222/PkzyWjocFEAHmi8AgAN0SyZhkVAPzBQbramtjLXGiEUFUi+oI5oS0fYBFYv ! WVBCDwFwct3dOR04GP/TaDbk+9qBNQdgIwoBFdOpM2e61xhfPJ+edm+tmcD08fbCEADauACare7b ! BgA9/OFOO5SBu8P92AkQQIWsDKd9CFchbdjVvgYzoTiiPH90FJdoctO5B94iaAEEAGmgVQbodHz4 ! X1Aqf8cEJECg/QDwPfSZ3GfhGuQ12AUg3f5dmhpN6ANB1mgAjxZo/W8jm4MMwKEABF+sXusnutbu ! TeGBeAg49XUZS35wNfO95x3RdFzgKWwbrvDVg0unCkIIOKBr0Pp1Oa1GKaQ3/vbGMaEdQItQCo1I ! DvZRUveehUvLUVZGRKMwLA0nNEsM/F78EN7wW4TYILDD1yjWui61C6yL+AWQ/IuC9CrdNt4RK9Ar ! ZlIP+CttBVrHX1dSmSvC0fiM8BX0jcgIs8cNhax5vHUHHXUI5YPoTt6E3QHwofCg4uJOLcJ3joXN ! fIlIhQopKBy+/i8XWg0dZqeX+AHB6BBJQ+TySHR56QkRlhDmGrgP04stqEnPHjz40EA3aEmAs9Wk ! CRr+kblnhRsuFjPtVVVoi+CgdGcV0zvFFl/BzRYuOUhVroYUWnfhBaHBQYk8gw+CNd0SAIgllpQV ! Nmi5OEMoKD1G2PC+WI1xaO/yFRXkFsuxDKAzdgognxJYzBS75WvYb7AbqxhomW29PlBVNUy2bIPW ! VVopiukstIIhyVgzBxnbRPJUVUaJaJCx7DYwkaIEcHFVe785sxvchs0CdR//NR4FZsTMWB9gqdzL ! 3l3nIy1QCesQaN7F4jAabo/rRcQgxDjSwwj/2TP/V1craJ1WR2y7sGEzdQQv6wLwV+8mFwljVuOI ! vRuGxkm8gZrRnPgt93bhUzPbmhkADFNo3JJ7oY1xrPwaGGAXBzBBmd9EuwpyUwDYU1CNRZjHiiyb ! qzlwJ/gcTbzGWe/13crRuMxutJphRe3RO8Mv+PGlDV44GP2NTZhRKkoylzqzvYw2nFNQ7Uj/7UV6 ! NrRx1uMQZLZ10hasAazX2ugprbSkefj+iCNisjabnezHIKrGtvY2WzXs8P1OABbwzd6YWQwIEB8b ! bNhdswzoWTfoaJp097gH1gUY/PKEG6CEgxcrUhJGEvDFEpirF2ToTT/JNBm4lF4t8QKbPeUF1zWO ! Y2pl7gIEANtAhNnrA3LIgmjsEAxuZw7YThBzYYynrMOVYR3PATXr2ckSckjOFiCByQGBaFhEclIG ! vmQrdGwxPSz0uPuLQAg9Mex0KT2ATdMYCyHwA0k1U2HwpxH7vlWJPSSiZnuxUfeAuJ8RXIUNFhTs ! DNY47t8coBTP0f19ELVZu4pZaDCmU1GPfJ8WCo4UHUAAnwWENxU6GOECyUc+OTVsEd67TTajNGx0 ! EmgUN8Ih725/Igw3WR6UoBkTaPhxTOxmhU8aBRMozjeY1AwDqQBUjUL7kzZXdQEM4Gg4cw+UMUmH ! dzXQIsFwtenfPof4hVUFg8j/62ZTCZhgjt4H7gkzlBQH4mRn6GwJCLYK9HK0B5Nm9OQQmHFrsWvy ! eYkweyTTVrcGhs9epOOjfxL0V6XyyEYZnF5bX8UrOHjLUAGhqgsGQ+ioxVYaEC+QBnEo/F+0BEHr ! 9g+3wcHgED79zMZ4LOK7LhJTxHXJfjQdvX1WVRBBFMDNxq+9UYX2uZGLhCTIwIX/5vfYG8CD4BjA ! Y5fYytVdRTb/BY2WK3PBvXXJSQ8oCpQkdC+SzbZch4kEJgd0KqGNCbs0aEwsLKcD01s2gaYNGGeI ! LNzbR4Jti3YElHWEi1I7qbcBVIHE/R4A1AvN0sLQW+wQADr/1eG9VxsVbTHZmUuuNpF3hAEG6QBu ! y/YZm3R7Al4hD4X+T4CTbqEkoOGZDbhzl6EVPg7VTl7b3kkvHIZW4s5jkp26s6bWLlfQEEPdbNeo ! OQ83k4vUrGbHyo73D2UZajAb00knlBEatEq80GdfI9hzitCGnCBkgBvrSbJqLuFgDXcSeD/YR2iY ! H1x1Nh+NX7A/aDzrln0N+VmH64RM2OsbV4SLw8YYZrCRDQjmkz7GEXh4G4kGaVmJRgSlJYzRAyJe ! fCYLv1KpVh3xCnQ1gk1UFprjCFBRvAWDEekO4SwjjJgIbXBsB4w1PZAYBogd1c5MQiiUnSvwziK7 ! zyYSVjTgYCNq4Sy8BTnQuWkgMcK1htyFGqF+bC7BK2xydEmrFTd0Q6bpF9oEAddqI2iUdJj8pQLb ! YDfWGAYwNN6//28GBw+VwUmD4QJBi8GjQuvHxwUH2rUDBrHd7F3Danoy01sM4DxoQOgGXqeJE3od ! QPMcB9zZqISrMyalAOTMda6h1mwfCsTIGwlA42TmxCLr2yoHGign6xxBv66zgeFsS4gn+eS2M1jk ! xHUNwEmElkxwaKPTdixoAbPvfR2AaA/TBencYK66LTgFYylUPcPsEPoXTUZhrhGrLIUaMBEam4uF ! eEgvRD9EiJGBh6i0wBXGO2yyLBkVcDXIi9ksBvlh/+aJtzQkZLnBFNpZYRNg/FBeXFAA2dkTw4xc ! AF0bE6SsVYLARF9g32pIhInwAXUcPaCRsLOMNMIzmBCaGRggjySwkwFLVmgYQIlm+Y7RhRh1avwU ! S569YWQUafh0QNhAsFdizuh0sDCbS/LkdFR8HJFtBiU4zs14DrORpewfdEA1/vsAtvUDiXSlHEC+ ! qBfZkQ3YqlamVqIyWWBYeV4MOzmMhoNWPDX8bJKRjdgFPNj0irWMFxE2RN/pQvdcuyS0XnTqylmA ! kgNiZyiUiVAWzyR1Za6DuUscYDSEswh2uwhgSggQj9khcYRcBF3VLvF203RUagtZEY19xCzzq6Gl ! G90G9IkFq6sAaMDE2zb2DKsakBOMG78ACIXW3MgXWcAwiS8vu5WgESwLHNyL661t7UDEG4gVBwYz ! wfbBzGsn1h/wKysZuzOdEmwg4hZAGfQlJ08ubXka+DNs58lulCOfiY5cbQ66c4w0fJjBBZR+u2Uz ! LAWsjH+QIJt1tHzFbdkCvKgPpAQqKItlFKHZiR0tXfCGPzUsoi5svVKvbuIZgBRVu2wYdhvu4b6A ! YngEOtcYEGo78DuVhCo+FjxzE1vW1JlBVZVwKA6bDTtBgCcjPdhkO0GIKGR7sRaROi1UKDIVId2h ! k9WjtxREtgd8KK1qCmRFNPme3UBbQKAssiBx4MmaGarBUKOUKYZUNmAUDVVMqw0Xr6E7Nm9b1gzG ! M0DEE4AH5BaPF+srUwAQLfHW1LxWGld0b+UQ//8hDJXdZoP/AnZhgPlcdU6KSAGXl7e3QAgwfEoE ! M34ebnQMcnUa32L/O0DGBg1G6zMGAwpGT0+n0sESJg1PUfR8M/w1ejwKKB9PiAbUBhXaoH/rBYgO ! RkBPcJmhJIzV22uAJqhLKMGNj8Kh3ryoVith6fjI2APchhRAAOTgA74WwLEAf7EmiT/wEy4Dj52d ! XL6t4TFMTIXYu8AwUCJ1zVaA+Okl9GZ3F4GEeXAfTZRPkF0dg3bY7y+IdqDTZjhWjYzQZbkSjVig ! ESyNBLG11qwLLUauK+zOdIUONOEK+AYxOGHFAGLUYALoNsA8W1WkBI1T5nZGtrh4pH6g/TLYicgM ! dwsRCCr2jXWErWTt/NnMwHt2Wzu/8BA3EXuzt5E51OAQRR2O9QwEaAepakTAfMUXJaheVlOz4nXN ! jVSdXdSeThxQcJvtXry3U1NEKlNmYzsDt03YPqlDj6TnXq474PFi1moPzS/F2U7UCnkNZHPfNrLg ! YOwsyAjWLBOLQ3hnXDUjU0xoq9enNGpb2B/YZel+WezbSkNqXVMN+P8xclX6PIAnAEcsaQk4ZInW ! A4AXqQhTl3gQkKVEMgRgKKSbPAhpXeQoOWQ9LQioU2ykLTolv7vQS4R1AlahjA5GgzgBfhC3wHzw ! D74GajaU+xGLVq3u3A2QCRWLCYrTggI7accIr9BWwF5PkjxFBnx0FAsbGzSOsgjAV9744HKjbAL0 ! CV388ArUjm6bywlT75x4Jj2LSapV10SYCf+ffhgrPGMehB72GwjpbtHPrFk7w1nIdRYfaPhIMKlT ! adwdkWoo3fvtjF/4KPt1C2hYIhkcml5npEuL7KKLLOxHX02ps6IoWx9EKJzFF1kMBAPBvTwDFYQ1 ! 6xoIsYTZkBYaDQnxvr9ATuvEgKQ1SwBSHVuDXziLTQcEj0E7TYQJfGOyfcMbgwqDwyhTV7MwJHEg ! M5uNxq2FVUmuYDCxM1wkdK1DXaD0mi0bmGsqUnRMmBFrSP4ztYSWGCasPwxKuGKx7jm68Sy5XU+O ! Hw9z3AJG3HUtSvjxXx7/MFNpRrBjT4TrADOLGNC2753DNfRD3Go7x3VFLsND6cMZ5rsb//Nz/X4U ! kgCO2K+gymwtAsIvUpgW2czmWgiPMfxeAzsgB+B0GnjlGTmQyBCWoudADuz060MptAhyIAf2GMLr ! IEugB4VCoT0sWYPqS6VrO2uMyPP+flifBWQkDGjvFBGzkM0MbGzs/NcgCl9AYKkfiHX0bnf6S76Z ! exTrGxYfHCjBNwgPsUD0FBZqalLtgkVdF56bCaUrGC2ZBQyeH8Tq0lnDV75tAFZCbBx4NP83n9/Q ! ASc+Hm1Zo8bTDqc+M20IeUu063toPdjxixEPwh7lYKMs2OBdkNMQFQLrYaYg+7ZIjzsHOSQMMA4P ! oOlYfRo2Bz8TXPuHBEcfQHQcagaLZ6UKQzq1bFkANTAKT80FkRJE4oweCF9RonPRmgBeM9EI8RER ! qoA6H4MaAFNLQitNF4DA1V5V2/sM2qgDBAoEXBuqUpCu/wTRSGxU6v4MhAgIRhvlfhg3i1UIGk5M ! qrei/QLqVytBEAJ7IoE5vqE27hONNBAIw54+elY0ElJzk9kLtziMrwBO8l30f4vZDYvWK1YEK9GJ ! FeMrrY1t1UYIa7tX/gyAsTPM+okBK34EmCOxdHfujO4sUfybiFZS6idszUrSFtpEP4Q110BnGzZ5 ! dsgirUCQqvKXCEiCYNXuDHQuF1dQ/NtqhPjT0K/riiRFbDAWhqJGzAC//X8sVTPSO8JWdDOLSFjK ! dCyJUIX+X7YUAggYi3EM994b9lKD5uUPYHf7iTGLQBwgFFFMJgwwZ4ClCrw0uKkICy5g2JAAPRb2 ! NQtd9XQ6i0Y+MyQkLMuuRbc9FA0K3j80LAjptnhzHhooUFHxJA3H+AhgbgAAVO9WsDVfLRA294oB ! Df1rYQdmOsGM50Z8JBg4Yu/gsArcj80793UKP7embzFbZCCJfhjcCmAgsLk1vqFFyX4oOX4kkQ4k ! 0AlwjZ2BahhuhAOapGubJ4mGPvxMd3/hl6SJeBSLVhfPiXoMfQy099nHX/f270AMAXj5CHxZBA9/ ! VB+4EdP/F7b24IlKEFLXUTfaG9JQ99KB4oBEE+A+bWVSiyaMGTjZA/hfQU9WOXoUdQ/jbs26w24O ! H+ylC1YbWDLCk8lfuPppEDeqPE9xU1UQzAQE2+52KHYK+QOhPgAI8OhNFDaLVCOP+gS/+4f27zuF ! lcNLvQXB4/uJXBmJh3fAtwjIDQ+HxCckjdA1GbbRbIUEtj2ISR6JDRvf2o7sQYsvBYsOihEcBKPU ! b3w1FhAEg+EPQr4u84JzfxZ0FccADVXdbBiceeP23SV/66Iii1AQwekowQhdBiYHdnYYJIj9N8/X ! 2iHuFwW9BBFIM8mavu0KjmYIQHaLXhyJWAbeYnvcib0fAxOJg0MEwffe/yVzA8H39YXSdCHHA1aU ! 0XzydDHdX3Bo9sEghp3NbSWBYykHJvrRcsQc2H7aJzzse6vgbKRv/XUYowJVKJihEPNaLLPb1jas ! ApIiAU9pAnPSVl1qoDONSNJSHq1jcy4SRFQM+QvYmZd8sww54wgtAq25F8xj5O3hSty29lzjweEY ! SAvkSTQJDc1VS4Qzg0grFMbaQokGOhwUkIHJgP2tSDfiEAPKiUg5CgzJRXK+CAtzsyWXhDY/OcIy ! hxtINBI260AwmyHlM1npbSAE5FikaGwH/ZACdQmLx5vCCKfawTm3Z3JqY6TszmQWFlBHbscBAznc ! EsIDFkhPN4oKs0JgOJ1TfD4kB8iRVgIEDtghhMnSIIkos4SQEkYhH+w124V4TjDzBrj4O2EalpFp ! LEjLZrOCcAAlapbk2woA/QxDASn9Ym7J/QY4CwcybZplt0x+A3Q0ru0oNWmWy84PA/UyYjOX0eBl ! mq4LG6y4W+3FA0l/01f/egtAgcM8iUN0mASN1mJrDwQFWb7rbx3Y4EcoUrNXynUGdQ07soFdPldR ! 6j3MKMfyBLbtxgFGNAIwDjjuAXy2FlEIIHQOtlvrwsG/0B9gRzDAw4KvQLLf/G1qRYnOtWpkYyDL ! Czko8Vb25c4UT9cCR6EoxkklGoKhwAFf2Zd6GINZ6VcojJD3ww7bIvdyQOlQKCi50zloH58rUR4N ! EtbALqI2AhbeulUyA9geiV4svDjFYkjMyARKug+97KoAg+yiOFNvONgaaC1i+ylDsmsK0bbWEkgu ! S//379oW3xAwVjvIvVQKFURzBSsv4NrywUjrBSwHHowDg/gHNzqXCRkME0NA2FrAa/0Yg/0Dc5w9 ! rbZvuJ6WDcbkSIoPxxRMrvv7/5SL0YvN0+KDxQhjC/JHMYk4b9Xeu4kvcs7rBDevpgeLyN03tcDR ! 6LUBf4lLGHeRYxT2LHAHpIPtAxkBzRwONr3/B8HuA9PuK+k/syd+QUYV6qhIh1Ikp+ETu9uNDTBR ! DjhSzkTcJHYdva5cITT451EPLFJaHSjxEN4QXznzFegUia6171zAYmbsWHEGYRR1hzfkA/j9WBRw ! bl28ziBzLKn6+qAGPZct0D9MLE/2fEDiQpvBJwDy1JeLzhZ4V2qC4Qdy6hAz0a+iurW3/zjti8E7 ! xfoEiWxcSyYBW2LYQYuJA+lM0heHTXRuvCrHHAWFnRarG75rfBpEO9Z1I7+LeyiYFL5rvBmL1zux ! FXMHK8JIV9cd2y5kK/JziTV1Z7RMQchwo0JIBARTNAe6L7bmfwdHMGrWo0zRNrzNOjErykn/SywH ! GfluzwQ+VXUgYvfWtsnNB/JOi87Ci8ikXhqGCXewCwWG7g0WyXadwjvBBcE+X6LQmhREMCSBAvOl ! i8PjF7rKLRzfAyvQ86TaXBtte7slRANSDUtdFfAYOtO1KwwWiXgcKbFqcy0BaF1kGMkgjzGEByqW ! DnM4MsZVcjIOktJic3QfJf8/JcggmB9joW/Zhx0G1tA84Aiagpu7gfqgBRPyBX4FM9E32H0fRo2E ! CAJHd2ycpZsDSCj5UGEMnHjj+Y0FDkgOx0NuNPY2TfAE6wiucVMuNLrRkggRCoNiLXNoqeR3nlky ! vjQGjkgLkwMsCE6xH5tiiYv8EJ9LDMUEV2gNtpFhCAgDhmr7YfcwZ3KYMLgTochzITzhvTbZNMcx ! aTWgaTvdXDcgct9wGiRvGRosfUMQjVNRUjRXAM6mzfHjUFE97LJtZtdG8IUh+wjmBfjwFRZPZdA0 ! 4h+Jt7NgNzUCXQ+De9L78ejbWTvoczPjSjsF67n32tr6+UqY9vRjzQ2h+Qf6LvnN3sHfpYvJ+Iy5 ! FCPG5lTBAY22GjTX5jR2tFUQrrXd7pc0cxvJK+rRDEWE7XANCxKKcUCkNy1Ajy/0uyMSuc10AzPy ! g+gSzZfcJR5ZKyT4Cx/AC7dAHvY76XM7meAEHx6NHFgwnenJ7Ea/O9d8d1WLDI2pI84m91qtvQ4U ! YtSQG5cRTo3XFRzhjAp6t346HgPQOyqHqXVRYin30yo5EOlczF2omfCCkxUN2reXCt8divzrAgCo ! DEFImY/8BxLaw3X1d4leeoKF0G0vE5gVQCQmUdiMmT5QQI3fCSwkUfw1XOsSUjw2Oz9RQgWyUcAE ! eWvPFMM8ayBlCQdABg80Pc6yQ0wkHxVM7KPJnSQKGQglNM/3NODadz2fPCAr7hgC2xx5UKROhFcE ! sC1keQQGKUjWwgIPD3Neazwwl93qYovYBNArnTgDag5efFZM6M5NBnDq2e5LNgQ7JZp5tntAdFZd ! uHhxdrZUAB0nGSQKD00+DSMYmjgUnLEpzCEYmK+VQInSAIO5JBssAKGdz27rtY2LJmialtrplaA1 ! 99pMUXeF2hewux1ySZChMwYww+DTxqENUVxh/cvnZo03MxgYej9VUfIG++G35Ndq/SvRwwPqUE5L ! 2Z7sSkyNMYtpOVEibK5h0CsBZpLqL7MEst0VUlE6Q4XLTn1rMmrHQRj4PUvM/VhrRkBISFGJeQRG ! RDhwhCEYEUsg6BFco02zrPKEp2BvEGaEFVLIxoCL90hUysShE5/PAM45QQSTimdwb0He9wPug1FP ! YEoguNFYuAgLhpZFE5/PnhRCIHxq/FCUebzDSDaQ1HmMz4EUSCgrjhhRNnsjnf11Blulgy2yh09R ! qDrXRoRkHSJolBR8VcYIW567HLisa5FS3VAGLyHNIDXPuNqskElw/oH9dC4EQ18kTCQcsIUQ7BhS ! hLBHKAs+CTsrJW+kXEhQUqbwer1nBwxApmZZTuju50FQVlN0S1OENvce0XQ3oXvoIDdLlb99LolW ! BH9QK9WLbgjjbkC+lWx9PmYIvkfGOBgxQy6Lx0xWtgatFlXFY0NLVtJLIU2ZO50hIB1CmKCXJDCE ! MA0YkX01IchTT7D+U9hrrEVDSCpD/3K5bdWUNxM4AwA5KzpcLpfN2sE7ED63Qh5D2DVds2L4JxZ4 ! A/k+wCXFDBvvDA6wEDSiDDtXGIUrRQFHWGka5QI83YtYRigY4ADn9w0YCFdjVGOBHelPtwy4EYO7 ! 7911Cux7Fwv0wgzNXPnbD4bvEYvfO75VgfuwFZnDcgW4CCvYgkUr/rgPjKGt6MHt2++iEL9hEIoW ! g8YbrFbxA/lyyCFnCPLz9Mghhxz19vchhxxy+Pn6hxxyyPv8/f422M4h/wNNvGTrTFEJnxkVFhLu ! VuptRhNIdfSxDbnx8tp238b38Uy/CIs19/frixKxdbf1hxMxXRdbPx+T4PBfC8EIn5UIC6FsglBu ! S5ZQlwZyQO10SgTDJdXoeA8fHKE3d4Uau4Uiik+jRYhQEPRG4B1aDIhIEXUAAMNhwB0PSBjD3xR/ ! GFp4xSB2zgNGEjQWTJLwVsjaLWwu2m4MwQw0wX59miZcxbwQwkYsgAJ9sAeJM006aONX3N/+Bmyo ! TU89OwItdBwanc4QCgo/GDlrkmwoRnosicBWrpZ+O4wpK6lttbQie635hYkGZd0a0VLcVX+UVlJj ! wIYdIk0RT1UQd0aVzO6pPOrIo34cuALXma5InSgNQK6jgYy1pqMwcrpB/F+ldBNJ99kbydODwfrc ! L7bvTWE2XWZjECuWaiXFErZFsjysvhRUO/hzREBcBLt4Lla6DrXtMAC5F+AVso7P0+DQ2s+5LwDH ! CAvINnngLEE/952N7goscryuhfgjIEIwtlQIVshJGDJrhEe/FNPouG7BReItuPQr+ECKAcUWi0nH ! TLNFj5UIBq+oEK1Ed6F0g+AProuvBdsm6WIiHwJAr0XD5qANqqi/4ycfIZ0bcgeC2kLA3vvMGq9I ! 3HnQPpJvWOfYCL6LBNr7Zk5MuU0EA8jOrTPTtdaRsNRyA9fQXINq0071RZJDgsHMZV6WA0lYwihE ! ZDAckIYMRASF8FIIQbhZZQyNDMGIQWQIkAfYAgzAQA45DAUNOBSgb34Da6l3A44V1XUDwis3QNGe ! MzXWH+0jH9XwCpaxWgHahe1TJZ6XLC2OdSE+Sg1KmzA7wRFULQjbg5MpDPsI6w+0EaeOf2eGFFIj ! I02ihXJiPAxuIBkybWJdDrnBTmNhIl6PEeKWyGKe2wGQc3+fhELzCYhK/xFBSDtQCMdzH5H2B04M ! Zg0GNkdJYc8oN7AAFSiwIeP2Phkf4E0KiApCSES9BFwRBvbPFBjdMvCLKwrix0MfWTNQ4CvNExcR ! qkx3kgj0FMNKCQEEXN0wGODYYgb5EXhQZWr9K81TVrLNFeZQScjrtJhWHmShiokDPuDv/VCD/wd2 ! FT88g+8I6AzvlZFMiUw3UFYdCku2i7LqGzvmgmKzTiA6K20GfynTbjz5Uyv9i2tk0Qgr9O+JC1v+ ! i2Qi4RJBAXyRTGQ7/pB0RmWz3C50MUcDDEiQTkkTS0ObxOJKu0wvV0G+GmHtS+IE+QzioUcWIFFT ! bCASnY6NBBN2EGc6Vt0M2Nt1CaFbWR0APz51HLJWVRmNFnADdbpT6yBSVbCJflG6AROFPpyiS7TV ! ltP+NxpbUylO5PpSx0cYLLxXNI3it3ddXkwe+3QGg32lYi5qugwfCL7CMPeExcIpz4Hs8KJB7Cr3 ! jCT0Bvy0JGm6Bfr97VfPRANITKZpmqZQVFhcYJqmaZpkaGxwdHgNcgFvfImsJHwyvf1CiQHvflyE ! RI1EA0NKiVd3gS667TkIdR9xGIERov/KlG7AiSmJKkq+GFt4jxqcF7kRjS9soKeYO0M5KD1Bg8C0 ! QTeABCZ283b57Lvx+M1zBppiug8rtHgubvR/OS51CEqD7gQ71QU7+qUb/zbbLHYlVPq+UYk70+av ! cwa7t/8SjVyMRCszeCVTwwTREXLyb+FmiNCVo4UcDESNo16gWwMr8bpAeRAR4OtONqIDzuWILAvd ! 3N/a9kqHM9sDTBxISeWMHMVYhPsXde/dSotbIwN9tM3/HBWM1gVsh4QcPSh/jA2h8Hg7iVx4QokR ! Ensc7Y74pghDO9lyxVeL3/dCp9nI2IwUNZSJIV3vmYYCA3EkHmGdzpmixxUAEsSh8RG/HTwPj4EC ! MzRlhwUeikQNuQo729wC70mF0uwrPiD9O00iB9t7D44HYBQ41r9gyc0sLfhsujgDRM9E/98r00UD ! zzvX8CYS0FG3GtccIEnLuIlm+n+NfQE7x3Yng8//9xotYQG3YcduGEEErn2+0e5uYcVt4B8HK8cS ! cu3Zji1L1yS/O+eLsXxjI0d9A/iB/4jY7yZ7P304ICsswi+NlITYNrpxoAeJOIu5P3Q4RYRdn0OI ! TKC0hCyXaGL71suIBTG9xteLSr7Vwq/874v108FDK/CJFPd0NxY7dJ/rCUoYKOChKza88AaP/1qM ! bum2NxyK0AkcKtOIPTGLCI0NvPEMkX9yB8YOwOufj74rujcpDJPxcxSB/sld2V34G9KD4qD2YIhx ! 6yAgFIDcd1Tz5gKKFDEMbfFu7XmAwks0MSGxBLLwRcv2DockR7rCJrY24ry0OxVzHrf8Fk3VxVgw ! d4k5jTzV6HaGY6RxBIYdcubVFAVXJkZ6jcIxgWsRbv+FwnQIM9DR6Ad1+FhKDm2EhkMoYIwcjQWu ! 0D4YMSRPI/rLOl/BfpT7GIPoBE+IJivfORgnjnUzCCN13HUVGurwxMhKICvSwvr4eJgcUpBA68HT ! 23h1mh5OkRtCS3f1Ddc79XQXkSwBdE37C1hrIQEMCggMi4AkD1+xPNBKo2E4aGcAaeASZBgLA4cT ! eF9mNFVkb/U4SRg0UtPYaBBjHeQuEOGQYgQVVWJRL4FScIX2YIPFIv47gzgATUwoO9HOZEg4exZM ! sDe6cwhkUVYeqFJRS/ze+j11JCeDOhYIgf1qdxO3BMAAPx2rkGY5geRPUdjAIR8WHvt1H7x88MiG ! 4yP8dAKYg5HFhi8jSzCBnQF0QlRJMEtgRSMPIA5fIN8NAHtAGdwF4N0NoQQKnIkCEA/b7qaUxwEI ! EccCOEDIUYCN0wHtDGNr1FYD2Nd7wHb9N9r248F3dgMVLBF77zsdroCu6Fjo9zIg4o80bPcI6iBW ! FCvFA9USLNRW5jBWljhwcKNC/A6LSzxVBTZDPJPqcRMSzYv3pKaVS/URWcqmA8VV2zn+F0ssA/2i ! CnV+QXSLzm1EKA2RdR9zNFfYwu7qmivunxCEV8iBLCdHV1ZsocY6RzB8zV74hIK911p7guSMioLh ! 1IthWihUlvCV6olRcjUYXnHoxQsfzFlauHC7+YtpnFEgO3EwNzj+4diNHTvuUUEcOXMJK/VOLdVl ! qDTOSTHNbkK5V4E2tA5c4kuaHCwgg/g8IoutjjrRSUERi6XtvkSJyBphCAvWRx1y4r/BW+xYolcw ! I8rIihzOjTSdq9qIziyENTJOg8AV4AHT6gRnh36wAK05BL4jawydDuz2AWBeBDYDyzhVF+wfQHTH ! g+MPK8M0MbK1r0BODavLI6QPSTPJRA8gNCFHpmycMQUBwJspG5TPO8NzK0BzYQ9ZGIP55+Kr9nPV ! h9dBJpdyRm05Wwc8WU76z3AVZXO0we7H9ReCUMBI15S8SSj9O/gGETv3cheL90WKDkaITf8a0eCD ! BoPrAusB61qBb8cncSwfO992E4sdsLNv1By0Rk919hgoEG3JdmZLnusZvwYEokDPzxlwRUmBYbv6 ! ETsScjoOcjP5Rpihts5RtZwQSQQT3ub4VXQr8z6s8LLORXyhrTvzD4IHLRdobvJJl4t02cVlwesv ! 0GNvHtlzAt44K/kzjRTNjLExVprCxBz6FvAO4hJTRgjqz4k+K2aVXKFnVg1W6QXYC6dzYiB0VlfC ! ZrMiz1rb77UD5OByPxBmrFSTkf71iGgNurXtAytBWECLMUHTwXuJOXdfiUFnmv1rFDe9Zp//JTiK ! BWZkZGQ8QEhM2IpX9MzMUT3gC3Li2O9bh+kLLQSFARdz7G4qceuYxAyL4WDPUMPMS4UZ2T1QXFJq ! 6rv84P9ogFPQW2ShoVBLwdZbdCUHGGjLiUW3oMZl6L4KagKruAkqaBeDDTyJRSk6mwZAV0QGgB3B ! DWjI+jvyNW9hDWSh/BoAo0QFuR8rpUu9OR1AGPozN7dBvmxOAGEYqGgM6n22ibEIcCeioWA/5pao ! DgCUbVwMCVoqmu2cUAOQoGkIwJCvKQIEMgDfoL4LTqEMezDSgD4idci3/d06RgiKBjrDdAQ8DfIS ! BF2zbQ8gdvLU0E6ksKb29la1xUXQMxH01OsOK4oW/fMgdtjr9WoKWJVQTyqW+GiXHap6w69rnjMc ! a0XsVAmJTYhecHEEy5xZCi7/dYiMjdCIF2MoBRTtjRWNEKUDBCykYsN8L9Ksw+B97rktL/hg7AUP ! AABJQIAAvkoMAIwFENN0r+kDERIMAwgHTdM0TQkGCgULBHRN0zQMAw0CPw79P0jTAQ8gaW5mbGF0 ! ZSAxLu++/b8BMyBDb3B5cmlnaHQPOTk1LQQ4IE1h3nuz/3JrIEFkbGVyIEtXY2977733e4N/e3dr ! X03TdN+nE7MXGx8jNE3TNCszO0NT0zRN02Nzg6PD2UVYT+MB+wEDDMmQDAIDBNMMyZAFAHDCLNmy ! X0cvf9N031v38xk/ITG60zRNQWGBwUCBNE3T7AMBAgMEBgjTNE3TDBAYIDAjW2FNQGDn1xKWcGTH ! Bqer8i1hQq+zAwuCIIMMDA1g0BrqHnrPjgOEirIBAAb/y3+qQ3JlYXRlRGljdG9yeSAoJXPB/v+J ! KZRNYXBWaWV3T2ZGaWxlFSl792YrEB1waW5nF28/A2YQAkVuZCAZdHVyJSyY+25zICVkUxcUAwb2 ! gxNJbml0Mhg+b98swM9cb2Z0d2EcXE1prf1t92Nyb3MNXFc3ZG93c1xDLxft//L/bnRWZXJzaW9u ! XFVuc3RhbGwAVGltZUjWtnb7Um9tYW4LaGkKMXpCkNZasNt3pWwgJGcWNPbb7fYgeW9EIGMpcHWH ! ci4gQ2xltuYK/2sgTmV4dCARF10udXtvrdC0HBlLY2VsFRwG67ZuaR1oFVOxcFsuW2vtAdt5FjLA ! AS4LNrK1ZGEPUCCg2dgsYK8u9dMgBtuzmztDbxGVXEmgUGEUABnabWVDtShms12yha2hmDJn3HS4 ! KVMemjMko9/6s2awdvsap3PELqtvLgAbLZtFjmOJHBy6C+EUIWKBbgxw7bUhVrSli6ivUDhcTUlm ! X3Y6LLZ9cHSudlVMY2gSZzMLi/C2BHkqg0Ada7uFc1p0dnMsKm9CYQwgDKEEnYl30ba3JYP3X09w ! O20RbRe6rZRMZw9SLV9TEHBrY66wwFMrVCNGCGy/0fBcIwvHUFpncmFtTt/7mG0CZUOTaSEPTBth ! wuFvYWQE3xoA30e3uXclY29Y0HQaX0U0G7CGJTsLLgeF+GHbGnInMCenMTAwBCYwNLVkEnY6JS+H ! OLkNcAAyF0U1zLXGYBhF31sfG1mjbZxPdgZ3w6ogsmHNudnpFiceewiFQxlNtz8AGwut/QpzPwoK ! /Ab4WRC2/cNFU1NBTFdBWQlvLsr+O/YsCnAtTk8sTkVWRVIrguHYn0NBTkNFTFxTS+dLDWzDjQdk ! det5LpdJMsSh9/q3ycPdNAiwIhVSZW1nVQrbK79leGUiIC0UAi361n4LxywubMAi53diAy66tcJD ! ADA0PxCVREJsW8NWR1V1PVsZXQI9EW60J34ARLUdYXn9NsOkSTerZDsybTrsSUtleTkKN3Vs2hFY ! uCBub/pjASBrHbJJBfdLkr/pI3SctdzbqCFT7GNhlNogvyoAI/Z/37UtCnJKd1kvJW0vgEg6JcoO ! 8dxNICen+/XYbspcE0dmHnNoSJLhwlIrYas70q9tbf4WZBVmAG4K2axbdwCRZxZfdn8PGMOCNG9j ! D+ipgeUt82J1aV/ZbxuBr/CeBUPeGgAwQHgYFgdcACMHTG3WzWfN3zvMGk35YTwrxTen2AkM/UMc ! f7aNx4xmdQ8XZ0dvz9UZGq5wkehkJhZ9OpJ98zoVIwAuYhNMAaMOa2E011wztiEbZMCgCQxjdINE ! ZCFpEnJYZLUkB2AjChZWINmEH2PzP1AMIeNLk2SmIqz3HssTfhEnDtmylq0XQlMRaCesbgBBb5T4 ! JQTec3UInYcKdOWFBp4vcG5h1iBmcrSxFhIiS1BjM91OLH1lHt5ybcMZxlP3QMdtQXIEY/dYMToW ! pGYby/RcR4HGMSBkH4Srfa/HTwVXajcj5l67bG1iZEwkvyvKXRM4cJ88dmFsIoJrEVAOoje92lt2 ! 4yJZlV6rBeMkT2J5VFIY17aUNJsnY0QXdqClpNcC4R9cao21QsR+uRtlZTaHOz3wYz8Y5/Fy2xyc ! Ht4gPd0Ka5dhDW3ZFxGDchk4DcawxehzRwci3BbKa3R3bmg1XNZlcFpQi2QvYgyt0BzugiYVrTvR ! Pj3NW29vJ0gYzYSbMWr3I1jgmOyFeU1vbHM/c38OwVrhDZCFL2NCtGPLXxh0eVqaLaArIKy8r9N1 ! HRBRsAegA5S5N3tNgHAXG+e1X8lydE5ifCkLZnDfDLpm9WWeZ3MRh2EYWjdptS0xljW0YSGfcm0v ! W8KRHXAbbg/oC1ihLX5dxwOGzTZHqQkv4h06aBmDowVgvAHXNGdHUAAHEFRzH2yQk01SHwBwMEBk ! kKYbwB9QCmAFoQYZIKBIMsgggz+AQODIIIMNBh9YGMggTTeQf1M7eEjTDDI40FERIIMMMmgosIMM ! MsgIiEjwDDbIIARUBxQMMljTVeN/K3QyyCCDNMgNyCCDDGQkqCCDDDIEhEQZbLLJ6J9cHxwZpGkG ! mFRTfBuEQQY82J8X/2SQQQZsLLiQQQYZDIxMQQYZZPgDUgYZZJASoyNyGWSQQTLEC2SQQQZiIqSQ ! QQYZAoJCQQYZZOQHWgYZZJAalEN6GWSQQTrUE2SQQQZqKrSQQQYZCopKQQYZZPQFVkEGaZoWwAAz ! BhlkkHY2zA8ZZJBBZiasZJBBBgaGRpBBBhnsCV5BBhlkHpxjBhlkkH4+3BsbZJDBH24uvA9kkMEG ! Dh+OTgZhSBr8/1H/EUGGpEGD/3FBhmSQMcJhBhlkkCGiAYGGZJBBQeJZhmSQQRmSeYZkkEE50mkZ ! ZJBBKbIJZJBBBolJ8ja9QYZVFRf/AgEGGeRCdTXKBhlkSGUlqhlkkEEFhUUZZEgG6l0dGWRIBpp9 ! PRlkSAbabS1kkEEGug2NZEgGGU36U2RIBhkTw3NkSAYZM8ZjkEEGGSOmA0gGGWSDQ+ZIBhlkWxuW ! SAYZZHs71kEGGWRrK7YGGWSQC4tL9ggZZEhXF0gGGWR3N85BBhlkZyeuBhlkkAeHR+4GGWRIXx+e ! BhlkSH8/3gYZbEhvHy++Geyw4w+fjx9PZKgkBv7/wUqGkqGh4aFkKBmR0YZKhpKx8clkKBlKqelK ! hpKhmdmoZCgZufmGkqFkxaXlZCgZSpXVSoaSobX1KBlKhs2thpKhZO2d3WQoGUq9/ZKhZKjDoygZ ! Sobjk4aSoWTTs/MZSoZKy6uSoWQo65soGUqG27uhZKhk+8cZSoaSp+eXkqFkKNe3SoZKhvfPoWQo ! Ga/vGUqGkp/fv++kbyj/fwWfVwe5p+ke7w8RWxDf0yxP0w8FWQRVQfd0Z09dQD8DD1gCr3TuaToP ! IVwgnw8J0zTL01oIVoHADDLI2WB/AoEZySEnhxgHBhxycshhYAQDISeHnDEwDR1iyckMwa8C3QhD ! D91keehu1DLiaWNaAnJl7H8TldXUc3Vic2NyaWJlZCdIiGUrS3YENrJYHkcjS0JcimF0ec0UYIQr ! xRseo9lbtmyzKD1j03wpSx8DAQNN0zRNBw8fP3//NE3TPAEDBw8fClxE0z9/t6MqSsaxAVlFEGED ! aQ4qKChuyd+noCz7BAAAoAkA5XK5TP8A5wDeANZcLpfLAL0AhABCADkAMcrlcrkAKQAYABAACAuy ! k98/3v8ApWPuAKxwBGU3714GpuzA3AAF/xf/5mZdwjcP/gYIBcneygIXDzdlKXuT7wYAF+12vrI3 ! /7a/BqamCLuwmXMMDgsXpgbdfx/YN/tSW0r6UkFCWgVZL7a9n1JBQlsXJ+8LEYjnA3sGN/YgJqUC ! dG63sBWvBRQQiOy9kd3GF/7uJgUGN2u3mw/6QEr7UTFRMVoFAB0bsK9aC1oXWgUQSmvNtYVvYLp1 ! BVQ1979uFW4UBWV1hqYQFjcXuSEbiwsdFm8R2dZt7u1dA0dARgEFEc1Yb93ITjb6C/lAb7oVuDeY ! e115AQAS6A8wNzNGCx1vQTGaO3mQWEhSWBAFhf6UfeYNC0r6Ud8UZWQQJRBzv5FPFqamZHUVlRcL ! HQZYNwoAb0MN2WaHdUgLFzHgiEb2BTFvMhDMYJ6zFabPCwzZN6xZFwUU3/szd854CiNaAwsSdsMc ! OhcFQldPumGcEXr+kwi/smW4wwu2BZ9vS7LUEfD8cv4NHWZv2AMGBMkLlqSFbxEHBfZestkDdwv3 ! N71hM0L5BwUXUrKF5w/v7iF8s2FJBwX2V97C3iwP+ze5JYSz99kHBfrHxQjZmw8hb/kwzmavagcF ! AxVD2ABbxptvVZYxuyxvRwWbTKdTym+B8gGY+5LNa2l1FudvsKYYFxET7FpvCPls0gVvR1ExSZot ! awBbb3WMEfZ6bwNv88O0sm1ZAltvF5vY9xbY381yJt98gb0CDW9J/Pk5WcImPQNvWvoeL0Iitwn7 ! KZBN9mmH9t/rlPHaBlLXEb8vzpi0sjfxhxUro/WgMFWfnTFpZTfx81okAkjOCwwPb3tJOq1m6wsM ! K/sWUvcL/jdG2EsG4gkLgAaiLIcBjDZRwwHHwEgJUhQh+nsBsi0DIFFL0XQncPi9jrruAU0TIANh ! PXMJhdFS1CFyqWY2lKit6FB9Rfd5lqhfQF//gotobnPd5yUxVwd6PzVkDXOf65p3bAEgB1F0GQ9z ! mxs7JS1vFQV5B4Wf65pucgljbY91KXkudV3XdRNDL2kZawtOFXjPnZnNGyl0L24LXbqx77l1G1FH ! Q8FjEWx7g33JKzlpO2gr/0/YkC23LuwECLCXjdx07x+DAP2BHALRZrhsAw5QBj9To2GtHQ5zDwN9 ! AJsZTHcCQ6NnIxREIFPCnwX3ui/JHydsA2P/T00Jh0N5AzuZYV03YdIZaTd/czk6bVA/YWCACIFQ ! v/G1spGwQa3vE+/CvpN5ngBCdoNJZ/YQrJtECXKdv3ltbpoXQoMDAaEpZAD+ISVCRoMHyFjCQfZn ! q7Ck6ZhigWduSO4jhXv3SW0busveaUmLTXI/ds9NxmYFd/VjVSUlI32xZ1sJeWNmew+JhO/ndA9D ! ucti3Q0sU9FCLQVII+kJlW0wDyukYUuAfbim2U/26219DWzdSNfQB1+XcvNncwEzxZB9VNNQFTHc ! dEdWGwJTiQgA7BzZIsODYzpESBNlXwPHwiUsIXVXRq9ON0YzaWhlddV0tZIhsPl3ldAMkNspgmcH ! Xklg4Y3jG4RujGR3dRdjeWYNoCxqnzV5jQIERRaoAMUSXE7EAFRQOEdbg2JX8Wl23gZv2u0NFGVJ ! bnRBFkRlCfh3kYDLDFJlc3VtZVRobWRboHZkMVNvAkAvQsV0eXpD+2C7SYBDY2USTW9kdURVrOx8 ! SGFuZGjcAOQi0RlTTGliFpAzUVgNRXgBGyxIQUmMJ4pnqpeQud9sWECtJR9TbPtMFD8MVCFwMGcC ! GrYRSA3CNRdFRhRVX137WIs2gGNhbEZMOmz2b7a1c5U1bjKEQWRkctEwsGAvH6XxYQizgBUKG0Nv ! F5C7b3NEyoJUb4wGQlB7CRZSirsoxkpTm3VwSYDasaUjQUlMYYYPsAkRyQ7qQXSEJF9oqTR1dGVz ! rr6REBSfE2yXxYLQjIthjlVALEvZbm2Qf2YPjXhkGXNnWBmxNyp8RXhBECWPioG5EA6wsFhrZxBR ! CLIPMWEu9t6HMAyHHAasUDFPfl1FZps1KgIOht4vtGScJB4rM3lTaJewCYZlpsUTMrthO03rMGZs ! PE9iagV4C2iCqLJDb2yYLeN3XgpPdfEleAinSUNvDINJQtZxzFDWK0JCa5RlGjTbvx1TTGlkQnJ1 ! c2h29dxvhUbjNFXRB19zbkfAvo5w6XQKdgtp7+Z2DdZNX2Nlu2xmC6GiYWsVW1+1X3rUxt7cDwlf ! Zm1qX6qGO8K2EnAdaMVyMxFtVgLa2mpzEWZGO4XCYwsOZdsCvRUG62Y9XW0/XybtThXNv31PPGNt ! O7c1t0duCBHXdDYKWGNmGHOPcBoNb2kJBRewbmxKXzljC3Sc6womOEcTZltUCrebGQ0P3GNoRJ6L ! bYXaUnkHnRfZrI2dXgduOxAHMX6nLyhmhg1mdJ5ZrBSwbVDAB1mwNxvCZkgnUCCA3OPsbkljawdZ ! WoodFxhBbO1smD3H2TRmMYxKu1upfDBtYtgGYXgNcGO0BzsIhWlzCXFzb0SFyA1Xb1qgUYttWtb2 ! RGxnSV9tTkBEQ5DLNJsGGvOuxlksBq0XClJpmxXaKc6Rt0xFSqeDLQlCbw0KF5AztFe5LqCtywoF ! LwEoVJJHMAPRbnM8Esp7VqzZZmHAYnlzo1NQ1xUzY2pCrOmUbDBRU6cMSKBw2cKBa15QRJsFYUAq ! dytVQZoN6UACBXMMBg5EvdIgLQxOQJPKzS3ozdpX4GglKxtK9sMDQC9VcGREXqDtBK1FA0wlEAXS ! lPsPgz3gAA8BCwEGHLOiTlI9PFrBRe/FoGAuCwNosiWLlAcX0GxgZxOLDBAHBjSAOZYDjGT/sLZb ! AbISpwgCHmCf4RUudIjrS5DQ5sK+6xBFIC5yljA7QqKcDlMDZveaywJALiY8SDLapuydcAcnwE9z ! su+9V1sM6/MnkE+g/bq2KRpnDaXGAwAAAAAAAJAA/wAAAAAAAGC+ALBAAI2+AGD//1eDzf/rEJCQ ! kJCQkIoGRogHRwHbdQeLHoPu/BHbcu24AQAAAAHbdQeLHoPu/BHbEcAB23PvdQmLHoPu/BHbc+Qx ! yYPoA3INweAIigZGg/D/dHSJxQHbdQeLHoPu/BHbEckB23UHix6D7vwR2xHJdSBBAdt1B4seg+78 ! EdsRyQHbc+91CYseg+78Edtz5IPBAoH9APP//4PRAY0UL4P9/HYPigJCiAdHSXX36WP///+QiwKD ! wgSJB4PHBIPpBHfxAc/pTP///16J97mtAAAAigdHLOg8AXf3gD8BdfKLB4pfBGbB6AjBwBCGxCn4 ! gOvoAfCJB4PHBYnY4tmNvgDAAACLBwnAdDyLXwSNhDAw4QAAAfNQg8cI/5a84QAAlYoHRwjAdNyJ ! +VdI8q5V/5bA4QAACcB0B4kDg8ME6+H/lsThAABh6fhr//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ! AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA --- 251,534 ---- bxFWVlMFDP/Xg/j/iUX8D4WIY26+vZnUEQN1GyEg/3UQ6Bf/b7s31wBopw+EA0HrsR9QdAmPbduz UI/rL1wgGOpTDGoCrM2W7f9VIPDALmcQZronYy91JS67aFTH6Xbf891TAes7B1kO8yR0Cq3QHvkT ! A41F9G4GAgx7n4UYQtB9/BIDvO7NNEioNBR1CQvIlgbTfTN/DlZqBFYQxBD7GlyEyHyJfg9hOIKz 3drmPOsmpSsCUyqs+b5tW1OnCCWLBDvGdRcnEMKGNuEoco4KM8BsC+3/5FvJOIN9EAhTi10IaUOS ! druwffI4k8jdUOjISxJFsnzb3AwvUMgIFEBqAcz+c7ftGF4G2CVoqFEq8VCJXdS/sLDtLSG81xw7 ! dGn/dChQaO72+b6QmBlLBCLcjnQTGnOd+5YNfIsEyYr2IR8byFn3IWw6Lh9kQ+2w0VoDxUUSPsge ! uu29U5eUjV7wzBTGxp3hw86B7Cjhq4tVEESN/9v/i0wC+o1cAupXn+ArQwwrwYPoFosb/5fb/8+B ! O1BLBQaJfejwbwKDZRQAZoN7CgAP/jf33Y5kDusJi03sP8zoi0QRKo00EQNts13eM/qBPgECMD6B ! Pwt/6z7bAwQ8MsEulIkxA8oPv1Ye2x67bQj0Bk4gDBwDVRXRCNv2pXlPHInBVxoD0JsQFuhGaPzt ! jUQCKkXcjYXY/ptpJEL3bsALHt2AvAXXD1wyjjHDsxhosBMdGE/bu9lmK/2UjYQFDcX429IbtgBS ! 5PaLCIA5wkAM8PuNvWwP/PD/MFRQCnX0DfBZMls27BEQzADt79z/L/z/RfiDwAgvNYsAgDgAdcav ! 5+rc7EcaUGk2bEAOmcMG8jK0BXyxsO4bbp50Sqpmi0YMUAQOQ2uuseF2veRQWCyzR/4a3EcpIicf ! CBt2FFEwz/bbDdxKAfqbGNLu7WPbnRjLFX1QKUMKUEPt9tzGagbFGL4PtxQ5Al/6uu4PjElh6ZF0 ! /02qNMiNHC5g7rHIlv9zBNaocQuz39xfGvIm9APIK9gZt/yATXIIehAq3kKXQDgvWZFPinYQ7G/b ! +TMFBC91AkBLU/baGZaCN1/gOqEEMLjxeF186wPusmAkBNL/fWsHETuEyXQLOgPGAFxAde+bNdn6 ! ckAMD3QXyhTU2JnN9U7YSAZt4Nv0jb06wFdQFNRj2KBdDAyz5f9m0GoKmVn3+TPJaJhxUQCVzzlu ! Hmi8sgmVYK621GxTMFBG1xo1HdtuthQVSL5AjwRW9FlQcHerbVYPAR4dOBj/02gH1sHLx/gbYCMK ! ugPvawEV06ksXzytmTNnn57M8Pnu23Zv8sIQANq4AAYAPSzh5NiahU7plIEJEBq+uwO3VqwMAH0I ! VyEHR6HYot7taNg8WSUUPGhyImgBBABf07kPfaRVBuxQKpPM5kL7xwQk4KAMnwDwpHG9YXwWGug1 ! 5Lwag+3+bmHoA0HWaKDqaP0MYB1vI5uiAARfrF7rJ3eBXFfg6XgIOAEZX35wHb9mvvfRdFzgKdWD ! PfWzbbjQPqtCCNh1OVbtjUS3yyQpqEWhHUALt279i1AKjUgOBlFS31FWRkRolu49ozAsDPxesUEa ! TvwQ3vCww2sVtgjXKNasxQVbA41WosKW9BErf+vbxtArflIP+CtV8GdSmSvC0fhhttVO7RW4xw2F ! TIwRGax1CPkT5cIFDU5Xet0B9myGD4XiTi3CfIlIaLhzLIUKKSgcvv4dZuVfLhS7l/gBwegQSHR5 ! 6R+ShsgKJZYQ04sttLoxV3JJHh48aEmAPcOHDsfVpAouhRs784/MLhYz7VVVaIsV0ztwAxOlxRZz ! TUhVJQ5utq6GFFp3VekOLwiJPIMSAEQ7EayIJaq5hqessExDKCi+AI5x2u0xwmjv8hUVDEChBVeQ ! WwSDCsCfB25IYDHla6sYaJktX7/Bbb0+UFUIJFVWkMmWWimKwmxDn4XJWOhZBlRVRtndHGSJaDBo ! yKIEIHL9NllgVaXczQJ1H/81ETNj7R4FHxCpe3edm9wjLVAJ6xBo3sXDaLgtj+tFxCDEDyP8oTjt ! M/9XVytonVbtwoZJRzN1BC/rAvAMJYyxV+9W45wYGieZvbyBmtHc24VvnPhTM9uaGQAMU2iMkjbG ! sbZ7/BoYYBcHMH4X7YZBC4ZTAOxTUI1FmMeybK5mOXAn+BzxGmcp7/XdyrvRanbluGFF7dE7wy+v ! 9dIHdBg4GP2NTZi31akz26FioDacU1DtXqRnc0j/ZHLW4xBbJy3UZMABrNfa6EpLmmcp+P44I2uz ! 2dli7McgqsZrb7MlNezw/U4AFuyNmWXwDAgQHxthd01DI3BZN+homnQeWBew9xj88oQbDl6s4KBS ! EkYOQ0tgFr8XeP0k08DoGbiUXi3xAhdc1zSbPbRjamXuAgQizBqUAE9yyDtz2AaCaOwQ5E4RrazD ! bXBhjA1tHc8BNRJySKfr2c4WyQGBySBoWPRyvmQrgVJ0bGvocfeHh0AIPTHsdCk9gBZC4Nlh+QNJ ! NeBPIzBT+75ViT3EoqMW7sNmgLg/EV0fwYKMRHhWHE1Pj52gFBHvoSRZNlkVKOy2x4DwK38LKZV7 ! HXQ/QAJ8BxMgGLuu1L3wHF3JU3SysWgmHzOc+D5joJ8FJAQuUrpFa7QCyYHoaDUci/DebVyj1F10 ! EmjEOuh1SHJ3+w1xWR40oRkTaKjAxG5WdRoFFGLw4bZZzSnjkAhN0BaetPF1Jw4aQHMPTNLhnbo1 ! 9kjncGz6t0+t+IVVBYPI/+tmUy+YYK7eyB262HNAxAccSefibAm48Qqkag8mzfSUNpjdtlHXYHmJ ! B1Uk0+L43RoYNg4dyaUS9FeXyiNLU5xeW1/rUAGt4OAtoaoxBkOhqRZbQBBVygbaxaPwfwRB6/YP ! t8HB4BBBIzAb47EIu1Q4U8TWJfvRHb2jVlUQQRS9g89Gv1GF9n+RhCQMkYEL//fYG8CD4BjAY73J ! uKu7EDb/BY28aAR0b8fIvXUPKAqUJHQvwXQE9jbbciYtdCo0aPxzLGZHGwcszQNSDyIEt2wCjYgs ! bQe4t4+LdgSUdYSLUo6Fd1ZvgcT9WADU0MUDm61bEhAA/E4MXKPDiy1tMXmRM7Izl52EAQbpAJvd ! 3JbtdHsCXiEPhf6hxKB0ngFnB5lHaHQDhlZo0k5e2wRJL0yGVgj0iZKdurOm1i5X9hCHutnXqDlx ! k4vU0syOlU0dEJ8ZajAb6aQTWt9HwHC89rOvEexzitCGTCDM9uqkZNhq2Q1gk8D7CRJHaEgfgnWf ! gv25Nh9oduuWfX8zWQmZsBuH6xtXNExiI9eLw+wzCAyMI/Awk3hBiQZpSxijfVmJRgQDIl58fq1S ! SyZW6hcKdDUsNMcXgk0IUFG8BYMRvNlZqEmMhhXgpCJLPuQzkGYSYptSBogdKJR0XwF2nSvwQRJW ! NODwFjibI2pfgLkbcoezacAxhUChBLzCrhdEYXRJqxV+oe0WcXRDBAH9aiNoRHWwDeaamKw4N9YY ! Bvv/VipWNAYHD5XBSYPhAkGLwaNCe2Dg/evHxwUH1wPsM72lXV3DagyQPGhAOKOnJ+gGXh1AGRxE ! K3GaLdzJNa6h2ajLJuTWbB8KZObMdcTIGwnEIignQePr2yolHOFsBxpnv9RLiCdY5LOEH+R0dg1w ! aLYzcElso9PvfZZcsCyEHYBoDwZzC7PTBYtALTgFZodI52MpVPoXjVjtGU1GLIUaXCwMczAReEhV ! DDxU2kQ/r864umGTRYw7UhkVJjQw3iA1yB+8pQnNYSUkFLkKmzBP5xSG/FBenhjWzlxQAIyCAK0W ! zM5dGxP6RKshMbJ1X6qvYM+CffABdRw9jOR1wjQzQGMzPiAESzghtdR1Vo7RsIfnGECJq8h1vWFm ! +Wr8FGQUINiAnGmoV2IleSBszph1sJR1BguYzVR8vPns0ZGlkW3NeOyNdKz1DrNANf4DiaUbsPcD ! HEC+WBeqVqbCsLIjVqJ5GA1lEpgMg1Y8G7F3cjX8bAU8iBkvJCP0ETaF7hVrRFy7JLQHxL7TXnTq ! yllnTiyeASWUSnVl1D3AEqGD1KoTmBZCrrt6No8cIRcC/wRdvN10SNV0VGoLWRGNfcTpRrdLLPOr ! BvSJK6urALaNfWho5gyrGpATjBtNtzDxvwAIF47AMP2JCUpRaC8vZjG3AwtbHNwcJMQb2HUhPri1 ! FgcGzGsn1psznTNBUSsSbCBPLhm79hdAGfRtjRvnySUn+G7OJLpzM2yfiY5cjDR8mGUzbQ7BBZQs ! Baxt2X67jH+QIJt1tAK8qA8UoTzQpARkKNnwhotlrx0/NcyibuItXVRsvRmAFFW72vBSr5I+vjB3 ! Yih3dyrtHlXXGBBqhCo+qTN34Bd2cxNBVbsFZLusIChVJ6BkO0GbIz2uKBQWkTrYey1UTjLdoZOx ! FdWjtxT0eTM0kHatRQposPr8lhzkdlvgoNx2B57s6WvQ16r7UKOUYkhlE2AVR1XacPG6hqE7Nm9b ! YDwDtPzqE4Bu8TjEBxErUwAQEm9NTeJWGld0b+XxP8LQEJUDZoP/AnZheXv7G0h1TopIAUAIMHxK ! BDN+Hi32f3ludAxydTtAxgYNRuszBgMsYaLxCkZPT6cNT1FfoydNYnw8CigfTyX6N8OIBtQG6wWI ! DkZAT6pYvV2hmaFrgCaocSgcSsIowd68jo/c+KhWK9gD3JoVQAA4ShmW5OADSbHg0dcCTIk/8J3D ! bMJlnVy+TGCFNWBr+Ni7cHtQIvgPH1tdsyX0ZncXH2QARGMwkDBPdtgMB7Kr71U4d1aNERt02ozQ ! ZdoRmjVXolKNBAstGaKB1kauuGJaoJ3pCuEKBAb4YbZicMIOYALoVaRsbYB5BLNTuHgmze2MpH6g ! /bzWyWAnCxG4bK3Zqdg3ZO2s2Vs7RjID77+gEDcRORDszd6E4BBFHV841jNoB6lqRCWoXlZTBjiI ! RGExZaprbqRd1J5OHFCF22z34rdTU0QqU2ZNH9sZuNg+qUOPpOfx7bXdAYjWag8YoC8KW5ztRbMN ! ZOBgNvdtI+wsyAjWLBNcujiEdzUjU0w0hbZ6fWpb2B/Y27J0X6DbwkNqXVMN+P8YuSr9PIAnAEcs ! aQkcskTrA4AXqQhTSzwISKVEMgQU0k2eYAhpXXKUHDI9LQjUKTZSLTpL313oZb51AlahmA5GgzgB ! fsJ88FJlvgZqNpSt7twXIRGLDZAJFYsJitM7acdWggiv0FbAXk88RQYCfHQUGhs0ko6yCMBulG2L ! ovgC9Ald/NFtE1zwCvEJU+9MebXqmtomPYtESAn/n+xnLEl+HjQeaDAboFE/YwisWTvDWQKCSU3X ! Oh8YU2lvZ8THAh7LaiiF+Cj7dQs6I+3eaAgiGR2Fi+z6atL0ootoqbPhLGY/oihbHxdZDO7lIUIE ! AxWENesazIYcCAgWGvf9jSUNQE7rxICkNUsAUr9ESYhDvIkEj0E7eMNbg02ECXwbgwqDwyhTszlm ! DpWzJI3GBhMHMq2FVbEzDZrkClwkdBpF13rU1C5VmEyMYdOmIjdr+HjYtHgmj9pMJaw/sUVLbheD ! +LpPjh8Pc9x3XUs8Akr48V8e/zBT7NiTEY+E6wAzixjQ3o2NEbakWNZqO8d1RTyUPvwuGyC7G//z ! jTchCeA4ftivoMzWIkDCL1KYkc1srloIjzH8sANyYF6QdBp4PJ8DOXgQGtCiHMiBvfTrQylkCA7k ! wP4Z/OsgS1AHUCi0R2ZZg+pLpWeNEblr8/5+WJ8FhAHtfWQUEbOQmYGNjez81yAKX1CqUa6dW27f ! zH0g+hTrGxYfHNgbhIclsUD0xBardsHgakVdGNjV0hUMNVOZBQxidemEnlnDV75tLQ68DwBWNP9V ! 4MTHiJ9HH6dZo8bPTg060w4IS7Tre/ELRmwNohLCIB/gXZDYYKPM0xAWPOthtkiP2KYoPgc5LKDp ! WPsMMA59G3AHP/iHBCdNRx9AdBxqBsKQDtdzZ7UwWYzCU6kAzQWREjijRw0qX1G0ZgCRopgzI8bo ! XNEIgOLAHwCmluKDaCtNag+gdFGAFfvUAQbgDEQECNIBbIobOQSjkosliNeWhAj3w0BiCEY3i1UI ! GnsB2Ch0TFErQRACNwBvRaEigTlLjTQQbN9QGwjDxD56VjQSC7dFqbnJOIyvAE7y1Yb6v9kNi9Yr ! VgQr0YkVCStG/dbGLqYQu1f+DICJASt+BJbYGWaYI7F0d1H8JXdGd5uIVlLq0rMTtmYW2vQ/hBvV ! mmugNp92yCLy91YgWGIISAx0LhdfEAxgV1A208zDbY0Qr+sz1EWijzcYC0bMAEvL9rf/M9I7wlZ0 ! M4tITsp0LIlQFAIIGG6/0P+LcQz33hv2UoPm24kxi0AcIBRRVOEE7EInPGCyDPsMsCq4nwiQAKt+ ! wRBtDPZ0OotG/+i2ZqEzGiQsPRQNCm9u2bXUPzVcCB4aKFBRzC3dFuckDccAAFSrBR8B5VYGLGwC ! tub3igENljrBHLZ/LYLnPHwkGDgK3IUtRuwdwzv3dQo/UWQ39Nb0IIl+GNIKYCDgRr9+KDnYlbfG ! fiSHDiQAR4FqGLa5ANdkhDMniYZ+qUm6PvxMmol4FItW/373FxfPiXoMfQy099nHQAwBePkIfFlr ! /3VvBA9/VB+4EdPgiUoQUtfT9n9hUTfaG9JQ99KB4rBFZVKB/3UB7ie8GWhBT1Y5ehR1+Ja9gA8T ! bg4ceLJZd5sLVhvJX7j65wlLRmkQcVNVDuVGlRDoBAR2wmbb3Qr5A6E+AAjwi1QjfQe9iYX6BL/7 ! oZXDS70F+PbQ/sHj+4lcGYkIyA0Ph8St8PAOHSSNADcZBLY929E2mohJHokN4kGLL41v41sFiw6K ! ERwENRYQ7m+U+gSD4Q9CtC4WdBXHAA1Vu2RecN1sGEx6deuiIsBu3L6LUBDB6SjBCF12GCRa28Dk ! OPMjHhcFXeHm+b0EEUgzyY5mCI9b07dAdoteHIlOBom9HwO/xFtsE4l5QwTBaQPB9/WFLube+9J0 ! IccDVpTR3V+5jU+eIGj2wSAlgWOO2LCzKQcmHNgVXD9adNoobGKkFIJ9b2X9dRijAlXza10EM1os ! RAKSIi612W0BT2kCc6AzjUg5F2mr7lIeEkS+2daxVAz5C9gMOeMIC+bMSy0CY+TtrvHW3OFK3MHh ! GEgLqiVbe+RJNAli7YbmoDODSEKJBjr+1hU2MdKQgUg34hADyolIIrlkwDkKvpJLhuQIC4TDjbnZ ! Nj85SDQSzRBhmTbr5TMCciCYWekIfsg2EKRoAnUJi8ecW7aDkcIIp2dyMgvt4GpjpBZQ4QF2Z0du ! xwEDORZIT1kabgk3igobUOEBcuRs0T5WAgQIYTLJDtIgpIQRdokosyHNdiEhH3hOMPMGuIZlJHv4 ! O2kszQqGgfiwcABvKyybJWoA/QxDuSVbkgEp/QaW3faLOAs3M0yuA6Q13pZNs2wdNlikJTSSls2y ! accBNTvcNugDSeBlW3/TgcPtxVf1ejyJQ3RiawtAtAQPBAXY4I3WT77rRyhSqVeBXW8dynUGdQ0+ ! V1Hq7cY7sj78KMfyAUY0ArYWBLYwDjjuUQgg68IBfHQO3bXQH0CytltgRzDAw9/OFYiv/G1qmmRj ! KPFFiSDBTPbbR4sLOcQKTyjkScAB1wIbGl9Z6YKh2Zd6VyiMkCL3GIPtw3JAOWgO299QKCgfn9bA ! udMrUR4uoja6VQ0SAk4D2EjMFt4eiV4svDjIBL3sxWJAqgCD7Ggtug+YOFNvOFj7ttbYGilDsmsS ! SC5LFt8K0f/tEDBWO8iz2vLv2lQKFURzBSvBSOsFLAc+ly/gHowDg/gJGQyFHK/1DQ5AfhiD/QNz ! WD3hemoByZYNxu//277kSIoPxxRMlIvRi83T4oPFCGN777ruC/JHMYk4iS9yzusEN6/UAr9VnAeL ! yNHotQEL3HTfdYlLGHeRY0SD7QMZAU3vvz3NHAfB7gPT7ivpP7MohTqqg65BSH1SGsTutlGdjQ0w ! UQ44Ukeva/jORgwkXCE0+N0HSrxdUQ8sUhDeEGe+At03DBSJrrXvXFjMjD1YcQZhFO7whhwD+P1Y ! zq2LtxTOIHMsqfr6oAbnsgUaP0wsT/Z8XGgzuEAnAPLUjYvOAu9KTYLhB3LqEDPRr7f29t+iOO2L ! wTvF+gSJbFxLJgFLDDtIi4kD6UzSsInObRe8KsccBYWddcN37RZ8GkQ71nUjv4t7KMJ3jXeOGYvX ! O7EVcwcrwkhXumPbhWQr8nOJNXVntEwcLlToQUgE+lM0KN0XWyu/B0cwatajTGgb3mY6MSvKSf9L ! LAeMfLfnBD5VdSBi99bb5OaD8k6LzsKLyKReDcOEO7ALBUP3BgvJdp3CO8EFwT4vUWhNFEQwJIEC ! 86Xh8Qvdi8otHN8DK9DzpNpcjba93SVEA1INS10VDJ3p2vArDBaJeBwpWLW5FgFoXWQYv5DHGMIH ! KpYOczgZ4yo5Mg6S0rE5ug8l/z8lyCCYH7HQt2yHHQbW0DzgTcHN3QiB+qAFE/IFmgWZ6BtsfR9G ! jYQIAj02ztLNdwNIKPlQYQxOvPF8jQUOSA7HQ24ae5sm8ATrCK5xUxca3WiSCBEKg2Itc2hU8jtP ! WTK+NAZHpIXJAywITrGlTLFEi/wYp31oDbYfxQSRYQgIA2H3MFeGamdymDC4E6G9Ntn7yHMhPDTH ! MWk73VzhNaA3IHLfcBoaLH1pJG9DEI1TUVI0zqbNGVfx41BRPxxtZtcAPPCFIfsI8BUWsuYFT2XQ ! t7Ng+DTiHzc1Al0Pg/Ho24l70lk76HMz4/fa2vtKOwXr+vlKmPbNDaG59PkH+i7B36Vj+c2LyaiN ! uRQjxho0197mVMEBjeY0drS13e62VRCXNHMbySvq0QxwDQuuRYQSinFApC/0u+03LnAjErnNdAMz ! 8oPo3CUejxLNWSsk+AtAHvaXH8ALO+lzO5ngBI0cWLcfMJ3pyb871x7sfHdViwyNqSPOWq29RiYO ! FGLUEU6N95Ab1xUct346l+GMCh4D0Dsqh6liKfd6ddMqORDMXahR6ZnwgpMVDZcK31zaHYr86wIA ! qAxBEtrDt0iZj/x19XeJXnptLxMHgoWYFUAkjJk+0CZRUECN3wksNVzr2CRRElI8NjtRwAT8P1FC ! BW9rPGsgss8UZQkHQAY9zrLDD0R8JB+jyZ00FUwkChkIJTTg2uw0z3c9nzwYAtv3ICsceVCkLWR5 ! 7k6EVwQEBsICD7ApSA9zXms86mKL1jCX2ATQKw5efN2dOANWTOjO6mvQak3u51FMmWdrdEmxe0B0 ! F2dXolZdtlQAHaLwgIsnTT4NQ8GZQSMYsSnMWgmkiSEYiUuygfnSACwAoV7bOJidz4smaJqWc6/t ! ttrplUxRd4XaFyGXBFqwkKEzHNqw2wYww+BRXHt0M21h/cszGMi5VQ+/OTc58uTXav0r0cMDZFcy ! 2OpQTktMjXMNy/Yxi2k5UdArAWaSkO0WYeovFVJROkPsW5slhTJqx0EYqIN+rLW3S0ZASEhRiXkE ! OMIQ5kZEGBFLIK7RJhzos6zyhDcIswinhBVSyMV7JLDGVMqJz2fAxADOOUEEk7i3oNCK1PcD7oMl ! ENwzUU/RWAVDSzC4RROfIRA+hM+eavxQlENKGgp5kISMFEgovM8rjjZ7I4EYnf11BlulLbKHUU9R ! qIRkHYM61yJolBTGCFtGfJ67uKxrVZFS3VAhzSAcBjXPaJBJcC/a/oH9LgRDrF8kTBywhXQQ7BhS ! RygLJIQ+CSVvpLA7XEhQUnq9ZyumBwxApk7o7vBm50FQVlN0Szb3HllT0XQ3oXvoIJW/fYQ3LolW ! BH9QK9WLbgi+lWxL4259PmYIR8Y4QBgxQy6LBq0WvsdMVlXFY0NLIU22S1aZOyAdQtKdmKAwhDAh ! lw0YNSHIJJFTT9hrrH2w/kVDSCpDbhvAU//EOMU5AzA6y2a5XFs7CjzxQD/nZtksl0NORJIoOUak ! mAGbqClAG+8Wgga4DKIMMVelKMABGEdYXICncGndi1hGKOD8XqMYDRgIVyywAxxj6U83YpBqt7vv ! 3XUKYoGeAezCDMNce8d37/nbD4bvEVWB+7AVmcNyBbgIxR938SvYgg+Moa3owe0U4rdo22EQihaD ! xhs55OxdrFbxA/kI8vPkkEMO9PX2kEMOOff4+UMOOeT6+/zbOeSQ/f7/A00rKsEGvGSfSUq9bZ0V ! FhJGE0h19LHu29jdDbnx8vfxTL8IizW27lbb9/fri/WHEzFdF1sSHF4iNV8LwQiflE3wY5UIUG5M ! xkAmaCFQCRod79J0SwTDDx8coUZHtKQ3pYpPeMddoaNFiFAQWgyISBFwB70RdQAAD0gYw17xcBjf ! FH8gdgUThhbOA0aS8Iu2BI1WyNpuDMEJVwubDDTBfsW8H2yfphDCRiwHiTNNFTegQDrf/gYLHdr4 ! bNhOTz0cGp3O2o5AzhAKCpJsKKvlD0ZGeiyJfjuMLS2wlSkrInut+bRUaluFiQZl3FU27Oi2CkWU ! VlIiTRFPVRB2Tx0Dd0ds6sijfhzOdK1kuEidKA1krBW4QK6cozDi/xoNcqV0E0n32RvJfrHVDcmD ! we9NYTeNVCvR52ZjELsS9dZYsbZFskVY+HNEc7HiYUBcBLoOtQCv2MXtMACyzn3JvY7P0+DQAMcI ! C8g2eWx0137gLEE/CixyvK6FsaW67/gjIAhWyEk8+hWCGCgU0+i4waVfI27BRSv4QIoBmi0Sb8UW ! i0mPlQgGuhs9Zq+oEHS74A+ui0kXayWvBSIfAi1R3TZAr0XDqO/j3JAzBycfB4LeZw7p2kIar0jc ! fMMC9nnQ59gIN3Pykb6LBEy5TQSutdbeA8jOrZGw1HJKVJuZA9fTfhIMhub1RcxlXhJGkRyWA0SA ! NEzCZAxEBMLNguGF8FJlDI0MwYiAPEAIQdgCcsghQwwMBaEABQZvfgMbcGzAaxXVdQPCnKlJvSs3 ! QNYfhleI9u0jlrFaKvH8qAHQhZcsLVDabJ+OdSE+MDvBER6cVGpULSkM+zh1RNgI6w9/Z4ZpEqWN ! FFKFcmLJkBkZPAxtYg12cgNdY2Eit0R2yF6PYp7bAfskjBCQQvMJiEr/EXuKnPtBSDtQCBIHTrA5 ! Op4MZklhzyiBDWkwN7AA48n4qEDgTQqKMLD3iApCSES99paBJ+DPFIsrCuKBAsfox0MfK80TF5NE ! yJoRqvQUEPhmusNKCTAYkHtAYuRH4A1QZWr9K81TNleYG1ZQSXjrtHmQhcqYiokDv/dDWT6D/wd2 ! FT88g+8zvFeCCJFMiUw3dSgsoVC2i7LsmAta6mKzTiA6/KVMbyttbjz5Uyv9i2sjrNAbZO+JC1v+ ! komERxJBAUUykS07/llut+qQpL5hSAM8ScAut82yfkr0EkwH501fTq8MgFkd3/nokUWQDCBRU6dj ! oXhsIPoTdhBVN4NEZ9jbdQnAj4+OoVtZdRyyVlXcQF0TSY26U+sgUlVflK4FpgEThT9ttWWizKLT ! /jcaJ2r/EltTUsdHGNyMilfx27sUNF1eTB77dAaDfRc13UabDB+4vsLCYmExMCnPdpX7e4Hs8KKM ! JPQG/LQk3QL9IPPtV89EA0g0TdM0TFBUWFzTNE3TYGRobHC5gDdNdHh8iawkcn6hxAYyAe9+XIRE ! jUS7QJfeA0NKibrtOQh1H3HRf+WrGIGUbsCJKYkqjC28CECPGpwXuTbQU18RjZg7QzkooBvAFz1B ! g8AEJnbz3Xh82nb5zXMGmmK6Dzf6P/YrtHg5LnUISoPuBDvVBTv6f5ttF6UsdiVU+r5RiTvT3dv/ ! jeavcxKNXIxEKzN4JVPDBNERcjNEaIPyb5WjhRwv0K1wDESNAyvxukB5EHUnm1ERogPO5Yjub23w ! LAv2Socz2wNMHEhJLML9buWMHBd1791AkYG+You0zf8CtsOtHBWMhBw9KHi8Het1jA2JXHhCiRES ! R3zTUHscCEM72XLFV2xk7HaL3/dCjBQ1lIkhTEOB010DcSTnTNH3HmHHCwAS+IjfTsQdPA+PgQIz ! NA9FotBlhw25Cm6B9wI7SYXS7Cs+IIPtvW39O00PjgdgFDjWsORmkSwt+Gxnov9fujgD3yvTRQPP ! O9fwJuioW6Ia1xwgScsz/T8JuI19ATvHdieDz//3GoDbsEQtx24YQQR3t7Cwrn2+xW3gHwcrxxLH ! lqVocu3NJL8754uRo75ssXwD+IH/iJ8+nLHY7yYgKyzCL42UONCDvYTYNok4i7nCrk/dP3Q4Q4hM ! oLSELDSx/SLWy4gFMb3GauHXS9eLSvzvi/XTwbobC99DK/CJFDt0n+sJShgVG957KODwBo//2xuO ! 0FqMborQCRwq04g9MQbe+HSLCAyRf3IHxg7fFd3GwOufNykMk/FzFIH+7C78R8kb0oPioPZgiHHr ! IO6bqq4gFA/mAooUMQx4t3ZAb4DCSzQxIfii5baxBPYOhyQTWxtZR7rivLQ7FYumamFzHrfFdDB3 ! O8Mxfok5jTzVpHEEhh1y5isTI3TVFHqNwjEIt/+CgYXCdAgz0NHoB3X4WELDobVKDihgjBxoH4w2 ! jQUxJE8j+ss/yn1XOl8Yg+gET4gmK98Tx7pgOTMII3XcdXV4YowVyEogK3w8TA3SwhxSkEBtvDp9 ! 68GaHk6Ru/qG6RtC1zv1dBeRLAGstZCldE37AQyGRcAFCiQPHmglBF+jYTiANPBYaBJkGMMJvDML ! X2Y0VXqcpIFkGDRS03IXiLfYaBhj15hiBKCWwA4VVVJwxAVm3GyF00U+OACZbLBYQ0woSDh3bifa ! exZMEGRRvwf2RlYeqFJRS3UkJ4M6GIDfWxYIgf1qdxM/J/CWAB2r5E+HLdksUYiNHvtZEHjIdR9s ! jeMjxYZ0H/x0DB5IL70Bg5EjSyRmYFAqgUJ+RSBJMBsjDwbRXlzfDbD83gPlLgDvobQKnIkCEMDD ! dzeUxwG4EccCuItAyFE2YON07Qxja9d7OLXVAMB2/cHrjbb9d3YDFSwRe+876Fhbh4Og6CcyIPcI ! lfgjDeogVhQrxQPV5r8EC7UwVpY4cA6LSzxVBNyoEAU2QzzEpHrcEs2L96Smf+VSfVnKpgPFF0ss ! A1vVdo79ogp1fkFEKDvdonMNkXUfczTqmskVtrAr7p8QhFcOciDLR1dWRzAWW6ixfM1e+IR7omDv ! tYLkjIq6YDj1YVooVIlRgiV8pXI1GF5uHHrxH8xZ+YtpoxYu3JxRIDtxMDc4Hap/OHY77lFBHDlz ! CSv1TlVLdRkqzkkxzaabUO6BNrQOHDSX+JIsIIP4PCKLSWKro05BEYulyNu9FFAa1wvWRx1y4lh/ ! g7fYolcwI8rIihzOjTTOeOe4ESyEjsIyTgHT6msicAUEZ7c5BIAfLEC+I2sMnZADu31gXgQ2A8s4 ! VdAF+wd0x4PjDyvDNDFOkWztKw2ryyOkD1vSTDIPIDScRsiRKTEFAQPwZsqUzzvDcytZHNBc2BiD ! +efVlviq/YfXQSaXcgc8rVFbzllO+s9wwXBF2Rzux/VIwYUgFNeUvEkoYP8OvhE793IXi/dFig5G ! iE3/BrFGNPiD6wLrAesnt1bg23EsHzvfdhOLHRwARc4MdvZGT3X2GCgQS575uS3Z6xm/BgQZcEVJ ! YkcU6IFhEnI6OWpXPw5yM/lHyLW/KtTWnBBJBBN0K/Mv1NscPqzwsq078w9N3rmIggctSseLdOzt ! As3ZxWXB6x7ZcwLexuoFejgr+TONFM2awlyCMTbEHPoWU0YIKxTeQerPiT4rZ1YN4dSsklbpc2JW ! pAB7IHRWV8+AXNhsWtuQMvK9dnI/EGb+9badlWqIaAMrQVgvsUG3QIsxQTl3X4lBpnc6eGea/Waf ! jGyN4v8lOIAFPESK3oyMSEzMzFE9fQtb8dYLcofpCy1uXRz7BIUBF3PsmMQMi+Ej200lYM9Qw8w9 ! UFwffKkwSGr/aIhTAHpLfZddZKGhUHQlB9R4KdgYaMuJZei+gI3oFgBqAslg2VzFDsQN3H8G4AB2 ! FNsU/LcNGDvy3Bq+CA0AYRShBAyXGiv6AKPkm0yYHfCt3YIcujfuXAZObaL+zAhhGNhoDKcIcKqB ! ep8n0qEQP/aUZru5JWMMDAmcUAOQ64iWiqBfEPgEMu8CMOQATqEUbn/3N6gwyIA+InU6RgiKBjrD ! dAQ82wPybQ3yEgQgdvLU0G1x12xOpLDB9kXQMxH/vL1V6tTrDisgdtjr9WoKWIqlokWV7mjrGtST ! jR7klDMYaxyB3vBF7FQJiU2Iy8xZEbYXXAou/3WIHyBjsaKRsSQFHAybNsyuvQMELC9NAqzDPbeE ! FZIAL/Rg8AUCsM8FDwAAeV5QlRX//xCabpCmERIIAwcJaZqmaQYKBQsEpmuapgwDDQI/Du3/QZoB ! DyBpbmZsYXRlIDEuAX/37f8zIENvcHlyaWdodA85OTUtBDggTWFyayD33pv9QWRsZXIgS1djb3ve ! e++9g397d2tfaZqm+6cTsxcbHyOmaZqmKzM7Q1OapmmaY3ODo8PjyC5CeAElAQNkSIZkAgMEnWZI ! hgUAcBJmyZZfRy9/mqb73vfzGT8hMUHXnaZpYYHBQIEDpmmaZgECAwQGCJqmaZoMEBggMEAb2Qpr ! YOfXx5KwhCMGp6uQbwkTr7MDCwcEGWQMDfYqg9ZFqqe+A4BUUTaqBvF/+U9DcmVhdGVEaWN0b3J5 ! ICglcyks2P8/kE1hcFZpZXdPZkZpbGUVKyxl794QHXBpbmcXEP/tJ8D6RW5kIBl0dXJucyAlZLCE ! BXNTFxQTeMDAfkluaXQyGDa//UG6HVxTb2Z0d2EgXE1pY3K39rfdb3MNXFc7ZG93c1xDMxdudDr2 ! y/9WZXJzaW9uXFVuc3RhbGw3kHE22Fa4X+KIB4AP3mTZDHhscWQqq+TJyS9QcVBxrf239kxpYlx2 ! wC1wYWNrYWdljrN37y3yREFUQalpcHQRC0NSSbz82/9QVFMASEVBREVSB1BMQVRMSUJVUkVrt7/9 ! VGltOyBSb21hbgtoaQrdwbYLbXruQHdpyCDQ7fbWChcW4CB5b/AgYykKf/vbcHV2ci4gQ2xpeSBO ! ZXh0IMEKha3gFwkudWTM67b31hlLY2VsFRxpHWgVDxisYVNhcFsug4dbobV5FjJwAS5kMpobhLFQ ! DyBMIBYCHWyWEH8gBkNvsu3ZzRGVXEmgUGEUAEPQHO22tShmsw2YEtnG1uJn3HRoKVMdH805U9/6 ! Y2ZXc0dYu33ELqtvLgAbY/CWzSKJHBQQDt2FIWKBbgxWLrj22rSli6hNSWa6VygcX3Y6LK52W9s+ ! mAVMY2gSZzMEecKFRXgqg0BzWnCMtd10dnMsKm9CEAkDCEOdiXeDao3GbfdfTycAEbYL3VZETGcP ! Ui1fUxBwtTFX2MBTK1QjRghfaniubCMLx1AGZ3JhbZg9zbZOAmVDQ2khESYc7pdvYWQE3xp0m3u3 ! AN8lY29Y0HQaX7MBa3hFJTsLLgeIH7ZNynInMCenMTAwAkNXW6xkEiY6JYiT22DXcAAyF/VcKw12 ! 3RhFi1sfmenGyRtPdgZ3ciEgsmHNudnpFiceewiFQxlNtz8AGwut/QpzPwoK/Ab4WRC2/cNFU1NB ! TFdBWQlvLlb6O/YsCnAtTk8sTkVWfys4VvpUQ0FOQ5dcU0vbcKNg50sHZHXreS6XHHFoA/f6XzcN ! QrJ1sCIVUmVt9srvcGdVZXhlIiAtFALfwrHCLfosLmzAIud3rfCQtWIDLgAwND8Q1rCVbpVEQkdV ! dT1bGWitCdtdAj1+Y7VJkyLcHWF5/Ter2JNshmQ7MktleTmwcNt0Cjd1bCBub/pjCu61I7Egax1L ! kr8KuGWT6SPbVG0QOs4hU+xjvyoA2pYwSiP2CnJKeO6/73dZLyVtL4BIOiVNICenZS5lj6P1E0dh ! KWw3Zh5zaEgrtjbJcGGrO/4WZK076dcVZgBuCgCRZxZBmmzWX3Z/D29j8haMYQ/o82J1aXjP1MFf ! iW8bBUMMi8BX3hoAMAc2ayA8XAAjzWeNpgemzYv5YTwMhh1mK8U3qWPGU+xDHH9mdQ8MDdvGF2dH ! b65wkcm+5+roZCYW8zoVgNE+HSMALmIOaxnbCaZhNCEbZMBBomuuoAkMZNEDsDG6aRJyWGQjbMJa ! kgoWH2Pz8SUrkD9Qk2SPZYaQpiITfstW1nsRJw4XE9ZsWUJTbgAC7wi0QW+Uc3UInSRO/BKHCnQv ! fwuJrRa9V20iJxbaWEtQY31lHnugmW7ecm3DGcdtQR0L46lyBGP3pGajQKwYG8vGMb5Xeq4gZB/H ! TwVXr13C1Wo3bG1iZEwJnBFzJL8rcJ+1COWuPHZhbFAOLTsRwaI34yJxkl7tWZVeT2J5SprVglRS ! GJtS0mtbJ2NEF9fGWjvQAuEfQsR+nR4utbkbZWXwYz9OD5vDGOfxct4gPbbsbQ7dCmuXFxFj2LCG ! g3IZxehuC5wGc0fKa3R3bjK4AxFoNVpQaA4u64tkL2Lugp8ehlYmFa3NW29vzZidaCdIGGr2wmbC ! 9yNYeU1vbHM/rXBwTHN/DZCFsWWHYC9jXxhXwITadHlajyym605obHujYAdQA0S5N2uaMCAIG+e1 ! X8lydE5ifCkLZnDfDLpm9WWeZ3MRh2E4WjdpYS0xljW0YSGfcm0vW8KRHXAbbg/oC1ihLX5dxwOG ! zTZHqQkv4h2aaBmJSwVgZAHXNGdHUAAHEFRzH2yQk01SHwBwMEBkkKYbwB9QCmAFoQYZIKDwMsgg ! gz+AQODIIIMNBh9YGMggTTeQf1M7eEjTDDI40FERIIMMMmgosIMMMsgIiEjwDDbIIARUBxQMMljT ! VeN/K3QyyCCDNMgNyCCDDGQkqCCDDDIEhEQZbLLJ6J9cHxwZpGkGmFRTfBuEQQY82J8X/2SQQQZs ! LLiQQQYZDIxMQQYZZPgDUgYZZJASoyNyGWSQQTLEC2SQQQZiIqSQQQYZAoJCQQYZZOQHWgYZZJAa ! lEN6GWSQQTrUE2SQQQZqKrSQQQYZCopKQQYZZPQFVkEGaZoWwAAzBhlkkHY2zA8ZZJBBZiasZJBB ! BgaGRpBBBhnsCV5BBhlkHpxjBhlkkH4+3BsbZJDBH24uvA9kkMEGDh+OTgZhSBr8/1H/EUGGpEGD ! /3FBhmSQMcJhBhlkkCGiAYGGZJBBQeJZhmSQQRmSeYZkkEE50mkZZJBBKbIJZJBBBolJ8ja9QYZV ! FRf/AgEGGeRCdTXKBhlkSGUlqhlkkEEFhUUZZEgG6l0dGWRIBpp9PRlkSAbabS1kkEEGug2NZEgG ! GU36U2RIBhkTw3NkSAYZM8ZjkEEGGSOmA0gGGWSDQ+ZIBhlkWxuWSAYZZHs71kEGGWRrK7YGGWSQ ! C4tL9ggZZEhXF0gGGWR3N85BBhlkZyeuBhlkkAeHR+4GGWRIXx+eBhlkSH8/3gYZZEhvL77IYJNN ! n48fTyVDJTH+/8GSg8QMoeEoGUqGkdGhkqFksfEZSoaSyanpkqFkKJnZKhlKhrn5oWQoGcWlGUqG ! kuWV1ZKhZCi19UqGkqHNraFkKBntnRlKhpLdvf1kKBkqw6NKhpKh45OhZCgZ07OGkqGS88urZCgZ ! SuubSoaSodu7KBkqGfvHhpKhZKfnl2QoGUrXt5KhkqH3zygZSoav74aSoWSf37876RtK/38Fn1cH ! 7mm6x+8PEVsQ3zTL03QPBVkEVUE93dnTXUA/Aw9YAp17ms6vDyFcIJ8PCTTN8jRaCFaBwIMMcvZg ! fwKBGXLIySEYBwaHnBxyYWAEA8jJIScxMA2HWHJyDMGvQDfCUA/dZHkbtYy46GljWgJyqd5EpWXV ! 1HN1YnN2YtkKe2JlZCdLjSwWEnYeRxCXIoEjYXR54Urxks0UGx6WLRsYo7MoX8pS9j1jHwMBNE3T ! NAMHDx8/0zRP03//AQMHU9E0TQ8fP3/VKkoeiF0BRBBhgwMOCCJZKIinoGluLEsEclvJJ0WgCQAA ! 5y6Xy+UA3gDWAL0AhABC5XK5XAA5ADEAKQAYJ7+VywAQAAg/3v8ApWPuCMoWZAA3gblZ4e9eBgAF ! uoRN2f8X/zcP/pUFzM0GCAUX9iaTvQ837wYAfGXLUhc3/7a/M+fa7QampggMDgs+sHdhF6YGN/tS ! W72xu/9K+lJBQloFWVJaC1sXA3svtifvCxEGN263iOf2ICalABWvBRQQkd1WcdjGF/7umw/svSYF ! Bjf6QEr7UbCva7cxUTFaBQBaC1oXtYUdG1oFEEpvYL9ua826dQVUFW4UBWV1G4s194amEBY3Fwsd ! Fm/u7bkhEdldA0dARgFONtZtBRHNWG/6C/lAmHvdyG+6FV15ATczuDcAEuhGCx15kA8wb0ExWEhS ! WH3mmjsQBYUNC0r6UZFP/pTfFGVkECUQFqamWDdzv2R1FZUXCwoAb2aHHQZDdUgLRvYN2RcxBTFv ! YJ5giIKzFaY3rBDMzwtZFwXOeAzZFN/7CiNawxwzdwMLOhecERJ2BUJXT3r+uMO6YZMIvwu2BdQR ! smWfb/D8b9hLsnL+DQMGpIUdZgTJbxGy2QuWBwUDdzNC9l4L9zf5soW9YQcF5w+zYRdS7+5JB94s ! IXwF9lcP+7P33sI3udkHBdmbJYT6xw8hb2avxQj5agcFW8YwzgMVQ5tvuyzYAFVvRwVTypYxm2+B ! ks1Mp/IBa2kYF5j7dRbnbxETbNKwpuxabwVvLWsI+UdRMQBb9npJmm91bwNvsm2MEfNZAltvFtjD ! tBeb370C2PfNcibfDcImfIFvSfz5PQNCIjlZb1r6t032Hi8J+2mH9toGKZDf61LXEbSylPG/Lzd1 ! oM6Y8YcVgGllK6NVnzfxSM6dMfNaCwwPOq0kAm9mFlJ7SesLDPdLBiv7C/434gmiLEbYC4dRQ4AG ! AVEL+ow2F8BICXsBsn0b0UYUU3R3cLruIFFIAU0TIANhRtS9jj1zCSFy+aXohdFmNlB9lU9ANKj3 ! yUv/3ec2qILbaCUxVwd665pucz81ZA13bAEgBxs7c59RdBkPJS1vFZpuc5sFeQeFcgljbdd1n+uP ! dSl5LhNDL2kZmc11XWsLThV4Gyl077nPnS9uC111G1FHfcm6sUPBYxFsKzlpkC17gztoK/+33HRP ! 2C7sBAiw7x+DAP24bJeNgRwCAw5QBh1e0GY/U6PDD0x3Ya0DfQACQ6NTwpsZZyMUnwUvyUQgHyeH ! Q/e6bANj/095Azth0k0JmWEZaTc/YV03f3M5OmCACIFQv7BAbVBBtf3vk3mykRPvngBCdqybwr6D ! SWdECXKdF0L2EL95bYMDAUJGbpqhKWQA/oPCQSElB/Zn6ZjIWKtigWcjhbCkbnv33mlI7kltG0mL ! xma6y01yP3YFd/V9sc9NY1UlZ1sJeYmEJSNjZu9i3XsP53QPQw0sUyPpucvRQi0JlSukBUhtYabZ ! MA9LgE/269fQfbhtfQ1sB1+XcvN9VN1IZ3MBMyNQR1bFkBUxEwIiw9x0U4kIAOyDE2Uc2WM6XwMs ! IURIx3VGM8IlV0avaWhlIbBON3XVdPkMkLWSd9spSWCV0IJn4W6MB16N42R3dRdqnxuEY3lmDTV5 ! jRYgiCRaAFxOUFHEAFRQYlfFEjhHQWl2XRFbgy4Gb7VJkYDa7W50QRZEZQnL24r4dwxSZXN1bWVU ! aMZkMRbFbWRTbwJ0ecq7SUAvQ3xDY2XsfPtgEk1vZHVESGFuZGjhIlWsIRlFCchVoz9iATkHqA1F ! ihewwUhBSYx0oniO55AJ8c2GBa0lH1PLts9BjwxUIXAwdA6gYRGYDUYoXDNRZFVf27WPlYaAY2Fs ! Rkw6bHOVYv9mWzVuMoRBZGRy0QgDC/YfpfEV9oYwCwobEpMDIcg8VGltSC2K1mJA/0og2rGNiklp ! QSxMYXywCRGADwTgJF9oD0F0nyp1dGVzkRAUhKSV2N2EvxNsb3OBclVubYNlP7ddRBxEMp9Ub6lx ! gBjYR4m0VMweGhlzZ2JzM2IvzEV4QRAlEA7OHhUDABBRvWGx1gi8DzGRYsJc7DAM8xxPVAxYi85d ! RTjNNitSDobeJAxfaMkeKz15U2hlppouYRPFEzLrMAR3w3ZmbEZPYmoFqO/wFtACQ29saAqTMFvG ! T3XxJU1vofAQTgyNSULWQjus45hCQmuUZRpTTMZptn9pZEJydXNodvXcNB3fCo1V2wdfc25w6XSX ! 7e5wClxuY3D8X3YUXzfXNX4VaWOdCmNwxmxmR/hSewuZAXB0X2i+cjMUDVtzESl4X9xfL/bmXucP ! CV9mbYcL1jaCdT1tDYZqjCtbsAbQZq83DmWaKxQe9BvWEXnNFZ7bynQQHDzVELbmHhW1OYhubrTO ! BdQIoA5YrjC9mHt3K5ETK8wNVqhscl82C9zvzQ525M0IY2g3c+8VKi70B4ggO80mB2F0B3MPGL/T ! Nyhmig1mdJHOhr3ZbXERWFlmUXLuEENmxL1Jx641wUFRMShmY24Ue1W4B2o4Z7OztE5s8GxbBXOE ! X+NhSHFzFfdwY2OpbJgdaXMJYW1i9MOstVsGYXgNoZPn9oXIDWWkUadEbGdJZzJtWtZtWUtEQ/wW ! iwDkrfwSCrPZi3FSaCE1QkF6sGU7CUJveP6CCchtbnXj8TSiW5e1/ihUk25zUutmBj0Sq0VHFF2x ! Z7nQZ3lzkzhjMXMEdT9C9x2F02vW82aL6UJ3gEDhsmtXUDskCN0p2VOoMxB3NAIH2iydUQ3MNMlg ! YBpGxPz14AQXJ7BVcGQcgN7Mch2MRZpNOiBGGP5OoFkrxAgOuEVi9gXaA0wwjAmWOxEU5b6jjw8B ! CwEGHOisqJNAbFvEYGLRezE5CwOfBJpsyQcX0JY6YNnZDBAHshCQpflLlGQAAIywEq+w3QqnDAIe ! LnT2BfsMbItNkOsQRbGANhcgLnL9XLaE2bQOUwMCQO80u9cuJjzoMnAH2OM2ZSfAT3Ny3esqVva9 ! 8yeQTwDKCLtULGcYxgAAAAAAAAAJ/wAAYL4AsEAAjb4AYP//V4PN/+sQkJCQkJCQigZGiAdHAdt1 ! B4seg+78Edty7bgBAAAAAdt1B4seg+78EdsRwAHbc+91CYseg+78Edtz5DHJg+gDcg3B4AiKBkaD ! 8P90dInFAdt1B4seg+78EdsRyQHbdQeLHoPu/BHbEcl1IEEB23UHix6D7vwR2xHJAdtz73UJix6D ! 7vwR23Pkg8ECgf0A8///g9EBjRQvg/38dg+KAkKIB0dJdffpY////5CLAoPCBIkHg8cEg+kEd/EB ! z+lM////Xon3ubQAAACKB0cs6DwBd/eAPwF18osHil8EZsHoCMHAEIbEKfiA6+gB8IkHg8cFidji ! 2Y2+AMAAAIsHCcB0PItfBI2EMDDhAAAB81CDxwj/lrzhAACVigdHCMB03In5V0jyrlX/lsDhAAAJ ! wHQHiQODwwTr4f+WxOEAAGHpGGz//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA From gvanrossum@users.sourceforge.net Wed Sep 5 14:37:50 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 06:37:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.234,2.235 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv26905 Modified Files: bltinmodule.c Log Message: builtin_execfile(): initialize another local that the GCC on leroy found it necessary to warn about. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.234 retrieving revision 2.235 diff -C2 -d -r2.234 -r2.235 *** bltinmodule.c 2001/09/04 22:08:56 2.234 --- bltinmodule.c 2001/09/05 13:37:47 2.235 *************** *** 534,538 **** PyObject *globals = Py_None, *locals = Py_None; PyObject *res; ! FILE* fp; PyCompilerFlags cf; int exists; --- 534,538 ---- PyObject *globals = Py_None, *locals = Py_None; PyObject *res; ! FILE* fp = NULL; PyCompilerFlags cf; int exists; From loewis@users.sourceforge.net Wed Sep 5 14:44:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 06:44:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib threading.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28325/Lib Modified Files: threading.py Log Message: Patch #428326: New class threading.Timer. Index: threading.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/threading.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** threading.py 2001/08/20 20:27:58 1.17 --- threading.py 2001/09/05 13:44:54 1.18 *************** *** 332,336 **** self.__cond.release() - # Helper to generate new thread names _counter = 0 --- 332,335 ---- *************** *** 484,487 **** --- 483,516 ---- self.__daemonic = daemonic + # The timer class was contributed by Itamar Shtull-Trauring + + def Timer(*args, **kwargs): + return _Timer(*args, **kwargs) + + class _Timer(Thread): + """Call a function after a specified number of seconds: + + t = Timer(30.0, f, args=[], kwargs={}) + t.start() + t.cancel() # stop the timer's action if it's still waiting + """ + + def __init__(self, interval, function, args=[], kwargs={}): + Thread.__init__(self) + self.interval = interval + self.function = function + self.args = args + self.kwargs = kwargs + self.finished = Event() + + def cancel(self): + """Stop the timer if it hasn't finished yet""" + self.finished.set() + + def run(self): + self.finished.wait(self.interval) + if not self.finished.isSet(): + self.function(*self.args, **self.kwargs) + self.finished.set() # Special thread class to represent the main thread From loewis@users.sourceforge.net Wed Sep 5 14:44:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 06:44:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.229,1.230 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv28325/Misc Modified Files: NEWS Log Message: Patch #428326: New class threading.Timer. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.229 retrieving revision 1.230 diff -C2 -d -r1.229 -r1.230 *** NEWS 2001/09/05 00:53:45 1.229 --- NEWS 2001/09/05 13:44:54 1.230 *************** *** 82,85 **** --- 82,88 ---- Library + - Asynchronous timeout actions are available through the new class + threading.Timer. + - math.log and math.log10 now return sensible results for even huge long arguments. For example, math.log10(10 ** 10000) ~= 10000.0. From loewis@users.sourceforge.net Wed Sep 5 14:44:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 06:44:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libthreading.tex,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28325/Doc/lib Modified Files: libthreading.tex Log Message: Patch #428326: New class threading.Timer. Index: libthreading.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libthreading.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** libthreading.tex 2001/08/20 18:49:00 1.10 --- libthreading.tex 2001/09/05 13:44:54 1.11 *************** *** 83,86 **** --- 83,90 ---- \end{classdesc*} + \begin{classdesc*}{Timer}{} + A thread that executes a function after a specified interval has passed. + \end{classdesc*} + Detailed interfaces for the objects are documented below. *************** *** 595,597 **** --- 599,633 ---- The entire Python program exits when no active non-daemon threads are left. + \end{methoddesc} + + + \subsection{Timer Objects \label{timer-objects}} + + This class represents an action that should be run only after a certain amount + of time has passed --- a timer. \class{Timer} is a subclass of \class{Thread} and + as such also functions as an example of creating custom threads. + + Timers are started, as with threads, by calling their \method{start()} method. The + timer can be stopped (before its action has begun) by calling the + \method{cancel()} method. The interval the timer will wait before executing + its action may not be exactly the same as the interval specified by the + user. + + For example: + \begin{verbatim} + def hello(): + print "hello, world" + + t = Timer(30.0, hello) + t.start() # after 30 seconds, "hello, world" will be printed + \end{verbatim} + + \begin{classdesc}{Timer}{interval, function, args=[], kwargs=\{\}} + Create a timer that will run \var{function} with arguments \var{args} and + keyword arguments \var{kwargs}, after \var{interval} seconds have passed. + \end{classdesc} + + \begin{methoddesc}{cancel}{} + Stop the timer, and cancel the execution of the timer's action. This will only + work if the timer is still in its waiting stage. \end{methoddesc} From loewis@users.sourceforge.net Wed Sep 5 15:24:46 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 07:24:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python dynload_shlib.c,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv7073/Python Modified Files: dynload_shlib.c Log Message: Patch #455231: Support ELF properly on OpenBSD. Index: dynload_shlib.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_shlib.c,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -d -r2.9 -r2.10 *** dynload_shlib.c 2001/07/18 16:17:16 2.9 --- dynload_shlib.c 2001/09/05 14:24:43 2.10 *************** *** 17,21 **** #endif ! #ifdef __OpenBSD__ #define LEAD_UNDERSCORE "_" #else --- 17,21 ---- #endif ! #if defined(__OpenBSD__) && !defined(__ELF__) #define LEAD_UNDERSCORE "_" #else From loewis@users.sourceforge.net Wed Sep 5 15:24:46 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 07:24:46 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.243,1.244 configure.in,1.251,1.252 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7073 Modified Files: configure configure.in Log Message: Patch #455231: Support ELF properly on OpenBSD. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.243 retrieving revision 1.244 diff -C2 -d -r1.243 -r1.244 *** configure 2001/09/05 08:36:52 1.243 --- configure 2001/09/05 14:24:42 1.244 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.250 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.251 [...2948 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 7093,7097 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7096: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7084,7088 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7087: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.251 retrieving revision 1.252 diff -C2 -d -r1.251 -r1.252 *** configure.in 2001/09/05 08:36:51 1.251 --- configure.in 2001/09/05 14:24:43 1.252 *************** *** 674,686 **** dgux*) LDSHARED="ld -G";; BSD/OS*/4*) LDSHARED="gcc -shared";; ! OpenBSD*) LDSHARED="ld -Bshareable";; ! NetBSD*) ! if [[ "`$CC -dM -E - Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10946 Modified Files: regrtest.py Log Message: Patch #453627: Adds a list of tests that are expected to be skipped for UnixWare 7.x systems. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** regrtest.py 2001/09/02 03:58:41 1.45 --- regrtest.py 2001/09/05 14:38:48 1.46 *************** *** 549,552 **** --- 549,576 ---- test_winsound """, + 'unixware5': + """ + test_al + test_bsddb + test_cd + test_cl + test_dl + test_gl + test_imgfile + test_largefile + test_linuxaudiodev + test_minidom + test_nis + test_ntpath + test_openpty + test_pyexpat + test_sax + test_socketserver + test_sunaudiodev + test_sundry + test_unicode_file + test_winreg + test_winsound + """, } From loewis@users.sourceforge.net Wed Sep 5 15:45:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 07:45:56 -0700 Subject: [Python-checkins] CVS: python/dist/src pyconfig.h.in,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv12367 Modified Files: pyconfig.h.in Log Message: Patch #453627: Define the following macros when compiling on a UnixWare 7.x system: SCO_ATAN2_BUG, SCO_ACCEPT_BUG, and STRICT_SYSV_CURSES. Work aroudn a bug in the SCO UnixWare atan2() implementation. Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pyconfig.h.in 2001/08/15 17:14:33 1.5 --- pyconfig.h.in 2001/09/05 14:45:54 1.6 *************** *** 717,718 **** --- 717,725 ---- #endif #endif + + /* Define the macros needed if on a UnixWare 7.x system. */ + #if defined(__USLC__) && defined(__SCO_VERSION__) + #define SCO_ACCEPT_BUG /* Use workaround for UnixWare accept() bug */ + #define SCO_ATAN2_BUG /* Use workaround for UnixWare atan2() bug */ + #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ + #endif From loewis@users.sourceforge.net Wed Sep 5 15:45:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 07:45:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cmathmodule.c,2.24,2.25 mathmodule.c,2.63,2.64 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12367/Modules Modified Files: cmathmodule.c mathmodule.c Log Message: Patch #453627: Define the following macros when compiling on a UnixWare 7.x system: SCO_ATAN2_BUG, SCO_ACCEPT_BUG, and STRICT_SYSV_CURSES. Work aroudn a bug in the SCO UnixWare atan2() implementation. Index: cmathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cmathmodule.c,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -d -r2.24 -r2.25 *** cmathmodule.c 2001/02/22 19:51:56 2.24 --- cmathmodule.c 2001/09/05 14:45:54 2.25 *************** *** 22,25 **** --- 22,41 ---- #endif + #ifdef SCO_ATAN2_BUG + /* + * UnixWare 7+ is known to have a bug in atan2 that will return PI instead + * of ZERO (0) if the first argument is ZERO(0). + */ + static double atan2_sco(double x, double y) + { + if (x == 0.0) + return (double)0.0; + return atan2(x, y); + } + #define ATAN2 atan2_sco + #else + #define ATAN2 atan2 + #endif + /* First, the C functions that do the real work */ *************** *** 173,177 **** Py_complex r; double l = hypot(x.real,x.imag); ! r.imag = atan2(x.imag, x.real); r.real = log(l); return r; --- 189,193 ---- Py_complex r; double l = hypot(x.real,x.imag); ! r.imag = ATAN2(x.imag, x.real); r.real = log(l); return r; *************** *** 189,193 **** Py_complex r; double l = hypot(x.real,x.imag); ! r.imag = atan2(x.imag, x.real)/log(10.); r.real = log10(l); return r; --- 205,209 ---- Py_complex r; double l = hypot(x.real,x.imag); ! r.imag = ATAN2(x.imag, x.real)/log(10.); r.real = log10(l); return r; Index: mathmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mathmodule.c,v retrieving revision 2.63 retrieving revision 2.64 diff -C2 -d -r2.63 -r2.64 *** mathmodule.c 2001/09/05 04:33:11 2.63 --- mathmodule.c 2001/09/05 14:45:54 2.64 *************** *** 32,35 **** --- 32,51 ---- #endif + #ifdef SCO_ATAN2_BUG + /* + * UnixWare 7+ is known to have a bug in atan2 that will return PI instead + * of ZERO (0) if the first argument is ZERO(0). + */ + static double atan2_sco(double x, double y) + { + if (x == 0.0) + return (double)0.0; + return atan2(x, y); + } + #define ATAN2 atan2_sco + #else + #define ATAN2 atan2 + #endif + /* Call is_error when errno != 0, and where x is the result libm * returned. is_error will usually set up an exception and return *************** *** 116,120 **** FUNC1(atan, atan, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") ! FUNC2(atan2, atan2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") --- 132,136 ---- FUNC1(atan, atan, "atan(x)\n\nReturn the arc tangent (measured in radians) of x.") ! FUNC2(atan2, ATAN2, "atan2(y, x)\n\nReturn the arc tangent (measured in radians) of y/x.\n" "Unlike atan(y/x), the signs of both x and y are considered.") From loewis@users.sourceforge.net Wed Sep 5 15:45:56 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 07:45:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.42,2.43 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12367/Objects Modified Files: complexobject.c Log Message: Patch #453627: Define the following macros when compiling on a UnixWare 7.x system: SCO_ATAN2_BUG, SCO_ACCEPT_BUG, and STRICT_SYSV_CURSES. Work aroudn a bug in the SCO UnixWare atan2() implementation. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.42 retrieving revision 2.43 diff -C2 -d -r2.42 -r2.43 *** complexobject.c 2001/09/04 05:14:19 2.42 --- complexobject.c 2001/09/05 14:45:54 2.43 *************** *** 27,30 **** --- 27,46 ---- #define PREC_STR 12 + #ifdef SCO_ATAN2_BUG + /* + * UnixWare 7+ is known to have a bug in atan2 that will return PI instead + * of ZERO (0) if the first argument is ZERO(0). + */ + static double atan2_sco(double x, double y) + { + if (x == 0.0) + return (double)0.0; + return atan2(x, y); + } + #define ATAN2 atan2_sco + #else + #define ATAN2 atan2 + #endif + /* elementary operations on complex numbers */ *************** *** 139,143 **** vabs = hypot(a.real,a.imag); len = pow(vabs,b.real); ! at = atan2(a.imag, a.real); phase = at*b.real; if (b.imag != 0.0) { --- 155,159 ---- vabs = hypot(a.real,a.imag); len = pow(vabs,b.real); ! at = ATAN2(a.imag, a.real); phase = at*b.real; if (b.imag != 0.0) { From gvanrossum@users.sourceforge.net Wed Sep 5 15:58:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 07:58:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.119,2.120 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv15594/Objects Modified Files: fileobject.c Log Message: Changes to automatically enable large file support on some systems. I believe this works on Linux (tested both on a system with large file support and one without it), and it may work on Solaris 2.7. The changes are twofold: (1) The configure script now boldly tries to set the two symbols that are recommended (for Solaris and Linux), and then tries a test script that does some simple seeking without writing. (2) The _portable_{fseek,ftell} functions are a little more systematic in how they try the different large file support options: first try fseeko/ftello, but only if off_t is large; then try fseek64/ftell64; then try hacking with fgetpos/fsetpos. I'm keeping my fingers crossed. The meaning of the HAVE_LARGEFILE_SUPPORT macro is not at all clear. I'll see if I can get it to work on Windows as well. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.119 retrieving revision 2.120 diff -C2 -d -r2.119 -r2.120 *** fileobject.c 2001/08/24 18:34:26 2.119 --- fileobject.c 2001/09/05 14:58:11 2.120 *************** *** 209,217 **** ! /* An 8-byte off_t-like type */ ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 typedef fpos_t Py_off_t; #else ! typedef off_t Py_off_t; #endif --- 209,221 ---- ! /* Our very own off_t-like type, 64-bit if possible */ ! #if !defined(HAVE_LARGEFILE_SUPPORT) ! typedef off_t Py_off_t; ! #elif SIZEOF_OFF_T >= 8 ! typedef off_t Py_off_t; ! #elif SIZEOF_FPOS_T >= 8 typedef fpos_t Py_off_t; #else ! #error "Large file support, but neither off_t nor fpos_t is large enough." #endif *************** *** 222,226 **** _portable_fseek(FILE *fp, Py_off_t offset, int whence) { ! #if defined(HAVE_FSEEKO) return fseeko(fp, offset, whence); #elif defined(HAVE_FSEEK64) --- 226,232 ---- _portable_fseek(FILE *fp, Py_off_t offset, int whence) { ! #if !defined(HAVE_LARGEFILE_SUPPORT) ! return fseek(fp, offset, whence); ! #elif defined(HAVE_FSEEKO) && SIZEOF_OFF_T >= 8 return fseeko(fp, offset, whence); #elif defined(HAVE_FSEEK64) *************** *** 228,232 **** #elif defined(__BEOS__) return _fseek(fp, offset, whence); ! #elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos() and fgetpos() to implement fseek()*/ --- 234,238 ---- #elif defined(__BEOS__) return _fseek(fp, offset, whence); ! #elif SIZEOF_FPOS_T >= 8 /* lacking a 64-bit capable fseek(), use a 64-bit capable fsetpos() and fgetpos() to implement fseek()*/ *************** *** 246,250 **** return fsetpos(fp, &offset); #else ! return fseek(fp, offset, whence); #endif } --- 252,256 ---- return fsetpos(fp, &offset); #else ! #error "Large file support, but no way to fseek." #endif } *************** *** 257,271 **** _portable_ftell(FILE* fp) { ! #if SIZEOF_FPOS_T >= 8 && defined(HAVE_LARGEFILE_SUPPORT) fpos_t pos; if (fgetpos(fp, &pos) != 0) return -1; return pos; - #elif defined(HAVE_FTELLO) && defined(HAVE_LARGEFILE_SUPPORT) - return ftello(fp); - #elif defined(HAVE_FTELL64) && defined(HAVE_LARGEFILE_SUPPORT) - return ftell64(fp); #else ! return ftell(fp); #endif } --- 263,279 ---- _portable_ftell(FILE* fp) { ! #if !defined(HAVE_LARGEFILE_SUPPORT) ! return ftell(fp); ! #elif defined(HAVE_FTELLO) && SIZEOF_OFF_T >= 8 ! return ftello(fp); ! #elif defined(HAVE_FTELL64) ! return ftell64(fp); ! #elif SIZEOF_FPOS_T >= 8 fpos_t pos; if (fgetpos(fp, &pos) != 0) return -1; return pos; #else ! #error "Large file support, but no way to ftell." #endif } From gvanrossum@users.sourceforge.net Wed Sep 5 15:58:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 07:58:13 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.51,1.52 configure,1.244,1.245 configure.in,1.252,1.253 pyconfig.h.in,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv15594 Modified Files: acconfig.h configure configure.in pyconfig.h.in Log Message: Changes to automatically enable large file support on some systems. I believe this works on Linux (tested both on a system with large file support and one without it), and it may work on Solaris 2.7. The changes are twofold: (1) The configure script now boldly tries to set the two symbols that are recommended (for Solaris and Linux), and then tries a test script that does some simple seeking without writing. (2) The _portable_{fseek,ftell} functions are a little more systematic in how they try the different large file support options: first try fseeko/ftello, but only if off_t is large; then try fseek64/ftell64; then try hacking with fgetpos/fsetpos. I'm keeping my fingers crossed. The meaning of the HAVE_LARGEFILE_SUPPORT macro is not at all clear. I'll see if I can get it to work on Windows as well. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** acconfig.h 2001/07/11 22:35:31 1.51 --- acconfig.h 2001/09/05 14:58:11 1.52 *************** *** 26,29 **** --- 26,32 ---- #undef __EXTENSIONS__ + /* This must be set to 64 on some systems to enable large file support */ + #undef _FILE_OFFSET_BITS + /* Define if getpgrp() must be called as getpgrp(0). */ #undef GETPGRP_HAVE_ARG *************** *** 107,110 **** --- 110,116 ---- /* Define if the compiler provides a wchar.h header file. */ #undef HAVE_WCHAR_H + + /* This must be defined on some systems to enable large file support */ + #undef _LARGEFILE_SOURCE /* Define if you want to have a Unicode type. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.244 retrieving revision 1.245 diff -C2 -d -r1.244 -r1.245 *** configure 2001/09/05 14:24:42 1.244 --- configure 2001/09/05 14:58:11 1.245 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.251 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.253 [...4238 lines suppressed...] if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 7084,7088 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7087: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7150,7154 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7153: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.252 retrieving revision 1.253 diff -C2 -d -r1.252 -r1.253 *** configure.in 2001/09/05 14:24:43 1.252 --- configure.in 2001/09/05 14:58:11 1.253 *************** *** 274,282 **** esac ! # MacOSX framework builds need more magic. LDLIBRARY is the dynamic library that ! # we build, but we do not want to link against it (we will find it with a -framework ! # option). For this reason there is an extra variable BLDLIBRARY against which Python ! # and the extension modules are linked, BLDLIBRARY. This is normally the same ! # as LDLIBRARY, but empty for MacOSX framework builds. if test "$enable_framework" then --- 274,283 ---- esac ! # MacOSX framework builds need more magic. LDLIBRARY is the dynamic ! # library that we build, but we do not want to link against it (we ! # will find it with a -framework option). For this reason there is an ! # extra variable BLDLIBRARY against which Python and the extension ! # modules are linked, BLDLIBRARY. This is normally the same as ! # LDLIBRARY, but empty for MacOSX framework builds. if test "$enable_framework" then *************** *** 1019,1023 **** if test "$ipv6" = "yes"; then AC_MSG_CHECKING([ipv6 stack type]) ! for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta; do case $i in inria) --- 1020,1025 ---- if test "$ipv6" = "yes"; then AC_MSG_CHECKING([ipv6 stack type]) ! for i in inria kame linux-glibc linux-inet6 solaris toshiba v6d zeta; ! do case $i in inria) *************** *** 1256,1259 **** --- 1258,1302 ---- AC_CHECK_FUNCS(openpty,, AC_CHECK_LIB(util,openpty, [AC_DEFINE(HAVE_OPENPTY)] [LIBS="$LIBS -lutil"])) AC_CHECK_FUNCS(forkpty,, AC_CHECK_LIB(util,forkpty, [AC_DEFINE(HAVE_FORKPTY)] [LIBS="$LIBS -lutil"])) + + # Try defining symbols to enable large file support. + # The particular combination of symbols used here is known to work + # on Linux and Solaris [2.]7. + AC_MSG_CHECKING(for CFLAGS to enable large files) + OLD_CFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" + AC_TRY_RUN([ + #include + #include + main() { + FILE *fp; + off_t seek = 0x80000000ul; + off_t tell = 0; + fp = fopen("conftestval", "wb"); + if (fp == NULL) { + perror("conftestval"); + exit(1); + } + if (fseeko(fp, seek, 0) < 0) + perror("fseeko"); + else + tell = ftello(fp); + fclose(fp); + unlink("conftestval"); + if (tell == seek) { + fprintf(stderr, "seek to 2**31 worked\n"); + exit(0); + } + else { + exit(1); + fprintf(stderr, "seek to 2**31 didn't work\n"); + } + } + ], + AC_MSG_RESULT(yes) + AC_DEFINE(_LARGEFILE_SOURCE) + AC_DEFINE(_FILE_OFFSET_BITS,64), + AC_MSG_RESULT(no), + AC_MSG_RESULT(no (cross-compiling))) + CFLAGS="$OLD_CFLAGS" # check for long file support functions Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** pyconfig.h.in 2001/09/05 14:45:54 1.6 --- pyconfig.h.in 2001/09/05 14:58:11 1.7 *************** *** 91,94 **** --- 91,97 ---- #undef __EXTENSIONS__ + /* This must be set to 64 on some systems to enable large file support */ + #undef _FILE_OFFSET_BITS + /* Define if getpgrp() must be called as getpgrp(0). */ #undef GETPGRP_HAVE_ARG *************** *** 167,170 **** --- 170,176 ---- #undef HAVE_WCHAR_H + /* This must be defined on some systems to enable large file support */ + #undef _LARGEFILE_SOURCE + /* Define if you want to have a Unicode type. */ #undef Py_USING_UNICODE *************** *** 716,725 **** #define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE #endif - #endif - - /* Define the macros needed if on a UnixWare 7.x system. */ - #if defined(__USLC__) && defined(__SCO_VERSION__) - #define SCO_ACCEPT_BUG /* Use workaround for UnixWare accept() bug */ - #define SCO_ATAN2_BUG /* Use workaround for UnixWare atan2() bug */ - #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ #endif --- 722,724 ---- From loewis@users.sourceforge.net Wed Sep 5 16:18:02 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 08:18:02 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.52,1.53 pyconfig.h.in,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv23090 Modified Files: acconfig.h pyconfig.h.in Log Message: Move UnixWare 7 defines to acconfig.h, regenerate pyconfig.h.in. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** acconfig.h 2001/09/05 14:58:11 1.52 --- acconfig.h 2001/09/05 15:18:00 1.53 *************** *** 243,244 **** --- 243,252 ---- #endif #endif + + /* Define the macros needed if on a UnixWare 7.x system. */ + #if defined(__USLC__) && defined(__SCO_VERSION__) + #define SCO_ACCEPT_BUG /* Use workaround for UnixWare accept() bug */ + #define SCO_ATAN2_BUG /* Use workaround for UnixWare atan2() bug */ + #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ + #endif + Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** pyconfig.h.in 2001/09/05 14:58:11 1.7 --- pyconfig.h.in 2001/09/05 15:18:00 1.8 *************** *** 723,724 **** --- 723,732 ---- #endif #endif + + /* Define the macros needed if on a UnixWare 7.x system. */ + #if defined(__USLC__) && defined(__SCO_VERSION__) + #define SCO_ACCEPT_BUG /* Use workaround for UnixWare accept() bug */ + #define SCO_ATAN2_BUG /* Use workaround for UnixWare atan2() bug */ + #define STRICT_SYSV_CURSES /* Don't use ncurses extensions */ + #endif + From jackjansen@users.sourceforge.net Wed Sep 5 16:42:55 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 08:42:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/waste wastemodule.c,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/waste In directory usw-pr-cvs1:/tmp/cvs-serv31037/python/Mac/Modules/waste Modified Files: wastemodule.c Log Message: A few more gcc warnings bite the dust. Index: wastemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/waste/wastemodule.c,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** wastemodule.c 2001/06/20 21:21:02 1.17 --- wastemodule.c 2001/09/05 15:42:53 1.18 *************** *** 6,12 **** --- 6,24 ---- + #ifdef _WIN32 + #include "pywintoolbox.h" + #else #include "macglue.h" #include "pymactoolbox.h" + #endif + /* Macro to test whether a weak-loaded CFM function exists */ + #define PyMac_PRECHECK(rtn) do { if ( &rtn == NULL ) {\ + PyErr_SetString(PyExc_NotImplementedError, \ + "Not available in this shared library/OS version"); \ + return NULL; \ + }} while(0) + + #include #include *************** *** 214,218 **** return (PyObject *)it; } ! WEOObj_Convert(PyObject *v, WEObjectReference *p_itself) { if (!WEOObj_Check(v)) --- 226,230 ---- return (PyObject *)it; } ! int WEOObj_Convert(PyObject *v, WEObjectReference *p_itself) { if (!WEOObj_Check(v)) *************** *** 382,386 **** return (PyObject *)it; } ! wasteObj_Convert(PyObject *v, WEReference *p_itself) { if (!wasteObj_Check(v)) --- 394,398 ---- return (PyObject *)it; } ! int wasteObj_Convert(PyObject *v, WEReference *p_itself) { if (!wasteObj_Check(v)) *************** *** 1062,1066 **** Py_INCREF(Py_None); _res = Py_None; - pText__error__: ; return _res; } --- 1074,1077 ---- From jackjansen@users.sourceforge.net Wed Sep 5 16:43:13 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 08:43:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res _Resmodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv31134/python/Mac/Modules/res Modified Files: _Resmodule.c Log Message: A few more gcc warnings bite the dust. Index: _Resmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/_Resmodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _Resmodule.c 2001/09/05 10:29:27 1.3 --- _Resmodule.c 2001/09/05 15:43:11 1.4 *************** *** 441,445 **** else _self->ob_freeit = NULL; ! return Py_BuildValue("i", old); } --- 441,446 ---- else _self->ob_freeit = NULL; ! _res = Py_BuildValue("i", old); ! return _res; } *************** *** 1379,1383 **** memcpy(*h, buf, len); HUnlock(h); ! return ResObj_New(h); } --- 1380,1385 ---- memcpy(*h, buf, len); HUnlock(h); ! _res = ResObj_New(h); ! return _res; } *************** *** 1404,1408 **** rv = (ResourceObject *)ResObj_New(h); rv->ob_freeit = PyMac_AutoDisposeHandle; ! return (PyObject *)rv; } --- 1406,1411 ---- rv = (ResourceObject *)ResObj_New(h); rv->ob_freeit = PyMac_AutoDisposeHandle; ! _res = (PyObject *)rv; ! return _res; } From jackjansen@users.sourceforge.net Wed Sep 5 16:43:36 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 08:43:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd _Qdmodule.c,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv31239/python/Mac/Modules/qd Modified Files: _Qdmodule.c Log Message: A few more gcc warnings bite the dust. Index: _Qdmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/_Qdmodule.c,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** _Qdmodule.c 2001/09/05 10:29:02 1.3 --- _Qdmodule.c 2001/09/05 15:43:33 1.4 *************** *** 123,127 **** } ! QdRGB_Convert(PyObject *v, RGBColorPtr p_itself) { long red, green, blue; --- 123,127 ---- } ! int QdRGB_Convert(PyObject *v, RGBColorPtr p_itself) { long red, green, blue; From jackjansen@users.sourceforge.net Wed Sep 5 16:44:35 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 08:44:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/qd qdsupport.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/qd In directory usw-pr-cvs1:/tmp/cvs-serv31583/python/Mac/Modules/qd Modified Files: qdsupport.py Log Message: A few more gcc warnings bite the dust. Index: qdsupport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/qd/qdsupport.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** qdsupport.py 2001/09/05 10:29:07 1.35 --- qdsupport.py 2001/09/05 15:44:33 1.36 *************** *** 168,172 **** } ! QdRGB_Convert(PyObject *v, RGBColorPtr p_itself) { long red, green, blue; --- 168,172 ---- } ! int QdRGB_Convert(PyObject *v, RGBColorPtr p_itself) { long red, green, blue; From jackjansen@users.sourceforge.net Wed Sep 5 16:44:40 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 08:44:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Modules/res resedit.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Modules/res In directory usw-pr-cvs1:/tmp/cvs-serv31614/python/Mac/Modules/res Modified Files: resedit.py Log Message: A few more gcc warnings bite the dust. Index: resedit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Modules/res/resedit.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** resedit.py 2001/09/05 10:31:52 1.5 --- resedit.py 2001/09/05 15:44:37 1.6 *************** *** 14,18 **** memcpy(*h, buf, len); HUnlock(h); ! return ResObj_New(h); """ --- 14,19 ---- memcpy(*h, buf, len); HUnlock(h); ! _res = ResObj_New(h); ! return _res; """ *************** *** 44,48 **** rv = (ResourceObject *)ResObj_New(h); rv->ob_freeit = PyMac_AutoDisposeHandle; ! return (PyObject *)rv; """ --- 45,50 ---- rv = (ResourceObject *)ResObj_New(h); rv->ob_freeit = PyMac_AutoDisposeHandle; ! _res = (PyObject *)rv; ! return _res; """ *************** *** 93,97 **** else _self->ob_freeit = NULL; ! return Py_BuildValue("i", old); """ f = ManualGenerator("AutoDispose", AutoDispose_body) --- 95,100 ---- else _self->ob_freeit = NULL; ! _res = Py_BuildValue("i", old); ! return _res; """ f = ManualGenerator("AutoDispose", AutoDispose_body) From loewis@users.sourceforge.net Wed Sep 5 18:09:50 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 10:09:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.144,1.145 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv20171/Doc/api Modified Files: api.tex Log Message: Patch #449815: Set filesystemencoding based on CODESET. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.144 retrieving revision 1.145 diff -C2 -d -r1.144 -r1.145 *** api.tex 2001/09/04 22:08:55 1.144 --- api.tex 2001/09/05 17:09:48 1.145 *************** *** 3021,3025 **** Setting encoding to NULL causes the default encoding to be used which ! is UTF-8. Error handling is set by errors which may also be set to NULL meaning --- 3021,3029 ---- Setting encoding to NULL causes the default encoding to be used which ! is \ASCII{}. The file system calls should use ! \var{Py_FileSystemDefaultEncoding} as the encoding for file ! names. This variable should be treated as read-only: On some systems, ! it will be a pointer to a static string, on others, it will change at ! run-time, e.g. when the application invokes setlocale. Error handling is set by errors which may also be set to NULL meaning From loewis@users.sourceforge.net Wed Sep 5 18:09:50 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 10:09:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode_file.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20171/Lib/test Modified Files: test_unicode_file.py Log Message: Patch #449815: Set filesystemencoding based on CODESET. Index: test_unicode_file.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode_file.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_unicode_file.py 2001/05/13 08:04:26 1.1 --- test_unicode_file.py 2001/09/05 17:09:48 1.2 *************** *** 7,12 **** try: from test_support import TESTFN_ENCODING except ImportError: ! raise TestSkipped("No Unicode filesystem semantics on this platform.") TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) --- 7,24 ---- try: from test_support import TESTFN_ENCODING + oldlocale = None except ImportError: ! import locale ! # try to run the test in an UTF-8 locale. If this locale is not ! # available, avoid running the test since the locale's encoding ! # might not support TESTFN_UNICODE. Likewise, if the system does ! # not support locale.CODESET, Unicode file semantics is not ! # available, either. ! oldlocale = locale.setlocale(locale.LC_CTYPE) ! try: ! locale.setlocale(locale.LC_CTYPE,"en_US.UTF-8") ! TESTFN_ENCODING = locale.nl_langinfo(locale.CODESET) ! except (locale.Error, AttributeError): ! raise TestSkipped("No Unicode filesystem semantics on this platform.") TESTFN_ENCODED = TESTFN_UNICODE.encode(TESTFN_ENCODING) *************** *** 80,81 **** --- 92,95 ---- os.rmdir(abs_encoded) print "All the Unicode tests appeared to work" + if oldlocale: + locale.setlocale(locale.LC_CTYPE, oldlocale) From loewis@users.sourceforge.net Wed Sep 5 18:09:50 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Wed, 05 Sep 2001 10:09:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _localemodule.c,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20171/Modules Modified Files: _localemodule.c Log Message: Patch #449815: Set filesystemencoding based on CODESET. Index: _localemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_localemodule.c,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -d -r2.22 -r2.23 *** _localemodule.c 2001/08/15 17:14:33 2.22 --- _localemodule.c 2001/09/05 17:09:48 2.23 *************** *** 154,158 **** Py_DECREF(ulo); } ! static PyObject* --- 154,161 ---- Py_DECREF(ulo); } ! ! #if defined(HAVE_LANGINFO_H) && defined(CODESET) ! static int fileencoding_uses_locale = 0; ! #endif static PyObject* *************** *** 204,207 **** --- 207,226 ---- /* things that got wrong up to here are ignored */ PyErr_Clear(); + #if defined(HAVE_LANGINFO_H) && defined(CODESET) + if (Py_FileSystemDefaultEncoding == NULL) + fileencoding_uses_locale = 1; + if (fileencoding_uses_locale) { + char *codeset = nl_langinfo(CODESET); + PyObject *enc = NULL; + if (*codeset && (enc = PyCodec_Encoder(codeset))) { + /* Release previous file encoding */ + if (Py_FileSystemDefaultEncoding) + free (Py_FileSystemDefaultEncoding); + Py_FileSystemDefaultEncoding = strdup(codeset); + Py_DECREF(enc); + } else + PyErr_Clear(); + } + #endif } else { /* get locale */ From gvanrossum@users.sourceforge.net Wed Sep 5 18:52:33 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 10:52:33 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_largefile.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32268 Modified Files: test_largefile.py Log Message: Remove a debug print left in the code by Fred. Index: test_largefile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_largefile.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_largefile.py 2001/08/20 22:37:34 1.5 --- test_largefile.py 2001/09/05 17:52:31 1.6 *************** *** 131,133 **** os.unlink(name) - print >>sys.stderr, name, "exists:", os.path.exists(name) --- 131,132 ---- From bckfnn@users.sourceforge.net Wed Sep 5 19:40:35 2001 From: bckfnn@users.sourceforge.net (Finn Bock) Date: Wed, 05 Sep 2001 11:40:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib zipfile.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10317 Modified Files: zipfile.py Log Message: [ #458701 ] Patch to zipfile.py for Java Patch by Jim Ahlstrom which lets java's zipfile classes read zipfiles create by zipfile.py. Index: zipfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/zipfile.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** zipfile.py 2001/07/19 19:44:25 1.15 --- zipfile.py 2001/09/05 18:40:33 1.16 *************** *** 384,394 **** self._writecheck(zinfo) fp = open(filename, "rb") ! zinfo.flag_bits = 0x08 zinfo.header_offset = self.fp.tell() # Start of header bytes self.fp.write(zinfo.FileHeader()) zinfo.file_offset = self.fp.tell() # Start of file bytes - CRC = 0 - compress_size = 0 - file_size = 0 if zinfo.compress_type == ZIP_DEFLATED: cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, --- 384,395 ---- self._writecheck(zinfo) fp = open(filename, "rb") ! zinfo.flag_bits = 0x00 zinfo.header_offset = self.fp.tell() # Start of header bytes + # Must overwrite CRC and sizes with correct data later + zinfo.CRC = CRC = 0 + zinfo.compress_size = compress_size = 0 + zinfo.file_size = file_size = 0 self.fp.write(zinfo.FileHeader()) zinfo.file_offset = self.fp.tell() # Start of file bytes if zinfo.compress_type == ZIP_DEFLATED: cmpr = zlib.compressobj(zlib.Z_DEFAULT_COMPRESSION, *************** *** 416,422 **** zinfo.CRC = CRC zinfo.file_size = file_size ! # Write CRC and file sizes after the file data self.fp.write(struct.pack(" Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv11436 Modified Files: NEWS Log Message: Describe -E (which was added to 2.2a2). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.230 retrieving revision 1.231 diff -C2 -d -r1.230 -r1.231 *** NEWS 2001/09/05 13:44:54 1.230 --- NEWS 2001/09/05 18:43:35 1.231 *************** *** 222,225 **** --- 222,232 ---- have been assigned now returns an empty dictionary instead of None. + - A new command line option, -E, was added which disables the use of + all environment variables, or at least those that are specifically + significant to Python. Usually those have a name starting with + "PYTHON". This was used to fix a problem where the tests fail if + the user happens to have PYTHONHOME or PYTHONPATH pointing to an + older distribution. + Library From gvanrossum@users.sourceforge.net Wed Sep 5 19:55:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 11:55:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python.man,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv15052 Modified Files: python.man Log Message: Document -Q. Move arguments around to be in strict alphabetical order. Add breaks in SYNOPSIS. Index: python.man =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python.man,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** python.man 2001/07/26 21:25:58 1.20 --- python.man 2001/09/05 18:55:34 1.21 *************** *** 8,11 **** --- 8,17 ---- ] [ + .B \-E + ] + [ + .B \-h + ] + [ .B \-i ] *************** *** 13,21 **** .B \-O ] ! [ ! .B \-S ] [ ! .B \-E ] [ --- 19,29 ---- .B \-O ] ! .br ! [ ! .B -Q ! .I argument ] [ ! .B \-S ] [ *************** *** 25,36 **** .B \-u ] - [ - .B \-v - ] [ ! .B \-x ] ! [ ! .B \-h ] [ --- 33,42 ---- .B \-u ] [ ! .B \-U ] ! .br ! [ ! .B \-v ] [ *************** *** 41,44 **** --- 47,53 ---- .I argument ] + [ + .B \-x + ] .br [ *************** *** 79,86 **** --- 88,107 ---- .SH COMMAND LINE OPTIONS .TP + .BI "\-c " command + Specify the command to execute (see next section). + This terminates the option list (following options are passed as + arguments to the command). + .TP .B \-d Turn on parser debugging output (for wizards only, depending on compilation options). .TP + .B \-E + Ignore environment variables like PYTHONPATH and PYTHONHOME that modify + the behavior of the interpreter. + .TP + .B \-h + Prints the usage for the interpreter executable and exits. + .TP .B \-i When a script is passed as first argument or the \fB\-c\fP option is *************** *** 96,99 **** --- 117,129 ---- to \fI.pyo\fP. Given twice, causes docstrings to be discarded. .TP + .BI "\-Q " argument + Division control; see PEP 238. The argument must be one of "old" (the + default, int/int and long/long return an int or long), "new" (new + division semantics, i.e. int/int and long/long returns a float), + "warn" (old division semantics with a warning for int/int and + long/long), or "warnall" (old division semantics with a warning for + all use of the division operator). For a use of "warnall", see the + Tools/scripts/fixdiv.py script. + .TP .B \-S Disable the import of the module *************** *** 103,110 **** that it entails. .TP - .B \-E - Ignore environment variables like PYTHONPATH and PYTHONHOME that modify - the behavior of the interpreter. - .TP .B \-t Issue a warning when a source file mixes tabs and spaces for --- 133,136 ---- *************** *** 122,133 **** at exit. .TP - .B \-x - Skip the first line of the source. This is intended for a DOS - specific hack only. Warning: the line numbers in error messages will - be off by one! - .TP - .B \-h - Prints the usage for the interpreter executable and exits. - .TP .B \-V Prints the Python version number of the executable and exits. --- 148,151 ---- *************** *** 198,205 **** is thus equivalent to an omitted line number. .TP ! .BI "\-c " command ! Specify the command to execute (see next section). ! This terminates the option list (following options are passed as ! arguments to the command). .SH INTERPRETER INTERFACE The interpreter interface resembles that of the UNIX shell: when --- 216,223 ---- is thus equivalent to an omitted line number. .TP ! .B \-x ! Skip the first line of the source. This is intended for a DOS ! specific hack only. Warning: the line numbers in error messages will ! be off by one! .SH INTERPRETER INTERFACE The interpreter interface resembles that of the UNIX shell: when From gvanrossum@users.sourceforge.net Wed Sep 5 19:57:53 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 11:57:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc python.man,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv15594 Modified Files: python.man Log Message: Change the date field to use $Date$ so it won't be outrageously out of date. Index: python.man =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/python.man,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** python.man 2001/09/05 18:55:34 1.21 --- python.man 2001/09/05 18:57:51 1.22 *************** *** 1,3 **** ! .TH PYTHON "1" "5 September, 2000" .SH NAME python \- an interpreted, interactive, object-oriented programming language --- 1,3 ---- ! .TH PYTHON "1" "$Date$" .SH NAME python \- an interpreted, interactive, object-oriented programming language From gvanrossum@users.sourceforge.net Wed Sep 5 20:11:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 12:11:51 -0700 Subject: [Python-checkins] CVS: python/dist/src configure.in,1.253,1.254 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv19236 Modified Files: configure.in Log Message: SF bug #427073: DLINCLDIR defined incorrectly (Skip Montanaro). I don't know what difference it makes, but '/' indeed makes less sense as an include dir than '.', so I'm changing the default. Just so I can close the bug. ;-) Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.253 retrieving revision 1.254 diff -C2 -d -r1.253 -r1.254 *** configure.in 2001/09/05 14:58:11 1.253 --- configure.in 2001/09/05 19:11:49 1.254 *************** *** 1168,1172 **** # -I${DLINCLDIR} is added to the compile rule for importdl.o AC_SUBST(DLINCLDIR) ! DLINCLDIR=/ AC_MSG_CHECKING(for --with-sgi-dl) --- 1168,1172 ---- # -I${DLINCLDIR} is added to the compile rule for importdl.o AC_SUBST(DLINCLDIR) ! DLINCLDIR=. AC_MSG_CHECKING(for --with-sgi-dl) From gvanrossum@users.sourceforge.net Wed Sep 5 20:13:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 12:13:19 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.245,1.246 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv19552 Modified Files: configure Log Message: SF bug #427073: DLINCLDIR defined incorrectly (Skip Montanaro). I don't know what difference it makes, but '/' indeed makes less sense as an include dir than '.', so I'm changing the default. Just so I can close the bug. ;-) Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.245 retrieving revision 1.246 diff -C2 -d -r1.245 -r1.246 *** configure 2001/09/05 14:58:11 1.245 --- configure 2001/09/05 19:13:16 1.246 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.253 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.254 # Guess values for system-dependent variables and create Makefiles. *************** *** 4436,4440 **** # -I${DLINCLDIR} is added to the compile rule for importdl.o ! DLINCLDIR=/ echo $ac_n "checking for --with-sgi-dl""... $ac_c" 1>&6 --- 4436,4440 ---- # -I${DLINCLDIR} is added to the compile rule for importdl.o ! DLINCLDIR=. echo $ac_n "checking for --with-sgi-dl""... $ac_c" 1>&6 From montanaro@users.sourceforge.net Wed Sep 5 20:27:15 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Wed, 05 Sep 2001 12:27:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmailbox.tex,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22869 Modified Files: libmailbox.tex Log Message: typo... Index: libmailbox.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmailbox.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** libmailbox.tex 2001/08/03 18:39:36 1.21 --- libmailbox.tex 2001/09/05 19:27:13 1.22 *************** *** 108,112 **** Return the next message in the mailbox, created with the optional \var{factory} argument passed into the mailbox object's constructor. ! By defaul this is an \class{rfc822.Message} object (see the \refmodule{rfc822} module). Depending on the mailbox implementation the \var{fp} attribute of this object may be a true --- 108,112 ---- Return the next message in the mailbox, created with the optional \var{factory} argument passed into the mailbox object's constructor. ! By default this is an \class{rfc822.Message} object (see the \refmodule{rfc822} module). Depending on the mailbox implementation the \var{fp} attribute of this object may be a true From gvanrossum@users.sourceforge.net Wed Sep 5 20:29:58 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 12:29:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk Tkinter.py,1.156,1.157 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv23520 Modified Files: Tkinter.py Log Message: class Listbox: add itemcget, to satisfy SF patch #457713. Fix up docstring for itemconfigure. Index: Tkinter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/Tkinter.py,v retrieving revision 1.156 retrieving revision 1.157 diff -C2 -d -r1.156 -r1.157 *** Tkinter.py 2001/09/01 18:29:55 1.156 --- Tkinter.py 2001/09/05 19:29:56 1.157 *************** *** 2364,2369 **** """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) def itemconfigure(self, index, cnf=None, **kw): ! """Configure resources of an item. The values for resources are specified as keyword arguments. --- 2364,2373 ---- """Shift the y-view according to NUMBER which is measured in "units" or "pages" (WHAT).""" self.tk.call(self._w, 'yview', 'scroll', number, what) + def itemcget(self, index, option): + """Return the resource value for an ITEM and an OPTION.""" + return self.tk.call( + (self._w, 'itemcget') + (index, '-'+option)) def itemconfigure(self, index, cnf=None, **kw): ! """Configure resources of an ITEM. The values for resources are specified as keyword arguments. From gvanrossum@users.sourceforge.net Wed Sep 5 20:45:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 12:45:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib cgi.py,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26272 Modified Files: cgi.py Log Message: Class FieldStorage: add two new methods, getfirst() and getlist(), that provide a somewhat more uniform interface to getting values. This is from SF patch #453691. Index: cgi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** cgi.py 2001/08/09 21:40:30 1.66 --- cgi.py 2001/09/05 19:45:34 1.67 *************** *** 565,568 **** --- 565,590 ---- return default + def getfirst(self, key, default=None): + """ Return the first value received.""" + if self.has_key(key): + value = self[key] + if type(value) is type([]): + return value[0].value + else: + return value.value + else: + return default + + def getlist(self, key): + """ Return list of received values.""" + if self.has_key(key): + value = self[key] + if type(value) is type([]): + return map(lambda v: v.value, value) + else: + return [value.value] + else: + return [] + def keys(self): """Dictionary style keys() method.""" From gvanrossum@users.sourceforge.net Wed Sep 5 20:51:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 05 Sep 2001 12:51:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Demo/pysvr Makefile,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/pysvr In directory usw-pr-cvs1:/tmp/cvs-serv27492 Modified Files: Makefile Log Message: Use the build directory by default, and update the version. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/pysvr/Makefile,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** Makefile 2001/06/02 06:16:02 1.5 --- Makefile 2001/09/05 19:51:08 1.6 *************** *** 12,28 **** OPT=-g ! # Where Python is installed, and which version ! INST=/usr/local ! VER=2.0 ! # Expressions using the above definitions -- no need to change PYVER=python$(VER) # Use these defs when compiling against installed Python ! PYC=$(INST)/lib/$(PYVER)/config ! PYINCL=-I$(INST)/include/$(PYVER) -I$(PYC) ! PYLIBS=$(PYC)/lib$(PYVER).a # Use these defs when compiling against built Python ! ##PYINCL=-I../../Include -I../../sparc ! ##PYLIBS=../../sparc/lib$(PYVER).a # Libraries to link with -- very installation dependent --- 12,31 ---- OPT=-g ! # Which Python version we're using ! VER=2.2 ! # Expressions using the above definitions PYVER=python$(VER) + # Use these defs when compiling against installed Python ! ##INST=/usr/local ! ##PYC=$(INST)/lib/$(PYVER)/config ! ##PYINCL=-I$(INST)/include/$(PYVER) -I$(PYC) ! ##PYLIBS=$(PYC)/lib$(PYVER).a ! # Use these defs when compiling against built Python ! PLAT=linux ! PYINCL=-I../../Include -I../../$(PLAT) ! PYLIBS=../../$(PLAT)/lib$(PYVER).a # Libraries to link with -- very installation dependent From jackjansen@users.sourceforge.net Wed Sep 5 21:08:10 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 13:08:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_repr.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31600/Python/Lib/test Modified Files: test_repr.py Log Message: LongReprTest fails on the Mac because it uses filenames with more than 32 characters per component. This makes mkdir() calls and such fail with EINVAL. For now I am disabling the test on the Mac, and I'll open a bugreport. Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_repr.py 2001/09/05 02:26:26 1.4 --- test_repr.py 2001/09/05 20:08:07 1.5 *************** *** 267,269 **** run_unittest(ReprTests) ! run_unittest(LongReprTest) --- 267,270 ---- run_unittest(ReprTests) ! if os.name != 'mac': ! run_unittest(LongReprTest) From tim_one@users.sourceforge.net Wed Sep 5 21:18:51 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 05 Sep 2001 13:18:51 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0042.txt,1.54,1.55 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1947 Modified Files: pep-0042.txt Log Message: Added section for IEEE-754 support requests. Index: pep-0042.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0042.txt,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** pep-0042.txt 2001/08/09 16:53:49 1.54 --- pep-0042.txt 2001/09/05 20:18:49 1.55 *************** *** 64,67 **** --- 64,73 ---- http://sf.net/bugs/?func=detailbug&bug_id=116405&group_id=5470 + - Non-accidental IEEE-754 support (Infs, NaNs, settable traps, etc). + Big project. + + pickle lacks float('inf') + http://sf.net/tracker/index.php?func=detail&aid=445484&group_id=5470&atid=355470 + Standard Library *************** *** 229,240 **** http://sf.net/tracker/?func=detail&aid=426539&group_id=5470&atid=105470 ! - Jim Fulton suggested the following: I wonder if it would be a good idea to have a new kind of temporary file that stored data in memory unless: ! - The data exceeds some size, or ! - Somebody asks for a fileno. Then the cgi module (and other apps) could use this thing in a --- 235,246 ---- http://sf.net/tracker/?func=detail&aid=426539&group_id=5470&atid=105470 ! - Jim Fulton suggested the following: I wonder if it would be a good idea to have a new kind of temporary file that stored data in memory unless: ! - The data exceeds some size, or ! - Somebody asks for a fileno. Then the cgi module (and other apps) could use this thing in a *************** *** 249,255 **** append a newline, or to append something else than a newline. ! Proposal: ! - get rid of the input size check - add an optional argument giving the delimiter string to be --- 255,261 ---- append a newline, or to append something else than a newline. ! Proposal: ! - get rid of the input size check - add an optional argument giving the delimiter string to be From jackjansen@users.sourceforge.net Wed Sep 5 23:04:27 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 15:04:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/OSXResources/app Info.plist,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/OSXResources/app In directory usw-pr-cvs1:/tmp/cvs-serv24985/OSXResources/app Modified Files: Info.plist Log Message: Python is a Shell, not a Viewer. Index: Info.plist =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/OSXResources/app/Info.plist,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Info.plist 2001/09/04 21:28:03 1.1 --- Info.plist 2001/09/05 22:04:25 1.2 *************** *** 21,25 **** CFBundleTypeRole ! Viewer --- 21,25 ---- CFBundleTypeRole ! Shell From jackjansen@users.sourceforge.net Wed Sep 5 23:07:54 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Wed, 05 Sep 2001 15:07:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macgetargv.c,1.24,1.25 macmain.c,1.67,1.68 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv25188/Python Modified Files: macgetargv.c macmain.c Log Message: Changes to make these work under OSX as the main program for a fullblown drag and drop application. To my surprise it is starting to work already: Python actually executes a script dropped on it. To be done: - Make sure this still works in MacPython - Don't lose argv[0] in the process - Applet support Index: macgetargv.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macgetargv.c,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** macgetargv.c 2001/06/20 20:50:19 1.24 --- macgetargv.c 2001/09/05 22:07:52 1.25 *************** *** 28,31 **** --- 28,32 ---- #include + #ifdef WITHOUT_FRAMEWORKS #include #include *************** *** 41,44 **** --- 42,48 ---- #include #include + #else + #include + #endif /* WITHOUT_FRAMEWORKS */ #if UNIVERSAL_INTERFACES_VERSION >= 0x0340 *************** *** 55,59 **** FSSpec PyMac_ApplicationFSSpec; char PyMac_ApplicationPath[256]; - static int applocation_inited; /* Duplicate a string to the heap. We also export this since it isn't standard --- 59,62 ---- *************** *** 71,82 **** #endif /* Initialize FSSpec and full name of current application */ OSErr ! PyMac_init_process_location() { ProcessSerialNumber currentPSN; ProcessInfoRec info; OSErr err; if ( applocation_inited ) return 0; --- 74,104 ---- #endif + #if TARGET_API_MAC_OSX + OSErr + PyMac_GetFullPath(FSSpec *fss, char *path) + { + FSRef fsr; + OSErr err; + + *path = '\0'; + err = FSpMakeFSRef(fss, &fsr); + if ( err ) return err; + err = (OSErr)FSRefMakePath(&fsr, path, 1024); + if ( err ) return err; + return 0; + } + #endif /* TARGET_API_MAC_OSX */ + + + #if !TARGET_API_MAC_OSX /* Initialize FSSpec and full name of current application */ OSErr ! PyMac_init_process_location(void) { ProcessSerialNumber currentPSN; ProcessInfoRec info; OSErr err; + static int applocation_inited; if ( applocation_inited ) return 0; *************** *** 93,96 **** --- 115,119 ---- return 0; } + #endif /* !TARGET_API_MAC_OSX */ /* Check that there aren't any args remaining in the event */ *************** *** 148,160 **** long i, ndocs, size; FSSpec fss; ! char path[256]; got_one = 1; ! if (err = AEGetParamDesc(theAppleEvent, ! keyDirectObject, typeAEList, &doclist)) return err; ! if (err = get_missing_params(theAppleEvent)) return err; ! if (err = AECountItems(&doclist, &ndocs)) return err; for(i = 1; i <= ndocs; i++) { --- 171,183 ---- long i, ndocs, size; FSSpec fss; ! char path[1024]; got_one = 1; ! if ((err = AEGetParamDesc(theAppleEvent, ! keyDirectObject, typeAEList, &doclist))) return err; ! if ((err = get_missing_params(theAppleEvent))) return err; ! if ((err = AECountItems(&doclist, &ndocs))) return err; for(i = 1; i <= ndocs; i++) { *************** *** 175,179 **** static void ! set_ae_handlers() { open_doc_upp = NewAEEventHandlerUPP(&handle_open_doc); --- 198,202 ---- static void ! set_ae_handlers(void) { open_doc_upp = NewAEEventHandlerUPP(&handle_open_doc); *************** *** 194,198 **** static void ! reset_ae_handlers() { AERemoveEventHandler(kCoreEventClass, kAEOpenApplication, --- 217,221 ---- static void ! reset_ae_handlers(void) { AERemoveEventHandler(kCoreEventClass, kAEOpenApplication, *************** *** 209,213 **** static void ! event_loop() { EventRecord event; --- 232,236 ---- static void ! event_loop(void) { EventRecord event; *************** *** 230,241 **** int ! PyMac_GetArgv(pargv, noevents) ! char ***pargv; ! int noevents; { - arg_count = 0; (void)PyMac_init_process_location(); arg_vector[arg_count++] = strdup(PyMac_ApplicationPath); if( !noevents ) { --- 253,266 ---- int ! PyMac_GetArgv(char ***pargv, int noevents) { arg_count = 0; + #if TARGET_API_MAC_OSX + /* In an OSX bundle argv[0] is okay */ + arg_count++; + #else (void)PyMac_init_process_location(); arg_vector[arg_count++] = strdup(PyMac_ApplicationPath); + #endif /* TARGET_API_MAC_OSX */ if( !noevents ) { Index: macmain.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Python/macmain.c,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** macmain.c 2001/09/01 22:37:48 1.67 --- macmain.c 2001/09/05 22:07:52 1.68 *************** *** 31,34 **** --- 31,35 ---- #include "macglue.h" + #ifdef WITHOUT_FRAMEWORKS #include #include *************** *** 42,45 **** --- 43,50 ---- #include #endif /* USE_APPEARANCE */ + #else + #include + #endif /* WITHOUT_FRAMEWORKS */ + #ifdef __MWERKS__ #include *************** *** 48,60 **** #if __profile__ == 1 #include ! #endif ! #endif #include #ifdef USE_MAC_SHARED_LIBRARY extern PyMac_AddLibResources(void); #endif - //#ifdef USE_GUSI - //#include "GUSISIOUX.h" - //#endif #define STARTUP "PythonStartup" --- 53,63 ---- #if __profile__ == 1 #include ! #endif /* __profile__ */ ! #endif /* __MWERKS__ */ ! #include #ifdef USE_MAC_SHARED_LIBRARY extern PyMac_AddLibResources(void); #endif #define STARTUP "PythonStartup" *************** *** 82,86 **** void PyMac_Exit(int); /* Forward */ ! static void init_appearance() { #ifdef USE_APPEARANCE --- 85,89 ---- void PyMac_Exit(int); /* Forward */ ! static void init_appearance(void) { #ifdef USE_APPEARANCE *************** *** 100,104 **** static void ! init_mac_world() { #if !TARGET_API_MAC_CARBON --- 103,107 ---- static void ! init_mac_world(void) { #if !TARGET_API_MAC_CARBON *************** *** 128,133 **** DialogPtr dialog; Rect rect; - int old_argc = *argcp; - int i; /* --- 131,134 ---- *************** *** 192,196 **** --- 193,200 ---- } #endif + #if !TARGET_API_MAC_OSX if ( item == OPT_CMDLINE ) { + int old_argc = *argcp; + int i; int new_argc, newer_argc; char **new_argv, **newer_argv; *************** *** 210,213 **** --- 214,218 ---- /* XXXX Is it not safe to use free() here, apparently */ } + #endif /* !TARGET_API_MAC_OSX */ #define OPT_ITEM(num, var) \ if ( item == (num) ) { \ *************** *** 284,288 **** #ifdef USE_SIOUX /* Set various SIOUX flags. Some are changed later based on options */ ! /* SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */ SIOUXSettings.asktosaveonclose = 0; SIOUXSettings.showstatusline = 0; --- 289,295 ---- #ifdef USE_SIOUX /* Set various SIOUX flags. Some are changed later based on options */ ! #if 0 ! SIOUXSettings.standalone = 0; /* XXXX Attempting to keep sioux from eating events */ ! #endif SIOUXSettings.asktosaveonclose = 0; SIOUXSettings.showstatusline = 0; *************** *** 292,297 **** /* Get options from preference file (or from applet resource fork) */ PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */ PyMac_PreferenceOptions(&PyMac_options); ! if ( embedded ) { static char *emb_argv[] = {"embedded-python", 0}; --- 299,307 ---- /* Get options from preference file (or from applet resource fork) */ PyMac_options.keep_console = POPT_KEEPCONSOLE_OUTPUT; /* default-default */ + PyMac_options.unixnewlines = 1; + #if !TARGET_API_MAC_OSX PyMac_PreferenceOptions(&PyMac_options); ! #endif ! if ( embedded ) { static char *emb_argv[] = {"embedded-python", 0}; *************** *** 302,305 **** --- 312,316 ---- /* Create argc/argv. Do it before we go into the options event loop. */ *argcp = PyMac_GetArgv(argvp, PyMac_options.noargs); + #if !TARGET_API_MAC_OSX #ifndef NO_ARGV0_CHDIR if (*argcp >= 1 && (*argvp)[0] && (*argvp)[0][0]) { *************** *** 315,318 **** --- 326,330 ---- } #endif + #endif /* Do interactive option setting, if allowed and + + CFBundleTypeOSTypes + + **** + fold + disk CFBundleTypeRole From jackjansen@users.sourceforge.net Tue Sep 11 14:08:12 2001 From: jackjansen@users.sourceforge.net (Jack Jansen) Date: Tue, 11 Sep 2001 06:08:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Python macmain.c,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Python In directory usw-pr-cvs1:/tmp/cvs-serv19343 Modified Files: macmain.c Log Message: Mods by Donovan Preston (with changes by me to make them "go with the flow") that will detect an __main__.py or __rawmain__.py in the application bundle. This file is then exectued as the main script. We now have applets in MachO Python!!! The difference between __main__ and __rawmain__ is that the former gets a complete simulated argv (so you can drop files on the applet and the script sees them in sys.argv) while the latter skips the argv simulation and the %s = %s' % ( anchor, name, reallink) ! if inspect.isbuiltin(object): argspec = '(...)' else: --- 660,664 ---- title = '%s = %s' % ( anchor, name, reallink) ! if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object): argspec = '(...)' else: *************** *** 914,918 **** skipdocs = 1 title = self.bold(name) + ' = ' + realname ! if inspect.isbuiltin(object): argspec = '(...)' else: --- 917,921 ---- skipdocs = 1 title = self.bold(name) + ' = ' + realname ! if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object): argspec = '(...)' else: From gvanrossum@users.sourceforge.net Thu Sep 20 06:27:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 19 Sep 2001 22:27:26 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv24841 Modified Files: PLAN.txt Log Message: AFAICT pydoc/inspect do the right thing again. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** PLAN.txt 2001/09/10 02:40:26 1.8 --- PLAN.txt 2001/09/20 05:27:24 1.9 *************** *** 32,37 **** Support pickling (via __reduce__?) - Make inspect and pydoc do the right thing for new-style classes. - Support mixed multiple inheritance from classic and new-style classes? --- 32,35 ---- *************** *** 41,44 **** --- 39,45 ---- Done (mostly) ------------- + + Make inspect and pydoc do the right thing for new-style classes. *** + done *** Do binary operators properly. nb_add should try to call self.__add__ From gvanrossum@users.sourceforge.net Thu Sep 20 06:30:26 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Wed, 19 Sep 2001 22:30:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.246,1.247 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv25243 Modified Files: NEWS Log Message: News about compiler and pydoc. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.246 retrieving revision 1.247 diff -C2 -d -r1.246 -r1.247 *** NEWS 2001/09/19 13:47:32 1.246 --- NEWS 2001/09/20 05:30:24 1.247 *************** *** 63,70 **** same time, some mappings not sanctioned by IANA were removed. - Tools - - The "compiler" package has been brought up to date to the state of ! Python 2.2 bytecode generation. Build --- 63,76 ---- same time, some mappings not sanctioned by IANA were removed. - The "compiler" package has been brought up to date to the state of ! Python 2.2 bytecode generation. It has also been promoted from a ! Tool to a standard library package. (Tools/compiler still exists as ! a sample driver.) ! ! - pydoc and inspect are now aware of new-style classes; ! e.g. help(list) at the interactive prompt now shows proper ! documentation for all operations on list objects. ! ! Tools Build From tim_one@users.sourceforge.net Thu Sep 20 06:47:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 19 Sep 2001 22:47:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib inspect.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27494/python/Lib Modified Files: inspect.py Log Message: Ensure that isfunction(obj) and (the new) ismethoddescriptor(obj) never both return true. This restores pydoc's ability to deduce argument lists for functions and methods coded in Python. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** inspect.py 2001/09/20 05:13:38 1.22 --- inspect.py 2001/09/20 05:47:55 1.23 *************** *** 59,63 **** def ismethoddescriptor(object): ! """Return true if the object is a method descriptor, and ismethod false. This is new in Python 2.2, and, for example, is true of int.__add__. --- 59,65 ---- def ismethoddescriptor(object): ! """Return true if the object is a method descriptor. ! ! But not if ismethod() or isclass() or isfunction() are true. This is new in Python 2.2, and, for example, is true of int.__add__. *************** *** 66,76 **** usually sensible, and __doc__ often is. ! Methods implemented via descriptors that also pass the ismethod() test ! return false from the ismethoddescriptor() test, simply because ! ismethod() is more informative -- you can, e.g., count on having the ! im_func attribute (etc) when an object passes the latter.""" return (hasattr(object, "__get__") and not hasattr(object, "__set__") # else it's a data descriptor and not ismethod(object) # mutual exclusion and not isclass(object)) --- 68,79 ---- usually sensible, and __doc__ often is. ! Methods implemented via descriptors that also pass one of the other ! tests return false from the ismethoddescriptor() test, simply because ! the other tests promise more -- you can, e.g., count on having the ! im_func attribute (etc) when an object passes ismethod().""" return (hasattr(object, "__get__") and not hasattr(object, "__set__") # else it's a data descriptor and not ismethod(object) # mutual exclusion + and not isfunction(object) and not isclass(object)) From tim_one@users.sourceforge.net Thu Sep 20 07:08:26 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 19 Sep 2001 23:08:26 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.42,1.43 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29903/python/Lib Modified Files: pydoc.py Log Message: Since inspect.isfunction(obj) is a precondition for calling inspect.getargspec(obj), test isfunction() directly in pydoc.py instead of trying to indirectly deduce isfunction() in pydoc by virtue of failing a combination of other tests. This shouldn't have any visible effect, except perhaps to squash a TypeError death if there was some path thru this code that was inferring isfunction() by mistake. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.42 retrieving revision 1.43 diff -C2 -d -r1.42 -r1.43 *** pydoc.py 2001/09/20 05:13:38 1.42 --- pydoc.py 2001/09/20 06:08:24 1.43 *************** *** 660,666 **** title = '%s = %s' % ( anchor, name, reallink) ! if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object): ! argspec = '(...)' ! else: args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec( --- 660,664 ---- title = '%s = %s' % ( anchor, name, reallink) ! if inspect.isfunction(object): args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec( *************** *** 669,672 **** --- 667,672 ---- decl = 'lambda' argspec = argspec[1:-1] # remove parentheses + else: + argspec = '(...)' decl = title + argspec + (note and self.small(self.grey( *************** *** 917,923 **** skipdocs = 1 title = self.bold(name) + ' = ' + realname ! if inspect.isbuiltin(object) or inspect.ismethoddescriptor(object): ! argspec = '(...)' ! else: args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec( --- 917,921 ---- skipdocs = 1 title = self.bold(name) + ' = ' + realname ! if inspect.isfunction(object): args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec( *************** *** 926,929 **** --- 924,929 ---- title = 'lambda' argspec = argspec[1:-1] # remove parentheses + else: + argspec = '(...)' decl = title + argspec + note From bwarsaw@users.sourceforge.net Thu Sep 20 07:30:43 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 19 Sep 2001 23:30:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_support.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1120 Modified Files: test_support.py Log Message: run_suite(): Factor this out of run_unittest() for tests that build their own test suite from a multitude of classes (like test_email.py will be doing). run_unittest(): Call run_suite() after making a suite from the testclass. Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** test_support.py 2001/09/10 01:39:21 1.30 --- test_support.py 2001/09/20 06:30:41 1.31 *************** *** 158,162 **** ! def run_unittest(testclass): """Run tests from a unittest.TestCase-derived class.""" if verbose: --- 158,162 ---- ! def run_suite(suite): """Run tests from a unittest.TestCase-derived class.""" if verbose: *************** *** 165,169 **** runner = BasicTestRunner() - suite = unittest.makeSuite(testclass) result = runner.run(suite) if not result.wasSuccessful(): --- 165,168 ---- *************** *** 176,179 **** --- 175,184 ---- % (testclass.__module__, testclass.__name__)) raise TestFailed(err) + + + def run_unittest(testclass): + """Run tests from a unittest.TestCase-derived class.""" + run_suite(unittest.makeSuite(testclass)) + #======================================================================= From bwarsaw@users.sourceforge.net Thu Sep 20 07:31:24 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 19 Sep 2001 23:31:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_support.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1276 Modified Files: test_support.py Log Message: run_suite(): Oops, update a docstring. Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** test_support.py 2001/09/20 06:30:41 1.31 --- test_support.py 2001/09/20 06:31:22 1.32 *************** *** 159,163 **** def run_suite(suite): ! """Run tests from a unittest.TestCase-derived class.""" if verbose: runner = unittest.TextTestRunner(sys.stdout, verbosity=2) --- 159,163 ---- def run_suite(suite): ! """Run tests from a unittest.TestSuite-derived class.""" if verbose: runner = unittest.TextTestRunner(sys.stdout, verbosity=2) From tim_one@users.sourceforge.net Thu Sep 20 08:55:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 20 Sep 2001 00:55:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.127,2.128 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17248/python/Objects Modified Files: fileobject.c Log Message: SF bug [#463093] File methods need doc strings. Now they don't. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.127 retrieving revision 2.128 diff -C2 -d -r2.127 -r2.128 *** fileobject.c 2001/09/19 13:47:32 2.127 --- fileobject.c 2001/09/20 07:55:22 2.128 *************** *** 1282,1302 **** } static PyMethodDef file_methods[] = { ! {"readline", (PyCFunction)file_readline, METH_VARARGS}, ! {"read", (PyCFunction)file_read, METH_VARARGS}, ! {"write", (PyCFunction)file_write, METH_OLDARGS}, ! {"fileno", (PyCFunction)file_fileno, METH_NOARGS}, ! {"seek", (PyCFunction)file_seek, METH_VARARGS}, #ifdef HAVE_FTRUNCATE ! {"truncate", (PyCFunction)file_truncate, METH_VARARGS}, #endif ! {"tell", (PyCFunction)file_tell, METH_NOARGS}, ! {"readinto", (PyCFunction)file_readinto, METH_OLDARGS}, ! {"readlines", (PyCFunction)file_readlines, METH_VARARGS}, ! {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS}, ! {"writelines", (PyCFunction)file_writelines, METH_O}, ! {"flush", (PyCFunction)file_flush, METH_NOARGS}, ! {"close", (PyCFunction)file_close, METH_NOARGS}, ! {"isatty", (PyCFunction)file_isatty, METH_NOARGS}, {NULL, NULL} /* sentinel */ }; --- 1282,1382 ---- } + static char readline_doc[] = + "readline([size]) -> next line from the file, as a string.\n" + "\n" + "Retain newline. A non-negative size argument limits the maximum\n" + "number of bytes to return (an incomplete line may be returned then).\n" + "Return an empty string at EOF."; + + static char read_doc[] = + "read([size]) -> read at most size bytes, returned as a string.\n" + "\n" + "If the size argument is negative or omitted, read until EOF is reached."; + + static char write_doc[] = + "write(str) -> None. Write string str to file.\n" + "\n" + "Note that due to buffering, flush() or close() may be needed before\n" + "the file on disk reflects the data written."; + + static char fileno_doc[] = + "fileno() -> integer \"file descriptor\".\n" + "\n" + "This is needed for lower-level file interfaces, such os.read()."; + + static char seek_doc[] = + "seek(offset[, whence]) -> None. Move to new file position.\n" + "\n" + "Argument offset is a byte count. Optional argument whence defaults to\n" + "0 (offset from start of file, offset should be >= 0); other values are 1\n" + "(move relative to current position, positive or negative), and 2 (move\n" + "relative to end of file, usually negative, although many platforms allow\n" + "seeking beyond the end of a file).\n" + "\n" + "Note that not all file objects are seekable."; + + #ifdef HAVE_FTRUNCATE + static char truncate_doc[] = + "truncate([size]) -> None. Truncate the file to at most size bytes.\n" + "\n" + "Size defaults to the current file position, as returned by tell()."; + #endif + + static char tell_doc[] = + "tell() -> current file position, an integer (may be a long integer)."; + + static char readinto_doc[] = + "readinto() -> Undocumented. Don't use this; it may go away."; + + static char readlines_doc[] = + "readlines([size]) -> list of strings, each a line from the file.\n" + "\n" + "Call readline() repeatedly and return a list of the lines so read.\n" + "The optional size argument, if given, is an approximate bound on the\n" + "total number of bytes in the lines returned."; + + static char xreadlines_doc[] = + "xreadlines() -> next line from the file, as a string.\n" + "\n" + "Equivalent to xreadlines.xreadlines(file). This is like readline(), but\n" + "often quicker, due to reading ahead internally."; + + static char writelines_doc[] = + "writelines(list of strings) -> None. Write the strings to the file.\n" + "\n" + "Note that newlines are not added. This is equivalent to calling write()\n" + "for each string in the list."; + + static char flush_doc[] = + "flush() -> None. Flush the internal I/O buffer."; + + static char close_doc[] = + "close() -> None or (perhaps) an integer. Close the file.\n" + "\n" + "Sets data attribute .closed to true. A closed file cannot be used for\n" + "further I/O operations. close() may be called more than once without\n" + "error. Some kinds of file objects (for example, opened by popen())\n" + "may return an exit status upon closing."; + + static char isatty_doc[] = + "isatty() -> true or false. True if the file is connected to a tty device."; + static PyMethodDef file_methods[] = { ! {"readline", (PyCFunction)file_readline, METH_VARARGS, readline_doc}, ! {"read", (PyCFunction)file_read, METH_VARARGS, read_doc}, ! {"write", (PyCFunction)file_write, METH_OLDARGS, write_doc}, ! {"fileno", (PyCFunction)file_fileno, METH_NOARGS, fileno_doc}, ! {"seek", (PyCFunction)file_seek, METH_VARARGS, seek_doc}, #ifdef HAVE_FTRUNCATE ! {"truncate", (PyCFunction)file_truncate, METH_VARARGS, truncate_doc}, #endif ! {"tell", (PyCFunction)file_tell, METH_NOARGS, tell_doc}, ! {"readinto", (PyCFunction)file_readinto, METH_OLDARGS, readinto_doc}, ! {"readlines", (PyCFunction)file_readlines, METH_VARARGS, readlines_doc}, ! {"xreadlines", (PyCFunction)file_xreadlines, METH_NOARGS, xreadlines_doc}, ! {"writelines", (PyCFunction)file_writelines, METH_O, writelines_doc}, ! {"flush", (PyCFunction)file_flush, METH_NOARGS, flush_doc}, ! {"close", (PyCFunction)file_close, METH_NOARGS, close_doc}, ! {"isatty", (PyCFunction)file_isatty, METH_NOARGS, isatty_doc}, {NULL, NULL} /* sentinel */ }; From lemburg@users.sourceforge.net Thu Sep 20 11:33:40 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:33:40 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings base64_codec.py,1.1,1.2 hex_codec.py,1.1,1.2 quopri_codec.py,1.1,1.2 uu_codec.py,1.1,1.2 zlib_codec.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv16662/Lib/encodings Modified Files: base64_codec.py hex_codec.py quopri_codec.py uu_codec.py zlib_codec.py Log Message: Patch #462635 by Andrew Kuchling correcting bugs in the new codecs -- the self argument does matter for Python functions (it does not for C functions which most other codecs use). Index: base64_codec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/base64_codec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** base64_codec.py 2001/05/15 12:00:02 1.1 --- base64_codec.py 2001/09/20 10:33:38 1.2 *************** *** 45,50 **** class Codec(codecs.Codec): ! encode = base64_encode ! decode = base64_decode class StreamWriter(Codec,codecs.StreamWriter): --- 45,52 ---- class Codec(codecs.Codec): ! def encode(self, input,errors='strict'): ! return base64_encode(input,errors) ! def decode(self, input,errors='strict'): ! return base64_decode(input,errors) class StreamWriter(Codec,codecs.StreamWriter): Index: hex_codec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/hex_codec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** hex_codec.py 2001/05/15 12:00:02 1.1 --- hex_codec.py 2001/09/20 10:33:38 1.2 *************** *** 45,50 **** class Codec(codecs.Codec): ! encode = hex_encode ! decode = hex_decode class StreamWriter(Codec,codecs.StreamWriter): --- 45,52 ---- class Codec(codecs.Codec): ! def encode(self, input,errors='strict'): ! return hex_encode(input,errors) ! def decode(self, input,errors='strict'): ! return hex_decode(input,errors) class StreamWriter(Codec,codecs.StreamWriter): Index: quopri_codec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/quopri_codec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** quopri_codec.py 2001/05/15 15:34:07 1.1 --- quopri_codec.py 2001/09/20 10:33:38 1.2 *************** *** 42,47 **** class Codec(codecs.Codec): ! encode = quopri_encode ! decode = quopri_decode class StreamWriter(Codec, codecs.StreamWriter): --- 42,49 ---- class Codec(codecs.Codec): ! def encode(self, input,errors='strict'): ! return quopri_encode(input,errors) ! def decode(self, input,errors='strict'): ! return quopri_decode(input,errors) class StreamWriter(Codec, codecs.StreamWriter): Index: uu_codec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/uu_codec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** uu_codec.py 2001/05/15 12:00:02 1.1 --- uu_codec.py 2001/09/20 10:33:38 1.2 *************** *** 95,101 **** class Codec(codecs.Codec): ! encode = uu_encode ! decode = uu_decode ! class StreamWriter(Codec,codecs.StreamWriter): pass --- 95,103 ---- class Codec(codecs.Codec): ! def encode(self,input,errors='strict'): ! return uu_encode(input,errors) ! def decode(self,input,errors='strict'): ! return uu_decode(input,errors) ! class StreamWriter(Codec,codecs.StreamWriter): pass Index: zlib_codec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/zlib_codec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** zlib_codec.py 2001/05/15 12:00:02 1.1 --- zlib_codec.py 2001/09/20 10:33:38 1.2 *************** *** 46,51 **** class Codec(codecs.Codec): ! encode = zlib_encode ! decode = zlib_decode class StreamWriter(Codec,codecs.StreamWriter): --- 46,53 ---- class Codec(codecs.Codec): ! def encode(self, input, errors='strict'): ! return zlib_encode(input, errors) ! def decode(self, input, errors='strict'): ! return zlib_decode(input, errors) class StreamWriter(Codec,codecs.StreamWriter): From lemburg@users.sourceforge.net Thu Sep 20 11:35:47 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:35:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include unicodeobject.h,2.34,2.35 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv17012/Include Modified Files: unicodeobject.h Log Message: Patch #435971: UTF-7 codec by Brian Quinlan. Index: unicodeobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/unicodeobject.h,v retrieving revision 2.34 retrieving revision 2.35 diff -C2 -d -r2.34 -r2.35 *** unicodeobject.h 2001/09/19 11:21:03 2.34 --- unicodeobject.h 2001/09/20 10:35:45 2.35 *************** *** 608,611 **** --- 608,629 ---- ); + /* --- UTF-7 Codecs ------------------------------------------------------- */ + + extern DL_IMPORT(PyObject*) PyUnicode_DecodeUTF7( + const char *string, /* UTF-7 encoded string */ + int length, /* size of string */ + const char *errors /* error handling */ + ); + + extern DL_IMPORT(PyObject*) PyUnicode_EncodeUTF7( + const Py_UNICODE *data, /* Unicode char buffer */ + int length, /* number of Py_UNICODE chars to encode */ + int encodeSetO, /* force the encoder to encode characters in + Set O, as described in RFC2152 */ + int encodeWhiteSpace, /* force the encoder to encode space, tab, + carriage return and linefeed characters */ + const char *errors /* error handling */ + ); + /* --- UTF-8 Codecs ------------------------------------------------------- */ From lemburg@users.sourceforge.net Thu Sep 20 11:35:47 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:35:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings aliases.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv17012/Lib/encodings Modified Files: aliases.py Log Message: Patch #435971: UTF-7 codec by Brian Quinlan. Index: aliases.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/aliases.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** aliases.py 2001/08/10 13:58:50 1.9 --- aliases.py 2001/09/20 10:35:45 1.10 *************** *** 15,18 **** --- 15,22 ---- 'latin1': 'latin_1', + # UTF-7 + 'utf7': 'utf_7', + 'u7': 'utf_7', + # UTF-8 'utf': 'utf_8', From lemburg@users.sourceforge.net Thu Sep 20 11:35:48 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:35:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _codecsmodule.c,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17012/Modules Modified Files: _codecsmodule.c Log Message: Patch #435971: UTF-7 codec by Brian Quinlan. Index: _codecsmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_codecsmodule.c,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -d -r2.9 -r2.10 *** _codecsmodule.c 2001/08/17 18:39:25 2.9 --- _codecsmodule.c 2001/09/20 10:35:46 2.10 *************** *** 125,128 **** --- 125,144 ---- static PyObject * + utf_7_decode(PyObject *self, + PyObject *args) + { + const char *data; + int size; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "t#|z:utf_7_decode", + &data, &size, &errors)) + return NULL; + + return codec_tuple(PyUnicode_DecodeUTF7(data, size, errors), + size); + } + + static PyObject * utf_8_decode(PyObject *self, PyObject *args) *************** *** 383,386 **** --- 399,426 ---- static PyObject * + utf_7_encode(PyObject *self, + PyObject *args) + { + PyObject *str, *v; + const char *errors = NULL; + + if (!PyArg_ParseTuple(args, "O|z:utf_7_encode", + &str, &errors)) + return NULL; + + str = PyUnicode_FromObject(str); + if (str == NULL) + return NULL; + v = codec_tuple(PyUnicode_EncodeUTF7(PyUnicode_AS_UNICODE(str), + PyUnicode_GET_SIZE(str), + 0, + 0, + errors), + PyUnicode_GET_SIZE(str)); + Py_DECREF(str); + return v; + } + + static PyObject * utf_8_encode(PyObject *self, PyObject *args) *************** *** 633,636 **** --- 673,678 ---- {"utf_8_encode", utf_8_encode, 1}, {"utf_8_decode", utf_8_decode, 1}, + {"utf_7_encode", utf_7_encode, 1}, + {"utf_7_decode", utf_7_decode, 1}, {"utf_16_encode", utf_16_encode, 1}, {"utf_16_le_encode", utf_16_le_encode, 1}, From lemburg@users.sourceforge.net Thu Sep 20 11:35:48 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:35:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17012/Lib/test Modified Files: test_unicode.py Log Message: Patch #435971: UTF-7 codec by Brian Quinlan. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_unicode.py 2001/07/25 16:05:58 1.36 --- test_unicode.py 2001/09/20 10:35:45 1.37 *************** *** 378,381 **** --- 378,407 ---- print 'Testing builtin codecs...', + # UTF-7 specific encoding tests: + utfTests = [(u'A\u2262\u0391.', 'A+ImIDkQ.'), # RFC2152 example + (u'Hi Mom -\u263a-!', 'Hi Mom -+Jjo--!'), # RFC2152 example + (u'\u65E5\u672C\u8A9E', '+ZeVnLIqe-'), # RFC2152 example + (u'Item 3 is \u00a31.', 'Item 3 is +AKM-1.'), # RFC2152 example + (u'+', '+-'), + (u'+-', '+--'), + (u'+?', '+-?'), + (u'\?', '+AFw?'), + (u'+?', '+-?'), + (ur'\\?', '+AFwAXA?'), + (ur'\\\?', '+AFwAXABc?'), + (ur'++--', '+-+---')] + + for x,y in utfTests: + verify( x.encode('utf-7') == y ) + + try: + unicode('+3ADYAA-', 'utf-7') # surrogates not supported + except UnicodeError: + pass + else: + raise TestFailed, "unicode('+3ADYAA-', 'utf-7') failed to raise an exception" + + verify(unicode('+3ADYAA-', 'utf-7', 'replace') == u'\ufffd') + # UTF-8 specific encoding tests: verify(u'\u20ac'.encode('utf-8') == \ *************** *** 440,443 **** --- 466,470 ---- verify(u'hello'.encode('ascii') == 'hello') + verify(u'hello'.encode('utf-7') == 'hello') verify(u'hello'.encode('utf-8') == 'hello') verify(u'hello'.encode('utf8') == 'hello') *************** *** 448,452 **** # Roundtrip safety for BMP (just the first 1024 chars) u = u''.join(map(unichr, range(1024))) ! for encoding in ('utf-8', 'utf-16', 'utf-16-le', 'utf-16-be', 'raw_unicode_escape', 'unicode_escape', 'unicode_internal'): verify(unicode(u.encode(encoding),encoding) == u) --- 475,479 ---- # Roundtrip safety for BMP (just the first 1024 chars) u = u''.join(map(unichr, range(1024))) ! for encoding in ('utf-7', 'utf-8', 'utf-16', 'utf-16-le', 'utf-16-be', 'raw_unicode_escape', 'unicode_escape', 'unicode_internal'): verify(unicode(u.encode(encoding),encoding) == u) From lemburg@users.sourceforge.net Thu Sep 20 11:35:48 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 03:35:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.113,2.114 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17012/Objects Modified Files: unicodeobject.c Log Message: Patch #435971: UTF-7 codec by Brian Quinlan. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** unicodeobject.c 2001/09/12 05:18:58 2.113 --- unicodeobject.c 2001/09/20 10:35:46 2.114 *************** *** 636,639 **** --- 636,939 ---- } + /* --- UTF-7 Codec -------------------------------------------------------- */ + + /* see RFC2152 for details */ + + static + char utf7_special[128] = { + /* indicate whether a UTF-7 character is special i.e. cannot be directly + encoded: + 0 - not special + 1 - special + 2 - whitespace (optional) + 3 - RFC2152 Set O (optional) */ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 3, 3, 3, 3, 3, 3, 0, 0, 0, 3, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 1, 3, 3, 3, + 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 1, 1, + + }; + + #define SPECIAL(c, encodeO, encodeWS) \ + (((c)>127 || utf7_special[(c)] == 1) || \ + (encodeWS && (utf7_special[(c)] == 2)) || \ + (encodeO && (utf7_special[(c)] == 3))) + + #define B64(n) ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"[(n) & 0x3f]) + #define B64CHAR(c) (isalnum(c) || (c) == '+' || (c) == '/') + #define UB64(c) ((c) == '+' ? 62 : (c) == '/' ? 63 : (c) >= 'a' ? \ + (c) - 71 : (c) >= 'A' ? (c) - 65 : (c) + 4) + + #define ENCODE(out, ch, bits) \ + while (bits >= 6) { \ + *out++ = B64(ch >> (bits-6)); \ + bits -= 6; \ + } + + #define DECODE(out, ch, bits, surrogate) \ + while (bits >= 16) { \ + Py_UNICODE outCh = (Py_UNICODE) ((ch >> (bits-16)) & 0xffff); \ + bits -= 16; \ + if (surrogate) { \ + /* We have already generated an error for the high surrogate + so let's not bother seeing if the low surrogate is correct or not */\ + surrogate = 0; \ + } else if (0xDC00 <= outCh && outCh <= 0xDFFF) { \ + /* This is a surrogate pair. Unfortunately we can't represent \ + it in a 16-bit character */ \ + surrogate = 1; \ + errmsg = "code pairs are not supported"; \ + goto utf7Error; \ + } else { \ + *out++ = outCh; \ + } \ + } \ + + static + int utf7_decoding_error(Py_UNICODE **dest, + const char *errors, + const char *details) + { + if ((errors == NULL) || + (strcmp(errors,"strict") == 0)) { + PyErr_Format(PyExc_UnicodeError, + "UTF-7 decoding error: %.400s", + details); + return -1; + } + else if (strcmp(errors,"ignore") == 0) { + return 0; + } + else if (strcmp(errors,"replace") == 0) { + if (dest != NULL) { + **dest = Py_UNICODE_REPLACEMENT_CHARACTER; + (*dest)++; + } + return 0; + } + else { + PyErr_Format(PyExc_ValueError, + "UTF-7 decoding error; unknown error handling code: %.400s", + errors); + return -1; + } + } + + PyObject *PyUnicode_DecodeUTF7(const char *s, + int size, + const char *errors) + { + const char *e; + PyUnicodeObject *unicode; + Py_UNICODE *p; + const char *errmsg = ""; + int inShift = 0; + unsigned int bitsleft = 0; + unsigned long charsleft = 0; + int surrogate = 0; + + unicode = _PyUnicode_New(size); + if (!unicode) + return NULL; + if (size == 0) + return (PyObject *)unicode; + + p = unicode->str; + e = s + size; + + while (s < e) { + Py_UNICODE ch = *s; + + if (inShift) { + if ((ch == '-') || !B64CHAR(ch)) { + inShift = 0; + s++; + + /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate); + if (bitsleft >= 6) { + /* The shift sequence has a partial character in it. If + bitsleft < 6 then we could just classify it as padding + but that is not the case here */ + + errmsg = "partial character in shift sequence"; + goto utf7Error; + } + /* According to RFC2152 the remaining bits should be zero. We + choose to signal an error/insert a replacement character + here so indicate the potential of a misencoded character. */ + + /* On x86, a << b == a << (b%32) so make sure that bitsleft != 0 */ + if (bitsleft && charsleft << (sizeof(charsleft) * 8 - bitsleft)) { + errmsg = "non-zero padding bits in shift sequence"; + goto utf7Error; + } + + if (ch == '-') { + if ((s < e) && (*(s) == '-')) { + *p++ = '-'; + inShift = 1; + } + } else if (SPECIAL(ch,0,0)) { + errmsg = "unexpected special character"; + goto utf7Error; + } else { + *p++ = ch; + } + } else { + charsleft = (charsleft << 6) | UB64(ch); + bitsleft += 6; + s++; + /* p, charsleft, bitsleft, surrogate = */ DECODE(p, charsleft, bitsleft, surrogate); + } + } + else if ( ch == '+' ) { + s++; + if (s < e && *s == '-') { + s++; + *p++ = '+'; + } else + { + inShift = 1; + bitsleft = 0; + } + } + else if (SPECIAL(ch,0,0)) { + errmsg = "unexpected special character"; + s++; + goto utf7Error; + } + else { + *p++ = ch; + s++; + } + continue; + utf7Error: + if (utf7_decoding_error(&p, errors, errmsg)) + goto onError; + } + + if (inShift) { + if (utf7_decoding_error(&p, errors, "unterminated shift sequence")) + goto onError; + } + + if (_PyUnicode_Resize(&unicode, p - unicode->str)) + goto onError; + + return (PyObject *)unicode; + + onError: + Py_DECREF(unicode); + return NULL; + } + + + PyObject *PyUnicode_EncodeUTF7(const Py_UNICODE *s, + int size, + int encodeSetO, + int encodeWhiteSpace, + const char *errors) + { + PyObject *v; + /* It might be possible to tighten this worst case */ + unsigned int cbAllocated = 5 * size; + int inShift = 0; + int i = 0; + unsigned int bitsleft = 0; + unsigned long charsleft = 0; + char * out; + char * start; + + if (size == 0) + return PyString_FromStringAndSize(NULL, 0); + + v = PyString_FromStringAndSize(NULL, cbAllocated); + if (v == NULL) + return NULL; + + start = out = PyString_AS_STRING(v); + for (;i < size; ++i) { + Py_UNICODE ch = s[i]; + + if (!inShift) { + if (ch == '+') { + *out++ = '+'; + *out++ = '-'; + } else if (SPECIAL(ch, encodeSetO, encodeWhiteSpace)) { + charsleft = ch; + bitsleft = 16; + *out++ = '+'; + /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft); + inShift = bitsleft > 0; + } else { + *out++ = (char) ch; + } + } else { + if (!SPECIAL(ch, encodeSetO, encodeWhiteSpace)) { + *out++ = B64(charsleft << (6-bitsleft)); + charsleft = 0; + bitsleft = 0; + /* Characters not in the BASE64 set implicitly unshift the sequence + so no '-' is required, except if the character is itself a '-' */ + if (B64CHAR(ch) || ch == '-') { + *out++ = '-'; + } + inShift = 0; + *out++ = (char) ch; + } else { + bitsleft += 16; + charsleft = (charsleft << 16) | ch; + /* out, charsleft, bitsleft = */ ENCODE(out, charsleft, bitsleft); + + /* If the next character is special then we dont' need to terminate + the shift sequence. If the next character is not a BASE64 character + or '-' then the shift sequence will be terminated implicitly and we + don't have to insert a '-'. */ + + if (bitsleft == 0) { + if (i + 1 < size) { + Py_UNICODE ch2 = s[i+1]; + + if (SPECIAL(ch2, encodeSetO, encodeWhiteSpace)) { + + } else if (B64CHAR(ch2) || ch2 == '-') { + *out++ = '-'; + inShift = 0; + } else { + inShift = 0; + } + + } + else { + *out++ = '-'; + inShift = 0; + } + } + } + } + } + if (bitsleft) { + *out++= B64(charsleft << (6-bitsleft) ); + *out++ = '-'; + } + + if (_PyString_Resize(&v, out - start)) { + Py_DECREF(v); + return NULL; + } + return v; + } + + #undef SPECIAL + #undef B64 + #undef B64CHAR + #undef UB64 + #undef ENCODE + #undef DECODE + /* --- UTF-8 Codec -------------------------------------------------------- */ From lemburg@users.sourceforge.net Thu Sep 20 13:53:18 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 05:53:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12271/Lib/test Modified Files: test_unicode.py Log Message: Implement the changes proposed in patch #413333. unicode(obj) now works just like str(obj) in that it tries __str__/tp_str on the object in case it finds that the object is not a string or buffer. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test_unicode.py 2001/09/20 10:35:45 1.37 --- test_unicode.py 2001/09/20 12:53:13 1.38 *************** *** 430,433 **** --- 430,434 ---- verify(unicode('hello','latin-1') == u'hello') + # Compatibility to str(): class String: x = '' *************** *** 445,448 **** --- 446,453 ---- verify(str(o) == 'abc') + for obj in (123, 123.45, 123L): + verify(unicode(obj) == unicode(str(obj))) + + # Error handling try: u'Andr\202 x'.encode('ascii') From lemburg@users.sourceforge.net Thu Sep 20 13:53:18 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 05:53:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.114,2.115 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12271/Objects Modified Files: unicodeobject.c Log Message: Implement the changes proposed in patch #413333. unicode(obj) now works just like str(obj) in that it tries __str__/tp_str on the object in case it finds that the object is not a string or buffer. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.114 retrieving revision 2.115 diff -C2 -d -r2.114 -r2.115 *** unicodeobject.c 2001/09/20 10:35:46 2.114 --- unicodeobject.c 2001/09/20 12:53:16 2.115 *************** *** 399,406 **** const char *errors) { ! const char *s; int len; int owned = 0; PyObject *v; if (obj == NULL) { --- 399,407 ---- const char *errors) { ! const char *s = NULL; int len; int owned = 0; PyObject *v; + int reclevel; if (obj == NULL) { *************** *** 410,460 **** /* Coerce object */ ! if (PyInstance_Check(obj)) { ! PyObject *func; ! func = PyObject_GetAttrString(obj, "__str__"); ! if (func == NULL) { ! PyErr_SetString(PyExc_TypeError, ! "coercing to Unicode: instance doesn't define __str__"); ! return NULL; } ! obj = PyEval_CallObject(func, NULL); ! Py_DECREF(func); ! if (obj == NULL) ! return NULL; ! owned = 1; ! } ! if (PyUnicode_Check(obj)) { ! if (encoding) { ! PyErr_SetString(PyExc_TypeError, ! "decoding Unicode is not supported"); ! return NULL; } ! if (PyUnicode_CheckExact(obj)) { ! Py_INCREF(obj); ! v = obj; } - else { - /* For a subclass of unicode, return a true unicode object - with the same string value. */ - v = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj), - PyUnicode_GET_SIZE(obj)); - } - goto done; - } - else if (PyString_Check(obj)) { - s = PyString_AS_STRING(obj); - len = PyString_GET_SIZE(obj); } ! else if (PyObject_AsCharBuffer(obj, &s, &len)) { ! /* Overwrite the error message with something more useful in ! case of a TypeError. */ ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_Format(PyExc_TypeError, ! "coercing to Unicode: need string or buffer, " ! "%.80s found", ! obj->ob_type->tp_name); goto onError; } ! /* Convert to Unicode */ if (len == 0) { --- 411,473 ---- /* Coerce object */ ! for (reclevel = 0; reclevel < 2; reclevel++) { ! ! if (PyUnicode_Check(obj)) { ! if (encoding) { ! PyErr_SetString(PyExc_TypeError, ! "decoding Unicode is not supported"); ! goto onError; ! } ! if (PyUnicode_CheckExact(obj)) { ! Py_INCREF(obj); ! v = obj; ! } ! else { ! /* For a subclass of unicode, return a true unicode object ! with the same string value. */ ! v = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(obj), ! PyUnicode_GET_SIZE(obj)); ! } ! goto done; } ! else if (PyString_Check(obj)) { ! s = PyString_AS_STRING(obj); ! len = PyString_GET_SIZE(obj); ! break; } ! else { ! PyObject *w; ! ! /* Try char buffer interface */ ! if (PyObject_AsCharBuffer(obj, &s, &len)) ! PyErr_Clear(); ! else ! break; ! ! /* Mimic the behaviour of str(object) if everything else ! fails (see PyObject_Str()); this also covers instances ! which implement __str__. */ ! if (obj->ob_type->tp_str == NULL) ! w = PyObject_Repr(obj); ! else ! w = (*obj->ob_type->tp_str)(obj); ! if (w == NULL) ! goto onError; ! if (owned) { ! Py_DECREF(obj); ! } ! obj = w; ! owned = 1; } } ! ! if (s == NULL) { ! PyErr_Format(PyExc_TypeError, ! "coercing to Unicode: __str__ recursion limit exceeded " ! "(last type: %.80s)", ! obj->ob_type->tp_name); goto onError; } ! /* Convert to Unicode */ if (len == 0) { From lemburg@users.sourceforge.net Thu Sep 20 13:56:16 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 05:56:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings utf_7.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv13130/Lib/encodings Added Files: utf_7.py Log Message: Python part of the UTF-7 codec by Brian Quinlan. --- NEW FILE: utf_7.py --- """ Python 'utf-7' Codec Written by Brian Quinlan (brian@sweetapp.com). """ import codecs ### Codec APIs class Codec(codecs.Codec): # Note: Binding these as C functions will result in the class not # converting them to methods. This is intended. encode = codecs.utf_7_encode decode = codecs.utf_7_decode class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### encodings module API def getregentry(): return (Codec.encode,Codec.decode,StreamReader,StreamWriter) From lemburg@users.sourceforge.net Thu Sep 20 13:59:39 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 05:59:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.247,1.248 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13939/Misc Modified Files: NEWS Log Message: Note about enhancements to unicode(). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.247 retrieving revision 1.248 diff -C2 -d -r1.247 -r1.248 *** NEWS 2001/09/20 05:30:24 1.247 --- NEWS 2001/09/20 12:59:37 1.248 *************** *** 4,7 **** --- 4,13 ---- Core + - PyUnicode_FromEncodedObject() now works very much like + PyObject_Str(obj) in that it tries to use __str__/tp_str + on the object if the object is not a string or buffer. This + makes unicode() behave like str() when applied to non-string/buffer + objects. + - PyFile_WriteObject now passes Unicode object to the file's write method. As a result, all file-like object which may be the target From gvanrossum@users.sourceforge.net Thu Sep 20 14:38:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 06:38:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.150,2.151 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22476 Modified Files: object.c Log Message: _PyObject_GetDictPtr(): when the offset is negative, always align -- we can't trust that tp_basicsize is aligned. Fixes SF bug #462848. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.150 retrieving revision 2.151 diff -C2 -d -r2.150 -r2.151 *** object.c 2001/09/18 20:38:53 2.150 --- object.c 2001/09/20 13:38:22 2.151 *************** *** 1151,1166 **** if (dictoffset < 0) { dictoffset += tp->tp_basicsize; assert(dictoffset > 0); /* Sanity check */ ! if (tp->tp_itemsize > 0) { ! int n = ((PyVarObject *)obj)->ob_size; ! if (n > 0) { ! dictoffset += tp->tp_itemsize * n; ! /* Round up, if necessary */ ! if (tp->tp_itemsize % PTRSIZE != 0) { ! dictoffset += PTRSIZE - 1; ! dictoffset /= PTRSIZE; ! dictoffset *= PTRSIZE; ! } ! } } } --- 1151,1161 ---- if (dictoffset < 0) { dictoffset += tp->tp_basicsize; + dictoffset += tp->tp_itemsize * ((PyVarObject *)obj)->ob_size; assert(dictoffset > 0); /* Sanity check */ ! /* Round up, if necessary */ ! if (dictoffset % PTRSIZE != 0) { ! dictoffset /= PTRSIZE; ! dictoffset += 1; ! dictoffset *= PTRSIZE; } } From jhylton@users.sourceforge.net Thu Sep 20 15:59:02 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 20 Sep 2001 07:59:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler/compiler ast.txt,1.4,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler/compiler In directory usw-pr-cvs1:/tmp/cvs-serv8300 Removed Files: ast.txt Log Message: Moved to Tools/compiler along with astgen.py --- ast.txt DELETED --- From jhylton@users.sourceforge.net Thu Sep 20 16:02:29 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 20 Sep 2001 08:02:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler README,1.1,1.2 setup.py,1.2,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler In directory usw-pr-cvs1:/tmp/cvs-serv9507 Modified Files: README Removed Files: setup.py Log Message: Remove setup.py, unnecessary since compiler package is the std library. Update README. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/compiler/README,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** README 2001/08/08 19:10:11 1.1 --- README 2001/09/20 15:02:27 1.2 *************** *** 1,6 **** ! This directory contains modules for a a Python source to bytecode compiler ! written in pure Python. To install the compiler modules so they're ! available for use by third-party Python software, run 'python setup.py ! install'. compile.py Demo that compiles a Python module into a .pyc file --- 1,4 ---- ! This directory contains support tools for the Python compiler package, ! which is now part of the standard library. compile.py Demo that compiles a Python module into a .pyc file *************** *** 19,21 **** builtin compiler. - setup.py Setup file for installing the compiler code as a package. --- 17,18 ---- --- setup.py DELETED --- From jhylton@users.sourceforge.net Thu Sep 20 16:27:32 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Thu, 20 Sep 2001 08:27:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools README,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools In directory usw-pr-cvs1:/tmp/cvs-serv15679 Modified Files: README Log Message: Update description of Tools/compiler Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/README,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** README 2001/08/06 19:33:52 1.9 --- README 2001/09/20 15:27:30 1.10 *************** *** 11,17 **** description. Still under development! ! compiler A Python source to bytecode compiler written in ! Python, including an interface for manipulating ! abstract syntax trees. Still under development. faqwiz FAQ Wizard. --- 11,16 ---- description. Still under development! ! compiler Tools used to maintain the compiler package in the ! standard library. faqwiz FAQ Wizard. From akuchling@users.sourceforge.net Thu Sep 20 16:48:04 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Thu, 20 Sep 2001 08:48:04 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv20442 Modified Files: pep-0247.txt Log Message: Removed the reset() method Renamed digestsize to digest_size Swap order of key, string arguments to new() Various minor rewrites Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** pep-0247.txt 2001/09/17 15:09:37 1.4 --- pep-0247.txt 2001/09/20 15:48:02 1.5 *************** *** 6,10 **** Type: Informational Created: 23-Mar-2001 ! Post-History: Abstract --- 6,10 ---- Type: Informational Created: 23-Mar-2001 ! Post-History: 20-Sep-2001 Abstract *************** *** 24,28 **** Hash function modules define one function: ! new([string], [key]) Create a new hashing object and return it. You can now feed --- 24,29 ---- Hash function modules define one function: ! new([string]) ! new([key] , [string]) Create a new hashing object and return it. You can now feed *************** *** 38,69 **** Arbitrary additional keyword arguments can be added to this function, but if they're not supplied, sensible default values ! should be used. For example, 'rounds' and 'digestsize' could ! be added for a hash function which supports a different output ! size and a different number of rounds. Hash function modules define one variable: ! digestsize An integer value; the size of the digest produced by the hashing objects created by this module, measured in bytes. You could also obtain this value by creating a sample object ! and accessing its 'digestsize' attribute, but it can be convenient to have this value available from the module. Hashes with a variable output size will set this variable to 0. ! The attributes of a hashing object are: ! digestsize ! An integer value; the size of the digest produced by the hashing object, measured in bytes. If the hash has a variable ! output size, this output size must be chosen when the ! hashing object is created, and this attribute must contain the selected size. Therefore 0 is *not* a legal value for this attribute. ! The methods for hashing objects are always the following: copy() --- 39,72 ---- Arbitrary additional keyword arguments can be added to this function, but if they're not supplied, sensible default values ! should be used. For example, 'rounds' and 'digest_size' ! keywords could be added for a hash function which supports a ! variable number of rounds and several different output sizes, ! and they should default to values believed to be secure. Hash function modules define one variable: ! digest_size An integer value; the size of the digest produced by the hashing objects created by this module, measured in bytes. You could also obtain this value by creating a sample object ! and accessing its 'digest_size' attribute, but it can be convenient to have this value available from the module. Hashes with a variable output size will set this variable to 0. ! Hashing objects require a single attribute: ! digest_size ! This attribute is identical to the module-level digest_size ! variable, measuring the size of the digest produced by the hashing object, measured in bytes. If the hash has a variable ! output size, this output size must be chosen when the hashing ! object is created, and this attribute must contain the selected size. Therefore 0 is *not* a legal value for this attribute. ! Hashing objects require the following methods: copy() *************** *** 86,111 **** method mustn't alter the object. - reset() - - Reset this hashing object to its initial state, as if the - object was created from new(key=) - (XXX what should this do for a keyed hash? A proposed - semantic follows:). There is no way to supply a starting - string as there is for the new() function, and there's no way - to change the key specified for a keyed hash. - update(arg) Update this hashing object with the string 'arg'. ! For convenience, hashing objects also have a digest_size ! attribute, measuring the size of the resulting digest in bytes. ! This is identical to the module-level digest_size variable. ! Here's an example, using a module named 'MD5': >>> from Crypto.Hash import MD5 >>> m = MD5.new() ! >>> m.digestsize 16 >>> m.update('abc') --- 89,104 ---- method mustn't alter the object. update(arg) Update this hashing object with the string 'arg'. ! Hashing modules can define additional module-level functions or ! object methods and still be compliant with this specification. ! Here's an example, using a module named 'MD5': >>> from Crypto.Hash import MD5 >>> m = MD5.new() ! >>> m.digest_size 16 >>> m.update('abc') *************** *** 114,119 **** >>> m.hexdigest() '900150983cd24fb0d6963f7d28e17f72' - Or, more compactly: - >>> MD5.new('abc').digest() '\x90\x01P\x98<\xd2O\xb0\xd6\x96?}(\xe1\x7fr' --- 107,110 ---- *************** *** 122,133 **** Changes ! 2001-09-17: Renamed clear() to reset; added digestsize attribute to objects; added .hexdigest() method. Acknowledgements ! Thanks to Andrew Archibald, Rich Salz, and the readers of the ! python-crypto list for their comments on this PEP. --- 113,126 ---- Changes ! 2001-09-17: Renamed clear() to reset(); added digest_size attribute to objects; added .hexdigest() method. + 2001-09-20: Removed reset() method completely. Acknowledgements ! Thanks to Andrew Archibald, Rich Salz, Itamar Shtull-Trauring, and ! the readers of the python-crypto list for their comments on this ! PEP. From bwarsaw@users.sourceforge.net Thu Sep 20 17:02:32 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Thu, 20 Sep 2001 09:02:32 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.133,1.134 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25037 Modified Files: pep-0000.txt Log Message: Added PEP 272, API for Secret-Key Encryption Algorithms, Kuchling Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.133 retrieving revision 1.134 diff -C2 -d -r1.133 -r1.134 *** pep-0000.txt 2001/09/13 16:47:13 1.133 --- pep-0000.txt 2001/09/20 16:02:29 1.134 *************** *** 41,44 **** --- 41,45 ---- I 248 Python Database API Specification v1.0 Lemburg I 249 Python Database API Specification v2.0 Lemburg + I 272 API for Secret-Key Encryption Algorithms Kuchling Accepted PEPs (accepted for Python 2.2; may not be implemented yet) *************** *** 226,229 **** --- 227,231 ---- S 270 uniq method for list objects Petrone S 271 Prefixing sys.path by command line option Giacometti + I 272 API for Secret-Key Encryption Algorithms Kuchling From akuchling@users.sourceforge.net Thu Sep 20 17:06:18 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Thu, 20 Sep 2001 09:06:18 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0272.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv25751 Added Files: pep-0272.txt Log Message: Initial check-in of PEP 272, "API for Secret-Key Encryption Algorithms" --- NEW FILE: pep-0272.txt --- PEP: XXX Title: API for Secret-Key Encryption Algorithms Version: $Revision: 1.1 $ Author: A.M. Kuchling Status: Draft Type: Informational Created: 18-Sep-2001 Post-History: Abstract This document specifies a standard API for secret-key encryption algorithms, such as DES or Rijndael, making it easier to switch between different algorithms and implementations. The API is intended to be suitable for both block and stream ciphers. Introduction Encryption algorithms transform their input data (called plaintext) in some way that is dependent on a variable key, producing ciphertext. The transformation can easily be reversed, if and only if one knows the key (we hope). The key is a sequence of bits chosen from some very large space of possible keys. Block ciphers take multibyte inputs of a fixed size (frequently 8 or 16 bytes long) and encrypt them. Block ciphers can be operated in various feedback modes. The feedback modes supported in this specification are: Number Constant Description 1 ECB Electronic Code Book 2 CBC Cipher Block Chaining 3 CFB Cipher FeedBack 4 PGP Variant of CFB used by the OpenPGP standard In a strict formal sense, stream ciphers encrypt data bit-by-bit; practically, stream ciphers work on a character-by-character basis. Stream ciphers use exactly the same interface as block ciphers, with a block length that will always be 1; this is how block and stream ciphers can be distinguished. The only feedback mode available for stream ciphers is ECB mode. Specification All cipher algorithms share a common interface. After importing a given module, there is exactly one function and two variables available. Secret-key encryption modules define one function: new(key, mode, [IV], **kwargs) Returns a ciphering object, using the secret key contained in the string 'key', and using the feedback mode 'mode', which must be one of the constants from the following table. If 'mode' is CBC or CFB, 'IV' must be provided, and must be a string of the same length as the block size. Not providing a value of 'IV' will result in a XXXError exception being raised. (what exception? ValueError? ciphermodule.error?) Depending on the algorithm, a module may support additional keyword arguments to this function. The most common keyword argument will likely be 'rounds', to set the number of rounds to be used. Secret-key encryption modules define two variables: blocksize An integer value; the size of the blocks encrypted by this module. For all feedback modes, the length of strings passed to the encrypt() and decrypt() must be a multiple of the block size. For stream ciphers, \code{blocksize} will be 1. keysize An integer value; the size of the keys required by this module. If keysize is zero, then the algorithm accepts arbitrary-length keys. You cannot pass a key of length 0 (that is, the null string '') as such a variable-length key. All cipher objects have at least three attributes: blocksize An integer value equal to the size of the blocks encrypted by this object. For algorithms with a variable block size, this value is equal to the block size selected for this object. IV Contains the initial value which will be used to start a cipher feedback mode; it will always be a string exactly one block in length. After encrypting or decrypting a string, this value is updated to reflect the modified feedback text. It is read-only, and cannot be assigned a new value. keysize (XXX this is in mxCrypto, but do we actually need this? I can't remember why it was there, and it seems stupid.) An integer value equal to the size of the keys used by this object. If keysize is zero, then the algorithm accepts arbitrary-length keys. For algorithms that support variable length keys, this will be 0. Identical to the module variable of the same name. It does *not* contain the size of the key actually The methods for secret-key encryption objects are as follows: decrypt(string) Decrypts 'string, using the key-dependent data in the object, and with the appropriate feedback mode. The string's length must be an exact multiple of the algorithm's block size. Returns a string containing the plaintext. encrypt(string) Encrypts a non-null string, using the key-dependent data in the object, and with the appropriate feedback mode. The string's length must be an exact multiple of the algorithm's block size; for stream ciphers, the string can be of any length. Returns a string containing the ciphertext. Here's an example, using a module named 'DES': >>> import DES >>> obj = DES.new('abcdefgh', DES.ECB) >>> plain="Guido van Rossum is a space alien." >>> len(plain) 34 >>> obj.encrypt(plain) Traceback (innermost last): File "", line 1, in ? ValueError: Strings for DES must be a multiple of 8 in length >>> ciph=obj.encrypt(plain+'XXXXXX') >>> ciph '\021,\343Nq\214DY\337T\342pA\372\255\311s\210\363,\300j\330\250\312\347\342I\3215w\03561\303dgb/\006' >>> obj.decrypt(ciph) 'Guido van Rossum is a space alien.XXXXXX' References RFC2440: "OpenPGP Message Format" (http://rfc2440.x42.com, http://www.faqs.org/rfcs/rfc2440.html) Applied Cryptography Copyright This document has been placed in the public domain. Local Variables: mode: indented-text indent-tabs-mode: nil End: From akuchling@users.sourceforge.net Thu Sep 20 17:12:28 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Thu, 20 Sep 2001 09:12:28 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0272.txt,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv27026 Modified Files: pep-0272.txt Log Message: 'blocksize' -> 'block_size', 'keysize' -> 'key_size' Rip out the key_size attribute of cipher objects Set PEP number Various rewrites Index: pep-0272.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0272.txt,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** pep-0272.txt 2001/09/20 16:06:16 1.1 --- pep-0272.txt 2001/09/20 16:12:26 1.2 *************** *** 1,3 **** ! PEP: XXX Title: API for Secret-Key Encryption Algorithms Version: $Revision$ --- 1,3 ---- ! PEP: 272 Title: API for Secret-Key Encryption Algorithms Version: $Revision$ *************** *** 11,15 **** This document specifies a standard API for secret-key encryption ! algorithms, such as DES or Rijndael, making it easier to switch between different algorithms and implementations. The API is intended to be suitable for both block and stream ciphers. --- 11,15 ---- This document specifies a standard API for secret-key encryption ! algorithms such as DES or Rijndael, making it easier to switch between different algorithms and implementations. The API is intended to be suitable for both block and stream ciphers. *************** *** 21,31 **** plaintext) in some way that is dependent on a variable key, producing ciphertext. The transformation can easily be reversed, ! if and only if one knows the key (we hope). The key is a sequence ! of bits chosen from some very large space of possible keys. ! Block ciphers take multibyte inputs of a fixed size (frequently 8 ! or 16 bytes long) and encrypt them. Block ciphers can be operated ! in various feedback modes. The feedback modes supported in this ! specification are: Number Constant Description --- 21,30 ---- plaintext) in some way that is dependent on a variable key, producing ciphertext. The transformation can easily be reversed, ! if and only if one knows the key. The key is a sequence of bits ! chosen from some very large space of possible keys. ! Block ciphers encrypt multibyte inputs of a fixed size (frequently ! 8 or 16 bytes long), and can be operated in various feedback ! modes. The feedback modes supported in this specification are: Number Constant Description *************** *** 33,38 **** 2 CBC Cipher Block Chaining 3 CFB Cipher FeedBack ! 4 PGP Variant of CFB used by the OpenPGP standard In a strict formal sense, stream ciphers encrypt data bit-by-bit; practically, stream ciphers work on a character-by-character --- 32,41 ---- 2 CBC Cipher Block Chaining 3 CFB Cipher FeedBack ! 4 PGP Variant of CFB + See _Applied Cryptography_ for descriptions of the first three + feedback modes. The PGP feedback mode is described in the OpenPGP + RFC. + In a strict formal sense, stream ciphers encrypt data bit-by-bit; practically, stream ciphers work on a character-by-character *************** *** 45,51 **** Specification ! All cipher algorithms share a common interface. After importing a ! given module, there is exactly one function and two variables ! available. Secret-key encryption modules define one function: --- 48,52 ---- Specification ! All cipher algorithms share a common interface. Secret-key encryption modules define one function: *************** *** 69,89 **** Secret-key encryption modules define two variables: ! blocksize An integer value; the size of the blocks encrypted by this module. For all feedback modes, the length of strings passed to the encrypt() and decrypt() must be a multiple of the block size. ! For stream ciphers, \code{blocksize} will be 1. ! keysize An integer value; the size of the keys required by this ! module. If keysize is zero, then the algorithm accepts arbitrary-length keys. You cannot pass a key of length 0 (that is, the null string '') as such a variable-length key. ! All cipher objects have at least three attributes: ! blocksize An integer value equal to the size of the blocks encrypted by --- 70,90 ---- Secret-key encryption modules define two variables: ! block_size An integer value; the size of the blocks encrypted by this module. For all feedback modes, the length of strings passed to the encrypt() and decrypt() must be a multiple of the block size. ! For stream ciphers, \code{block_size} will be 1. ! key_size An integer value; the size of the keys required by this ! module. If key_size is zero, then the algorithm accepts arbitrary-length keys. You cannot pass a key of length 0 (that is, the null string '') as such a variable-length key. ! Cipher objects require two attributes: ! block_size An integer value equal to the size of the blocks encrypted by *************** *** 99,113 **** It is read-only, and cannot be assigned a new value. ! keysize (XXX this is in mxCrypto, but do we actually need this? ! I can't remember why it was there, and it seems stupid.) ! ! An integer value equal to the size of the keys used by this ! object. If keysize is zero, then the algorithm accepts ! arbitrary-length keys. For algorithms that support variable ! length keys, this will be 0. Identical to the module variable ! of the same name. It does *not* contain the size of the key ! actually ! ! The methods for secret-key encryption objects are as follows: decrypt(string) --- 100,104 ---- It is read-only, and cannot be assigned a new value. ! Cipher objects require the following methods: decrypt(string) *************** *** 120,124 **** encrypt(string) ! Encrypts a non-null string, using the key-dependent data in the object, and with the appropriate feedback mode. The string's length must be an exact multiple of the algorithm's --- 111,115 ---- encrypt(string) ! Encrypts a non-empty string, using the key-dependent data in the object, and with the appropriate feedback mode. The string's length must be an exact multiple of the algorithm's From lemburg@users.sourceforge.net Thu Sep 20 17:37:25 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 09:37:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_unicode,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv600/Lib/test/output Modified Files: test_unicode Log Message: Update test output after the unicode() change. Index: test_unicode =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_unicode,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** test_unicode 2000/08/08 08:04:03 1.10 --- test_unicode 2001/09/20 16:37:23 1.11 *************** *** 1,3 **** --- 1,4 ---- test_unicode + * u' ' u'7 hello 123' Testing Unicode comparisons... done. Testing Unicode contains method... done. From lemburg@users.sourceforge.net Thu Sep 20 18:23:00 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 10:23:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_unicode,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv10095/Lib/test/output Modified Files: test_unicode Log Message: Fix Unicode .join() method to raise a TypeError for sequence elements which are not Unicode objects or strings. (This matches the string.join() behaviour.) Fix a memory leak in the .join() method which occurs in case the Unicode resize fails. Restore the test_unicode output. Index: test_unicode =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_unicode,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_unicode 2001/09/20 16:37:23 1.11 --- test_unicode 2001/09/20 17:22:58 1.12 *************** *** 1,4 **** test_unicode - * u' ' u'7 hello 123' Testing Unicode comparisons... done. Testing Unicode contains method... done. --- 1,3 ---- From lemburg@users.sourceforge.net Thu Sep 20 18:23:00 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 20 Sep 2001 10:23:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10095/Objects Modified Files: unicodeobject.c Log Message: Fix Unicode .join() method to raise a TypeError for sequence elements which are not Unicode objects or strings. (This matches the string.join() behaviour.) Fix a memory leak in the .join() method which occurs in case the Unicode resize fails. Restore the test_unicode output. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -d -r2.115 -r2.116 *** unicodeobject.c 2001/09/20 12:53:16 2.115 --- unicodeobject.c 2001/09/20 17:22:58 2.116 *************** *** 3198,3201 **** --- 3198,3209 ---- if (!PyUnicode_Check(item)) { PyObject *v; + if (!PyString_Check(item)) { + PyErr_Format(PyExc_TypeError, + "sequence item %i: expected string or Unicode," + " %.80s found", + i, item->ob_type->tp_name); + Py_DECREF(item); + goto onError; + } v = PyUnicode_FromObject(item); Py_DECREF(item); *************** *** 3206,3211 **** itemlen = PyUnicode_GET_SIZE(item); while (reslen + itemlen + seplen >= sz) { ! if (_PyUnicode_Resize(&res, sz*2)) goto onError; sz *= 2; p = PyUnicode_AS_UNICODE(res) + reslen; --- 3214,3221 ---- itemlen = PyUnicode_GET_SIZE(item); while (reslen + itemlen + seplen >= sz) { ! if (_PyUnicode_Resize(&res, sz*2)) { ! Py_DECREF(item); goto onError; + } sz *= 2; p = PyUnicode_AS_UNICODE(res) + reslen; From gvanrossum@users.sourceforge.net Thu Sep 20 20:18:32 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 12:18:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _localemodule.c,2.23,2.24 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv5031 Modified Files: _localemodule.c Log Message: PyLocale_setlocale(): silence compiler warning about free() of a const char *. Index: _localemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_localemodule.c,v retrieving revision 2.23 retrieving revision 2.24 diff -C2 -d -r2.23 -r2.24 *** _localemodule.c 2001/09/05 17:09:48 2.23 --- _localemodule.c 2001/09/20 19:18:30 2.24 *************** *** 216,220 **** /* Release previous file encoding */ if (Py_FileSystemDefaultEncoding) ! free (Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = strdup(codeset); Py_DECREF(enc); --- 216,220 ---- /* Release previous file encoding */ if (Py_FileSystemDefaultEncoding) ! free((char *)Py_FileSystemDefaultEncoding); Py_FileSystemDefaultEncoding = strdup(codeset); Py_DECREF(enc); From fdrake@users.sourceforge.net Thu Sep 20 20:18:54 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 20 Sep 2001 12:18:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.147,1.148 refcounts.dat,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv5089 Modified Files: api.tex refcounts.dat Log Message: Document all the Py*_CheckExact() functions. Document many more of the PyLong_{As,From}*() functions. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.147 retrieving revision 1.148 diff -C2 -d -r1.147 -r1.148 *** api.tex 2001/09/06 17:12:44 1.147 --- api.tex 2001/09/20 19:18:52 1.148 *************** *** 1681,1690 **** \begin{cfuncdesc}{PyObject*}{PyObject_Type}{PyObject *o} ! On success, returns a type object corresponding to the object ! type of object \var{o}. On failure, returns \NULL{}. This is ! equivalent to the Python expression \samp{type(\var{o})}. \bifuncindex{type} \end{cfuncdesc} \begin{cfuncdesc}{int}{PyObject_Length}{PyObject *o} Return the length of object \var{o}. If the object \var{o} provides --- 1681,1696 ---- \begin{cfuncdesc}{PyObject*}{PyObject_Type}{PyObject *o} ! When \var{o} is non-\NULL, returns a type object corresponding to the ! object type of object \var{o}. On failure, raises ! \exception{SystemError} and returns \NULL. This is equivalent to the ! Python expression \code{type(\var{o})}. \bifuncindex{type} \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyObject_TypeCheck}{PyObject *o, PyTypeObject *type} + Return true if the object \var{o} is of type \var{type} or a subtype + of \var{type}. Both parameters must be non-\NULL. + \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyObject_Length}{PyObject *o} Return the length of object \var{o}. If the object \var{o} provides *************** *** 2366,2370 **** \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} ! Returns true if \var{o} is of type \cdata{PyInt_Type}. \end{cfuncdesc} --- 2372,2384 ---- \begin{cfuncdesc}{int}{PyInt_Check}{PyObject* o} ! Returns true if \var{o} is of type \cdata{PyInt_Type} or a subtype of ! \cdata{PyInt_Type}. ! \versionchanged[Allowed subtypes to be accepted]{2.2} ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyInt_CheckExact}{PyObject* o} ! Returns true if \var{o} is of type \cdata{PyInt_Type}, but not a ! subtype of \cdata{PyInt_Type}. ! \versionadded{2.2} \end{cfuncdesc} *************** *** 2411,2415 **** \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyLongObject}. \end{cfuncdesc} --- 2425,2437 ---- \begin{cfuncdesc}{int}{PyLong_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyLongObject} or a subtype of ! \ctype{PyLongObject}. ! \versionchanged[Allowed subtypes to be accepted]{2.2} ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyLong_CheckExact}{PyObject *p} ! Returns true if its argument is a \ctype{PyLongObject}, but not a ! subtype of \ctype{PyLongObject}. ! \versionadded{2.2} \end{cfuncdesc} *************** *** 2424,2427 **** --- 2446,2459 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyLong_FromLongLong}{long long v} + Returns a new \ctype{PyLongObject} object from a C \ctype{long long}, + or \NULL{} on failure. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromUnsignedLongLong}{unsigned long long v} + Returns a new \ctype{PyLongObject} object from a C \ctype{unsigned + long long}, or \NULL{} on failure. + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyLong_FromDouble}{double v} Returns a new \ctype{PyLongObject} object from the integer part of *************** *** 2429,2432 **** --- 2461,2497 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, + int base} + Return a new \ctype{PyLongObject} based on the string value in + \var{str}, which is interpreted according to the radix in \var{base}. + If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first + character in \var{str} which follows the representation of the + number. If \var{base} is \code{0}, the radix will be determined base + on the leading characters of \var{str}: if \var{str} starts with + \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts + with \code{'0'}, radix 8 will be used; otherwise radix 10 will be + used. If \var{base} is not \code{0}, it must be between \code{2} and + \code{36}, inclusive. Leading spaces are ignored. If there are no + digits, \exception{ValueError} will be raised. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromUnicode}{Py_UNICODE *u, + int length, int base} + Convert a sequence of Unicode digits to a Python long integer value. + The first parameter, \var{u}, points to the first character of the + Unicode string, \var{length} gives the number of characters, and + \var{base} is the radix for the conversion. The radix must be in the + range [2, 36]; if it is out of range, \exception{ValueError} will be + raised. + \versionadded{1.6} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyLong_FromVoidPtr}{void *p} + Create a Python integer or long integer from the pointer \var{p}. The + pointer value can be retrieved from the resulting value using + \cfunction{PyLong_AsVoidPtr()}. + \versionadded{1.5.2} + \end{cfuncdesc} + \begin{cfuncdesc}{long}{PyLong_AsLong}{PyObject *pylong} Returns a C \ctype{long} representation of the contents of *************** *** 2443,2463 **** \end{cfuncdesc} \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} ! Returns a C \ctype{double} representation of the contents of \var{pylong}. \end{cfuncdesc} ! \begin{cfuncdesc}{PyObject*}{PyLong_FromString}{char *str, char **pend, ! int base} ! Return a new \ctype{PyLongObject} based on the string value in ! \var{str}, which is interpreted according to the radix in \var{base}. ! If \var{pend} is non-\NULL, \code{*\var{pend}} will point to the first ! character in \var{str} which follows the representation of the ! number. If \var{base} is \code{0}, the radix will be determined base ! on the leading characters of \var{str}: if \var{str} starts with ! \code{'0x'} or \code{'0X'}, radix 16 will be used; if \var{str} starts ! with \code{'0'}, radix 8 will be used; otherwise radix 10 will be ! used. If \var{base} is not \code{0}, it must be between \code{2} and ! \code{36}, inclusive. Leading spaces are ignored. If there are no ! digits, \exception{ValueError} will be raised. \end{cfuncdesc} --- 2508,2541 ---- \end{cfuncdesc} + \begin{cfuncdesc}{long long}{PyLong_AsLongLong}{PyObject *pylong} + Return a C \ctype{long long} from a Python long integer. If + \var{pylong} cannot be represented as a \ctype{long long}, an + \exception{OverflowError} will be raised. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{unsigned long long}{PyLong_AsUnsignedLongLong}{PyObject + *pylong} + Return a C \ctype{unsigned long long} from a Python long integer. If + \var{pylong} cannot be represented as an \ctype{unsigned long long}, + an \exception{OverflowError} will be raised if the value is positive, + or a \exception{TypeError} will be raised if the value is negative. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{double}{PyLong_AsDouble}{PyObject *pylong} ! Returns a C \ctype{double} representation of the contents of ! \var{pylong}. If \var{pylong} cannot be approximately represented as ! a \ctype{double}, an \exception{OverflowError} exception is raised and ! \code{-1.0} will be returned. \end{cfuncdesc} ! \begin{cfuncdesc}{void*}{PyLong_AsVoidPtr}{PyObject *pylong} ! Convert a Python integer or long integer \var{pylong} to a C ! \ctype{void} pointer. If \var{pylong} cannot be converted, an ! \exception{OverflowError} will be raised. This is only assured to ! produce a usable \ctype{void} pointer for values created with ! \cfunction{PyLong_FromVoidPtr()}. ! \versionadded{1.5.2} \end{cfuncdesc} *************** *** 2478,2482 **** \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyFloatObject}. \end{cfuncdesc} --- 2556,2568 ---- \begin{cfuncdesc}{int}{PyFloat_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyFloatObject} or a subtype ! of \ctype{PyFloatObject}. ! \versionchanged[Allowed subtypes to be accepted]{2.2} ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyFloat_CheckExact}{PyObject *p} ! Returns true if its argument is a \ctype{PyFloatObject}, but not a ! subtype of \ctype{PyFloatObject}. ! \versionadded{2.2} \end{cfuncdesc} *************** *** 2570,2576 **** \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyComplexObject}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} Create a new Python complex number object from a C --- 2656,2670 ---- \begin{cfuncdesc}{int}{PyComplex_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyComplexObject} or a subtype ! of \ctype{PyComplexObject}. ! \versionchanged[Allowed subtypes to be accepted]{2.2} \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyComplex_CheckExact}{PyObject *p} + Returns true if its argument is a \ctype{PyComplexObject}, but not a + subtype of \ctype{PyComplexObject}. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyComplex_FromCComplex}{Py_complex v} Create a new Python complex number object from a C *************** *** 2621,2627 **** \begin{cfuncdesc}{int}{PyString_Check}{PyObject *o} ! Returns true if the object \var{o} is a string object. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyString_FromString}{const char *v} Returns a new string object with the value \var{v} on success, and --- 2715,2729 ---- \begin{cfuncdesc}{int}{PyString_Check}{PyObject *o} ! Returns true if the object \var{o} is a string object or an instance ! of a subtype of the string type. ! \versionchanged[Allowed subtypes to be accepted]{2.2} \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyString_CheckExact}{PyObject *o} + Returns true if the object \var{o} is a string object, but not an + instance of a subtype of the string type. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyString_FromString}{const char *v} Returns a new string object with the value \var{v} on success, and *************** *** 2836,2842 **** \begin{cfuncdesc}{int}{PyUnicode_Check}{PyObject *o} ! Returns true if the object \var{o} is a Unicode object. \end{cfuncdesc} \begin{cfuncdesc}{int}{PyUnicode_GET_SIZE}{PyObject *o} Returns the size of the object. o has to be a --- 2938,2952 ---- \begin{cfuncdesc}{int}{PyUnicode_Check}{PyObject *o} ! Returns true if the object \var{o} is a Unicode object or an instance ! of a Unicode subtype. ! \versionchanged[Allowed subtypes to be accepted]{2.2} \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyUnicode_CheckExact}{PyObject *o} + Returns true if the object \var{o} is a Unicode object, but not an + instance of a subtype. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyUnicode_GET_SIZE}{PyObject *o} Returns the size of the object. o has to be a *************** *** 3624,3628 **** \begin{cfuncdesc}{int}{PyTuple_Check}{PyObject *p} ! Return true if the argument is a tuple object. \end{cfuncdesc} --- 3734,3746 ---- \begin{cfuncdesc}{int}{PyTuple_Check}{PyObject *p} ! Return true if \var{p} is a tuple object or an instance of a subtype ! of the tuple type. ! \versionchanged[Allowed subtypes to be accepted]{2.2} ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyTuple_CheckExact}{PyObject *p} ! Return true if \var{p} is a tuple object, but not an instance of ! a subtype of the tuple type. ! \versionadded{2.2} \end{cfuncdesc} *************** *** 3984,3990 **** \begin{cfuncdesc}{int}{PyFile_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyFileObject}. \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyFile_FromString}{char *filename, char *mode} On success, returns a new file object that is opened on the --- 4102,4116 ---- \begin{cfuncdesc}{int}{PyFile_Check}{PyObject *p} ! Returns true if its argument is a \ctype{PyFileObject} or a subtype of ! \ctype{PyFileObject}. ! \versionchanged[Allowed subtypes to be accepted]{2.2} \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyFile_CheckExact}{PyObject *p} + Returns true if its argument is a \ctype{PyFileObject}, but not a + subtype of \ctype{PyFileObject}. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyFile_FromString}{char *filename, char *mode} On success, returns a new file object that is opened on the *************** *** 4160,4164 **** \begin{cfuncdesc}{int}{PyModule_Check}{PyObject *p} ! Returns true if its argument is a module object. \end{cfuncdesc} --- 4286,4298 ---- \begin{cfuncdesc}{int}{PyModule_Check}{PyObject *p} ! Returns true if \var{p} is a module object, or a subtype of a ! module object. ! \versionchanged[Allowed subtypes to be accepted]{2.2} ! \end{cfuncdesc} ! ! \begin{cfuncdesc}{int}{PyModule_CheckExact}{PyObject *p} ! Returns true if \var{p} is a module object, but not a subtype of ! \cdata{PyModule_Type}. ! \versionadded{2.2} \end{cfuncdesc} Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** refcounts.dat 2001/09/06 18:06:46 1.30 --- refcounts.dat 2001/09/20 19:18:52 1.31 *************** *** 450,453 **** --- 450,459 ---- PyLong_FromLong:long:v:: + PyLong_FromLongLong:PyObject*::+1: + PyLong_FromLongLong:long long:v:: + + PyLong_FromUnsignedLongLong:PyObject*::+1: + PyLong_FromUnsignedLongLong:unsigned long long:v:: + PyLong_FromString:PyObject*::+1: PyLong_FromString:char*:str:: *************** *** 455,460 **** --- 461,474 ---- PyLong_FromString:int:base:: + PyLong_FromUnicode:PyObject*::+1: + PyLong_FromUnicode:Py_UNICODE:u:: + PyLong_FromUnicode:int:length:: + PyLong_FromUnicode:int:base:: + PyLong_FromUnsignedLong:PyObject*::+1: PyLong_FromUnsignedLong:unsignedlong:v:: + + PyLong_FromVoidPtr:PyObject*::+1: + PyLong_FromVoidPtr:void*:p:: PyMapping_Check:int::: From tim_one@users.sourceforge.net Thu Sep 20 20:55:32 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 20 Sep 2001 12:55:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.84,1.85 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13132/python/Doc/lib Modified Files: libfuncs.tex Log Message: Document new file() constructor, with the body of open()'s text, plus a "new in 2.2" blurb at the end. Replace open()'s text by pointing back to file(). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.84 retrieving revision 1.85 diff -C2 -d -r1.84 -r1.85 *** libfuncs.tex 2001/09/06 19:04:29 1.84 --- libfuncs.tex 2001/09/20 19:55:29 1.85 *************** *** 253,256 **** --- 253,299 ---- \end{funcdesc} + \begin{funcdesc}{file}{filename\optional{, mode\optional{, bufsize}}} + Return a new file object (described earlier under Built-in Types). + The first two arguments are the same as for \code{stdio}'s + \cfunction{fopen()}: \var{filename} is the file name to be opened, + \var{mode} indicates how the file is to be opened: \code{'r'} for + reading, \code{'w'} for writing (truncating an existing file), and + \code{'a'} opens it for appending (which on \emph{some} \UNIX{} + systems means that \emph{all} writes append to the end of the file, + regardless of the current seek position). + + Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for + updating (note that \code{'w+'} truncates the file). Append + \code{'b'} to the mode to open the file in binary mode, on systems + that differentiate between binary and text files (else it is + ignored). If the file cannot be opened, \exception{IOError} is + raised. + + If \var{mode} is omitted, it defaults to \code{'r'}. When opening a + binary file, you should append \code{'b'} to the \var{mode} value + for improved portability. (It's useful even on systems which don't + treat binary and text files differently, where it serves as + documentation.) + \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O} + \index{I/O control!buffering} + The optional \var{bufsize} argument specifies the + file's desired buffer size: 0 means unbuffered, 1 means line + buffered, any other positive value means use a buffer of + (approximately) that size. A negative \var{bufsize} means to use + the system default, which is usually line buffered for for tty + devices and fully buffered for other files. If omitted, the system + default is used.\footnote{ + Specifying a buffer size currently has no effect on systems that + don't have \cfunction{setvbuf()}. The interface to specify the + buffer size is not done using a method that calls + \cfunction{setvbuf()}, because that may dump core when called + after any I/O has been performed, and there's no reliable way to + determine whether this is the case.} + + The \function{file()} constructor is new in Python 2.2. The previous + spelling, \function{open()}, is retained for compatibility, and is an + alias for \function{file()}. + \end{funcdesc} + \begin{funcdesc}{filter}{function, list} Construct a list from those elements of \var{list} for which *************** *** 480,519 **** \begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}} ! Return a new file object (described earlier under Built-in Types). ! The first two arguments are the same as for \code{stdio}'s ! \cfunction{fopen()}: \var{filename} is the file name to be opened, ! \var{mode} indicates how the file is to be opened: \code{'r'} for ! reading, \code{'w'} for writing (truncating an existing file), and ! \code{'a'} opens it for appending (which on \emph{some} \UNIX{} ! systems means that \emph{all} writes append to the end of the file, ! regardless of the current seek position). ! ! Modes \code{'r+'}, \code{'w+'} and \code{'a+'} open the file for ! updating (note that \code{'w+'} truncates the file). Append ! \code{'b'} to the mode to open the file in binary mode, on systems ! that differentiate between binary and text files (else it is ! ignored). If the file cannot be opened, \exception{IOError} is ! raised. ! ! If \var{mode} is omitted, it defaults to \code{'r'}. When opening a ! binary file, you should append \code{'b'} to the \var{mode} value ! for improved portability. (It's useful even on systems which don't ! treat binary and text files differently, where it serves as ! documentation.) ! \index{line-buffered I/O}\index{unbuffered I/O}\index{buffer size, I/O} ! \index{I/O control!buffering} ! The optional \var{bufsize} argument specifies the ! file's desired buffer size: 0 means unbuffered, 1 means line ! buffered, any other positive value means use a buffer of ! (approximately) that size. A negative \var{bufsize} means to use ! the system default, which is usually line buffered for for tty ! devices and fully buffered for other files. If omitted, the system ! default is used.\footnote{ ! Specifying a buffer size currently has no effect on systems that ! don't have \cfunction{setvbuf()}. The interface to specify the ! buffer size is not done using a method that calls ! \cfunction{setvbuf()}, because that may dump core when called ! after any I/O has been performed, and there's no reliable way to ! determine whether this is the case.} \end{funcdesc} --- 523,527 ---- \begin{funcdesc}{open}{filename\optional{, mode\optional{, bufsize}}} ! An alias for the \function{file()} function above. \end{funcdesc} *************** *** 539,543 **** Python 2.2. In Python 2.1 and before, if both arguments were of integer types and the second argument was negative, an exception was raised.) ! If the second argument is negative, the third argument must be omitted. If \var{z} is present, \var{x} and \var{y} must be of integer types, and \var{y} must be non-negative. (This restriction was added in --- 547,551 ---- Python 2.2. In Python 2.1 and before, if both arguments were of integer types and the second argument was negative, an exception was raised.) ! If the second argument is negative, the third argument must be omitted. If \var{z} is present, \var{x} and \var{y} must be of integer types, and \var{y} must be non-negative. (This restriction was added in From fdrake@users.sourceforge.net Thu Sep 20 21:43:30 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 20 Sep 2001 13:43:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpyexpat.tex,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24843/lib Modified Files: libpyexpat.tex Log Message: Fill in a few more descriptions for xml.parsers.expat. Index: libpyexpat.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpyexpat.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** libpyexpat.tex 2001/02/15 05:37:51 1.15 --- libpyexpat.tex 2001/09/20 20:43:28 1.16 *************** *** 34,38 **** \begin{excdesc}{ExpatError} ! The exception raised when Expat reports an error. \end{excdesc} --- 34,40 ---- \begin{excdesc}{ExpatError} ! The exception raised when Expat reports an error. See section ! \ref{expaterror-objects}, ``ExpatError Exceptions,'' for more ! information on interpreting Expat errors. \end{excdesc} *************** *** 170,174 **** handlers. \versionchanged[Can be changed at any time to affect the result ! type.]{1.6} \end{memberdesc} --- 172,176 ---- handlers. \versionchanged[Can be changed at any time to affect the result ! type]{1.6} \end{memberdesc} *************** *** 515,527 **** \begin{datadescni}{XML_CQUANT_NONE} \end{datadescni} \begin{datadescni}{XML_CQUANT_OPT} ! The model is option: it can appear once or not at all, as for \code{A?}. \end{datadescni} \begin{datadescni}{XML_CQUANT_PLUS} ! The model must occur one or more times (\code{A+}). \end{datadescni} --- 517,530 ---- \begin{datadescni}{XML_CQUANT_NONE} + No modifier is given, so it can appear exactly once, as for \code{A}. \end{datadescni} \begin{datadescni}{XML_CQUANT_OPT} ! The model is optional: it can appear once or not at all, as for \code{A?}. \end{datadescni} \begin{datadescni}{XML_CQUANT_PLUS} ! The model must occur one or more times (like \code{A+}). \end{datadescni} *************** *** 550,556 **** --- 553,563 ---- \begin{datadescni}{XML_ERROR_BAD_CHAR_REF} + A character reference referred to a character which is illegal in XML + (for example, character \code{0}, or `\code{\&\#0;}'. \end{datadescni} \begin{datadescni}{XML_ERROR_BINARY_ENTITY_REF} + An entity reference referred to an entity which was declared with a + notation, so cannot be parsed. \end{datadescni} *************** *** 563,566 **** --- 570,576 ---- \begin{datadescni}{XML_ERROR_INVALID_TOKEN} + Raised when an input byte could not properly be assigned to a + character; for example, a NUL byte (value \code{0}) in a UTF-8 input + stream. \end{datadescni} *************** *** 570,577 **** \begin{datadescni}{XML_ERROR_MISPLACED_XML_PI} \end{datadescni} \begin{datadescni}{XML_ERROR_NO_ELEMENTS} ! The document contains no elements. \end{datadescni} --- 580,590 ---- \begin{datadescni}{XML_ERROR_MISPLACED_XML_PI} + An XML declaration was found somewhere other than the start of the + input data. \end{datadescni} \begin{datadescni}{XML_ERROR_NO_ELEMENTS} ! The document contains no elements (XML requires all documents to ! contain exactly one top-level element).. \end{datadescni} *************** *** 581,590 **** --- 594,607 ---- \begin{datadescni}{XML_ERROR_PARAM_ENTITY_REF} + A parameter entity reference was found where it was not allowed. \end{datadescni} \begin{datadescni}{XML_ERROR_PARTIAL_CHAR} + \end{datadescni} \begin{datadescni}{XML_ERROR_RECURSIVE_ENTITY_REF} + An entity reference contained another reference to the same entity; + possibly via a different name, and possibly indirectly. \end{datadescni} *************** *** 598,601 **** --- 615,620 ---- \begin{datadescni}{XML_ERROR_UNCLOSED_TOKEN} + Some token (such as a start tag) was not closed before the end of the + stream or the next token was encountered. \end{datadescni} From gvanrossum@users.sourceforge.net Thu Sep 20 21:46:20 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 13:46:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxsubtype.c,2.5,2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv25248/Modules Modified Files: xxsubtype.c Log Message: Add optional docstrings to member descriptors. For backwards compatibility, this required all places where an array of "struct memberlist" structures was declared that is referenced from a type's tp_members slot to change the type of the structure to PyMemberDef; "struct memberlist" is now only used by old code that still calls PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef argument. As examples, I added actual docstrings to the attributes of a few types: file, complex, instance method, super, and xxsubtype.spamlist. Also converted the symtable to new style getattr. Index: xxsubtype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xxsubtype.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** xxsubtype.c 2001/08/16 09:10:42 2.5 --- xxsubtype.c 2001/09/20 20:46:18 2.6 *************** *** 149,154 **** } ! static struct memberlist spamdict_members[] = { ! {"state", T_INT, offsetof(spamdictobject, state), READONLY}, {0} }; --- 149,155 ---- } ! static PyMemberDef spamdict_members[] = { ! {"state", T_INT, offsetof(spamdictobject, state), READONLY, ! "an int variable for demonstration purposes"}, {0} }; From gvanrossum@users.sourceforge.net Thu Sep 20 21:46:20 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 13:46:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,2.3,2.4 object.h,2.90,2.91 structmember.h,2.17,2.18 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv25248/Include Modified Files: descrobject.h object.h structmember.h Log Message: Add optional docstrings to member descriptors. For backwards compatibility, this required all places where an array of "struct memberlist" structures was declared that is referenced from a type's tp_members slot to change the type of the structure to PyMemberDef; "struct memberlist" is now only used by old code that still calls PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef argument. As examples, I added actual docstrings to the attributes of a few types: file, complex, instance method, super, and xxsubtype.spamlist. Also converted the symtable to new style getattr. Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/descrobject.h,v retrieving revision 2.3 retrieving revision 2.4 diff -C2 -d -r2.3 -r2.4 *** descrobject.h 2001/09/06 21:54:11 2.3 --- descrobject.h 2001/09/20 20:46:18 2.4 *************** *** 22,26 **** extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *, ! struct memberlist *); extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *, struct getsetlist *); --- 22,26 ---- extern DL_IMPORT(PyObject *) PyDescr_NewMethod(PyTypeObject *, PyMethodDef *); extern DL_IMPORT(PyObject *) PyDescr_NewMember(PyTypeObject *, ! struct PyMemberDef *); extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *, struct getsetlist *); Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.90 retrieving revision 2.91 diff -C2 -d -r2.90 -r2.91 *** object.h 2001/09/18 20:38:53 2.90 --- object.h 2001/09/20 20:46:18 2.91 *************** *** 275,279 **** /* Attribute descriptor and subclassing stuff */ struct PyMethodDef *tp_methods; ! struct memberlist *tp_members; struct getsetlist *tp_getset; struct _typeobject *tp_base; --- 275,279 ---- /* Attribute descriptor and subclassing stuff */ struct PyMethodDef *tp_methods; ! struct PyMemberDef *tp_members; struct getsetlist *tp_getset; struct _typeobject *tp_base; Index: structmember.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/structmember.h,v retrieving revision 2.17 retrieving revision 2.18 diff -C2 -d -r2.17 -r2.18 *** structmember.h 2001/09/17 19:28:07 2.17 --- structmember.h 2001/09/20 20:46:18 2.18 *************** *** 29,32 **** --- 29,33 ---- struct memberlist { + /* Obsolete version, for binary backwards compatibility */ char *name; int type; *************** *** 35,38 **** --- 36,48 ---- }; + typedef struct PyMemberDef { + /* Current version, use this */ + char *name; + int type; + int offset; + int flags; + char *doc; + } PyMemberDef; + /* Types */ #define T_SHORT 0 *************** *** 67,72 **** --- 77,88 ---- + /* Obsolete API, for binary backwards compatibility */ DL_IMPORT(PyObject *) PyMember_Get(char *, struct memberlist *, char *); DL_IMPORT(int) PyMember_Set(char *, struct memberlist *, char *, PyObject *); + + /* Current API, use this */ + DL_IMPORT(PyObject *) PyMember_GetOne(char *, struct PyMemberDef *); + DL_IMPORT(int) PyMember_SetOne(char *, struct PyMemberDef *, PyObject *); + #ifdef __cplusplus From gvanrossum@users.sourceforge.net Thu Sep 20 21:46:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 13:46:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.148,2.149 complexobject.c,2.46,2.47 descrobject.c,2.11,2.12 fileobject.c,2.128,2.129 frameobject.c,2.56,2.57 funcobject.c,2.43,2.44 moduleobject.c,2.37,2.38 sliceobject.c,2.8,2.9 typeobject.c,2.65,2.66 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv25248/Objects Modified Files: classobject.c complexobject.c descrobject.c fileobject.c frameobject.c funcobject.c moduleobject.c sliceobject.c typeobject.c Log Message: Add optional docstrings to member descriptors. For backwards compatibility, this required all places where an array of "struct memberlist" structures was declared that is referenced from a type's tp_members slot to change the type of the structure to PyMemberDef; "struct memberlist" is now only used by old code that still calls PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef argument. As examples, I added actual docstrings to the attributes of a few types: file, complex, instance method, super, and xxsubtype.spamlist. Also converted the symtable to new style getattr. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.148 retrieving revision 2.149 diff -C2 -d -r2.148 -r2.149 *** classobject.c 2001/09/18 20:23:28 2.148 --- classobject.c 2001/09/20 20:46:18 2.149 *************** *** 2007,2014 **** #define OFF(x) offsetof(PyMethodObject, x) ! static struct memberlist instancemethod_memberlist[] = { ! {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED}, ! {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED}, ! {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED}, {NULL} /* Sentinel */ }; --- 2007,2017 ---- #define OFF(x) offsetof(PyMethodObject, x) ! static PyMemberDef instancemethod_memberlist[] = { ! {"im_class", T_OBJECT, OFF(im_class), READONLY|RESTRICTED, ! "the class associated with a method"}, ! {"im_func", T_OBJECT, OFF(im_func), READONLY|RESTRICTED, ! "the function (or other callable) implementing a method"}, ! {"im_self", T_OBJECT, OFF(im_self), READONLY|RESTRICTED, ! "the instance to which a method is bound; None for unbound methods"}, {NULL} /* Sentinel */ }; Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.46 retrieving revision 2.47 diff -C2 -d -r2.46 -r2.47 *** complexobject.c 2001/09/19 01:13:10 2.46 --- complexobject.c 2001/09/20 20:46:18 2.47 *************** *** 626,632 **** }; ! static struct memberlist complex_members[] = { ! {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0}, ! {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0}, {0}, }; --- 626,634 ---- }; ! static PyMemberDef complex_members[] = { ! {"real", T_DOUBLE, offsetof(PyComplexObject, cval.real), 0, ! "the real part of a complex number"}, ! {"imag", T_DOUBLE, offsetof(PyComplexObject, cval.imag), 0, ! "the imaginary part of a complex number"}, {0}, }; Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.11 retrieving revision 2.12 diff -C2 -d -r2.11 -r2.12 *** descrobject.c 2001/09/06 21:55:04 2.11 --- descrobject.c 2001/09/20 20:46:18 2.12 *************** *** 22,26 **** typedef struct { COMMON; ! struct memberlist *d_member; } PyMemberDescrObject; --- 22,26 ---- typedef struct { COMMON; ! PyMemberDef *d_member; } PyMemberDescrObject; *************** *** 127,132 **** if (descr_check((PyDescrObject *)descr, obj, type, &res)) return res; ! return PyMember_Get((char *)obj, descr->d_member, ! descr->d_member->name); } --- 127,131 ---- if (descr_check((PyDescrObject *)descr, obj, type, &res)) return res; ! return PyMember_GetOne((char *)obj, descr->d_member); } *************** *** 182,187 **** if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; ! return PyMember_Set((char *)obj, descr->d_member, ! descr->d_member->name, value); } --- 181,185 ---- if (descr_setcheck((PyDescrObject *)descr, obj, value, &res)) return res; ! return PyMember_SetOne((char *)obj, descr->d_member, value); } *************** *** 290,294 **** static PyObject * ! member_get_doc(PyMethodDescrObject *descr, void *closure) { if (descr->d_method->ml_doc == NULL) { --- 288,292 ---- static PyObject * ! method_get_doc(PyMethodDescrObject *descr, void *closure) { if (descr->d_method->ml_doc == NULL) { *************** *** 299,303 **** } ! static struct memberlist descr_members[] = { {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, --- 297,301 ---- } ! static PyMemberDef descr_members[] = { {"__objclass__", T_OBJECT, offsetof(PyDescrObject, d_type), READONLY}, {"__name__", T_OBJECT, offsetof(PyDescrObject, d_name), READONLY}, *************** *** 305,308 **** --- 303,321 ---- }; + static struct getsetlist method_getset[] = { + {"__doc__", (getter)method_get_doc}, + {0} + }; + + static PyObject * + member_get_doc(PyMemberDescrObject *descr, void *closure) + { + if (descr->d_member->doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyString_FromString(descr->d_member->doc); + } + static struct getsetlist member_getset[] = { {"__doc__", (getter)member_get_doc}, *************** *** 356,360 **** 0, /* tp_methods */ descr_members, /* tp_members */ ! member_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 369,373 ---- 0, /* tp_methods */ descr_members, /* tp_members */ ! method_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ *************** *** 394,398 **** 0, /* tp_methods */ descr_members, /* tp_members */ ! 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 407,411 ---- 0, /* tp_methods */ descr_members, /* tp_members */ ! member_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ *************** *** 508,512 **** PyObject * ! PyDescr_NewMember(PyTypeObject *type, struct memberlist *member) { PyMemberDescrObject *descr; --- 521,525 ---- PyObject * ! PyDescr_NewMember(PyTypeObject *type, PyMemberDef *member) { PyMemberDescrObject *descr; Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.128 retrieving revision 2.129 diff -C2 -d -r2.128 -r2.129 *** fileobject.c 2001/09/20 07:55:22 2.128 --- fileobject.c 2001/09/20 20:46:19 2.129 *************** *** 1384,1391 **** #define OFF(x) offsetof(PyFileObject, x) ! static struct memberlist file_memberlist[] = { ! {"softspace", T_INT, OFF(f_softspace)}, ! {"mode", T_OBJECT, OFF(f_mode), RO}, ! {"name", T_OBJECT, OFF(f_name), RO}, /* getattr(f, "closed") is implemented without this table */ {NULL} /* Sentinel */ --- 1384,1394 ---- #define OFF(x) offsetof(PyFileObject, x) ! static PyMemberDef file_memberlist[] = { ! {"softspace", T_INT, OFF(f_softspace), 0, ! "flag indicating that a space needs to be printed; used by print"}, ! {"mode", T_OBJECT, OFF(f_mode), RO, ! "file mode ('r', 'w', 'a', possibly with 'b' or '+' added)"}, ! {"name", T_OBJECT, OFF(f_name), RO, ! "file name"}, /* getattr(f, "closed") is implemented without this table */ {NULL} /* Sentinel */ Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.56 retrieving revision 2.57 diff -C2 -d -r2.56 -r2.57 *** frameobject.c 2001/08/30 00:32:51 2.56 --- frameobject.c 2001/09/20 20:46:19 2.57 *************** *** 11,15 **** #define OFF(x) offsetof(PyFrameObject, x) ! static struct memberlist frame_memberlist[] = { {"f_back", T_OBJECT, OFF(f_back), RO}, {"f_code", T_OBJECT, OFF(f_code), RO}, --- 11,15 ---- #define OFF(x) offsetof(PyFrameObject, x) ! static PyMemberDef frame_memberlist[] = { {"f_back", T_OBJECT, OFF(f_back), RO}, {"f_code", T_OBJECT, OFF(f_code), RO}, Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.43 retrieving revision 2.44 diff -C2 -d -r2.43 -r2.44 *** funcobject.c 2001/09/17 23:46:56 2.43 --- funcobject.c 2001/09/20 20:46:19 2.44 *************** *** 130,134 **** #define RR () ! static struct memberlist func_memberlist[] = { {"func_closure", T_OBJECT, OFF(func_closure), RESTRICTED|READONLY}, --- 130,134 ---- #define RR () ! static PyMemberDef func_memberlist[] = { {"func_closure", T_OBJECT, OFF(func_closure), RESTRICTED|READONLY}, Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** moduleobject.c 2001/08/29 23:53:09 2.37 --- moduleobject.c 2001/09/20 20:46:19 2.38 *************** *** 10,14 **** } PyModuleObject; ! struct memberlist module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, {0} --- 10,14 ---- } PyModuleObject; ! PyMemberDef module_members[] = { {"__dict__", T_OBJECT, offsetof(PyModuleObject, md_dict), READONLY}, {0} Index: sliceobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/sliceobject.c,v retrieving revision 2.8 retrieving revision 2.9 diff -C2 -d -r2.8 -r2.9 *** sliceobject.c 2001/08/02 04:15:00 2.8 --- sliceobject.c 2001/09/20 20:46:19 2.9 *************** *** 130,134 **** } ! static struct memberlist slice_members[] = { {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, --- 130,134 ---- } ! static PyMemberDef slice_members[] = { {"start", T_OBJECT, offsetof(PySliceObject, start), READONLY}, {"stop", T_OBJECT, offsetof(PySliceObject, stop), READONLY}, Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.65 retrieving revision 2.66 diff -C2 -d -r2.65 -r2.66 *** typeobject.c 2001/09/18 20:38:53 2.65 --- typeobject.c 2001/09/20 20:46:19 2.66 *************** *** 5,9 **** #include "structmember.h" ! static struct memberlist type_members[] = { {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, --- 5,9 ---- #include "structmember.h" ! static PyMemberDef type_members[] = { {"__basicsize__", T_INT, offsetof(PyTypeObject,tp_basicsize),READONLY}, {"__itemsize__", T_INT, offsetof(PyTypeObject, tp_itemsize), READONLY}, *************** *** 264,268 **** PyBufferProcs as_buffer; PyObject *name, *slots; ! struct memberlist members[1]; } etype; --- 264,268 ---- PyBufferProcs as_buffer; PyObject *name, *slots; ! PyMemberDef members[1]; } etype; *************** *** 673,677 **** PyTypeObject *type, *base, *tmptype, *winner; etype *et; ! struct memberlist *mp; int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak; --- 673,677 ---- PyTypeObject *type, *base, *tmptype, *winner; etype *et; ! PyMemberDef *mp; int i, nbases, nslots, slotoffset, dynamic, add_dict, add_weak; *************** *** 1088,1092 **** "type", /* tp_name */ sizeof(etype), /* tp_basicsize */ ! sizeof(struct memberlist), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ --- 1088,1092 ---- "type", /* tp_name */ sizeof(etype), /* tp_basicsize */ ! sizeof(PyMemberDef), /* tp_itemsize */ (destructor)type_dealloc, /* tp_dealloc */ 0, /* tp_print */ *************** *** 1193,1197 **** } ! static struct memberlist object_members[] = { {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, {0} --- 1193,1197 ---- } ! static PyMemberDef object_members[] = { {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, {0} *************** *** 1264,1268 **** static int ! add_members(PyTypeObject *type, struct memberlist *memb) { PyObject *dict = type->tp_defined; --- 1264,1268 ---- static int ! add_members(PyTypeObject *type, PyMemberDef *memb) { PyObject *dict = type->tp_defined; *************** *** 3222,3228 **** } superobject; ! static struct memberlist super_members[] = { ! {"__type__", T_OBJECT, offsetof(superobject, type), READONLY}, ! {"__obj__", T_OBJECT, offsetof(superobject, obj), READONLY}, {0} }; --- 3222,3230 ---- } superobject; ! static PyMemberDef super_members[] = { ! {"__thisclass__", T_OBJECT, offsetof(superobject, type), READONLY, ! "the class invoking super()"}, ! {"__self__", T_OBJECT, offsetof(superobject, obj), READONLY, ! "the instance invoking super(); may be None"}, {0} }; From gvanrossum@users.sourceforge.net Thu Sep 20 21:46:21 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 13:46:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.275,2.276 compile.c,2.223,2.224 structmember.c,2.20,2.21 symtable.c,2.5,2.6 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv25248/Python Modified Files: ceval.c compile.c structmember.c symtable.c Log Message: Add optional docstrings to member descriptors. For backwards compatibility, this required all places where an array of "struct memberlist" structures was declared that is referenced from a type's tp_members slot to change the type of the structure to PyMemberDef; "struct memberlist" is now only used by old code that still calls PyMember_Get/Set. The code in PyObject_GenericGetAttr/SetAttr now calls the new APIs PyMember_GetOne/SetOne, which take a PyMemberDef argument. As examples, I added actual docstrings to the attributes of a few types: file, complex, instance method, super, and xxsubtype.spamlist. Also converted the symtable to new style getattr. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.275 retrieving revision 2.276 diff -C2 -d -r2.275 -r2.276 *** ceval.c 2001/09/13 16:56:43 2.275 --- ceval.c 2001/09/20 20:46:19 2.276 *************** *** 193,197 **** }; ! static struct memberlist gen_memberlist[] = { {"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO}, {"gi_running", T_INT, offsetof(genobject, gi_running), RO}, --- 193,197 ---- }; ! static PyMemberDef gen_memberlist[] = { {"gi_frame", T_OBJECT, offsetof(genobject, gi_frame), RO}, {"gi_running", T_INT, offsetof(genobject, gi_running), RO}, Index: compile.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/compile.c,v retrieving revision 2.223 retrieving revision 2.224 diff -C2 -d -r2.223 -r2.224 *** compile.c 2001/09/14 20:08:07 2.223 --- compile.c 2001/09/20 20:46:19 2.224 *************** *** 74,78 **** #define OFF(x) offsetof(PyCodeObject, x) ! static struct memberlist code_memberlist[] = { {"co_argcount", T_INT, OFF(co_argcount), READONLY}, {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, --- 74,78 ---- #define OFF(x) offsetof(PyCodeObject, x) ! static PyMemberDef code_memberlist[] = { {"co_argcount", T_INT, OFF(co_argcount), READONLY}, {"co_nlocals", T_INT, OFF(co_nlocals), READONLY}, Index: structmember.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/structmember.c,v retrieving revision 2.20 retrieving revision 2.21 diff -C2 -d -r2.20 -r2.21 *** structmember.c 2001/09/17 19:28:08 2.20 --- structmember.c 2001/09/20 20:46:19 2.21 *************** *** 33,257 **** { struct memberlist *l; ! if (strcmp(name, "__members__") == 0) return listmembers(mlist); for (l = mlist; l->name != NULL; l++) { if (strcmp(l->name, name) == 0) { ! PyObject *v; ! if ((l->flags & READ_RESTRICTED) && ! PyEval_GetRestricted()) { ! PyErr_SetString(PyExc_RuntimeError, ! "restricted attribute"); ! return NULL; ! } ! addr += l->offset; ! switch (l->type) { ! case T_BYTE: ! v = PyInt_FromLong((long) ! (((*(char*)addr & 0xff) ! ^ 0x80) - 0x80)); ! break; ! case T_UBYTE: ! v = PyInt_FromLong((long) *(char*)addr & 0xff); ! break; ! case T_SHORT: ! v = PyInt_FromLong((long) *(short*)addr); ! break; ! case T_USHORT: ! v = PyInt_FromLong((long) ! *(unsigned short*)addr); ! break; ! case T_INT: ! v = PyInt_FromLong((long) *(int*)addr); ! break; ! case T_UINT: ! v = PyInt_FromLong((long) ! *(unsigned int*)addr); ! break; ! case T_LONG: ! v = PyInt_FromLong(*(long*)addr); ! break; ! case T_ULONG: ! v = PyLong_FromDouble((double) ! *(unsigned long*)addr); ! break; ! case T_FLOAT: ! v = PyFloat_FromDouble((double)*(float*)addr); ! break; ! case T_DOUBLE: ! v = PyFloat_FromDouble(*(double*)addr); ! break; ! case T_STRING: ! if (*(char**)addr == NULL) { ! Py_INCREF(Py_None); ! v = Py_None; ! } ! else ! v = PyString_FromString(*(char**)addr); ! break; ! case T_STRING_INPLACE: ! v = PyString_FromString((char*)addr); ! break; ! #ifdef macintosh ! case T_PSTRING: ! if (*(char**)addr == NULL) { ! Py_INCREF(Py_None); ! v = Py_None; ! } ! else ! v = PyString_FromStringAndSize( ! (*(char**)addr)+1, ! **(unsigned char**)addr); ! break; ! case T_PSTRING_INPLACE: ! v = PyString_FromStringAndSize( ! ((char*)addr)+1, ! *(unsigned char*)addr); ! break; ! #endif /* macintosh */ ! case T_CHAR: ! v = PyString_FromStringAndSize((char*)addr, 1); ! break; ! case T_OBJECT: ! v = *(PyObject **)addr; ! if (v == NULL) ! v = Py_None; ! Py_INCREF(v); ! break; ! default: ! PyErr_SetString(PyExc_SystemError, ! "bad memberlist type"); ! v = NULL; ! } ! return v; } } - PyErr_SetString(PyExc_AttributeError, name); return NULL; } int PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v) { struct memberlist *l; ! PyObject *oldv; ! for (l = mlist; l->name != NULL; l++) { if (strcmp(l->name, name) == 0) { ! if ((l->flags & READONLY) || l->type == T_STRING ! #ifdef macintosh ! || l->type == T_PSTRING ! #endif ! ) ! { ! PyErr_SetString(PyExc_TypeError, ! "readonly attribute"); ! return -1; ! } ! if ((l->flags & WRITE_RESTRICTED) && ! PyEval_GetRestricted()) { ! PyErr_SetString(PyExc_RuntimeError, ! "restricted attribute"); ! return -1; ! } ! if (v == NULL && l->type != T_OBJECT) { ! PyErr_SetString(PyExc_TypeError, ! "can't delete numeric/char attribute"); ! return -1; ! } ! addr += l->offset; ! switch (l->type) { ! case T_BYTE: ! case T_UBYTE: ! if (!PyInt_Check(v)) { ! PyErr_BadArgument(); ! return -1; ! } ! *(char*)addr = (char) PyInt_AsLong(v); ! break; ! case T_SHORT: ! case T_USHORT: ! if (!PyInt_Check(v)) { ! PyErr_BadArgument(); ! return -1; ! } ! *(short*)addr = (short) PyInt_AsLong(v); ! break; ! case T_UINT: ! case T_INT: ! if (!PyInt_Check(v)) { ! PyErr_BadArgument(); ! return -1; ! } ! *(int*)addr = (int) PyInt_AsLong(v); ! break; ! case T_LONG: ! if (!PyInt_Check(v)) { ! PyErr_BadArgument(); ! return -1; ! } ! *(long*)addr = PyInt_AsLong(v); ! break; ! case T_ULONG: ! if (PyInt_Check(v)) ! *(long*)addr = PyInt_AsLong(v); ! else if (PyLong_Check(v)) ! *(long*)addr = PyLong_AsLong(v); ! else { ! PyErr_BadArgument(); ! return -1; ! } ! break; ! case T_FLOAT: ! if (PyInt_Check(v)) ! *(float*)addr = ! (float) PyInt_AsLong(v); ! else if (PyFloat_Check(v)) ! *(float*)addr = ! (float) PyFloat_AsDouble(v); ! else { ! PyErr_BadArgument(); ! return -1; ! } ! break; ! case T_DOUBLE: ! if (PyInt_Check(v)) ! *(double*)addr = ! (double) PyInt_AsLong(v); ! else if (PyFloat_Check(v)) ! *(double*)addr = PyFloat_AsDouble(v); ! else { ! PyErr_BadArgument(); ! return -1; ! } ! break; ! case T_OBJECT: ! Py_XINCREF(v); ! oldv = *(PyObject **)addr; ! *(PyObject **)addr = v; ! Py_XDECREF(oldv); ! break; ! case T_CHAR: ! if (PyString_Check(v) && ! PyString_Size(v) == 1) { ! *(char*)addr = ! PyString_AsString(v)[0]; ! } ! else { ! PyErr_BadArgument(); ! return -1; ! } ! break; ! default: ! PyErr_SetString(PyExc_SystemError, ! "bad memberlist type"); ! return -1; ! } ! return 0; } } ! PyErr_SetString(PyExc_AttributeError, name); return -1; } --- 33,268 ---- { struct memberlist *l; ! if (strcmp(name, "__members__") == 0) return listmembers(mlist); for (l = mlist; l->name != NULL; l++) { if (strcmp(l->name, name) == 0) { ! PyMemberDef copy; ! copy.name = l->name; ! copy.type = l->type; ! copy.offset = l->offset; ! copy.flags = l->flags; ! copy.doc = NULL; ! return PyMember_GetOne(addr, ©); } } PyErr_SetString(PyExc_AttributeError, name); return NULL; } + PyObject * + PyMember_GetOne(char *addr, PyMemberDef *l) + { + PyObject *v; + if ((l->flags & READ_RESTRICTED) && + PyEval_GetRestricted()) { + PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); + return NULL; + } + addr += l->offset; + switch (l->type) { + case T_BYTE: + v = PyInt_FromLong( + (long) (((*(char*)addr & 0xff) ^ 0x80) - 0x80)); + break; + case T_UBYTE: + v = PyInt_FromLong((long) *(char*)addr & 0xff); + break; + case T_SHORT: + v = PyInt_FromLong((long) *(short*)addr); + break; + case T_USHORT: + v = PyInt_FromLong((long) *(unsigned short*)addr); + break; + case T_INT: + v = PyInt_FromLong((long) *(int*)addr); + break; + case T_UINT: + v = PyInt_FromLong((long) *(unsigned int*)addr); + break; + case T_LONG: + v = PyInt_FromLong(*(long*)addr); + break; + case T_ULONG: + v = PyLong_FromDouble((double) *(unsigned long*)addr); + break; + case T_FLOAT: + v = PyFloat_FromDouble((double)*(float*)addr); + break; + case T_DOUBLE: + v = PyFloat_FromDouble(*(double*)addr); + break; + case T_STRING: + if (*(char**)addr == NULL) { + Py_INCREF(Py_None); + v = Py_None; + } + else + v = PyString_FromString(*(char**)addr); + break; + case T_STRING_INPLACE: + v = PyString_FromString((char*)addr); + break; + #ifdef macintosh + case T_PSTRING: + if (*(char**)addr == NULL) { + Py_INCREF(Py_None); + v = Py_None; + } + else + v = PyString_FromStringAndSize( + (*(char**)addr)+1, + **(unsigned char**)addr); + break; + case T_PSTRING_INPLACE: + v = PyString_FromStringAndSize( + ((char*)addr)+1, + *(unsigned char*)addr); + break; + #endif /* macintosh */ + case T_CHAR: + v = PyString_FromStringAndSize((char*)addr, 1); + break; + case T_OBJECT: + v = *(PyObject **)addr; + if (v == NULL) + v = Py_None; + Py_INCREF(v); + break; + default: + PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); + v = NULL; + } + return v; + } + int PyMember_Set(char *addr, struct memberlist *mlist, char *name, PyObject *v) { struct memberlist *l; ! for (l = mlist; l->name != NULL; l++) { if (strcmp(l->name, name) == 0) { ! PyMemberDef copy; ! copy.name = l->name; ! copy.type = l->type; ! copy.offset = l->offset; ! copy.flags = l->flags; ! copy.doc = NULL; ! return PyMember_SetOne(addr, ©, v); } } ! PyErr_SetString(PyExc_AttributeError, name); return -1; + } + + int + PyMember_SetOne(char *addr, PyMemberDef *l, PyObject *v) + { + PyObject *oldv; + + if ((l->flags & READONLY) || l->type == T_STRING + #ifdef macintosh + || l->type == T_PSTRING + #endif + ) + { + PyErr_SetString(PyExc_TypeError, "readonly attribute"); + return -1; + } + if ((l->flags & WRITE_RESTRICTED) && PyEval_GetRestricted()) { + PyErr_SetString(PyExc_RuntimeError, "restricted attribute"); + return -1; + } + if (v == NULL && l->type != T_OBJECT) { + PyErr_SetString(PyExc_TypeError, + "can't delete numeric/char attribute"); + return -1; + } + addr += l->offset; + switch (l->type) { + case T_BYTE: + case T_UBYTE: + if (!PyInt_Check(v)) { + PyErr_BadArgument(); + return -1; + } + *(char*)addr = (char) PyInt_AsLong(v); + break; + case T_SHORT: + case T_USHORT: + if (!PyInt_Check(v)) { + PyErr_BadArgument(); + return -1; + } + *(short*)addr = (short) PyInt_AsLong(v); + break; + case T_UINT: + case T_INT: + if (!PyInt_Check(v)) { + PyErr_BadArgument(); + return -1; + } + *(int*)addr = (int) PyInt_AsLong(v); + break; + case T_LONG: + if (!PyInt_Check(v)) { + PyErr_BadArgument(); + return -1; + } + *(long*)addr = PyInt_AsLong(v); + break; + case T_ULONG: + if (PyInt_Check(v)) + *(long*)addr = PyInt_AsLong(v); + else if (PyLong_Check(v)) + *(long*)addr = PyLong_AsLong(v); + else { + PyErr_BadArgument(); + return -1; + } + break; + case T_FLOAT: + if (PyInt_Check(v)) + *(float*)addr = + (float) PyInt_AsLong(v); + else if (PyFloat_Check(v)) + *(float*)addr = + (float) PyFloat_AsDouble(v); + else { + PyErr_BadArgument(); + return -1; + } + break; + case T_DOUBLE: + if (PyInt_Check(v)) + *(double*)addr = (double) PyInt_AsLong(v); + else if (PyFloat_Check(v)) + *(double*)addr = PyFloat_AsDouble(v); + else { + PyErr_BadArgument(); + return -1; + } + break; + case T_OBJECT: + Py_XINCREF(v); + oldv = *(PyObject **)addr; + *(PyObject **)addr = v; + Py_XDECREF(oldv); + break; + case T_CHAR: + if (PyString_Check(v) && PyString_Size(v) == 1) { + *(char*)addr = PyString_AsString(v)[0]; + } + else { + PyErr_BadArgument(); + return -1; + } + break; + default: + PyErr_SetString(PyExc_SystemError, "bad memberdescr type"); + return -1; + } + return 0; } Index: symtable.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/symtable.c,v retrieving revision 2.5 retrieving revision 2.6 diff -C2 -d -r2.5 -r2.6 *** symtable.c 2001/06/18 22:08:13 2.5 --- symtable.c 2001/09/20 20:46:19 2.6 *************** *** 107,111 **** #define OFF(x) offsetof(PySymtableEntryObject, x) ! static struct memberlist ste_memberlist[] = { {"id", T_OBJECT, OFF(ste_id), READONLY}, {"name", T_OBJECT, OFF(ste_name), READONLY}, --- 107,111 ---- #define OFF(x) offsetof(PySymtableEntryObject, x) ! static PyMemberDef ste_memberlist[] = { {"id", T_OBJECT, OFF(ste_id), READONLY}, {"name", T_OBJECT, OFF(ste_name), READONLY}, *************** *** 120,129 **** }; - static PyObject * - ste_getattr(PySymtableEntryObject *ste, char *name) - { - return PyMember_Get((char *)ste, ste_memberlist, name); - } - PyTypeObject PySymtableEntry_Type = { PyObject_HEAD_INIT(&PyType_Type) --- 120,123 ---- *************** *** 134,138 **** (destructor)ste_dealloc, /* tp_dealloc */ 0, /* tp_print */ ! (getattrfunc)ste_getattr, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ --- 128,132 ---- (destructor)ste_dealloc, /* tp_dealloc */ 0, /* tp_print */ ! 0, /* tp_getattr */ 0, /* tp_setattr */ 0, /* tp_compare */ *************** *** 144,151 **** 0, /* tp_call */ 0, /* tp_str */ ! 0, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ }; --- 138,162 ---- 0, /* tp_call */ 0, /* tp_str */ ! PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ Py_TPFLAGS_DEFAULT, /* tp_flags */ 0, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + ste_memberlist, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + 0, /* tp_new */ }; From fdrake@users.sourceforge.net Thu Sep 20 22:33:45 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 20 Sep 2001 14:33:45 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_binhex.py,1.11,1.12 test_binop.py,1.5,1.6 test_call.py,1.1,1.2 test_codecs.py,1.1,1.2 test_codeop.py,1.2,1.3 test_commands.py,1.1,1.2 test_copy_reg.py,1.2,1.3 test_dircache.py,1.3,1.4 test_dospath.py,1.4,1.5 test_fnmatch.py,1.2,1.3 test_fpformat.py,1.3,1.4 test_glob.py,1.2,1.3 test_grp.py,1.8,1.9 test_hash.py,1.4,1.5 test_iter.py,1.19,1.20 test_mailbox.py,1.6,1.7 test_mhlib.py,1.4,1.5 test_mimetypes.py,1.1,1.2 test_operator.py,1.7,1.8 test_os.py,1.5,1.6 test_parser.py,1.9,1.10 test_pkgimport.py,1.3,1.4 test_pprint.py,1.5,1.6 test_pyclbr.py,1.3,1.4 test_quopri.py,1.4,1.5 test_repr.py,1.6,1.7 test_rfc822.py,1.12,1.13 test_sha.py,1.2,1.3 test_strop.py,1.14,1.15 test_time.py,1.7,1.8 test_traceback.py,1.3,1.4 test_unary.py,1.3,1.4 test_weakref.py,1.11,1.12 test_xmllib.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv3080 Modified Files: test_binhex.py test_binop.py test_call.py test_codecs.py test_codeop.py test_commands.py test_copy_reg.py test_dircache.py test_dospath.py test_fnmatch.py test_fpformat.py test_glob.py test_grp.py test_hash.py test_iter.py test_mailbox.py test_mhlib.py test_mimetypes.py test_operator.py test_os.py test_parser.py test_pkgimport.py test_pprint.py test_pyclbr.py test_quopri.py test_repr.py test_rfc822.py test_sha.py test_strop.py test_time.py test_traceback.py test_unary.py test_weakref.py test_xmllib.py Log Message: Change the PyUnit-based tests to use the test_main() approach. This allows using the tests with unittest.py as a script. The tests will still run when run as a script themselves. Index: test_binhex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binhex.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_binhex.py 2001/05/22 21:01:14 1.11 --- test_binhex.py 2001/09/20 21:33:42 1.12 *************** *** 43,45 **** ! test_support.run_unittest(BinHexTestCase) --- 43,50 ---- ! def test_main(): ! test_support.run_unittest(BinHexTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_binop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_binop.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_binop.py 2001/09/06 21:56:42 1.5 --- test_binop.py 2001/09/20 21:33:42 1.6 *************** *** 321,323 **** """ ! test_support.run_unittest(RatTestCase) --- 321,328 ---- """ ! def test_main(): ! test_support.run_unittest(RatTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_call.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_call.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_call.py 2001/05/29 16:26:16 1.1 --- test_call.py 2001/09/20 21:33:42 1.2 *************** *** 123,125 **** self.assertRaises(TypeError, {}.update, x=2, y=2) ! run_unittest(CFunctionCalls) --- 123,131 ---- self.assertRaises(TypeError, {}.update, x=2, y=2) ! ! def test_main(): ! run_unittest(CFunctionCalls) ! ! ! if __name__ == "__main__": ! test_main() Index: test_codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codecs.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_codecs.py 2001/06/19 20:09:28 1.1 --- test_codecs.py 2001/09/20 21:33:42 1.2 *************** *** 23,25 **** self.assertEquals(f.read(), u"spamspam") ! test_support.run_unittest(UTF16Test) --- 23,31 ---- self.assertEquals(f.read(), u"spamspam") ! ! def test_main(): ! test_support.run_unittest(UTF16Test) ! ! ! if __name__ == "__main__": ! test_main() Index: test_codeop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_codeop.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_codeop.py 2001/08/09 21:40:30 1.2 --- test_codeop.py 2001/09/20 21:33:42 1.3 *************** *** 88,90 **** compile("a = 1\n", "def", 'single').co_filename) ! run_unittest(CodeopTests) --- 88,96 ---- compile("a = 1\n", "def", 'single').co_filename) ! ! def test_main(): ! run_unittest(CodeopTests) ! ! ! if __name__ == "__main__": ! test_main() Index: test_commands.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_commands.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_commands.py 2001/07/23 04:08:01 1.1 --- test_commands.py 2001/09/20 21:33:42 1.2 *************** *** 43,45 **** self.assert_(re.match(pat, getstatus("/bin/ls"), re.VERBOSE)) ! run_unittest(CommandTests) --- 43,51 ---- self.assert_(re.match(pat, getstatus("/bin/ls"), re.VERBOSE)) ! ! def test_main(): ! run_unittest(CommandTests) ! ! ! if __name__ == "__main__": ! test_main() Index: test_copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_copy_reg.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_copy_reg.py 2001/05/22 20:38:44 1.2 --- test_copy_reg.py 2001/09/20 21:33:42 1.3 *************** *** 23,25 **** ! test_support.run_unittest(CopyRegTestCase) --- 23,30 ---- ! def test_main(): ! test_support.run_unittest(CopyRegTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_dircache.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dircache.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_dircache.py 2001/07/21 02:22:14 1.3 --- test_dircache.py 2001/09/20 21:33:42 1.4 *************** *** 66,68 **** self.assertEquals(lst, ['A/', 'test2', 'test_nonexistent']) ! run_unittest(DircacheTests) --- 66,74 ---- self.assertEquals(lst, ['A/', 'test2', 'test_nonexistent']) ! ! def test_main(): ! run_unittest(DircacheTests) ! ! ! if __name__ == "__main__": ! test_main() Index: test_dospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_dospath.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_dospath.py 2001/05/22 20:20:49 1.4 --- test_dospath.py 2001/09/20 21:33:42 1.5 *************** *** 54,56 **** ! test_support.run_unittest(DOSPathTestCase) --- 54,61 ---- ! def test_main(): ! test_support.run_unittest(DOSPathTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_fnmatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fnmatch.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_fnmatch.py 2001/05/22 20:25:05 1.2 --- test_fnmatch.py 2001/09/20 21:33:42 1.3 *************** *** 39,41 **** ! test_support.run_unittest(FnmatchTestCase) --- 39,46 ---- ! def test_main(): ! test_support.run_unittest(FnmatchTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_fpformat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_fpformat.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_fpformat.py 2001/07/23 16:30:21 1.3 --- test_fpformat.py 2001/09/20 21:33:42 1.4 *************** *** 67,69 **** self.fail("No exception on non-numeric sci") ! run_unittest(FpformatTest) --- 67,75 ---- self.fail("No exception on non-numeric sci") ! ! def test_main(): ! run_unittest(FpformatTest) ! ! ! if __name__ == "__main__": ! test_main() Index: test_glob.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_glob.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_glob.py 2001/08/09 21:40:30 1.2 --- test_glob.py 2001/09/20 21:33:42 1.3 *************** *** 107,109 **** os.path.join('aab', 'F')])) ! run_unittest(GlobTests) --- 107,115 ---- os.path.join('aab', 'F')])) ! ! def test_main(): ! run_unittest(GlobTests) ! ! ! if __name__ == "__main__": ! test_main() Index: test_grp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grp.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_grp.py 2001/05/18 21:38:52 1.8 --- test_grp.py 2001/09/20 21:33:42 1.9 *************** *** 20,22 **** ! test_support.run_unittest(GroupDatabaseTestCase) --- 20,27 ---- ! def test_main(): ! test_support.run_unittest(GroupDatabaseTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_hash.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_hash.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_hash.py 2001/05/18 21:50:02 1.4 --- test_hash.py 2001/09/20 21:33:42 1.5 *************** *** 29,31 **** ! test_support.run_unittest(HashEqualityTestCase) --- 29,36 ---- ! def test_main(): ! test_support.run_unittest(HashEqualityTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_iter.py 2001/09/08 04:00:12 1.19 --- test_iter.py 2001/09/20 21:33:42 1.20 *************** *** 695,697 **** self.assertEqual((a, b, c), (0, 1, 42)) ! run_unittest(TestCase) --- 695,703 ---- self.assertEqual((a, b, c), (0, 1, 42)) ! ! def test_main(): ! run_unittest(TestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_mailbox.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mailbox.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_mailbox.py 2001/06/19 20:20:05 1.6 --- test_mailbox.py 2001/09/20 21:33:42 1.7 *************** *** 97,99 **** ! test_support.run_unittest(MaildirTestCase) --- 97,104 ---- ! def test_main(): ! test_support.run_unittest(MaildirTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_mhlib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mhlib.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_mhlib.py 2001/08/11 23:22:43 1.4 --- test_mhlib.py 2001/09/20 21:33:42 1.5 *************** *** 332,334 **** del msg ! run_unittest(MhlibTests) --- 332,340 ---- del msg ! ! def test_main(): ! run_unittest(MhlibTests) ! ! ! if __name__ == "__main__": ! test_main() Index: test_mimetypes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mimetypes.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_mimetypes.py 2001/08/16 18:36:59 1.1 --- test_mimetypes.py 2001/09/20 21:33:42 1.2 *************** *** 40,42 **** ! test_support.run_unittest(MimeTypesTestCase) --- 40,47 ---- ! def test_main(): ! test_support.run_unittest(MimeTypesTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_operator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_operator.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_operator.py 2001/09/04 19:14:14 1.7 --- test_operator.py 2001/09/20 21:33:42 1.8 *************** *** 211,213 **** ! test_support.run_unittest(OperatorTestCase) --- 211,218 ---- ! def test_main(): ! test_support.run_unittest(OperatorTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_os.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_os.py 2001/08/22 19:24:42 1.5 --- test_os.py 2001/09/20 21:33:42 1.6 *************** *** 63,66 **** ! run_unittest(TemporaryFileTests) --- 63,70 ---- + def test_main(): + run_unittest(TemporaryFileTests) ! ! if __name__ == "__main__": ! test_main() Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** test_parser.py 2001/07/17 19:33:25 1.9 --- test_parser.py 2001/09/20 21:33:42 1.10 *************** *** 354,357 **** ! test_support.run_unittest(RoundtripLegalSyntaxTestCase) ! test_support.run_unittest(IllegalSyntaxTestCase) --- 354,365 ---- ! def test_main(): ! loader = unittest.TestLoader() ! suite = unittest.TestSuite() ! suite.addTest(loader.loadTestsFromTestCase(RoundtripLegalSyntaxTestCase)) ! suite.addTest(loader.loadTestsFromTestCase(IllegalSyntaxTestCase)) ! test_support.run_suite(suite) ! ! ! if __name__ == "__main__": ! test_main() Index: test_pkgimport.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pkgimport.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_pkgimport.py 2001/08/09 21:40:30 1.3 --- test_pkgimport.py 2001/09/20 21:33:42 1.4 *************** *** 76,78 **** self.assertEqual(getattr(module, var), 1) ! run_unittest(TestImport) --- 76,84 ---- self.assertEqual(getattr(module, var), 1) ! ! def test_main(): ! run_unittest(TestImport) ! ! ! if __name__ == "__main__": ! test_main() Index: test_pprint.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pprint.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_pprint.py 2001/08/17 18:39:24 1.5 --- test_pprint.py 2001/09/20 21:33:42 1.6 *************** *** 77,79 **** (native, got, function)) ! test_support.run_unittest(QueryTestCase) --- 77,85 ---- (native, got, function)) ! ! def test_main(): ! test_support.run_unittest(QueryTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_pyclbr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_pyclbr.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_pyclbr.py 2001/09/04 01:20:04 1.3 --- test_pyclbr.py 2001/09/20 21:33:42 1.4 *************** *** 154,156 **** # cm('pdb', pdb) ! run_unittest(PyclbrTest) --- 154,162 ---- # cm('pdb', pdb) ! ! def test_main(): ! run_unittest(PyclbrTest) ! ! ! if __name__ == "__main__": ! test_main() Index: test_quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_quopri.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_quopri.py 2001/08/03 20:40:18 1.4 --- test_quopri.py 2001/09/20 21:33:42 1.5 *************** *** 137,139 **** ! test_support.run_unittest(QuopriTestCase) --- 137,144 ---- ! def test_main(): ! test_support.run_unittest(QuopriTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_repr.py 2001/09/14 23:01:49 1.6 --- test_repr.py 2001/09/20 21:33:42 1.7 *************** *** 266,270 **** ! run_unittest(ReprTests) ! if os.name != 'mac': ! run_unittest(LongReprTest) --- 266,275 ---- ! def test_main(): ! run_unittest(ReprTests) ! if os.name != 'mac': ! run_unittest(LongReprTest) ! ! ! if __name__ == "__main__": ! test_main() Index: test_rfc822.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_rfc822.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** test_rfc822.py 2001/07/16 20:44:16 1.12 --- test_rfc822.py 2001/09/20 21:33:42 1.13 *************** *** 178,180 **** [('User J. Person', 'person@dom.ain')]) ! test_support.run_unittest(MessageTestCase) --- 178,186 ---- [('User J. Person', 'person@dom.ain')]) ! ! def test_main(): ! test_support.run_unittest(MessageTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_sha.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sha.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_sha.py 2001/05/22 21:43:17 1.2 --- test_sha.py 2001/09/20 21:33:42 1.3 *************** *** 28,30 **** ! test_support.run_unittest(SHATestCase) --- 28,35 ---- ! def test_main(): ! test_support.run_unittest(SHATestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_strop.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_strop.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_strop.py 2001/05/22 16:44:33 1.14 --- test_strop.py 2001/09/20 21:33:42 1.15 *************** *** 126,128 **** ! test_support.run_unittest(StropFunctionTestCase) --- 126,133 ---- ! def test_main(): ! test_support.run_unittest(StropFunctionTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_time.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_time.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_time.py 2001/05/22 17:02:02 1.7 --- test_time.py 2001/09/20 21:33:42 1.8 *************** *** 49,51 **** ! test_support.run_unittest(TimeTestCase) --- 49,56 ---- ! def test_main(): ! test_support.run_unittest(TimeTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_traceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_traceback.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_traceback.py 2001/04/18 01:19:27 1.3 --- test_traceback.py 2001/09/20 21:33:42 1.4 *************** *** 38,40 **** self.assert_(err[1].strip() == "[x for x in x] = x") ! run_unittest(TracebackCases) --- 38,46 ---- self.assert_(err[1].strip() == "[x for x in x] = x") ! ! def test_main(): ! run_unittest(TracebackCases) ! ! ! if __name__ == "__main__": ! test_main() Index: test_unary.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unary.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_unary.py 2001/08/30 19:15:20 1.3 --- test_unary.py 2001/09/20 21:33:42 1.4 *************** *** 50,52 **** self.assertRaises(TypeError, eval, "~2.0") ! run_unittest(UnaryOpTestCase) --- 50,58 ---- self.assertRaises(TypeError, eval, "~2.0") ! ! def test_main(): ! run_unittest(UnaryOpTestCase) ! ! ! if __name__ == "__main__": ! test_main() Index: test_weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_weakref.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** test_weakref.py 2001/09/06 14:52:39 1.11 --- test_weakref.py 2001/09/20 21:33:42 1.12 *************** *** 3,7 **** import weakref ! from test_support import run_unittest --- 3,7 ---- import weakref ! import test_support *************** *** 435,438 **** ! run_unittest(ReferencesTestCase) ! run_unittest(MappingTestCase) --- 435,446 ---- ! def test_main(): ! loader = unittest.TestLoader() ! suite = unittest.TestSuite() ! suite.addTest(loader.loadTestsFromTestCase(ReferencesTestCase)) ! suite.addTest(loader.loadTestsFromTestCase(MappingTestCase)) ! test_support.run_suite(suite) ! ! ! if __name__ == "__main__": ! test_main() Index: test_xmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_xmllib.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_xmllib.py 2001/05/22 20:22:06 1.5 --- test_xmllib.py 2001/09/20 21:33:42 1.6 *************** *** 28,30 **** ! test_support.run_unittest(XMLParserTestCase) --- 28,35 ---- ! def test_main(): ! test_support.run_unittest(XMLParserTestCase) ! ! ! if __name__ == "__main__": ! test_main() From gvanrossum@users.sourceforge.net Thu Sep 20 22:39:09 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 14:39:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv4166 Modified Files: test_descr.py Log Message: Change testdescr.py to use the test_main() approach. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** test_descr.py 2001/09/19 01:25:16 1.65 --- test_descr.py 2001/09/20 21:39:07 1.66 *************** *** 1953,1957 **** ! def all(): lists() dicts() --- 1953,1957 ---- ! def test_main(): lists() dicts() *************** *** 1993,1998 **** rich_comparisons() coercions() ! ! all() ! if verbose: print "All OK" --- 1993,1998 ---- rich_comparisons() coercions() ! if verbose: print "All OK" ! if __name__ == "__main__": ! test_main() From gvanrossum@users.sourceforge.net Thu Sep 20 22:45:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 14:45:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules xxsubtype.c,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv5414/Modules Modified Files: xxsubtype.c Log Message: Add optional docstrings to getset descriptors. Fortunately, there's no backwards compatibility to worry about, so I just pushed the 'closure' struct member to the back -- it's never used in the current code base (I may eliminate it, but that's more work because the getter and setter signatures would have to change.) As examples, I added actual docstrings to the getset attributes of a few types: file.closed, xxsubtype.spamdict.state. Index: xxsubtype.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xxsubtype.c,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** xxsubtype.c 2001/09/20 20:46:18 2.6 --- xxsubtype.c 2001/09/20 21:45:26 2.7 *************** *** 56,61 **** } ! static struct getsetlist spamlist_getsets[] = { ! {"state", (getter)spamlist_state_get, NULL, NULL}, {0} }; --- 56,62 ---- } ! static PyGetSetDef spamlist_getsets[] = { ! {"state", (getter)spamlist_state_get, NULL, ! "an int variable for demonstration purposes"}, {0} }; From gvanrossum@users.sourceforge.net Thu Sep 20 22:45:28 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 14:45:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include descrobject.h,2.4,2.5 object.h,2.91,2.92 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv5414/Include Modified Files: descrobject.h object.h Log Message: Add optional docstrings to getset descriptors. Fortunately, there's no backwards compatibility to worry about, so I just pushed the 'closure' struct member to the back -- it's never used in the current code base (I may eliminate it, but that's more work because the getter and setter signatures would have to change.) As examples, I added actual docstrings to the getset attributes of a few types: file.closed, xxsubtype.spamdict.state. Index: descrobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/descrobject.h,v retrieving revision 2.4 retrieving revision 2.5 diff -C2 -d -r2.4 -r2.5 *** descrobject.h 2001/09/20 20:46:18 2.4 --- descrobject.h 2001/09/20 21:45:26 2.5 *************** *** 1,13 **** ! /* XXX getter, setter, getsetlist and wrapperbase need 'Py'-prefixed names */ typedef PyObject *(*getter)(PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *); ! struct getsetlist { char *name; getter get; setter set; void *closure; ! }; typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, --- 1,14 ---- ! /* Descriptors */ typedef PyObject *(*getter)(PyObject *, void *); typedef int (*setter)(PyObject *, PyObject *, void *); ! typedef struct PyGetSetDef { char *name; getter get; setter set; + char *doc; void *closure; ! } PyGetSetDef; typedef PyObject *(*wrapperfunc)(PyObject *self, PyObject *args, *************** *** 24,28 **** struct PyMemberDef *); extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *, ! struct getsetlist *); extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); --- 25,29 ---- struct PyMemberDef *); extern DL_IMPORT(PyObject *) PyDescr_NewGetSet(PyTypeObject *, ! struct PyGetSetDef *); extern DL_IMPORT(PyObject *) PyDescr_NewWrapper(PyTypeObject *, struct wrapperbase *, void *); Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.91 retrieving revision 2.92 diff -C2 -d -r2.91 -r2.92 *** object.h 2001/09/20 20:46:18 2.91 --- object.h 2001/09/20 21:45:26 2.92 *************** *** 276,280 **** struct PyMethodDef *tp_methods; struct PyMemberDef *tp_members; ! struct getsetlist *tp_getset; struct _typeobject *tp_base; PyObject *tp_dict; --- 276,280 ---- struct PyMethodDef *tp_methods; struct PyMemberDef *tp_members; ! struct PyGetSetDef *tp_getset; struct _typeobject *tp_base; PyObject *tp_dict; From gvanrossum@users.sourceforge.net Thu Sep 20 22:45:29 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 14:45:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.149,2.150 descrobject.c,2.12,2.13 fileobject.c,2.129,2.130 frameobject.c,2.57,2.58 funcobject.c,2.44,2.45 methodobject.c,2.39,2.40 typeobject.c,2.66,2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv5414/Objects Modified Files: classobject.c descrobject.c fileobject.c frameobject.c funcobject.c methodobject.c typeobject.c Log Message: Add optional docstrings to getset descriptors. Fortunately, there's no backwards compatibility to worry about, so I just pushed the 'closure' struct member to the back -- it's never used in the current code base (I may eliminate it, but that's more work because the getter and setter signatures would have to change.) As examples, I added actual docstrings to the getset attributes of a few types: file.closed, xxsubtype.spamdict.state. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.149 retrieving revision 2.150 diff -C2 -d -r2.149 -r2.150 *** classobject.c 2001/09/20 20:46:18 2.149 --- classobject.c 2001/09/20 21:45:26 2.150 *************** *** 2037,2044 **** } ! static struct getsetlist instancemethod_getsetlist[] = { ! {"__dict__", (getter)im_get_dict}, ! {"__doc__", (getter)im_get_doc}, ! {"__name__", (getter)im_get_name}, {NULL} /* Sentinel */ }; --- 2037,2044 ---- } ! static PyGetSetDef instancemethod_getsetlist[] = { ! {"__dict__", (getter)im_get_dict, NULL, "same as im_func.__dict__"}, ! {"__doc__", (getter)im_get_doc, NULL, "same as im_func.__doc__"}, ! {"__name__", (getter)im_get_name, NULL, "same as im_func.__name__"}, {NULL} /* Sentinel */ }; Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.12 retrieving revision 2.13 diff -C2 -d -r2.12 -r2.13 *** descrobject.c 2001/09/20 20:46:18 2.12 --- descrobject.c 2001/09/20 21:45:26 2.13 *************** *** 27,31 **** typedef struct { COMMON; ! struct getsetlist *d_getset; } PyGetSetDescrObject; --- 27,31 ---- typedef struct { COMMON; ! PyGetSetDef *d_getset; } PyGetSetDescrObject; *************** *** 303,307 **** }; ! static struct getsetlist method_getset[] = { {"__doc__", (getter)method_get_doc}, {0} --- 303,307 ---- }; ! static PyGetSetDef method_getset[] = { {"__doc__", (getter)method_get_doc}, {0} *************** *** 318,322 **** } ! static struct getsetlist member_getset[] = { {"__doc__", (getter)member_get_doc}, {0} --- 318,322 ---- } ! static PyGetSetDef member_getset[] = { {"__doc__", (getter)member_get_doc}, {0} *************** *** 324,327 **** --- 324,342 ---- static PyObject * + getset_get_doc(PyGetSetDescrObject *descr, void *closure) + { + if (descr->d_getset->doc == NULL) { + Py_INCREF(Py_None); + return Py_None; + } + return PyString_FromString(descr->d_getset->doc); + } + + static PyGetSetDef getset_getset[] = { + {"__doc__", (getter)getset_get_doc}, + {0} + }; + + static PyObject * wrapper_get_doc(PyWrapperDescrObject *descr, void *closure) { *************** *** 333,337 **** } ! static struct getsetlist wrapper_getset[] = { {"__doc__", (getter)wrapper_get_doc}, {0} --- 348,352 ---- } ! static PyGetSetDef wrapper_getset[] = { {"__doc__", (getter)wrapper_get_doc}, {0} *************** *** 445,449 **** 0, /* tp_methods */ descr_members, /* tp_members */ ! 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 460,464 ---- 0, /* tp_methods */ descr_members, /* tp_members */ ! getset_getset, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ *************** *** 533,537 **** PyObject * ! PyDescr_NewGetSet(PyTypeObject *type, struct getsetlist *getset) { PyGetSetDescrObject *descr; --- 548,552 ---- PyObject * ! PyDescr_NewGetSet(PyTypeObject *type, PyGetSetDef *getset) { PyGetSetDescrObject *descr; *************** *** 779,783 **** } ! static struct getsetlist wrapper_getsets[] = { {"__name__", (getter)wrapper_name}, {"__doc__", (getter)wrapper_doc}, --- 794,798 ---- } ! static PyGetSetDef wrapper_getsets[] = { {"__name__", (getter)wrapper_name}, {"__doc__", (getter)wrapper_doc}, Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.129 retrieving revision 2.130 diff -C2 -d -r2.129 -r2.130 *** fileobject.c 2001/09/20 20:46:19 2.129 --- fileobject.c 2001/09/20 21:45:26 2.130 *************** *** 1401,1406 **** } ! static struct getsetlist file_getsetlist[] = { ! {"closed", (getter)get_closed, NULL, NULL}, {0}, }; --- 1401,1406 ---- } ! static PyGetSetDef file_getsetlist[] = { ! {"closed", (getter)get_closed, NULL, "flag set if the file is closed"}, {0}, }; Index: frameobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/frameobject.c,v retrieving revision 2.57 retrieving revision 2.58 diff -C2 -d -r2.57 -r2.58 *** frameobject.c 2001/09/20 20:46:19 2.57 --- frameobject.c 2001/09/20 21:45:26 2.58 *************** *** 34,38 **** } ! static struct getsetlist frame_getsetlist[] = { {"f_locals", (getter)frame_getlocals, NULL, NULL}, {0} --- 34,38 ---- } ! static PyGetSetDef frame_getsetlist[] = { {"f_locals", (getter)frame_getlocals, NULL, NULL}, {0} Index: funcobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/funcobject.c,v retrieving revision 2.44 retrieving revision 2.45 diff -C2 -d -r2.44 -r2.45 *** funcobject.c 2001/09/20 20:46:19 2.44 --- funcobject.c 2001/09/20 21:45:26 2.45 *************** *** 258,262 **** } ! static struct getsetlist func_getsetlist[] = { {"func_code", (getter)func_get_code, (setter)func_set_code}, {"func_defaults", (getter)func_get_defaults, --- 258,262 ---- } ! static PyGetSetDef func_getsetlist[] = { {"func_code", (getter)func_get_code, (setter)func_set_code}, {"func_defaults", (getter)func_get_defaults, Index: methodobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/methodobject.c,v retrieving revision 2.39 retrieving revision 2.40 diff -C2 -d -r2.39 -r2.40 *** methodobject.c 2001/08/30 13:58:58 2.39 --- methodobject.c 2001/09/20 21:45:26 2.40 *************** *** 160,164 **** } ! static struct getsetlist meth_getsets [] = { {"__doc__", (getter)meth_get__doc__, NULL, NULL}, {"__name__", (getter)meth_get__name__, NULL, NULL}, --- 160,164 ---- } ! static PyGetSetDef meth_getsets [] = { {"__doc__", (getter)meth_get__doc__, NULL, NULL}, {"__name__", (getter)meth_get__name__, NULL, NULL}, Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.66 retrieving revision 2.67 diff -C2 -d -r2.66 -r2.67 *** typeobject.c 2001/09/20 20:46:19 2.66 --- typeobject.c 2001/09/20 21:45:26 2.67 *************** *** 92,96 **** } ! struct getsetlist type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, {"__module__", (getter)type_module, NULL, NULL}, --- 92,96 ---- } ! PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, {"__module__", (getter)type_module, NULL, NULL}, *************** *** 660,664 **** } ! struct getsetlist subtype_getsets[] = { {"__dict__", subtype_dict, NULL, NULL}, {0}, --- 660,664 ---- } ! PyGetSetDef subtype_getsets[] = { {"__dict__", subtype_dict, NULL, NULL}, {0}, *************** *** 1283,1287 **** static int ! add_getset(PyTypeObject *type, struct getsetlist *gsp) { PyObject *dict = type->tp_defined; --- 1283,1287 ---- static int ! add_getset(PyTypeObject *type, PyGetSetDef *gsp) { PyObject *dict = type->tp_defined; From gvanrossum@users.sourceforge.net Thu Sep 20 22:49:55 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 20 Sep 2001 14:49:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.66,1.67 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7022 Modified Files: test_descr.py Log Message: Add a small test to verify that member and getset descriptors now have docstrings (using file.closed and file.name as examples). Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.66 retrieving revision 1.67 diff -C2 -d -r1.66 -r1.67 *** test_descr.py 2001/09/20 21:39:07 1.66 --- test_descr.py 2001/09/20 21:49:53 1.67 *************** *** 1952,1956 **** --- 1952,1963 ---- coerce(0j, C(0)) + def descrdoc(): + if verbose: print "Testing descriptor doc strings..." + def check(descr, what): + verify(descr.__doc__ == what, repr(descr.__doc__)) + check(file.closed, "flag set if the file is closed") # getset descriptor + check(file.name, "file name") # member descriptor + def test_main(): lists() *************** *** 1993,1996 **** --- 2000,2004 ---- rich_comparisons() coercions() + descrdoc() if verbose: print "All OK" From tim_one@users.sourceforge.net Fri Sep 21 08:56:19 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 21 Sep 2001 00:56:19 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0253.txt,1.16,1.17 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv16753 Modified Files: pep-0253.txt Log Message: Fixed a number of typos, and made some semantic updates in a few areas I was sure about. Index: pep-0253.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0253.txt,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** pep-0253.txt 2001/09/08 11:31:52 1.16 --- pep-0253.txt 2001/09/21 07:56:16 1.17 *************** *** 108,112 **** >>> type(type(type(a))) ! >>> In this example, type(a) is a "regular" type, and type(type(a)) is --- 108,112 ---- >>> type(type(type(a))) ! >>> In this example, type(a) is a "regular" type, and type(type(a)) is *************** *** 147,151 **** and initialize it at will.) ! Metatypes determine various *policies* for types,such as what happens when a type is called, how dynamic types are (whether a type's __dict__ can be modified after it is created), what the --- 147,151 ---- and initialize it at will.) ! Metatypes determine various *policies* for types, such as what happens when a type is called, how dynamic types are (whether a type's __dict__ can be modified after it is created), what the *************** *** 224,234 **** should always be a new reference, owned by the caller. ! One the tp_new slot has returned an object, further initialization is attempted by calling the tp_init() slot of the resulting object's type, if not NULL. This has the following signature: ! PyObject *tp_init(PyObject *self, ! PyObject *args, ! PyObject *kwds) It corresponds more closely to the __init__() method of classic --- 224,234 ---- should always be a new reference, owned by the caller. ! Once the tp_new slot has returned an object, further initialization is attempted by calling the tp_init() slot of the resulting object's type, if not NULL. This has the following signature: ! int tp_init(PyObject *self, ! PyObject *args, ! PyObject *kwds) It corresponds more closely to the __init__() method of classic *************** *** 238,242 **** they ensure. The tp_new() slot should ensure only the most essential invariants, without which the C code that implements the ! object's would break. The tp_init() slot should be used for overridable user-specific initializations. Take for example the dictionary type. The implementation has an internal pointer to a --- 238,242 ---- they ensure. The tp_new() slot should ensure only the most essential invariants, without which the C code that implements the ! objects would break. The tp_init() slot should be used for overridable user-specific initializations. Take for example the dictionary type. The implementation has an internal pointer to a *************** *** 273,276 **** --- 273,280 ---- (or raise an exception). + Both tp_new() and tp_init() should receive exactly the same 'args' + and 'kwds' arguments, and both should check that the arguments are + acceptable, because they may be called independently. + There's a third slot related to object creation: tp_alloc(). Its responsibility is to allocate the memory for the object, *************** *** 292,296 **** type->tp_basicsize + nitems * type->tp_itemsize ! This slot is only used for subclassable types. The tp_new() function of the base class must call the tp_alloc() slot of the type passed in as its first argument. It is the tp_new() --- 296,300 ---- type->tp_basicsize + nitems * type->tp_itemsize ! The tp_alloc slot is only used for subclassable types. The tp_new() function of the base class must call the tp_alloc() slot of the type passed in as its first argument. It is the tp_new() *************** *** 304,314 **** are renamed to tp_allocs and tp_deallocs.) - XXX The keyword arguments are currently not passed to tp_new(); - its kwds argument is always NULL. This is a relic from a previous - revision and should probably be fixed. Both tp_new() and - tp_init() should receive exactly the same arguments, and both - should check that the arguments are acceptable, because they may - be called independently. - Standard implementations for tp_alloc() and tp_new() are available. PyType_GenericAlloc() allocates an object from the --- 308,311 ---- *************** *** 333,337 **** of the base structure unchanged) and can override certain slots in the type object, leaving others the same. (Unlike C++ vtables, ! all Python type objects have the same memory lay-out.) The base type must do the following: --- 330,334 ---- of the base structure unchanged) and can override certain slots in the type object, leaving others the same. (Unlike C++ vtables, ! all Python type objects have the same memory layout.) The base type must do the following: *************** *** 358,362 **** at the end of an object's lifetime. The slots involved are tp_dealloc() (familiar to all who have ever implemented a Python ! extension type) and tp_free(), the new kid on he block. (The names aren't quite symmetric; tp_free() corresponds to tp_alloc(), which is fine, but tp_dealloc() corresponds to tp_new(). Maybe --- 355,359 ---- at the end of an object's lifetime. The slots involved are tp_dealloc() (familiar to all who have ever implemented a Python ! extension type) and tp_free(), the new kid on the block. (The names aren't quite symmetric; tp_free() corresponds to tp_alloc(), which is fine, but tp_dealloc() corresponds to tp_new(). Maybe *************** *** 399,403 **** with instances of the derived type. Before enabling subtyping of a particular type, its code should be checked to make sure that ! this won't break anything. --- 396,405 ---- with instances of the derived type. Before enabling subtyping of a particular type, its code should be checked to make sure that ! this won't break anything. It has proved useful in the prototype ! to add another type-checking macro for the built-in Python object ! types, to check for exact type match too (for example, ! PyDict_Check(x) is true if x is an instance of dictionary or of a ! dictionary subclass, while PyDict_CheckExact(x) is true only if x ! is a dictionary). *************** *** 428,432 **** additions. Also note that the base type is not referenced via a pointer; the actual contents of its structure must be included! ! (The goal is for the memory lay out of the beginning of the subtype instance to be the same as that of the base type instance.) --- 430,434 ---- additions. Also note that the base type is not referenced via a pointer; the actual contents of its structure must be included! ! (The goal is for the memory layout of the beginning of the subtype instance to be the same as that of the base type instance.) *************** *** 554,559 **** C = M("C", (B,), dict) ! (where dict is the dictionary resulting from execution of the ! class body). In other words, the metatype (M) is called. Note that even though the example has only one base, we still pass --- 556,561 ---- C = M("C", (B,), dict) ! where dict is the dictionary resulting from execution of the ! class body. In other words, the metatype (M) is called. Note that even though the example has only one base, we still pass *************** *** 578,586 **** There are two further refinements here. First, a useful feature is to be able to specify a metatype directly. If the class ! statement defines a variable __metaclass__, that is the metatype to call. (Note that setting __metaclass__ at the module level only affects class statements without a base class and without an explicit __metaclass__ declaration; but setting __metaclass__ in a ! class statement overrides the default metatype unconditionally.) Second, with multiple bases, not all bases need to have the same --- 580,588 ---- There are two further refinements here. First, a useful feature is to be able to specify a metatype directly. If the class ! suite defines a variable __metaclass__, that is the metatype to call. (Note that setting __metaclass__ at the module level only affects class statements without a base class and without an explicit __metaclass__ declaration; but setting __metaclass__ in a ! class suite overrides the default metatype unconditionally.) Second, with multiple bases, not all bases need to have the same *************** *** 591,596 **** raised and the class statement fails. ! This conflict resultion can be implemented in the metatypes ! itself: the class statement just calls the metatype of the first base (or that specified by the __metaclass__ variable), and this metatype's constructor looks for the most derived metatype. If --- 593,598 ---- raised and the class statement fails. ! This conflict resolution can be implemented by the metatype ! constructors: the class statement just calls the metatype of the first base (or that specified by the __metaclass__ variable), and this metatype's constructor looks for the most derived metatype. If *************** *** 622,636 **** In any case, the work for creating C is done by M's tp_new() slot. ! It allocates space for an "extended" type structure, which ! contains space for: the type object; the auxiliary structures ! (as_sequence etc.); the string object containing the type name (to ! ensure that this object isn't deallocated while the type object is ! still referencing it); and some more auxiliary storage (to be ! described later). It initializes this storage to zeros except for ! a few crucial slots (for example, tp_name is set to point to the ! type name) and then sets the tp_base slot to point to B. Then ! PyType_InitDict() is called to inherit B's slots. Finally, C's ! tp_dict slot is updated with the contents of the namespace ! dictionary (the third argument to the call to M). --- 624,637 ---- In any case, the work for creating C is done by M's tp_new() slot. ! It allocates space for an "extended" type structure, containing: ! the type object; the auxiliary structures (as_sequence etc.); the ! string object containing the type name (to ensure that this object ! isn't deallocated while the type object is still referencing it); and ! some auxiliary storage (to be described later). It initializes this ! storage to zeros except for a few crucial slots (for example, tp_name ! is set to point to the type name) and then sets the tp_base slot to ! point to B. Then PyType_InitDict() is called to inherit B's slots. ! Finally, C's tp_dict slot is updated with the contents of the ! namespace dictionary (the third argument to the call to M). *************** *** 673,679 **** (Here, 'dictionary' is the type of built-in dictionary objects, a.k.a. type({}) or {}.__class__ or types.DictType.) If we look at ! the structure lay-out, we find that an A instance has the lay-out of a dictionary followed by the __dict__ pointer, and a B instance ! has the same lay-out; since there are no structure member lay-out conflicts, this is okay. --- 674,680 ---- (Here, 'dictionary' is the type of built-in dictionary objects, a.k.a. type({}) or {}.__class__ or types.DictType.) If we look at ! the structure layout, we find that an A instance has the layout of a dictionary followed by the __dict__ pointer, and a B instance ! has the same layout; since there are no structure member layout conflicts, this is okay. *************** *** 689,693 **** (Here, 'object' is the base for all built-in types; its structure ! lay-out only contains the ob_refcnt and ob_type members.) This example is more complicated, because the __dict__ pointer for X instances has a different offset than that for Y instances. Where --- 690,694 ---- (Here, 'object' is the base for all built-in types; its structure ! layout only contains the ob_refcnt and ob_type members.) This example is more complicated, because the __dict__ pointer for X instances has a different offset than that for Y instances. Where *************** *** 701,705 **** followed by a __dict__ pointer), and a Y structure is 64 bytes (a dictionary structure followed by a __dict__ pointer). The Z ! structure has the same lay-out as the Y structure in this example. Each type object (X, Y and Z) has a "__dict__ offset" which is used to find the __dict__ pointer. Thus, the recipe for looking --- 702,706 ---- followed by a __dict__ pointer), and a Y structure is 64 bytes (a dictionary structure followed by a __dict__ pointer). The Z ! structure has the same layout as the Y structure in this example. Each type object (X, Y and Z) has a "__dict__ offset" which is used to find the __dict__ pointer. Thus, the recipe for looking *************** *** 723,727 **** ! Method resolution order (the lookup rule) With multiple inheritance comes the question of method resolution --- 724,728 ---- ! MRO: Method resolution order (the lookup rule) With multiple inheritance comes the question of method resolution *************** *** 777,781 **** hierarchies use single inheritance, and multiple inheritance is usually confined to mix-in classes. In fact, the problem shown ! here is probably the reason why multiple inheritance is impopular in classic Python. --- 778,782 ---- hierarchies use single inheritance, and multiple inheritance is usually confined to mix-in classes. In fact, the problem shown ! here is probably the reason why multiple inheritance is unpopular in classic Python. *************** *** 918,922 **** - should we return to the old __getattr__ semantics, and introduce a new name (__getallattr__?) for the new semantics? ! or introduce a new name (__getattrhook__?)for the old semantics? --- 919,923 ---- - should we return to the old __getattr__ semantics, and introduce a new name (__getallattr__?) for the new semantics? ! or introduce a new name (__getattrhook__?) for the old semantics? *************** *** 938,950 **** A prototype implementation of this PEP (and for PEP 252) is ! available from CVS as a branch named "descr-branch". To ! experiment with this implementation, proceed to check out Python ! from CVS according to the instructions at ! http://sourceforge.net/cvs/?group_id=5470 but add the arguments ! "-r descr-branch" to the cvs checkout command. (You can also ! start with an existing checkout and do "cvs update -r ! descr-branch".) For some examples of the features described here, ! see the file Lib/test/test_descr.py and the extension module ! Modules/xxsubtype.c. --- 939,945 ---- A prototype implementation of this PEP (and for PEP 252) is ! available from CVS, and in the series of Python 2.2 alpha releases. ! For some examples of the features described here, see the file ! Lib/test/test_descr.py and the extension module Modules/xxsubtype.c. From gvanrossum@users.sourceforge.net Fri Sep 21 16:36:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 08:36:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12134 Modified Files: test_unicode.py Log Message: Test basic functioning of unicode repr(). (If this breaks Jython, please let me know and we'll figure out how to fix the test.) Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** test_unicode.py 2001/09/20 12:53:13 1.38 --- test_unicode.py 2001/09/21 15:36:41 1.39 *************** *** 9,12 **** --- 9,23 ---- import sys + # Test basic sanity of repr() + verify(repr(u'abc') == "u'abc'") + verify(repr(u'ab\\c') == "u'ab\\\\c'") + verify(repr(u'ab\\') == "u'ab\\\\'") + verify(repr(u'\\c') == "u'\\\\c'") + verify(repr(u'\\') == "u'\\\\'") + verify(repr(u'\n') == "u'\\n'") + verify(repr(u'\r') == "u'\\r'") + verify(repr(u'\t') == "u'\\t'") + verify(repr(u'\b') == "u'\\x08'") + def test(method, input, output, *args): if verbose: From gvanrossum@users.sourceforge.net Fri Sep 21 16:38:19 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 08:38:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.116,2.117 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12553 Modified Files: unicodeobject.c Log Message: Fix a bug in rendering of \\ by repr() -- it rendered as \\\ instead of \\. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.116 retrieving revision 2.117 diff -C2 -d -r2.116 -r2.117 *** unicodeobject.c 2001/09/20 17:22:58 2.116 --- unicodeobject.c 2001/09/21 15:38:17 2.117 *************** *** 1759,1762 **** --- 1759,1763 ---- *p++ = '\\'; *p++ = (char) ch; + continue; } From gvanrossum@users.sourceforge.net Fri Sep 21 16:46:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 08:46:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15166 Modified Files: test_unicode.py Log Message: Add tests for repr() of strings containing string quotes as well. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** test_unicode.py 2001/09/21 15:36:41 1.39 --- test_unicode.py 2001/09/21 15:46:41 1.40 *************** *** 19,22 **** --- 19,26 ---- verify(repr(u'\t') == "u'\\t'") verify(repr(u'\b') == "u'\\x08'") + verify(repr(u"'\"") == """u'\\'"'""") + verify(repr(u"'\"") == """u'\\'"'""") + verify(repr(u"'") == '''u"'"''') + verify(repr(u'"') == """u'"'""") def test(method, input, output, *args): From gvanrossum@users.sourceforge.net Fri Sep 21 20:21:48 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 12:21:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pickle.py,1.51,1.52 zipfile.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv21725 Modified Files: pickle.py zipfile.py Log Message: Make these modules work when Python is compiled without Unicode support. Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** pickle.py 2001/08/28 22:21:18 1.51 --- pickle.py 2001/09/21 19:21:45 1.52 *************** *** 55,58 **** --- 55,64 ---- PyStringMap = None + try: + UnicodeType + except NameError: + UnicodeType = None + + MARK = '(' STOP = '.' *************** *** 305,310 **** self.write(BINUNICODE + s + encoding) else: ! object = object.replace(u"\\", u"\\u005c") ! object = object.replace(u"\n", u"\\u000a") self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') --- 311,316 ---- self.write(BINUNICODE + s + encoding) else: ! object = object.replace("\\", "\\u005c") ! object = object.replace("\n", "\\u000a") self.write(UNICODE + object.encode('raw-unicode-escape') + '\n') *************** *** 335,340 **** else: if unicode: ! object = object.replace(u"\\", u"\\u005c") ! object = object.replace(u"\n", u"\\u000a") object = object.encode('raw-unicode-escape') self.write(UNICODE + object + '\n') --- 341,346 ---- else: if unicode: ! object = object.replace("\\", "\\u005c") ! object = object.replace("\n", "\\u000a") object = object.encode('raw-unicode-escape') self.write(UNICODE + object + '\n') Index: zipfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/zipfile.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** zipfile.py 2001/09/18 02:26:39 1.17 --- zipfile.py 2001/09/21 19:21:45 1.18 *************** *** 67,71 **** # Used to compare file passed to ZipFile ! _STRING_TYPES = (type('s'), type(u's')) --- 67,74 ---- # Used to compare file passed to ZipFile ! import types ! _STRING_TYPES = (types.StringType,) ! if hasattr(types, "UnicodeType"): ! _STRING_TYPES = _STRING_TYPES + (types.UnicodeType,) From gvanrossum@users.sourceforge.net Fri Sep 21 20:22:36 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 12:22:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_grammar.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22030 Modified Files: test_grammar.py Log Message: Make these modules work when Python is compiled without Unicode support. Index: test_grammar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grammar.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_grammar.py 2001/08/27 21:50:42 1.36 --- test_grammar.py 2001/09/21 19:22:34 1.37 *************** *** 395,398 **** --- 395,401 ---- z = None del z + import types + if hasattr(types, "UnicodeType"): + exec r"""if 1: exec u'z=1+1\n' if z != 2: raise TestFailed, 'exec u\'z=1+1\'\\n' *************** *** 400,403 **** --- 403,407 ---- exec u'z=1+1' if z != 2: raise TestFailed, 'exec u\'z=1+1\'' + """ f() g = {} From gvanrossum@users.sourceforge.net Fri Sep 21 20:29:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 12:29:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.67,2.68 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23152/Objects Modified Files: typeobject.c Log Message: Change the name of the __getattr__ special method for new-style classes to __getattribute__, to make it crystal-clear that it doesn't have the same semantics as overriding __getattr__ on classic classes. This is a halfway checkin -- I'll proceed to add a __getattr__ hook that works the way it works in classic classes. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.67 retrieving revision 2.68 diff -C2 -d -r2.67 -r2.68 *** typeobject.c 2001/09/20 21:45:26 2.67 --- typeobject.c 2001/09/21 19:29:08 2.68 *************** *** 2062,2067 **** static struct wrapperbase tab_getattr[] = { ! {"__getattr__", (wrapperfunc)wrap_binaryfunc, ! "x.__getattr__('name') <==> x.name"}, {0} }; --- 2062,2067 ---- static struct wrapperbase tab_getattr[] = { ! {"__getattribute__", (wrapperfunc)wrap_binaryfunc, ! "x.__getattribute__('name') <==> x.name"}, {0} }; *************** *** 2878,2882 **** if (getattr_str == NULL) { ! getattr_str = PyString_InternFromString("__getattr__"); if (getattr_str == NULL) return NULL; --- 2878,2882 ---- if (getattr_str == NULL) { ! getattr_str = PyString_InternFromString("__getattribute__"); if (getattr_str == NULL) return NULL; *************** *** 3197,3201 **** TPSLOT("__call__", tp_call, slot_tp_call); TPSLOT("__str__", tp_str, slot_tp_str); ! TPSLOT("__getattr__", tp_getattro, slot_tp_getattro); TPSLOT("__setattr__", tp_setattro, slot_tp_setattro); TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare); --- 3197,3201 ---- TPSLOT("__call__", tp_call, slot_tp_call); TPSLOT("__str__", tp_str, slot_tp_str); ! TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro); TPSLOT("__setattr__", tp_setattro, slot_tp_setattro); TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare); From gvanrossum@users.sourceforge.net Fri Sep 21 20:29:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 12:29:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.67,1.68 test_descrtut.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv23152/Lib/test Modified Files: test_descr.py test_descrtut.py Log Message: Change the name of the __getattr__ special method for new-style classes to __getattribute__, to make it crystal-clear that it doesn't have the same semantics as overriding __getattr__ on classic classes. This is a halfway checkin -- I'll proceed to add a __getattr__ hook that works the way it works in classic classes. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.67 retrieving revision 1.68 diff -C2 -d -r1.67 -r1.68 *** test_descr.py 2001/09/20 21:49:53 1.67 --- test_descr.py 2001/09/21 19:29:08 1.68 *************** *** 679,685 **** def __init__(self): MT.__init__(self) ! def __getattr__(self, name): log.append(("getattr", name)) ! return MT.__getattr__(self, name) def __setattr__(self, name, value): log.append(("setattr", name, value)) --- 679,685 ---- def __init__(self): MT.__init__(self) ! def __getattribute__(self, name): log.append(("getattr", name)) ! return MT.__getattribute__(self, name) def __setattr__(self, name, value): log.append(("setattr", name, value)) *************** *** 882,887 **** return "spam" else: ! return object.__getattr__(self, name) ! C.__getattr__ = mygetattr verify(a.spam == "spam") a.new = 12 --- 882,887 ---- return "spam" else: ! return object.__getattribute__(self, name) ! C.__getattribute__ = mygetattr verify(a.spam == "spam") a.new = 12 *************** *** 1106,1114 **** class C(B): ! def __getattr__(self, name): if name == "foo": return ("getattr", name) else: ! return B.__getattr__(self, name) def __setattr__(self, name, value): if name == "foo": --- 1106,1114 ---- class C(B): ! def __getattribute__(self, name): if name == "foo": return ("getattr", name) else: ! return B.__getattribute__(self, name) def __setattr__(self, name, value): if name == "foo": Index: test_descrtut.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descrtut.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_descrtut.py 2001/09/09 06:12:01 1.5 --- test_descrtut.py 2001/09/21 19:29:08 1.6 *************** *** 193,197 **** '__eq__', '__ge__', ! '__getattr__', '__getitem__', '__getslice__', --- 193,197 ---- '__eq__', '__ge__', ! '__getattribute__', '__getitem__', '__getslice__', From gvanrossum@users.sourceforge.net Fri Sep 21 21:31:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 13:31:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.51,1.52 test_support.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7621 Modified Files: regrtest.py test_support.py Log Message: Change the way unexpected output is reported: rather than stopping at the first difference, let the test run till completion, then gather all the output and compare it to the expected output using difflib. XXX Still to do: produce diff output that only shows the sections that differ; currently it produces ndiff-style output because that's the easiest to produce with difflib, but this becomes a liability when the output is voluminous and there are only a few differences. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** regrtest.py 2001/09/18 20:34:19 1.51 --- regrtest.py 2001/09/21 20:31:52 1.52 *************** *** 283,296 **** outputdir = os.path.join(testdir, "output") outputfile = os.path.join(outputdir, test) ! try: ! if generate: ! cfp = StringIO.StringIO() ! elif verbose: ! cfp = sys.stdout ! else: ! cfp = Compare(outputfile, sys.stdout) ! except IOError: cfp = None ! print "Warning: can't open", outputfile try: save_stdout = sys.stdout --- 283,290 ---- outputdir = os.path.join(testdir, "output") outputfile = os.path.join(outputdir, test) ! if verbose or generate: cfp = None ! else: ! cfp = StringIO.StringIO() try: save_stdout = sys.stdout *************** *** 307,314 **** if indirect_test is not None: indirect_test() - if cfp and not (generate or verbose): - cfp.close() finally: sys.stdout = save_stdout except (ImportError, test_support.TestSkipped), msg: if not quiet: --- 301,313 ---- if indirect_test is not None: indirect_test() finally: sys.stdout = save_stdout + if cfp and test_support.output_comparison_denied(): + output = cfp.getvalue() + cfp = None + s = test + "\n" + if output.startswith(s): + output = output[len(s):] + sys.stdout.write(output) except (ImportError, test_support.TestSkipped), msg: if not quiet: *************** *** 327,332 **** return 0 else: if generate: - output = cfp.getvalue() if output == test + "\n": if os.path.exists(outputfile): --- 326,333 ---- return 0 else: + if not cfp: + return 1 + output = cfp.getvalue() if generate: if output == test + "\n": if os.path.exists(outputfile): *************** *** 334,349 **** # may have changed), but let the user know it isn't # needed: - fp = open(outputfile, "w") - fp.write(output) - fp.close() print "output file", outputfile, \ "is no longer needed; consider removing it" ! # else: ! # We don't need it, so don't create it. ! else: ! fp = open(outputfile, "w") ! fp.write(output) ! fp.close() ! return 1 def findtestdir(): --- 335,367 ---- # may have changed), but let the user know it isn't # needed: print "output file", outputfile, \ "is no longer needed; consider removing it" ! else: ! # We don't need it, so don't create it. ! return 1 ! fp = open(outputfile, "w") ! fp.write(output) ! fp.close() ! return 1 ! if os.path.exists(outputfile): ! fp = open(outputfile, "r") ! expected = fp.read() ! fp.close() ! else: ! expected = test + "\n" ! if output == expected: ! return 1 ! print "test", test, "produced unexpected output:" ! reportdiff(expected, output) ! return 0 ! ! def reportdiff(expected, output): ! print "*" * 70 ! import difflib ! a = expected.splitlines(1) ! b = output.splitlines(1) ! diff = difflib.ndiff(a, b) ! print ''.join(diff), ! print "*" * 70 def findtestdir(): *************** *** 384,443 **** if len(line) > indent: print line - - class Compare: - def __init__(self, filename, origstdout): - self.origstdout = origstdout - if os.path.exists(filename): - self.fp = open(filename, 'r') - else: - self.fp = StringIO.StringIO( - os.path.basename(filename) + "\n") - self.stuffthatmatched = [] - - def write(self, data): - if test_support.suppress_output_comparison(): - self.origstdout.write(data) - return - expected = self.fp.read(len(data)) - if data == expected: - self.stuffthatmatched.append(expected) - else: - # This Compare instance is spoofing stdout, so we need to write - # to stderr instead. - from sys import stderr as e - print >> e, "The actual stdout doesn't match the expected stdout." - if self.stuffthatmatched: - print >> e, "This much did match (between asterisk lines):" - print >> e, "*" * 70 - good = "".join(self.stuffthatmatched) - e.write(good) - if not good.endswith("\n"): - e.write("\n") - print >> e, "*" * 70 - print >> e, "Then ..." - else: - print >> e, "The first write to stdout clashed:" - # Note that the prompts are the same length in next two lines. - # This is so what we expected and what we got line up. - print >> e, "We expected (repr):", `expected` - print >> e, "But instead we got:", `data` - raise test_support.TestFailed('Writing: ' + `data`+ - ', expected: ' + `expected`) - - def writelines(self, listoflines): - map(self.write, listoflines) - - def flush(self): - pass - - def close(self): - leftover = self.fp.read() - if leftover: - raise test_support.TestFailed('Tail of expected stdout unseen: ' + - `leftover`) - self.fp.close() - - def isatty(self): - return 0 class _Set: --- 402,405 ---- Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** test_support.py 2001/09/20 06:31:22 1.32 --- test_support.py 2001/09/21 20:31:52 1.33 *************** *** 24,29 **** # _output_comparison controls whether regrtest will try to compare stdout # with an expected-output file. For straight regrtests, it should. ! # The doctest driver should set_output_comparison(0) for the duration, and ! # restore the old value when it's done. # Note that this control is in addition to verbose mode: output will be # compared if and only if _output_comparison is true and verbose mode is --- 24,28 ---- # _output_comparison controls whether regrtest will try to compare stdout # with an expected-output file. For straight regrtests, it should. ! # The doctest driver resets this flag by calling deny_output_comparison(). # Note that this control is in addition to verbose mode: output will be # compared if and only if _output_comparison is true and verbose mode is *************** *** 31,44 **** _output_comparison = 1 ! def set_output_comparison(newvalue): global _output_comparison ! oldvalue = _output_comparison ! _output_comparison = newvalue ! return oldvalue # regrtest's interface to _output_comparison. ! def suppress_output_comparison(): ! return not _output_comparison ! def unload(name): --- 30,43 ---- _output_comparison = 1 ! def deny_output_comparison(): global _output_comparison ! _output_comparison = 0 # regrtest's interface to _output_comparison. ! def output_comparison_denied(): ! global _output_comparison ! denied = not _output_comparison ! _output_comparison = 1 ! return denied def unload(name): *************** *** 200,208 **** verbosity = None ! oldvalue = set_output_comparison(0) ! try: ! f, t = doctest.testmod(module, verbose=verbosity) ! if f: ! raise TestFailed("%d of %d doctests failed" % (f, t)) ! finally: ! set_output_comparison(oldvalue) --- 199,204 ---- verbosity = None ! deny_output_comparison() ! f, t = doctest.testmod(module, verbose=verbosity) ! if f: ! raise TestFailed("%d of %d doctests failed" % (f, t)) From gvanrossum@users.sourceforge.net Fri Sep 21 21:45:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 13:45:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.52,1.53 test_support.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11637 Modified Files: regrtest.py test_support.py Log Message: Oops. I didn't expect that some tests (test_cookie) have expected output *and* doctest stuff. Assuming the doctest stuff comes after the expected output, this fixes that. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** regrtest.py 2001/09/21 20:31:52 1.52 --- regrtest.py 2001/09/21 20:45:44 1.53 *************** *** 288,292 **** cfp = StringIO.StringIO() try: ! save_stdout = sys.stdout try: if cfp: --- 288,292 ---- cfp = StringIO.StringIO() try: ! sys.save_stdout = sys.stdout try: if cfp: *************** *** 302,313 **** indirect_test() finally: ! sys.stdout = save_stdout ! if cfp and test_support.output_comparison_denied(): ! output = cfp.getvalue() ! cfp = None ! s = test + "\n" ! if output.startswith(s): ! output = output[len(s):] ! sys.stdout.write(output) except (ImportError, test_support.TestSkipped), msg: if not quiet: --- 302,306 ---- indirect_test() finally: ! sys.stdout = sys.save_stdout except (ImportError, test_support.TestSkipped), msg: if not quiet: Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** test_support.py 2001/09/21 20:31:52 1.33 --- test_support.py 2001/09/21 20:45:44 1.34 *************** *** 33,36 **** --- 33,37 ---- global _output_comparison _output_comparison = 0 + sys.stdout = sys.save_stdout # regrtest's interface to _output_comparison. From gvanrossum@users.sourceforge.net Fri Sep 21 22:06:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 14:06:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv17915 Modified Files: regrtest.py Log Message: reportdiff(): print a "plain diff" style diff. XXX This should really be a unified diff, but I can't be bothered. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** regrtest.py 2001/09/21 20:45:44 1.53 --- regrtest.py 2001/09/21 21:06:22 1.54 *************** *** 352,359 **** print "*" * 70 import difflib ! a = expected.splitlines(1) ! b = output.splitlines(1) ! diff = difflib.ndiff(a, b) ! print ''.join(diff), print "*" * 70 --- 352,385 ---- print "*" * 70 import difflib ! a = expected.splitlines() ! b = output.splitlines() ! sm = difflib.SequenceMatcher(a=a, b=b) ! tuples = sm.get_opcodes() ! def pair(x0, x1): ! x0 += 1 ! if x0 >= x1: ! return str(x0) ! else: ! return "%d,%d" % (x0, x1) ! for op, a0, a1, b0, b1 in tuples: ! if op == 'equal': ! pass ! elif op == 'delete': ! print pair(a0, a1) + "d" + pair(b0, b1) ! for line in a[a0:a1]: ! print "<", line ! elif op == 'replace': ! print pair(a0, a1) + "c" + pair(b0, b1) ! for line in a[a0:a1]: ! print "<", line ! print "---" ! for line in b[b0:b1]: ! print ">", line ! elif op == 'insert': ! print str(a0) + "a" + pair(b0, b1) ! for line in b[b0:b1]: ! print ">", line ! else: ! print "get_opcodes() returned bad tuple?!?!", (op, a0, a1, b0, b1) print "*" * 70 From fdrake@users.sourceforge.net Fri Sep 21 22:10:07 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 14:10:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.149,1.150 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv18697/tut Modified Files: tut.tex Log Message: Exceptions in interactive examlpes did not always include the indication of the source file using "in ?". Added a description of the bare "raise" statement. Added more description and examples for user-defined exceptions; this is part of a response to SF bug #443559. Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -d -r1.149 -r1.150 *** tut.tex 2001/09/06 18:41:15 1.149 --- tut.tex 2001/09/21 21:10:05 1.150 *************** *** 620,624 **** 'string' >>> string.strip('str') 'ing' # <- This is invalid ! File "", line 1 string.strip('str') 'ing' ^ --- 620,624 ---- 'string' >>> string.strip('str') 'ing' # <- This is invalid ! File "", line 1, in ? string.strip('str') 'ing' ^ *************** *** 729,733 **** >>> word[-10] # error Traceback (most recent call last): ! File "", line 1 IndexError: string index out of range \end{verbatim} --- 729,733 ---- >>> word[-10] # error Traceback (most recent call last): ! File "", line 1, in ? IndexError: string index out of range \end{verbatim} *************** *** 1835,1839 **** [[2, 4], [4, 16], [6, 36]] >>> [x, x**2 for x in vec] # error - parens required for tuples ! File "", line 1 [x, x**2 for x in vec] ^ --- 1835,1839 ---- [[2, 4], [4, 16], [6, 36]] >>> [x, x**2 for x in vec] # error - parens required for tuples ! File "", line 1, in ? [x, x**2 for x in vec] ^ *************** *** 2962,2966 **** \begin{verbatim} >>> while 1 print 'Hello world' ! File "", line 1 while 1 print 'Hello world' ^ --- 2962,2966 ---- \begin{verbatim} >>> while 1 print 'Hello world' ! File "", line 1, in ? while 1 print 'Hello world' ^ *************** *** 2988,3000 **** >>> 10 * (1/0) Traceback (most recent call last): ! File "", line 1 ZeroDivisionError: integer division or modulo >>> 4 + spam*3 Traceback (most recent call last): ! File "", line 1 NameError: spam >>> '2' + 2 Traceback (most recent call last): ! File "", line 1 TypeError: illegal argument type for built-in operation \end{verbatim} --- 2988,3000 ---- >>> 10 * (1/0) Traceback (most recent call last): ! File "", line 1, in ? ZeroDivisionError: integer division or modulo >>> 4 + spam*3 Traceback (most recent call last): ! File "", line 1, in ? NameError: spam >>> '2' + 2 Traceback (most recent call last): ! File "", line 1, in ? TypeError: illegal argument type for built-in operation \end{verbatim} *************** *** 3171,3175 **** >>> raise NameError, 'HiThere' Traceback (most recent call last): ! File "", line 1 NameError: HiThere \end{verbatim} --- 3171,3175 ---- >>> raise NameError, 'HiThere' Traceback (most recent call last): ! File "", line 1, in ? NameError: HiThere \end{verbatim} *************** *** 3179,3190 **** argument. \section{User-defined Exceptions \label{userExceptions}} ! Programs may name their own exceptions by assigning a string to a ! variable or creating a new exception class. For example: \begin{verbatim} ! >>> class MyError: ... def __init__(self, value): ... self.value = value --- 3179,3209 ---- argument. + If you need to determine whether an exception was raised but don't + intend to handle it, a simpler form of the \keyword{raise} statement + allows you to re-raise the exception: + + \begin{verbatim} + >>> try: + ... raise NameError, 'HiThere' + ... except NameError: + ... print 'An exception flew by!' + ... raise + ... + An exception flew by! + Traceback (most recent call last): + File "", line 2, in ? + NameError: HiThere + \end{verbatim} + \section{User-defined Exceptions \label{userExceptions}} ! Programs may name their own exceptions by creating a new exception ! class. Exceptions should typically be derived from the ! \exception{Exception} class, either directly or indirectly. For ! example: \begin{verbatim} ! >>> class MyError(Exception): ... def __init__(self, value): ... self.value = value *************** *** 3198,3214 **** ... My exception occurred, value: 4 ! >>> raise MyError, 1 Traceback (most recent call last): ! File "", line 1 ! __main__.MyError: 1 \end{verbatim} ! Many standard modules use this to report errors that may occur in ! functions they define. ! More information on classes is presented in chapter \ref{classes}, ! ``Classes.'' \section{Defining Clean-up Actions \label{cleanup}} --- 3217,3275 ---- ... My exception occurred, value: 4 ! >>> raise MyError, 'oops!' Traceback (most recent call last): ! File "", line 1, in ? ! __main__.MyError: 'oops!' \end{verbatim} ! Exception classes can be defined which do anything any other class can ! do, but are usually kept simple, often only offering a number of ! attributes that allow information about the error to be extracted by ! handlers for the exception. When creating a module which can raise ! several distinct errors, a common practice is to create a base class ! for exceptions defined by that module, and subclass that to create ! specific exception classes for different error conditions: ! \begin{verbatim} ! class Error(Exception): ! """Base class for exceptions in this module.""" ! pass ! ! class InputError(Error): ! """Exception raised for errors in the input. ! ! Attributes: ! expression -- input expression in which the error occurred ! message -- explanation of the error ! """ ! ! def __init__(self, expression, message): ! self.expression = expression ! self.message = message ! ! class TransitionError(Error): ! """Raised when an operation attempts a state transition that's not ! allowed. + Attributes: + previous -- state at beginning of transition + next -- attempted new state + message -- explanation of why the specific transition is not allowed + """ + + def __init__(self, previous, next, message): + self.previous = previous + self.next = next + self.message = message + \end{verbatim} + + Most exceptions are defined with names that end in ``Error,'' similar + to the naming of the standard exceptions. + Many standard modules define their own exceptions to report errors + that may occur in functions they define. More information on classes + is presented in chapter \ref{classes}, ``Classes.'' + + \section{Defining Clean-up Actions \label{cleanup}} *************** *** 3225,3229 **** Goodbye, world! Traceback (most recent call last): ! File "", line 2 KeyboardInterrupt \end{verbatim} --- 3286,3290 ---- Goodbye, world! Traceback (most recent call last): ! File "", line 2, in ? KeyboardInterrupt \end{verbatim} *************** *** 3235,3240 **** --- 3296,3306 ---- left via a \keyword{break} or \keyword{return} statement. + The code in the finally clause is useful for releasing external + resources (such as files or network connections), regardless of + whether or not the use of the resource was successful. + A \keyword{try} statement must either have one or more except clauses or one finally clause, but not both. + \chapter{Classes \label{classes}} From fdrake@users.sourceforge.net Fri Sep 21 22:12:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 14:12:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libexcs.tex,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv19370/lib Modified Files: libexcs.tex Log Message: Added reference to Tutorial section on user-defined exceptions for information on defining new exceptions. This closes SF bug #443559. Index: libexcs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libexcs.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -d -r1.40 -r1.41 *** libexcs.tex 2001/07/26 13:41:05 1.40 --- libexcs.tex 2001/09/21 21:12:30 1.41 *************** *** 11,15 **** The exceptions are defined in the module \module{exceptions}. This module never needs to be imported explicitly: the exceptions are ! provided in the built-in namespace. Two distinct string objects with the same value are considered different --- 11,16 ---- The exceptions are defined in the module \module{exceptions}. This module never needs to be imported explicitly: the exceptions are ! provided in the built-in namespace as well as the \module{exceptions} ! module. Two distinct string objects with the same value are considered different *************** *** 48,51 **** --- 49,59 ---- inappropriate error. + The built-in exception classes can be sub-classed to define new + exceptions; programmers are encouraged to at least derive new + exceptions from the \exception{Exception} base class. More + information on defining exceptions is available in the + \citetitle[../tut/tut.html]{Python Tutorial} under the heading + ``User-defined Exceptions.'' + \setindexsubitem{(built-in exception base class)} *************** *** 255,264 **** interactively). ! When class exceptions are used, instances of this class have ! atttributes \member{filename}, \member{lineno}, \member{offset} and ! \member{text} for easier access to the details; for string exceptions, ! the associated value is usually a tuple of the form ! \code{(message, (filename, lineno, offset, text))}. ! For class exceptions, \function{str()} returns only the message. \end{excdesc} --- 263,270 ---- interactively). ! Instances of this class have atttributes \member{filename}, ! \member{lineno}, \member{offset} and \member{text} for easier access ! to the details. \function{str()} of the exception instance returns ! only the message. \end{excdesc} *************** *** 270,274 **** You should report this to the author or maintainer of your Python ! interpreter. Be sure to report the version string of the Python interpreter (\code{sys.version}; it is also printed at the start of an interactive Python session), the exact error message (the exception's --- 276,280 ---- You should report this to the author or maintainer of your Python ! interpreter. Be sure to report the version of the Python interpreter (\code{sys.version}; it is also printed at the start of an interactive Python session), the exact error message (the exception's *************** *** 343,347 **** ! \setindexsubitem{(built-in warning category)} The following exceptions are used as warning categories; see the --- 349,353 ---- ! \setindexsubitem{(built-in warning)} The following exceptions are used as warning categories; see the From fdrake@users.sourceforge.net Fri Sep 21 22:18:18 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 14:18:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile,1.225,1.226 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv20745 Modified Files: Makefile Log Message: Bump version number. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile,v retrieving revision 1.225 retrieving revision 1.226 diff -C2 -d -r1.225 -r1.226 *** Makefile 2001/09/06 19:35:02 1.225 --- Makefile 2001/09/21 21:18:16 1.226 *************** *** 68,72 **** # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.2a3 PYTHON= python --- 68,72 ---- # This is the *documentation* release, and is used to construct the file # names of the downloadable tarballs. ! RELEASE=2.2a4 PYTHON= python From fdrake@users.sourceforge.net Fri Sep 21 22:18:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 14:18:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.65,1.66 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv20745/texinputs Modified Files: boilerplate.tex Log Message: Bump version number. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.65 retrieving revision 1.66 diff -C2 -d -r1.65 -r1.66 *** boilerplate.tex 2001/09/06 19:02:57 1.65 --- boilerplate.tex 2001/09/21 21:18:16 1.66 *************** *** 8,11 **** \date{\today} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{a3} % empty for final release \setshortversion{2.2} % major.minor only for software --- 8,11 ---- \date{\today} % XXX update before release! \release{2.2} % software release, not documentation ! \setreleaseinfo{a4} % empty for final release \setshortversion{2.2} % major.minor only for software From gvanrossum@users.sourceforge.net Fri Sep 21 22:24:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 14:24:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21933/Lib/test Modified Files: test_descr.py Log Message: Add the __getattr__ hook back. The rules are now: - if __getattribute__ exists, it is called first; if it doesn't exists, PyObject_GenericGetAttr is called first. - if the above raises AttributeError, and __getattr__ exists, it is called. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** test_descr.py 2001/09/21 19:29:08 1.68 --- test_descr.py 2001/09/21 21:24:49 1.69 *************** *** 881,887 **** if name == "spam": return "spam" ! else: ! return object.__getattribute__(self, name) ! C.__getattribute__ = mygetattr verify(a.spam == "spam") a.new = 12 --- 881,886 ---- if name == "spam": return "spam" ! raise AttributeError ! C.__getattr__ = mygetattr verify(a.spam == "spam") a.new = 12 *************** *** 1106,1114 **** class C(B): ! def __getattribute__(self, name): if name == "foo": return ("getattr", name) else: ! return B.__getattribute__(self, name) def __setattr__(self, name, value): if name == "foo": --- 1105,1113 ---- class C(B): ! def __getattr__(self, name): if name == "foo": return ("getattr", name) else: ! raise AttributeError def __setattr__(self, name, value): if name == "foo": From gvanrossum@users.sourceforge.net Fri Sep 21 22:24:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 21 Sep 2001 14:24:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.68,2.69 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21933/Objects Modified Files: typeobject.c Log Message: Add the __getattr__ hook back. The rules are now: - if __getattribute__ exists, it is called first; if it doesn't exists, PyObject_GenericGetAttr is called first. - if the above raises AttributeError, and __getattr__ exists, it is called. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.68 retrieving revision 2.69 diff -C2 -d -r2.68 -r2.69 *** typeobject.c 2001/09/21 19:29:08 2.68 --- typeobject.c 2001/09/21 21:24:49 2.69 *************** *** 2892,2895 **** --- 2892,2933 ---- } + static PyObject * + slot_tp_getattr_hook(PyObject *self, PyObject *name) + { + PyTypeObject *tp = self->ob_type; + PyObject *getattr, *getattribute, *res; + static PyObject *getattribute_str = NULL; + static PyObject *getattr_str = NULL; + + if (getattr_str == NULL) { + getattr_str = PyString_InternFromString("__getattr__"); + if (getattr_str == NULL) + return NULL; + } + if (getattribute_str == NULL) { + getattribute_str = + PyString_InternFromString("__getattribute__"); + if (getattribute_str == NULL) + return NULL; + } + getattr = _PyType_Lookup(tp, getattr_str); + getattribute = _PyType_Lookup(tp, getattribute_str); + if (getattr == NULL && getattribute == NULL) { + /* Avoid further slowdowns */ + if (tp->tp_getattro == slot_tp_getattr_hook) + tp->tp_getattro = PyObject_GenericGetAttr; + return PyObject_GenericGetAttr(self, name); + } + if (getattribute == NULL) + res = PyObject_GenericGetAttr(self, name); + else + res = PyObject_CallFunction(getattribute, "OO", self, name); + if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { + PyErr_Clear(); + res = PyObject_CallFunction(getattr, "OO", self, name); + } + return res; + } + static int slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) *************** *** 3198,3201 **** --- 3236,3240 ---- TPSLOT("__str__", tp_str, slot_tp_str); TPSLOT("__getattribute__", tp_getattro, slot_tp_getattro); + TPSLOT("__getattr__", tp_getattro, slot_tp_getattr_hook); TPSLOT("__setattr__", tp_setattro, slot_tp_setattro); TPSLOT("__lt__", tp_richcompare, slot_tp_richcompare); From fdrake@users.sourceforge.net Sat Sep 22 05:28:21 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 21:28:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27436 Added Files: test_profilehooks.py Log Message: Start of a test to make sure the profiler/tracer support in the core interpreter is reporting what we expect to see. --- NEW FILE: test_profilehooks.py --- import pprint import sys import unittest import test_support class HookWatcher: def __init__(self): self.frames = [] self.events = [] def callback(self, frame, event, arg): self.add_event(event, frame) def add_event(self, event, frame=None): """Add an event to the log.""" if frame is None: frame = sys._getframe(1) try: frameno = self.frames.index(frame) except ValueError: frameno = len(self.frames) self.frames.append(frame) self.events.append((frameno, event, ident(frame))) def get_events(self): """Remove calls to add_event().""" add_event = self.add_event.im_func.func_code disallowed = (add_event.co_firstlineno, add_event.co_name) return [item for item in self.events if item[2] != disallowed] class ProfileHookTestCase(unittest.TestCase): def check_events(self, callable, expected): events = capture_events(callable) if events != expected: self.fail("Expected events:\n%s\nReceived events:\n%s" % (pprint.pformat(expected), pprint.pformat(events))) def test_simple(self): def f(p): pass f_ident = ident(f) self.check_events(f, [(0, 'call', f_ident), (0, 'return', f_ident), ]) def test_exception(self): def f(p): try: 1/0 except: pass f_ident = ident(f) self.check_events(f, [(0, 'call', f_ident), (0, 'exception', f_ident), (0, 'return', f_ident), ]) def test_nested_exception(self): def f(p): 1/0 def g(p): try: f(p) except: pass f_ident = ident(f) g_ident = ident(g) self.check_events(g, [(0, 'call', g_ident), (1, 'call', f_ident), (1, 'exception', f_ident), # This isn't what I expected: (0, 'exception', g_ident), (0, 'return', g_ident), ]) def ident(function): if hasattr(function, "f_code"): code = function.f_code else: code = function.func_code return code.co_firstlineno, code.co_name def capture_events(callable): p = HookWatcher() sys.setprofile(p.callback) callable(p) sys.setprofile(None) return p.get_events() def show_events(callable): import pprint pprint.pprint(capture_events(callable)) def test_main(): test_support.run_unittest(ProfileHookTestCase) if __name__ == "__main__": test_main() From bwarsaw@users.sourceforge.net Sat Sep 22 05:33:50 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 21 Sep 2001 21:33:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_StringIO,1.5,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv28269/Lib/test/output Removed Files: test_StringIO Log Message: Converted test_StringIO.py to use unittest, so Lib/test/output/test_StringIO is no longer necessary. Also, added a test of the iterator protocol that's just been added to StringIO's and cStringIO's. --- test_StringIO DELETED --- From bwarsaw@users.sourceforge.net Sat Sep 22 05:33:49 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 21 Sep 2001 21:33:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_StringIO.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv28269/Lib/test Modified Files: test_StringIO.py Log Message: Converted test_StringIO.py to use unittest, so Lib/test/output/test_StringIO is no longer necessary. Also, added a test of the iterator protocol that's just been added to StringIO's and cStringIO's. Index: test_StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_StringIO.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_StringIO.py 2001/02/09 23:44:22 1.6 --- test_StringIO.py 2001/09/22 04:33:47 1.7 *************** *** 1,43 **** # Tests StringIO and cStringIO ! def do_test(module): ! s = ("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"+'\n')*5 ! f = module.StringIO(s) ! print f.read(10) ! print f.readline() ! print len(f.readlines(60)) - f = module.StringIO() - f.write('abcdef') - f.seek(3) - f.write('uvwxyz') - f.write('!') - print `f.getvalue()` - f.close() ! f = module.StringIO() ! f.writelines(["a", "b", "c"]) ! f.seek(0) ! print `f.getvalue()` ! f.close() ! f = module.StringIO() ! f.write(s) ! f.seek(10) ! f.truncate() ! print `f.getvalue()` ! f.seek(0) ! f.truncate(5) ! print `f.getvalue()` ! f.close() ! try: ! f.write("frobnitz") ! except ValueError, e: ! print "Caught expected ValueError writing to closed StringIO:" ! print e ! else: ! print "Failed to catch ValueError writing to closed StringIO." ! import StringIO, cStringIO ! do_test(StringIO) ! do_test(cStringIO) --- 1,73 ---- # Tests StringIO and cStringIO ! import unittest ! import StringIO ! import cStringIO ! import types ! import test_support ! class TestGenericStringIO(unittest.TestCase): ! # use a class variable MODULE to define which module is being tested ! def setUp(self): ! self._line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ! self._lines = (self._line + '\n') * 5 ! self._fp = self.MODULE.StringIO(self._lines) ! def test_reads(self): ! eq = self.assertEqual ! eq(self._fp.read(10), 'abcdefghij') ! eq(self._fp.readline(), 'klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n') ! eq(len(self._fp.readlines(60)), 2) ! ! def test_writes(self): ! f = self.MODULE.StringIO() ! f.write('abcdef') ! f.seek(3) ! f.write('uvwxyz') ! f.write('!') ! self.assertEqual(f.getvalue(), 'abcuvwxyz!') ! ! def test_writelines(self): ! f = self.MODULE.StringIO() ! f.writelines(['a', 'b', 'c']) ! f.seek(0) ! self.assertEqual(f.getvalue(), 'abc') ! ! def test_truncate(self): ! eq = self.assertEqual ! f = self.MODULE.StringIO() ! f.write(self._lines) ! f.seek(10) ! f.truncate() ! eq(f.getvalue(), 'abcdefghij') ! f.seek(0) ! f.truncate(5) ! eq(f.getvalue(), 'abcde') ! f.close() ! self.assertRaises(ValueError, f.write, 'frobnitz') ! ! def test_iterator(self): ! eq = self.assertEqual ! it = iter(self._fp) ! self.failUnless(isinstance(it, types.FunctionIterType)) ! i = 0 ! for line in self._fp: ! eq(line, self._line + '\n') ! i += 1 ! eq(i, 5) ! ! class TestStringIO(TestGenericStringIO): ! MODULE = StringIO ! ! class TestcStringIO(TestGenericStringIO): ! MODULE = cStringIO ! ! ! def test_main(): ! test_support.run_unittest(TestStringIO) ! test_support.run_unittest(TestcStringIO) ! ! if __name__ == '__main__': ! test_main() From fdrake@users.sourceforge.net Sat Sep 22 05:34:50 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 21 Sep 2001 21:34:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv28468/lib Modified Files: libstdtypes.tex Log Message: Note that files are iterable; describe what the iterator returns. This closes SF bug #463738. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -d -r1.68 -r1.69 *** libstdtypes.tex 2001/08/28 14:56:05 1.68 --- libstdtypes.tex 2001/09/22 04:34:48 1.69 *************** *** 1320,1323 **** --- 1320,1328 ---- + Files support the iterator protocol. Each iteration returns the same + result as \code{\var{file}.readline()}, and iteration ends when the + \method{readline()} method returns an empty string. + + File objects also offer a number of other interesting attributes. These are not required for file-like objects, but should be From bwarsaw@users.sourceforge.net Sat Sep 22 05:34:56 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 21 Sep 2001 21:34:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib StringIO.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28518/Lib Modified Files: StringIO.py Log Message: __iter__(): New method so that StringIO's can participate in the iterator protocol. Index: StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/StringIO.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** StringIO.py 2001/02/09 13:37:37 1.17 --- StringIO.py 2001/09/22 04:34:54 1.18 *************** *** 46,49 **** --- 46,52 ---- self.softspace = 0 + def __iter__(self): + return iter(self.readline, '') + def close(self): if not self.closed: From bwarsaw@users.sourceforge.net Sat Sep 22 05:37:02 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 21 Sep 2001 21:37:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cStringIO.c,2.28,2.29 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv28966/Modules Modified Files: cStringIO.c Log Message: I_getiter(): Function for the tp_iter slot of Itype so that cStringIO's can participate in the iterator protocol. Fill the Itype.tp_iter slot with I_getiter() Index: cStringIO.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cStringIO.c,v retrieving revision 2.28 retrieving revision 2.29 diff -C2 -d -r2.28 -r2.29 *** cStringIO.c 2001/02/09 23:44:22 2.28 --- cStringIO.c 2001/09/22 04:36:49 2.29 *************** *** 654,657 **** --- 654,675 ---- } + static PyObject * + I_getiter(Iobject *self) + { + PyObject *myreadline = PyObject_GetAttrString((PyObject*)self, + "readline"); + PyObject *emptystring = PyString_FromString(""); + PyObject *iter = NULL; + if (!myreadline || !emptystring) + goto finally; + + iter = PyCallIter_New(myreadline, emptystring); + finally: + Py_XDECREF(myreadline); + Py_XDECREF(emptystring); + return iter; + } + + static char Itype__doc__[] = "Simple type for treating strings as input file streams" *************** *** 660,684 **** static PyTypeObject Itype = { PyObject_HEAD_INIT(NULL) ! 0, /*ob_size*/ ! "StringI", /*tp_name*/ ! sizeof(Iobject), /*tp_basicsize*/ ! 0, /*tp_itemsize*/ /* methods */ ! (destructor)I_dealloc, /*tp_dealloc*/ ! (printfunc)0, /*tp_print*/ ! (getattrfunc)I_getattr, /*tp_getattr*/ ! (setattrfunc)0, /*tp_setattr*/ ! (cmpfunc)0, /*tp_compare*/ ! (reprfunc)0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)0, /*tp_hash*/ ! (ternaryfunc)0, /*tp_call*/ ! (reprfunc)0, /*tp_str*/ ! ! /* Space for future expansion */ ! 0L,0L,0L,0L, ! Itype__doc__ /* Documentation string */ }; --- 678,709 ---- static PyTypeObject Itype = { PyObject_HEAD_INIT(NULL) ! 0, /*ob_size*/ ! "StringI", /*tp_name*/ ! sizeof(Iobject), /*tp_basicsize*/ ! 0, /*tp_itemsize*/ /* methods */ ! (destructor)I_dealloc, /*tp_dealloc*/ ! (printfunc)0, /*tp_print*/ ! (getattrfunc)I_getattr, /*tp_getattr*/ ! (setattrfunc)0, /*tp_setattr*/ ! (cmpfunc)0, /*tp_compare*/ ! (reprfunc)0, /*tp_repr*/ ! 0, /*tp_as_number*/ ! 0, /*tp_as_sequence*/ ! 0, /*tp_as_mapping*/ ! (hashfunc)0, /*tp_hash*/ ! (ternaryfunc)0, /*tp_call*/ ! (reprfunc)0, /*tp_str*/ ! 0, /* tp_getattro */ ! 0, /* tp_setattro */ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT, /* tp_flags */ ! Itype__doc__, /* tp_doc */ ! 0, /* tp_traverse */ ! 0, /* tp_clear */ ! 0, /* tp_richcompare */ ! 0, /* tp_weaklistoffset */ ! (getiterfunc)I_getiter, /* tp_iter */ ! 0, /* tp_iternext */ }; From bwarsaw@users.sourceforge.net Sat Sep 22 05:44:23 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 21 Sep 2001 21:44:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.248,1.249 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv30058 Modified Files: NEWS Log Message: {String,cString}IO.StringIO's support iteration. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.248 retrieving revision 1.249 diff -C2 -d -r1.248 -r1.249 *** NEWS 2001/09/20 12:59:37 1.248 --- NEWS 2001/09/22 04:44:21 1.249 *************** *** 46,49 **** --- 46,53 ---- Library + - StringIO.StringIO instances and cStringIO.StringIO instances support + iteration just like file objects (i.e. their .readline() method is + called for each iteration until it returns an empty string). + - The codecs module has grown four new helper APIs to access builtin codecs: getencoder(), getdecoder(), getreader(), From tim_one@users.sourceforge.net Sat Sep 22 06:31:05 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 21 Sep 2001 22:31:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.54,1.55 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv2728/python/Lib/test Modified Files: regrtest.py Log Message: Since the most likely failure mode for an expected-output test is a change somewhere inside a line, use ndiff so that intraline difference marking can point out what changed within a line. I don't remember diff-style abbreviations either (haven't used it since '94, except to produce patches), so say the rest in English too. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.54 retrieving revision 1.55 diff -C2 -d -r1.54 -r1.55 *** regrtest.py 2001/09/21 21:06:22 1.54 --- regrtest.py 2001/09/22 05:31:03 1.55 *************** *** 350,385 **** def reportdiff(expected, output): - print "*" * 70 import difflib ! a = expected.splitlines() ! b = output.splitlines() sm = difflib.SequenceMatcher(a=a, b=b) tuples = sm.get_opcodes() def pair(x0, x1): x0 += 1 if x0 >= x1: ! return str(x0) else: ! return "%d,%d" % (x0, x1) for op, a0, a1, b0, b1 in tuples: if op == 'equal': pass elif op == 'delete': ! print pair(a0, a1) + "d" + pair(b0, b1) for line in a[a0:a1]: ! print "<", line elif op == 'replace': ! print pair(a0, a1) + "c" + pair(b0, b1) ! for line in a[a0:a1]: ! print "<", line ! print "---" ! for line in b[b0:b1]: ! print ">", line elif op == 'insert': ! print str(a0) + "a" + pair(b0, b1) for line in b[b0:b1]: ! print ">", line else: print "get_opcodes() returned bad tuple?!?!", (op, a0, a1, b0, b1) print "*" * 70 --- 350,392 ---- def reportdiff(expected, output): import difflib ! print "*" * 70 ! a = expected.splitlines(1) ! b = output.splitlines(1) sm = difflib.SequenceMatcher(a=a, b=b) tuples = sm.get_opcodes() + def pair(x0, x1): + # x0:x1 are 0-based slice indices; convert to 1-based line indices. x0 += 1 if x0 >= x1: ! return "line " + str(x0) else: ! return "lines %d-%d" % (x0, x1) ! for op, a0, a1, b0, b1 in tuples: if op == 'equal': pass + elif op == 'delete': ! print "***", pair(a0, a1), "of expected output missing:" for line in a[a0:a1]: ! print "-", line, ! elif op == 'replace': ! print "*** mismatch between", pair(a0, a1), "of expected", \ ! "output and", pair(b0, b1), "of actual output:" ! for line in difflib.ndiff(a[a0:a1], b[b0:b1]): ! print line, ! elif op == 'insert': ! print "***", pair(b0, b1), "of actual output doesn't appear", \ ! "in expected output after line", str(a1)+":" for line in b[b0:b1]: ! print "+", line, ! else: print "get_opcodes() returned bad tuple?!?!", (op, a0, a1, b0, b1) + print "*" * 70 From tim_one@users.sourceforge.net Sat Sep 22 07:10:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 21 Sep 2001 23:10:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib inspect.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv8019/python/Lib Modified Files: inspect.py Log Message: Add a function to compute a class's method resolution order. This is easy for 2.2 new-style classes, but trickier for classic classes, and different approaches are needed "depending". The function will allow later code to treat all flavors of classes uniformly. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -d -r1.23 -r1.24 *** inspect.py 2001/09/20 05:47:55 1.23 --- inspect.py 2001/09/22 06:10:55 1.24 *************** *** 164,167 **** --- 164,185 ---- return results + # ----------------------------------------------------------- class helpers + def _searchbases(cls, accum): + # Simulate the "classic class" search order. + if cls in accum: + return + accum.append(cls) + for base in cls.__bases__: + _searchbases(base, accum) + + def getmro(cls): + "Return tuple of base classes (including cls) in method resolution order." + if hasattr(cls, "__mro__"): + return cls.__mro__ + else: + result = [] + _searchbases(cls, result) + return tuple(result) + # -------------------------------------------------- source code extraction def indentsize(line): From tim_one@users.sourceforge.net Sat Sep 22 07:10:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 21 Sep 2001 23:10:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libinspect.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8019/python/Doc/lib Modified Files: libinspect.tex Log Message: Add a function to compute a class's method resolution order. This is easy for 2.2 new-style classes, but trickier for classic classes, and different approaches are needed "depending". The function will allow later code to treat all flavors of classes uniformly. Index: libinspect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libinspect.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libinspect.tex 2001/08/10 17:37:33 1.4 --- libinspect.tex 2001/09/22 06:10:55 1.5 *************** *** 239,243 **** \begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults, argformat, varargsformat, varkwformat, defaultformat}} ! Format a pretty argument spec from the four values returned by \function{getargspec()}. The other four arguments are the --- 239,243 ---- \begin{funcdesc}{formatargspec}{args\optional{, varargs, varkw, defaults, argformat, varargsformat, varkwformat, defaultformat}} ! Format a pretty argument spec from the four values returned by \function{getargspec()}. The other four arguments are the *************** *** 252,255 **** --- 252,263 ---- corresponding optional formatting functions that are called to turn names and values into strings. + \end{funcdesc} + + \begin{funcdesc}{getmro}{cls} + Return a tuple of class cls's base classes, including cls, in + method resolution order. No class appears more than once in this tuple. + Note that the method resolution order depends on cls's type. Unless a + very peculiar user-defined metatype is in use, cls will be the first + element of the tuple. \end{funcdesc} From tim_one@users.sourceforge.net Sat Sep 22 07:10:57 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 21 Sep 2001 23:10:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_inspect.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv8019/python/Lib/test Modified Files: test_inspect.py Log Message: Add a function to compute a class's method resolution order. This is easy for 2.2 new-style classes, but trickier for classic classes, and different approaches are needed "depending". The function will allow later code to treat all flavors of classes uniformly. Index: test_inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_inspect.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_inspect.py 2001/03/23 05:14:10 1.4 --- test_inspect.py 2001/09/22 06:10:55 1.5 *************** *** 214,215 **** --- 214,235 ---- except: pass + + # Test classic-class method resolution order. + class A: pass + class B(A): pass + class C(A): pass + class D(B, C): pass + + expected = (D, B, A, C) + got = inspect.getmro(D) + test(expected == got, "expected %r mro, got %r", expected, got) + + # The same w/ new-class MRO. + class A(object): pass + class B(A): pass + class C(A): pass + class D(B, C): pass + + expected = (D, B, C, A, object) + got = inspect.getmro(D) + test(expected == got, "expected %r mro, got %r", expected, got) From gvanrossum@users.sourceforge.net Sat Sep 22 18:10:46 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 22 Sep 2001 10:10:46 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.249,1.250 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv13012 Modified Files: NEWS Log Message: Add note about __getattribute__. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.249 retrieving revision 1.250 diff -C2 -d -r1.249 -r1.250 *** NEWS 2001/09/22 04:44:21 1.249 --- NEWS 2001/09/22 17:10:44 1.250 *************** *** 20,23 **** --- 20,32 ---- file() is now the preferred way to open a file. + - In 2.2a3, *for new-style classes only*, __getattr__ was called for + every attribute access. This was confusing because it differed + significantly from the behavior of classic classes, where it was + only called for missing attributes. Now, __getattr__ is called only + if regular attribute access raises AttributeError; to catch *all* + attribute access, *for new-style classes only*, you can use + __getattribute__. If both are defined, __getattribute__ is called + first, and if it raises AttributeError, __getattr__ is called. + - In 2.2a3, __new__ would only see sequential arguments passed to the type in a constructor call; __init__ would see both sequential and From tim_one@users.sourceforge.net Sat Sep 22 22:30:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 14:30:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts ndiff.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv24440/python/Tools/scripts Modified Files: ndiff.py Log Message: Make difflib.ndiff() and difflib.Differ.compare() generators. This restores the 2.1 ability of Tools/scripts/ndiff.py to start producing output before the entire comparison is complete. Index: ndiff.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/ndiff.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** ndiff.py 2001/08/12 22:25:01 1.9 --- ndiff.py 2001/09/22 21:30:22 1.10 *************** *** 74,80 **** a = f1.readlines(); f1.close() b = f2.readlines(); f2.close() ! ! diff = difflib.ndiff(a, b) ! sys.stdout.writelines(diff) return 1 --- 74,79 ---- a = f1.readlines(); f1.close() b = f2.readlines(); f2.close() ! for line in difflib.ndiff(a, b): ! print line, return 1 From tim_one@users.sourceforge.net Sat Sep 22 22:30:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 14:30:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libdifflib.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24440/python/Doc/lib Modified Files: libdifflib.tex Log Message: Make difflib.ndiff() and difflib.Differ.compare() generators. This restores the 2.1 ability of Tools/scripts/ndiff.py to start producing output before the entire comparison is complete. Index: libdifflib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libdifflib.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** libdifflib.tex 2001/08/13 19:31:59 1.8 --- libdifflib.tex 2001/09/22 21:30:22 1.9 *************** *** 33,37 **** \begin{classdesc*}{Differ} This is a class for comparing sequences of lines of text, and ! producing human-readable differences or deltas. Differ uses \class{SequenceMatcher} both to compare sequences of lines, and to compare sequences of characters within similar (near-matching) --- 33,37 ---- \begin{classdesc*}{Differ} This is a class for comparing sequences of lines of text, and ! producing human-readable differences or deltas. Differ uses \class{SequenceMatcher} both to compare sequences of lines, and to compare sequences of characters within similar (near-matching) *************** *** 86,90 **** charjunk}}} Compare \var{a} and \var{b} (lists of strings); return a ! \class{Differ}-style delta. Optional keyword parameters \var{linejunk} and \var{charjunk} are --- 86,90 ---- charjunk}}} Compare \var{a} and \var{b} (lists of strings); return a ! \class{Differ}-style delta (a generator generating the delta lines). Optional keyword parameters \var{linejunk} and \var{charjunk} are *************** *** 110,119 **** >>> print ''.join(diff), - one ! ? ^ + ore ! ? ^ - two - three ! ? - + tree + emu --- 110,119 ---- >>> print ''.join(diff), - one ! ? ^ + ore ! ? ^ - two - three ! ? - + tree + emu *************** *** 133,136 **** --- 133,137 ---- >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = list(diff) # materialize the generated delta into a list >>> print ''.join(restore(diff, 1)), one *************** *** 227,231 **** \method{get_longest_match()} returns \code{(\var{i}, \var{j}, \var{k})} such that \code{\var{a}[\var{i}:\var{i}+\var{k}]} is equal ! to \code{\var{b}[\var{j}:\var{j}+\var{k}]}, where \code{\var{alo} <= \var{i} <= \var{i}+\var{k} <= \var{ahi}} and \code{\var{blo} <= \var{j} <= \var{j}+\var{k} <= \var{bhi}}. --- 228,232 ---- \method{get_longest_match()} returns \code{(\var{i}, \var{j}, \var{k})} such that \code{\var{a}[\var{i}:\var{i}+\var{k}]} is equal ! to \code{\var{b}[\var{j}:\var{j}+\var{k}]}, where \code{\var{alo} <= \var{i} <= \var{i}+\var{k} <= \var{ahi}} and \code{\var{blo} <= \var{j} <= \var{j}+\var{k} <= \var{bhi}}. *************** *** 304,308 **** this case.} \lineii{'insert'}{\code{\var{b}[\var{j1}:\var{j2}]} should be ! inserted at \code{\var{a}[\var{i1}:\var{i1}]}. Note that \code{\var{i1} == \var{i2}} in this case.} --- 305,309 ---- this case.} \lineii{'insert'}{\code{\var{b}[\var{j1}:\var{j2}]} should be ! inserted at \code{\var{a}[\var{i1}:\var{i1}]}. Note that \code{\var{i1} == \var{i2}} in this case.} *************** *** 460,470 **** \begin{methoddesc}{compare}{a, b} ! Compare two sequences of lines; return the resulting delta (list). Each sequence must contain individual single-line strings ending with newlines. Such sequences can be obtained from the ! \method{readlines()} method of file-like objects. The list returned ! is also made up of newline-terminated strings, and ready to be used ! with the \method{writelines()} method of a file-like object. \end{methoddesc} --- 461,472 ---- \begin{methoddesc}{compare}{a, b} ! Compare two sequences of lines, and generate the delta (a sequence ! of lines). Each sequence must contain individual single-line strings ending with newlines. Such sequences can be obtained from the ! \method{readlines()} method of file-like objects. The delta generated ! also consists of newline-terminated strings, ready to be printed as-is ! via the \method{writeline()} method of a file-like object. \end{methoddesc} *************** *** 507,511 **** \begin{verbatim} ! >>> result = d.compare(text1, text2) \end{verbatim} --- 509,513 ---- \begin{verbatim} ! >>> result = list(d.compare(text1, text2)) \end{verbatim} From tim_one@users.sourceforge.net Sat Sep 22 22:30:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 14:30:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib difflib.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24440/python/Lib Modified Files: difflib.py Log Message: Make difflib.ndiff() and difflib.Differ.compare() generators. This restores the 2.1 ability of Tools/scripts/ndiff.py to start producing output before the entire comparison is complete. Index: difflib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/difflib.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** difflib.py 2001/08/12 22:25:01 1.4 --- difflib.py 2001/09/22 21:30:22 1.5 *************** *** 1,4 **** --- 1,6 ---- #! /usr/bin/env python + from __future__ import generators + """ Module difflib -- helpers for computing deltas between objects. *************** *** 23,28 **** 'Differ'] - TRACE = 0 - class SequenceMatcher: --- 25,28 ---- *************** *** 407,413 **** bestsize = bestsize + 1 - if TRACE: - print "get_matching_blocks", alo, ahi, blo, bhi - print " returns", besti, bestj, bestsize return besti, bestj, bestsize --- 407,410 ---- *************** *** 433,438 **** self.__helper(0, la, 0, lb, self.matching_blocks) self.matching_blocks.append( (la, lb, 0) ) - if TRACE: - print '*** matching blocks', self.matching_blocks return self.matching_blocks --- 430,433 ---- *************** *** 695,699 **** Finally, we compare the two: ! >>> result = d.compare(text1, text2) 'result' is a list of strings, so let's pretty-print it: --- 690,694 ---- Finally, we compare the two: ! >>> result = list(d.compare(text1, text2)) 'result' is a list of strings, so let's pretty-print it: *************** *** 732,736 **** compare(a, b) ! Compare two sequences of lines; return the resulting delta (list). """ --- 727,731 ---- compare(a, b) ! Compare two sequences of lines; generate the resulting delta. """ *************** *** 754,767 **** self.linejunk = linejunk self.charjunk = charjunk - self.results = [] def compare(self, a, b): r""" ! Compare two sequences of lines; return the resulting delta (list). Each sequence must contain individual single-line strings ending with newlines. Such sequences can be obtained from the `readlines()` method ! of file-like objects. The list returned is also made up of ! newline-terminated strings, ready to be used with the `writelines()` method of a file-like object. --- 749,761 ---- self.linejunk = linejunk self.charjunk = charjunk def compare(self, a, b): r""" ! Compare two sequences of lines; generate the resulting delta. Each sequence must contain individual single-line strings ending with newlines. Such sequences can be obtained from the `readlines()` method ! of file-like objects. The delta generated also consists of newline- ! terminated strings, ready to be printed as-is via the writeline() method of a file-like object. *************** *** 784,804 **** for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): if tag == 'replace': ! self._fancy_replace(a, alo, ahi, b, blo, bhi) elif tag == 'delete': ! self._dump('-', a, alo, ahi) elif tag == 'insert': ! self._dump('+', b, blo, bhi) elif tag == 'equal': ! self._dump(' ', a, alo, ahi) else: raise ValueError, 'unknown tag ' + `tag` - results = self.results - self.results = [] - return results def _dump(self, tag, x, lo, hi): ! """Store comparison results for a same-tagged range.""" for i in xrange(lo, hi): ! self.results.append('%s %s' % (tag, x[i])) def _plain_replace(self, a, alo, ahi, b, blo, bhi): --- 778,798 ---- for tag, alo, ahi, blo, bhi in cruncher.get_opcodes(): if tag == 'replace': ! g = self._fancy_replace(a, alo, ahi, b, blo, bhi) elif tag == 'delete': ! g = self._dump('-', a, alo, ahi) elif tag == 'insert': ! g = self._dump('+', b, blo, bhi) elif tag == 'equal': ! g = self._dump(' ', a, alo, ahi) else: raise ValueError, 'unknown tag ' + `tag` + for line in g: + yield line + def _dump(self, tag, x, lo, hi): ! """Generate comparison results for a same-tagged range.""" for i in xrange(lo, hi): ! yield '%s %s' % (tag, x[i]) def _plain_replace(self, a, alo, ahi, b, blo, bhi): *************** *** 807,815 **** # memory if the blocks are of very different sizes if bhi - blo < ahi - alo: ! self._dump('+', b, blo, bhi) ! self._dump('-', a, alo, ahi) else: ! self._dump('-', a, alo, ahi) ! self._dump('+', b, blo, bhi) def _fancy_replace(self, a, alo, ahi, b, blo, bhi): --- 801,813 ---- # memory if the blocks are of very different sizes if bhi - blo < ahi - alo: ! first = self._dump('+', b, blo, bhi) ! second = self._dump('-', a, alo, ahi) else: ! first = self._dump('-', a, alo, ahi) ! second = self._dump('+', b, blo, bhi) ! ! for g in first, second: ! for line in g: ! yield line def _fancy_replace(self, a, alo, ahi, b, blo, bhi): *************** *** 831,840 **** """ - if TRACE: - self.results.append('*** _fancy_replace %s %s %s %s\n' - % (alo, ahi, blo, bhi)) - self._dump('>', a, alo, ahi) - self._dump('<', b, blo, bhi) - # don't synch up unless the lines have a similarity score of at # least cutoff; best_ratio tracks the best score seen so far --- 829,832 ---- *************** *** 870,874 **** if eqi is None: # no identical pair either -- treat it as a straight replace ! self._plain_replace(a, alo, ahi, b, blo, bhi) return # no close pair, but an identical pair -- synch up on that --- 862,867 ---- if eqi is None: # no identical pair either -- treat it as a straight replace ! for line in self._plain_replace(a, alo, ahi, b, blo, bhi): ! yield line return # no close pair, but an identical pair -- synch up on that *************** *** 880,891 **** # a[best_i] very similar to b[best_j]; eqi is None iff they're not # identical - if TRACE: - self.results.append('*** best_ratio %s %s %s %s\n' - % (best_ratio, best_i, best_j)) - self._dump('>', a, best_i, best_i+1) - self._dump('<', b, best_j, best_j+1) # pump out diffs from before the synch point ! self._fancy_helper(a, alo, best_i, b, blo, best_j) # do intraline marking on the synch pair --- 873,880 ---- # a[best_i] very similar to b[best_j]; eqi is None iff they're not # identical # pump out diffs from before the synch point ! for line in self._fancy_helper(a, alo, best_i, b, blo, best_j): ! yield line # do intraline marking on the synch pair *************** *** 909,929 **** else: raise ValueError, 'unknown tag ' + `tag` ! self._qformat(aelt, belt, atags, btags) else: # the synch pair is identical ! self.results.append(' ' + aelt) # pump out diffs from after the synch point ! self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi) def _fancy_helper(self, a, alo, ahi, b, blo, bhi): if alo < ahi: if blo < bhi: ! self._fancy_replace(a, alo, ahi, b, blo, bhi) else: ! self._dump('-', a, alo, ahi) elif blo < bhi: ! self._dump('+', b, blo, bhi) def _qformat(self, aline, bline, atags, btags): r""" --- 898,924 ---- else: raise ValueError, 'unknown tag ' + `tag` ! for line in self._qformat(aelt, belt, atags, btags): ! yield line else: # the synch pair is identical ! yield ' ' + aelt # pump out diffs from after the synch point ! for line in self._fancy_helper(a, best_i+1, ahi, b, best_j+1, bhi): ! yield line def _fancy_helper(self, a, alo, ahi, b, blo, bhi): + g = [] if alo < ahi: if blo < bhi: ! g = self._fancy_replace(a, alo, ahi, b, blo, bhi) else: ! g = self._dump('-', a, alo, ahi) elif blo < bhi: ! g = self._dump('+', b, blo, bhi) + for line in g: + yield line + def _qformat(self, aline, bline, atags, btags): r""" *************** *** 950,960 **** btags = btags[common:].rstrip() ! self.results.append("- " + aline) if atags: ! self.results.append("? %s%s\n" % ("\t" * common, atags)) ! self.results.append("+ " + bline) if btags: ! self.results.append("? %s%s\n" % ("\t" * common, btags)) # With respect to junk, an earlier version of ndiff simply refused to --- 945,955 ---- btags = btags[common:].rstrip() ! yield "- " + aline if atags: ! yield "? %s%s\n" % ("\t" * common, atags) ! yield "+ " + bline if btags: ! yield "? %s%s\n" % ("\t" * common, btags) # With respect to junk, an earlier version of ndiff simply refused to *************** *** 1051,1055 **** def restore(delta, which): r""" ! Return one of the two sequences that generated a delta. Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract --- 1046,1050 ---- def restore(delta, which): r""" ! Generate one of the two sequences that generated a delta. Given a `delta` produced by `Differ.compare()` or `ndiff()`, extract *************** *** 1061,1064 **** --- 1056,1060 ---- >>> diff = ndiff('one\ntwo\nthree\n'.splitlines(1), ... 'ore\ntree\nemu\n'.splitlines(1)) + >>> diff = list(diff) >>> print ''.join(restore(diff, 1)), one *************** *** 1076,1084 **** % which) prefixes = (" ", tag) - results = [] for line in delta: if line[:2] in prefixes: ! results.append(line[2:]) ! return results def _test(): --- 1072,1078 ---- % which) prefixes = (" ", tag) for line in delta: if line[:2] in prefixes: ! yield line[2:] def _test(): From tim_one@users.sourceforge.net Sat Sep 22 22:30:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 14:30:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.250,1.251 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv24440/python/Misc Modified Files: NEWS Log Message: Make difflib.ndiff() and difflib.Differ.compare() generators. This restores the 2.1 ability of Tools/scripts/ndiff.py to start producing output before the entire comparison is complete. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.250 retrieving revision 1.251 diff -C2 -d -r1.250 -r1.251 *** NEWS 2001/09/22 17:10:44 1.250 --- NEWS 2001/09/22 21:30:22 1.251 *************** *** 31,35 **** - In 2.2a3, __new__ would only see sequential arguments passed to the type in a constructor call; __init__ would see both sequential and ! positional arguments. This made no sense whatsoever any more, so now both __new__ and __init__ see all arguments. --- 31,35 ---- - In 2.2a3, __new__ would only see sequential arguments passed to the type in a constructor call; __init__ would see both sequential and ! keyword arguments. This made no sense whatsoever any more, so now both __new__ and __init__ see all arguments. *************** *** 55,58 **** --- 55,62 ---- Library + - difflib.ndiff() and difflib.Differ.compare() are generators now. This + restores the ability of Tools/scripts/ndiff.py to start producing output + before the entire comparison is complete. + - StringIO.StringIO instances and cStringIO.StringIO instances support iteration just like file objects (i.e. their .readline() method is *************** *** 125,132 **** Tests Windows - Large file support now also works for files > 4GB, on filesystems ! that support it (NTFS under Windows 2000). --- 129,151 ---- Tests + - The "classic" standard tests, which work by comparing stdout to + an expected-output file under Lib/test/output/, no longer stop at + the first mismatch. Instead the test is run to completion, and a + variant of ndiff-style comparison is used to report all differences. + This is much easier to understand than the previous style of reporting. + + - The unittest-based standard tests now use regrtest's test_main() + convention, instead of running as a side-effect of merely being + imported. This allows these tests to be run in more natural and + flexible ways as unittests, outside the regrtest framework. + + - regrtest.py is much better integrated with unittest and doctest now, + especially in regard to reporting errors. + Windows - Large file support now also works for files > 4GB, on filesystems ! that support it (NTFS under Windows 2000). See "What's New in ! Python 2.2a3" for more detail. From tim_one@users.sourceforge.net Sat Sep 22 22:59:20 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 14:59:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts ndiff.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv29071/python/Tools/scripts Modified Files: ndiff.py Log Message: Fix restore (difflib.restore() became a generator too). Index: ndiff.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/ndiff.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** ndiff.py 2001/09/22 21:30:22 1.10 --- ndiff.py 2001/09/22 21:59:18 1.11 *************** *** 119,123 **** def restore(which): restored = difflib.restore(sys.stdin.readlines(), which) ! sys.stdout.writelines(restored) if __name__ == '__main__': --- 119,124 ---- def restore(which): restored = difflib.restore(sys.stdin.readlines(), which) ! for line in restored: ! print line, if __name__ == '__main__': From tim_one@users.sourceforge.net Sun Sep 23 03:00:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 19:00:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib inspect.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2693/python/Lib Modified Files: inspect.py Log Message: New function classify_class_attrs(). As a number of SF bug reports point out, pydoc doesn't tell you where class attributes were defined, gets several new 2.2 features wrong, and isn't aware of some new features checked in on Thursday . pydoc is hampered in part because inspect.py has the same limitations. Alas, I can't think of a way to fix this within the current architecture of inspect/pydoc: it's simply not possible in 2.2 to figure out everything needed just from examining the object you get back from class.attr. You also need the class context, and the method resolution order, and tests against various things that simply didn't exist before. OTOH, knowledge of how to do that is getting quite complex, so doesn't belong in pydoc. classify_class_attrs takes a different approach, analyzing all the class attrs "at once", and returning the most interesting stuff for each, all in one gulp. pydoc needs to be reworked to use this for classes (instead of the current "filter dir(class) umpteen times against assorted predicates" approach). Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/inspect.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** inspect.py 2001/09/22 06:10:55 1.24 --- inspect.py 2001/09/23 02:00:29 1.25 *************** *** 164,167 **** --- 164,252 ---- return results + def classify_class_attrs(cls): + """Return list of attribute-descriptor tuples. + + For each name in dir(cls), the return list contains a 4-tuple + with these elements: + + 0. The name (a string). + + 1. The kind of attribute this is, one of these strings: + 'class method' created via classmethod() + 'static method' created via staticmethod() + 'property' created via property() + 'method' any other flavor of method + 'data' not a method + + 2. The class which defined this attribute (a class). + + 3. The object as obtained directly from the defining class's + __dict__, not via getattr. This is especially important for + data attributes: C.data is just a data object, but + C.__dict__['data'] may be a data descriptor with additional + info, like a __doc__ string. + """ + + mro = getmro(cls) + names = dir(cls) + result = [] + for name in names: + # Get the object associated with the name. + # Getting an obj from the __dict__ sometimes reveals more than + # using getattr. Static and class methods are dramatic examples. + if name in cls.__dict__: + obj = cls.__dict__[name] + else: + obj = getattr(cls, name) + + # Figure out where it was defined. + # A complication: static classes in 2.2 copy dict entries from + # bases into derived classes, so it's not enough just to look for + # "the first" class with the name in its dict. OTOH: + # 1. Some-- but not all --methods in 2.2 come with an __objclass__ + # attr that answers the question directly. + # 2. Some-- but not all --classes in 2.2 have a __defined__ dict + # saying which names were defined by the class. + homecls = getattr(obj, "__objclass__", None) + if homecls is None: + # Try __defined__. + for base in mro: + if hasattr(base, "__defined__"): + if name in base.__defined__: + homecls = base + break + if homecls is None: + # Last chance (and first chance for classic classes): search + # the dicts. + for base in mro: + if name in base.__dict__: + homecls = base + break + + # Get the object again, in order to get it from the defining + # __dict__ instead of via getattr (if possible). + if homecls is not None and name in homecls.__dict__: + obj = homecls.__dict__[name] + + # Also get the object via getattr. + obj_via_getattr = getattr(cls, name) + + # Classify the object. + if isinstance(obj, staticmethod): + kind = "static method" + elif isinstance(obj, classmethod): + kind = "class method" + elif isinstance(obj, property): + kind = "property" + elif (ismethod(obj_via_getattr) or + ismethoddescriptor(obj_via_getattr)): + kind = "method" + else: + kind = "data" + + result.append((name, kind, homecls, obj)) + + return result + # ----------------------------------------------------------- class helpers def _searchbases(cls, accum): From tim_one@users.sourceforge.net Sun Sep 23 03:00:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 19:00:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_inspect.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv2693/python/Lib/test Modified Files: test_inspect.py Log Message: New function classify_class_attrs(). As a number of SF bug reports point out, pydoc doesn't tell you where class attributes were defined, gets several new 2.2 features wrong, and isn't aware of some new features checked in on Thursday . pydoc is hampered in part because inspect.py has the same limitations. Alas, I can't think of a way to fix this within the current architecture of inspect/pydoc: it's simply not possible in 2.2 to figure out everything needed just from examining the object you get back from class.attr. You also need the class context, and the method resolution order, and tests against various things that simply didn't exist before. OTOH, knowledge of how to do that is getting quite complex, so doesn't belong in pydoc. classify_class_attrs takes a different approach, analyzing all the class attrs "at once", and returning the most interesting stuff for each, all in one gulp. pydoc needs to be reworked to use this for classes (instead of the current "filter dir(class) umpteen times against assorted predicates" approach). Index: test_inspect.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_inspect.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_inspect.py 2001/09/22 06:10:55 1.5 --- test_inspect.py 2001/09/23 02:00:29 1.6 *************** *** 234,235 **** --- 234,436 ---- got = inspect.getmro(D) test(expected == got, "expected %r mro, got %r", expected, got) + + # Test classify_class_attrs. + def attrs_wo_objs(cls): + return [t[:3] for t in inspect.classify_class_attrs(cls)] + + class A: + def s(): pass + s = staticmethod(s) + + def c(cls): pass + c = classmethod(c) + + def getp(self): pass + p = property(getp) + + def m(self): pass + + def m1(self): pass + + datablob = '1' + + attrs = attrs_wo_objs(A) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', A) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class B(A): + def m(self): pass + + attrs = attrs_wo_objs(B) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + + class C(A): + def m(self): pass + def c(self): pass + + attrs = attrs_wo_objs(C) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'method', C) in attrs, 'missing plain method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', C) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class D(B, C): + def m1(self): pass + + attrs = attrs_wo_objs(D) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', D) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + # Repeat all that, but w/ new-style non-dynamic classes. + + class A(object): + __dynamic__ = 0 + + def s(): pass + s = staticmethod(s) + + def c(cls): pass + c = classmethod(c) + + def getp(self): pass + p = property(getp) + + def m(self): pass + + def m1(self): pass + + datablob = '1' + + attrs = attrs_wo_objs(A) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', A) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class B(A): + __dynamic__ = 0 + + def m(self): pass + + attrs = attrs_wo_objs(B) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + + class C(A): + __dynamic__ = 0 + + def m(self): pass + def c(self): pass + + attrs = attrs_wo_objs(C) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'method', C) in attrs, 'missing plain method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', C) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class D(B, C): + __dynamic__ = 0 + + def m1(self): pass + + attrs = attrs_wo_objs(D) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'method', C) in attrs, 'missing plain method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', D) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + # And again, but w/ new-style dynamic classes. + + class A(object): + __dynamic__ = 1 + + def s(): pass + s = staticmethod(s) + + def c(cls): pass + c = classmethod(c) + + def getp(self): pass + p = property(getp) + + def m(self): pass + + def m1(self): pass + + datablob = '1' + + attrs = attrs_wo_objs(A) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', A) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class B(A): + __dynamic__ = 1 + + def m(self): pass + + attrs = attrs_wo_objs(B) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'class method', A) in attrs, 'missing class method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + + class C(A): + __dynamic__ = 1 + + def m(self): pass + def c(self): pass + + attrs = attrs_wo_objs(C) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'method', C) in attrs, 'missing plain method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', C) in attrs, 'missing plain method') + test(('m1', 'method', A) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') + + class D(B, C): + __dynamic__ = 1 + + def m1(self): pass + + attrs = attrs_wo_objs(D) + test(('s', 'static method', A) in attrs, 'missing static method') + test(('c', 'method', C) in attrs, 'missing plain method') + test(('p', 'property', A) in attrs, 'missing property') + test(('m', 'method', B) in attrs, 'missing plain method') + test(('m1', 'method', D) in attrs, 'missing plain method') + test(('datablob', 'data', A) in attrs, 'missing data') From fdrake@users.sourceforge.net Sun Sep 23 03:05:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 22 Sep 2001 19:05:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.148,1.149 refcounts.dat,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv4691 Modified Files: api.tex refcounts.dat Log Message: Added API information for the PyCallIter_*() and PySeqIter_*() functions. Added signatures for some new PyType_*() functions. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.148 retrieving revision 1.149 diff -C2 -d -r1.148 -r1.149 *** api.tex 2001/09/20 19:18:52 1.148 --- api.tex 2001/09/23 02:05:26 1.149 *************** *** 2338,2342 **** --- 2338,2354 ---- \end{cfuncdesc} + \begin{cfuncdesc}{int}{PyType_IsSubtype}{PyTypeObject *a, PyTypeObject *b} + Returns true if \var{a} is a subtype of \var{b}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyType_GenericAlloc}{PyTypeObject *type, + int nitems} + \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyType_GenericNew}{PyTypeObject *type, + PyObject *args, PyObject *kwds} + \end{cfuncdesc} + + \subsection{The None Object \label{noneObject}} *************** *** 4357,4365 **** \subsection{CObjects \label{cObjects}} \obindex{CObject} Refer to \emph{Extending and Embedding the Python Interpreter}, ! section 1.12 (``Providing a C API for an Extension Module''), for more information on using these objects. --- 4369,4423 ---- + \subsection{Iterator Objects \label{iterator-objects}} + + Python provides two general-purpose iterator objects. The first, a + sequence iterator, works with an arbitrary sequence supporting the + \method{__getitem__()} method. The second works with a callable + object and a sentinel value, calling the callable for each item in the + sequence, and ending the iteration when the sentinel value is + returned. + + \begin{cvardesc}{PyTypeObject}{PySeqIter_Type} + Type object for iterator objects returned by + \cfunction{PySeqIter_New()} and the one-argument form of the + \function{iter()} built-in function for built-in sequence types. + \end{cvardesc} + + \begin{cfuncdesc}{int}{PySeqIter_Check}{op} + Return true if the type of \var{op} is \cdata{PySeqIter_Type}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PySeqIter_New}{PyObject *seq} + Return an iterator that works with a general sequence object, + \var{seq}. The iteration ends when the sequence raises + \exception{IndexError} for the subscripting operation. + \end{cfuncdesc} + + + \begin{cvardesc}{PyTypeObject}{PyCallIter_Type} + Type object for iterator objects returned by + \cfunction{PyCallIter_New()} and the two-argument form of the + \function{iter()} built-in function. + \end{cvardesc} + + \begin{cfuncdesc}{int}{PyCallIter_Check}{op} + Return true if the type of \var{op} is \cdata{PyCallIter_Type}. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyCallIter_New}{PyObject *callable, + PyObject *sentinel} + Return a new iterator. The first parameter, \var{callable}, can be + any Python callable object that can be called with no parameters; + each call to it should return the next item in the iteration. When + \var{callable} returns a value equal to \var{sentinel}, the + iteration will be terminated. + \end{cfuncdesc} + + \subsection{CObjects \label{cObjects}} \obindex{CObject} Refer to \emph{Extending and Embedding the Python Interpreter}, ! section 1.12 (``Providing a C API for an Extension Module), for more information on using these objects. Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** refcounts.dat 2001/09/20 19:18:52 1.31 --- refcounts.dat 2001/09/23 02:05:26 1.32 *************** *** 68,71 **** --- 68,75 ---- PyCObject_GetDesc:PyObject*:self:0: + PyCallIter_New:PyObject*::+1: + PyCallIter_New:PyObject*:callable:: + PyCallIter_New:PyObject*:sentinel:: + PyCallable_Check:int::: PyCallable_Check:PyObject*:o:0: *************** *** 845,848 **** --- 849,855 ---- PyRun_String:PyObject*:globals:0: PyRun_String:PyObject*:locals:0: + + PySeqIter_New:PyObject*::+1: + PySeqIter_New:PyObject*:seq:: PySequence_Check:int::: From bwarsaw@users.sourceforge.net Sun Sep 23 04:04:32 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sat, 22 Sep 2001 20:04:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv11210/email Log Message: Directory /cvsroot/python/python/dist/src/Lib/email added to the repository From bwarsaw@users.sourceforge.net Sun Sep 23 04:17:30 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sat, 22 Sep 2001 20:17:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Encoders.py,NONE,1.1 Errors.py,NONE,1.1 Generator.py,NONE,1.1 Image.py,NONE,1.1 Iterators.py,NONE,1.1 MIMEBase.py,NONE,1.1 Message.py,NONE,1.1 MessageRFC822.py,NONE,1.1 Parser.py,NONE,1.1 Text.py,NONE,1.1 Utils.py,NONE,1.1 __init__.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv12848 Added Files: Encoders.py Errors.py Generator.py Image.py Iterators.py MIMEBase.py Message.py MessageRFC822.py Parser.py Text.py Utils.py __init__.py Log Message: The email package version 1.0, prototyped as mimelib . There /are/ API differences between mimelib and email, but most of the implementations are shared (except where cool Py2.2 stuff like generators are used). --- NEW FILE: Encoders.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Module containing encoding functions for Image.Image and Text.Text. """ import base64 from quopri import encodestring as _encodestring # Helpers def _qencode(s): return _encodestring(s, quotetabs=1) def _bencode(s): # We can't quite use base64.encodestring() since it tacks on a "courtesy # newline". Blech! if not s: return s hasnewline = (s[-1] == '\n') value = base64.encodestring(s) if not hasnewline and value[-1] == '\n': return value[:-1] return value def encode_base64(msg): """Encode the message's payload in Base64. Also, add an appropriate Content-Transfer-Encoding: header. """ orig = msg.get_payload() encdata = _bencode(orig) msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'base64' def encode_quopri(msg): """Encode the message's payload in Quoted-Printable. Also, add an appropriate Content-Transfer-Encoding: header. """ orig = msg.get_payload() encdata = _qencode(orig) msg.set_payload(encdata) msg['Content-Transfer-Encoding'] = 'quoted-printable' def encode_7or8bit(msg): """Set the Content-Transfer-Encoding: header to 7bit or 8bit.""" orig = msg.get_payload() # We play a trick to make this go fast. If encoding to ASCII succeeds, we # know the data must be 7bit, otherwise treat it as 8bit. try: orig.encode('ascii') except UnicodeError: msg['Content-Transfer-Encoding'] = '8bit' else: msg['Content-Transfer-Encoding'] = '7bit' def encode_noop(msg): """Do nothing.""" --- NEW FILE: Errors.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """email package exception classes. """ class MessageError(Exception): """Base class for errors in this module.""" class MessageParseError(MessageError): """Base class for message parsing errors.""" class HeaderParseError(MessageParseError): """Error while parsing headers.""" class BoundaryError(MessageParseError): """Couldn't find terminating boundary.""" class MultipartConversionError(MessageError, TypeError): """Conversion to a multipart is prohibited.""" --- NEW FILE: Generator.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Classes to generate plain text from a message object tree. """ import time import re import random from types import ListType, StringType from cStringIO import StringIO # Intrapackage imports import Message import Errors SEMISPACE = '; ' BAR = '|' UNDERSCORE = '_' NL = '\n' SEMINLTAB = ';\n\t' SPACE8 = ' ' * 8 fcre = re.compile(r'^From ', re.MULTILINE) class Generator: """Generates output from a Message object tree. This basic generator writes the message to the given file object as plain text. """ # # Public interface # def __init__(self, outfp, mangle_from_=1, maxheaderlen=78): """Create the generator for message flattening. outfp is the output file-like object for writing the message to. It must have a write() method. Optional mangle_from_ is a flag that, when true, escapes From_ lines in the body of the message by putting a `>' in front of them. Optional maxheaderlen specifies the longest length for a non-continued header. When a header line is longer (in characters, with tabs expanded to 8 spaces), than maxheaderlen, the header will be broken on semicolons and continued as per RFC 2822. If no semicolon is found, then the header is left alone. Set to zero to disable wrapping headers. Default is 78, as recommended (but not required by RFC 2822. """ self._fp = outfp self._mangle_from_ = mangle_from_ self.__first = 1 self.__maxheaderlen = maxheaderlen def write(self, s): # Just delegate to the file object self._fp.write(s) def __call__(self, msg, unixfrom=0): """Print the message object tree rooted at msg to the output file specified when the Generator instance was created. unixfrom is a flag that forces the printing of a Unix From_ delimiter before the first object in the message tree. If the original message has no From_ delimiter, a `standard' one is crafted. By default, this is 0 to inhibit the printing of any From_ delimiter. Note that for subobjects, no From_ line is printed. """ if unixfrom: ufrom = msg.get_unixfrom() if not ufrom: ufrom = 'From nobody ' + time.ctime(time.time()) print >> self._fp, ufrom self._write(msg) # # Protected interface - undocumented ;/ # def _write(self, msg): # We can't write the headers yet because of the following scenario: # say a multipart message includes the boundary string somewhere in # its body. We'd have to calculate the new boundary /before/ we write # the headers so that we can write the correct Content-Type: # parameter. # # The way we do this, so as to make the _handle_*() methods simpler, # is to cache any subpart writes into a StringIO. The we write the # headers and the StringIO contents. That way, subpart handlers can # Do The Right Thing, and can still modify the Content-Type: header if # necessary. oldfp = self._fp try: self._fp = sfp = StringIO() self._dispatch(msg) finally: self._fp = oldfp # Write the headers. First we see if the message object wants to # handle that itself. If not, we'll do it generically. meth = getattr(msg, '_write_headers', None) if meth is None: self._write_headers(msg) else: meth(self) self._fp.write(sfp.getvalue()) def _dispatch(self, msg): # Get the Content-Type: for the message, then try to dispatch to # self._handle_maintype_subtype(). If there's no handler for the full # MIME type, then dispatch to self._handle_maintype(). If that's # missing too, then dispatch to self._writeBody(). ctype = msg.get_type() if ctype is None: # No Content-Type: header so try the default handler self._writeBody(msg) else: # We do have a Content-Type: header. specific = UNDERSCORE.join(ctype.split('/')).replace('-', '_') meth = getattr(self, '_handle_' + specific, None) if meth is None: generic = msg.get_main_type().replace('-', '_') meth = getattr(self, '_handle_' + generic, None) if meth is None: meth = self._writeBody meth(msg) # # Default handlers # def _write_headers(self, msg): for h, v in msg.items(): # We only write the MIME-Version: header for the outermost # container message. Unfortunately, we can't use same technique # as for the Unix-From above because we don't know when # MIME-Version: will occur. if h.lower() == 'mime-version' and not self.__first: continue # RFC 2822 says that lines SHOULD be no more than maxheaderlen # characters wide, so we're well within our rights to split long # headers. text = '%s: %s' % (h, v) if self.__maxheaderlen > 0 and len(text) > self.__maxheaderlen: text = self._split_header(text) print >> self._fp, text # A blank line always separates headers from body print >> self._fp def _split_header(self, text): maxheaderlen = self.__maxheaderlen # Find out whether any lines in the header are really longer than # maxheaderlen characters wide. There could be continuation lines # that actually shorten it. Also, replace hard tabs with 8 spaces. lines = [s.replace('\t', SPACE8) for s in text.split('\n')] for line in lines: if len(line) > maxheaderlen: break else: # No line was actually longer than maxheaderlen characters, so # just return the original unchanged. return text rtn = [] for line in text.split('\n'): # Short lines can remain unchanged if len(line.replace('\t', SPACE8)) <= maxheaderlen: rtn.append(line) else: # Try to break the line on semicolons, but if that doesn't # work, then just leave it alone. while len(text) > maxheaderlen: i = text.rfind(';', 0, maxheaderlen) if i < 0: rtn.append(text) break rtn.append(text[:i]) text = text[i+1:].lstrip() rtn.append(text) return SEMINLTAB.join(rtn) # # Handlers for writing types and subtypes # def _handle_text(self, msg): payload = msg.get_payload() if not isinstance(payload, StringType): raise TypeError, 'string payload expected' if self._mangle_from_: payload = fcre.sub('>From ', payload) self._fp.write(payload) # Default body handler _writeBody = _handle_text def _handle_multipart(self, msg, isdigest=0): # The trick here is to write out each part separately, merge them all # together, and then make sure that the boundary we've chosen isn't # present in the payload. msgtexts = [] for part in msg.get_payload(): s = StringIO() g = self.__class__(s) g(part, unixfrom=0) msgtexts.append(s.getvalue()) # Now make sure the boundary we've selected doesn't appear in any of # the message texts. alltext = NL.join(msgtexts) # BAW: What about boundaries that are wrapped in double-quotes? boundary = msg.get_boundary(failobj=_make_boundary(alltext)) # If we had to calculate a new boundary because the body text # contained that string, set the new boundary. We don't do it # unconditionally because, while set_boundary() preserves order, it # doesn't preserve newlines/continuations in headers. This is no big # deal in practice, but turns out to be inconvenient for the unittest # suite. if msg.get_boundary() <> boundary: msg.set_boundary(boundary) # Write out any preamble if msg.preamble is not None: self._fp.write(msg.preamble) # First boundary is a bit different; it doesn't have a leading extra # newline. print >> self._fp, '--' + boundary if isdigest: print >> self._fp # Join and write the individual parts joiner = '\n--' + boundary + '\n' if isdigest: # multipart/digest types effectively add an extra newline between # the boundary and the body part. joiner += '\n' self._fp.write(joiner.join(msgtexts)) print >> self._fp, '\n--' + boundary + '--', # Write out any epilogue if msg.epilogue is not None: self._fp.write(msg.epilogue) def _handle_multipart_digest(self, msg): self._handle_multipart(msg, isdigest=1) def _handle_message_rfc822(self, msg): s = StringIO() g = self.__class__(s) # A message/rfc822 should contain a scalar payload which is another # Message object. Extract that object, stringify it, and write that # out. g(msg.get_payload(), unixfrom=0) self._fp.write(s.getvalue()) class DecodedGenerator(Generator): """Generator a text representation of a message. Like the Generator base class, except that non-text parts are substituted with a format string representing the part. """ def __init__(self, outfp, mangle_from_=1, maxheaderlen=78, fmt=None): """Like Generator.__init__() except that an additional optional argument is allowed. Walks through all subparts of a message. If the subpart is of main type `text', then it prints the decoded payload of the subpart. Otherwise, fmt is a format string that is used instead of the message payload. fmt is expanded with the following keywords (in %(keyword)s format): type : Full MIME type of the non-text part maintype : Main MIME type of the non-text part subtype : Sub-MIME type of the non-text part filename : Filename of the non-text part description: Description associated with the non-text part encoding : Content transfer encoding of the non-text part The default value for fmt is None, meaning [Non-text (%(type)s) part of message omitted, filename %(filename)s] """ Generator.__init__(self, outfp, mangle_from_, maxheaderlen) if fmt is None: fmt = ('[Non-text (%(type)s) part of message omitted, ' 'filename %(filename)s]') self._fmt = fmt def _dispatch(self, msg): for part in msg.walk(): if part.get_main_type('text') == 'text': print >> self, part.get_payload(decode=1) else: print >> self, self._fmt % { 'type' : part.get_type('[no MIME type]'), 'maintype' : part.get_main_type('[no main MIME type]'), 'subtype' : part.get_subtype('[no sub-MIME type]'), 'filename' : part.get_filename('[no filename]'), 'description': part.get('Content-Description', '[no description]'), 'encoding' : part.get('Content-Transfer-Encoding', '[no encoding]'), } # Helper def _make_boundary(self, text=None): # Craft a random boundary. If text is given, ensure that the chosen # boundary doesn't appear in the text. boundary = ('=' * 15) + repr(random.random()).split('.')[1] + '==' if text is None: return boundary b = boundary counter = 0 while 1: cre = re.compile('^--' + re.escape(b) + '(--)?$', re.MULTILINE) if not cre.search(text): break b = boundary + '.' + str(counter) counter += 1 return b --- NEW FILE: Image.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class representing image/* type MIME documents. """ import imghdr # Intrapackage imports import MIMEBase import Errors import Encoders class Image(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" def __init__(self, _imagedata, _minor=None, _encoder=Encoders.encode_base64, **_params): """Create an image/* type MIME document. _imagedata is a string containing the raw image data. If this data can be decoded by the standard Python `imghdr' module, then the subtype will be automatically included in the Content-Type: header. Otherwise, you can specify the specific image subtype via the _minor parameter. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this Image instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding: or other headers to the message as necessary. The default encoding is Base64. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type: header. """ if _minor is None: _minor = imghdr.what(None, _imagedata) if _minor is None: raise TypeError, 'Could not guess image _minor type' MIMEBase.MIMEBase.__init__(self, 'image', _minor, **_params) self.set_payload(_imagedata) _encoder(self) --- NEW FILE: Iterators.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Various types of useful iterators and generators. """ from __future__ import generators from cStringIO import StringIO from types import StringType def body_line_iterator(msg): """Iterator over the parts, returning the lines in a string payload.""" for subpart in msg.walk(): payload = subpart.get_payload() if type(payload) is StringType: for line in StringIO(payload): yield line def typed_subpart_iterator(msg, major='text', minor=None): """Iterator over the subparts with a given MIME type. Use `major' as the main MIME type to match against; this defaults to "text". Optional `minor' is the MIME subtype to match against; if omitted, only the main type is matched. """ for subpart in msg.walk(): if subpart.get_main_type() == major: if minor is None or subpart.get_subtype() == minor: yield subpart --- NEW FILE: MIMEBase.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Base class for MIME specializations. """ import Message class MIMEBase(Message.Message): """Base class for MIME specializations.""" def __init__(self, _major, _minor, **_params): """This constructor adds a Content-Type: and a MIME-Version: header. The Content-Type: header is taken from the _major and _minor arguments. Additional parameters for this header are taken from the keyword arguments. """ Message.Message.__init__(self) ctype = '%s/%s' % (_major, _minor) self.add_header('Content-Type', ctype, **_params) self['MIME-Version'] = '1.0' --- NEW FILE: Message.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Basic message object for the email package object model. """ from __future__ import generators import re import base64 import quopri from cStringIO import StringIO from types import ListType SEMISPACE = '; ' # Intrapackage imports import Errors import Utils class Message: """Basic message object for use inside the object tree. A message object is defined as something that has a bunch of RFC 2822 headers and a payload. If the body of the message is a multipart, then the payload is a list of Messages, otherwise it is a string. These objects implement part of the `mapping' interface, which assumes there is exactly one occurrance of the header per message. Some headers do in fact appear multiple times (e.g. Received:) and for those headers, you must use the explicit API to set or get all the headers. Not all of the mapping methods are implemented. """ def __init__(self): self._headers = [] self._unixfrom = None self._payload = None # Defaults for multipart messages self.preamble = self.epilogue = None def __str__(self): """Return the entire formatted message as a string. This includes the headers, body, and `unixfrom' line. """ return self.as_string(unixfrom=1) def as_string(self, unixfrom=0): """Return the entire formatted message as a string. Optional `unixfrom' when true, means include the Unix From_ envelope header. """ from Generator import Generator fp = StringIO() g = Generator(fp) g(self, unixfrom=unixfrom) return fp.getvalue() def is_multipart(self): """Return true if the message consists of multiple parts.""" if type(self._payload) is ListType: return 1 return 0 # # Unix From_ line # def set_unixfrom(self, unixfrom): self._unixfrom = unixfrom def get_unixfrom(self): return self._unixfrom # # Payload manipulation. # def add_payload(self, payload): """Add the given payload to the current payload. If the current payload is empty, then the current payload will be made a scalar, set to the given value. """ if self._payload is None: self._payload = payload elif type(self._payload) is ListType: self._payload.append(payload) elif self.get_main_type() not in (None, 'multipart'): raise Errors.MultipartConversionError( 'Message main Content-Type: must be "multipart" or missing') else: self._payload = [self._payload, payload] # A useful synonym attach = add_payload def get_payload(self, i=None, decode=0): """Return the current payload exactly as is. Optional i returns that index into the payload. Optional decode is a flag indicating whether the payload should be decoded or not, according to the Content-Transfer-Encoding: header. When true and the message is not a multipart, the payload will be decoded if this header's value is `quoted-printable' or `base64'. If some other encoding is used, or the header is missing, the payload is returned as-is (undecoded). If the message is a multipart and the decode flag is true, then None is returned. """ if i is None: payload = self._payload elif type(self._payload) is not ListType: raise TypeError, i else: payload = self._payload[i] if decode: if self.is_multipart(): return None cte = self.get('content-transfer-encoding', '') if cte.lower() == 'quoted-printable': return Utils._qdecode(payload) elif cte.lower() == 'base64': return Utils._bdecode(payload) # Everything else, including encodings with 8bit or 7bit are returned # unchanged. return payload def set_payload(self, payload): """Set the payload to the given value.""" self._payload = payload # # MAPPING INTERFACE (partial) # def __len__(self): """Get the total number of headers, including duplicates.""" return len(self._headers) def __getitem__(self, name): """Get a header value. Return None if the header is missing instead of raising an exception. Note that if the header appeared multiple times, exactly which occurrance gets returned is undefined. Use getall() to get all the values matching a header field name. """ return self.get(name) def __setitem__(self, name, val): """Set the value of a header. Note: this does not overwrite an existing header with the same field name. Use __delitem__() first to delete any existing headers. """ self._headers.append((name, val)) def __delitem__(self, name): """Delete all occurrences of a header, if present. Does not raise an exception if the header is missing. """ name = name.lower() newheaders = [] for k, v in self._headers: if k.lower() <> name: newheaders.append((k, v)) self._headers = newheaders def __contains__(self, key): return key.lower() in [k.lower() for k, v in self._headers] def has_key(self, name): """Return true if the message contains the header.""" return self[name] <> None def keys(self): """Return a list of all the message's header field names. These will be sorted in the order they appeared in the original message, and may contain duplicates. Any fields deleted and re-inserted are always appended to the header list. """ return [k for k, v in self._headers] def values(self): """Return a list of all the message's header values. These will be sorted in the order they appeared in the original message, and may contain duplicates. Any fields deleted and re-inserted are alwyas appended to the header list. """ return [v for k, v in self._headers] def items(self): """Get all the message's header fields and values. These will be sorted in the order they appeared in the original message, and may contain duplicates. Any fields deleted and re-inserted are alwyas appended to the header list. """ return self._headers[:] def get(self, name, failobj=None): """Get a header value. Like __getitem__() but return failobj instead of None when the field is missing. """ name = name.lower() for k, v in self._headers: if k.lower() == name: return v return failobj # # Additional useful stuff # def get_all(self, name, failobj=None): """Return a list of all the values for the named field. These will be sorted in the order they appeared in the original message, and may contain duplicates. Any fields deleted and re-inserted are alwyas appended to the header list. """ values = [] name = name.lower() for k, v in self._headers: if k.lower() == name: values.append(v) return values def add_header(self, _name, _value, **_params): """Extended header setting. name is the header field to add. keyword arguments can be used to set additional parameters for the header field, with underscores converted to dashes. Normally the parameter will be added as key="value" unless value is None, in which case only the key will be added. Example: msg.add_header('content-disposition', 'attachment', filename='bud.gif') """ parts = [] for k, v in _params.items(): if v is None: parts.append(k.replace('_', '-')) else: parts.append('%s="%s"' % (k.replace('_', '-'), v)) if _value is not None: parts.insert(0, _value) self._headers.append((_name, SEMISPACE.join(parts))) def get_type(self, failobj=None): """Returns the message's content type. The returned string is coerced to lowercase and returned as a single string of the form `maintype/subtype'. If there was no Content-Type: header in the message, failobj is returned (defaults to None). """ missing = [] value = self.get('content-type', missing) if value is missing: return failobj return re.split(r';\s+', value)[0].lower() def get_main_type(self, failobj=None): """Return the message's main content type if present.""" missing = [] ctype = self.get_type(missing) if ctype is missing: return failobj parts = ctype.split('/') if len(parts) > 0: return ctype.split('/')[0] return failobj def get_subtype(self, failobj=None): """Return the message's content subtype if present.""" missing = [] ctype = self.get_type(missing) if ctype is missing: return failobj parts = ctype.split('/') if len(parts) > 1: return ctype.split('/')[1] return failobj def get_params(self, failobj=None, header='content-type'): """Return the message's Content-Type: parameters, as a list. Optional failobj is the object to return if there is no Content-Type: header. Optional header is the header to search instead of Content-Type: """ missing = [] value = self.get(header, missing) if value is missing: return failobj return re.split(r';\s+', value)[1:] def get_param(self, param, failobj=None, header='content-type'): """Return the parameter value if found in the Content-Type: header. Optional failobj is the object to return if there is no Content-Type: header. Optional header is the header to search instead of Content-Type: """ param = param.lower() missing = [] params = self.get_params(missing, header=header) if params is missing: return failobj for p in params: try: name, val = p.split('=', 1) except ValueError: # Must have been a bare attribute name = p val = '' if name.lower() == param: return Utils.unquote(val) return failobj def get_filename(self, failobj=None): """Return the filename associated with the payload if present. The filename is extracted from the Content-Disposition: header's `filename' parameter, and it is unquoted. """ missing = [] filename = self.get_param('filename', missing, 'content-disposition') if filename is missing: return failobj return Utils.unquote(filename.strip()) def get_boundary(self, failobj=None): """Return the boundary associated with the payload if present. The boundary is extracted from the Content-Type: header's `boundary' parameter, and it is unquoted. """ missing = [] boundary = self.get_param('boundary', missing) if boundary is missing: return failobj return Utils.unquote(boundary.strip()) def set_boundary(self, boundary): """Set the boundary parameter in Content-Type: to 'boundary'. This is subtly different than deleting the Content-Type: header and adding a new one with a new boundary parameter via add_header(). The main difference is that using the set_boundary() method preserves the order of the Content-Type: header in the original message. HeaderParseError is raised if the message has no Content-Type: header. """ params = self.get_params() if not params: # There was no Content-Type: header, and we don't know what type # to set it to, so raise an exception. raise Errors.HeaderParseError, 'No Content-Type: header found' newparams = [] foundp = 0 for p in params: if p.lower().startswith('boundary='): newparams.append('boundary="%s"' % boundary) foundp = 1 else: newparams.append(p) if not foundp: # The original Content-Type: header had no boundary attribute. # Tack one one the end. BAW: should we raise an exception # instead??? newparams.append('boundary="%s"' % boundary) # Replace the existing Content-Type: header with the new value newheaders = [] for h, v in self._headers: if h.lower() == 'content-type': value = v.split(';', 1)[0] newparams.insert(0, value) newheaders.append((h, SEMISPACE.join(newparams))) else: newheaders.append((h, v)) self._headers = newheaders def walk(self): """Walk over the message tree, yielding each subpart. The walk is performed in breadth-first order. This method is a generator. """ if self.is_multipart(): for subpart in self.get_payload(): for subsubpart in subpart.walk(): yield subsubpart else: yield self def get_charsets(self, failobj=None): """Return a list containing the charset(s) used in this message. The returned list of items describes the Content-Type: headers' charset parameter for this message and all the subparts in its payload. Each item will either be a string (the value of the charset parameter in the Content-Type: header of that part) or the value of the 'failobj' parameter (defaults to None), if the part does not have a main MIME type of "text", or the charset is not defined. The list will contain one string for each part of the message, plus one for the container message (i.e. self), so that a non-multipart message will still return a list of length 1. """ return [part.get_param('charset', failobj) for part in self.walk()] --- NEW FILE: MessageRFC822.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class for generating message/rfc822 MIME documents. """ import Message import MIMEBase class MessageRFC822(MIMEBase.MIMEBase): """Class for generating message/rfc822 MIME documents.""" def __init__(self, _msg): """Create a message/rfc822 type MIME document. _msg is a message object and must be an instance of Message, or a derived class of Message, otherwise a TypeError is raised. """ MIMEBase.MIMEBase.__init__(self, 'message', 'rfc822') if not isinstance(_msg, Message.Message): raise TypeError, 'Argument is not an instance of Message' self.set_payload(_msg) --- NEW FILE: Parser.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """A parser of RFC 2822 and MIME email messages. """ import re from cStringIO import StringIO # Intrapackage imports import Errors import Message bcre = re.compile('boundary="?([^"]+)"?', re.IGNORECASE) EMPTYSTRING = '' NL = '\n' class Parser: def __init__(self, _class=Message.Message): """Parser of RFC 2822 and MIME email messages. Creates an in-memory object tree representing the email message, which can then be manipulated and turned over to a Generator to return the textual representation of the message. The string must be formatted as a block of RFC 2822 headers and header continuation lines, optionally preceeded by a `Unix-from' header. The header block is terminated either by the end of the string or by a blank line. _class is the class to instantiate for new message objects when they must be created. This class must have a constructor that can take zero arguments. Default is Message.Message. """ self._class = _class def parse(self, fp): root = self._class() self._parseheaders(root, fp) self._parsebody(root, fp) return root def parsestr(self, text): return self.parse(StringIO(text)) def _parseheaders(self, container, fp): # Parse the headers, returning a list of header/value pairs. None as # the header means the Unix-From header. lastheader = '' lastvalue = [] lineno = 0 while 1: line = fp.readline()[:-1] if not line or not line.strip(): break lineno += 1 # Check for initial Unix From_ line if line.startswith('From '): if lineno == 1: container.set_unixfrom(line) continue else: raise Errors.HeaderParseError( 'Unix-from in headers after first rfc822 header') # # Header continuation line if line[0] in ' \t': if not lastheader: raise Errors.HeaderParseError( 'Continuation line seen before first header') lastvalue.append(line) continue # Normal, non-continuation header. BAW: this should check to make # sure it's a legal header, e.g. doesn't contain spaces. Also, we # should expose the header matching algorithm in the API, and # allow for a non-strict parsing mode (that ignores the line # instead of raising the exception). i = line.find(':') if i < 0: raise Errors.HeaderParseError( 'Not a header, not a continuation') if lastheader: container[lastheader] = NL.join(lastvalue) lastheader = line[:i] lastvalue = [line[i+1:].lstrip()] # Make sure we retain the last header if lastheader: container[lastheader] = NL.join(lastvalue) def _parsebody(self, container, fp): # Parse the body, but first split the payload on the content-type # boundary if present. boundary = isdigest = None ctype = container['content-type'] if ctype: mo = bcre.search(ctype) if mo: boundary = mo.group(1) isdigest = container.get_type() == 'multipart/digest' # If there's a boundary, split the payload text into its constituent # parts and parse each separately. Otherwise, just parse the rest of # the body as a single message. Note: any exceptions raised in the # recursive parse need to have their line numbers coerced. if boundary: preamble = epilogue = None # Split into subparts. The first boundary we're looking for won't # have the leading newline since we're at the start of the body # text. separator = '--' + boundary payload = fp.read() start = payload.find(separator) if start < 0: raise Errors.BoundaryError( "Couldn't find starting boundary: %s" % boundary) if start > 0: # there's some pre-MIME boundary preamble preamble = payload[0:start] start += len(separator) + 1 + isdigest terminator = payload.find('\n' + separator + '--', start) if terminator < 0: raise Errors.BoundaryError( "Couldn't find terminating boundary: %s" % boundary) if terminator+len(separator)+3 < len(payload): # there's some post-MIME boundary epilogue epilogue = payload[terminator+len(separator)+3:] # We split the textual payload on the boundary separator, which # includes the trailing newline. If the container is a # multipart/digest then the subparts are by default message/rfc822 # instead of text/plain. In that case, they'll have an extra # newline before the headers to distinguish the message's headers # from the subpart headers. if isdigest: separator += '\n\n' else: separator += '\n' parts = payload[start:terminator].split('\n' + separator) for part in parts: msgobj = self.parsestr(part) container.preamble = preamble container.epilogue = epilogue container.add_payload(msgobj) elif ctype == 'message/rfc822': # Create a container for the payload, but watch out for there not # being any headers left try: msg = self.parse(fp) except Errors.HeaderParseError: msg = self._class() self._parsebody(msg, fp) container.add_payload(msg) else: container.add_payload(fp.read()) --- NEW FILE: Text.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class representing text/* type MIME documents. """ import MIMEBase from Encoders import encode_7or8bit class Text(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" def __init__(self, _text, _minor='plain', _charset='us-ascii', _encoder=encode_7or8bit): """Create a text/* type MIME document. _text is the string for this message object. If the text does not end in a newline, one is added. _minor is the minor content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type: header. This defaults to "us-ascii". _encoder is a function which will perform the actual encoding for transport of the text data. It takes one argument, which is this Text instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding: or other headers to the message as necessary. The default encoding doesn't actually modify the payload, but it does set Content-Transfer-Encoding: to either `7bit' or `8bit' as appropriate. """ MIMEBase.MIMEBase.__init__(self, 'text', _minor, **{'charset': _charset}) if _text and _text[-1] <> '\n': _text += '\n' self.set_payload(_text) _encoder(self) --- NEW FILE: Utils.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Miscellaneous utilities. """ import re from rfc822 import unquote, quote, parseaddr from rfc822 import dump_address_pair from rfc822 import AddrlistClass as _AddrlistClass from rfc822 import parsedate_tz, parsedate, mktime_tz, formatdate from quopri import decodestring as _qdecode import base64 # Intrapackage imports from Encoders import _bencode, _qencode COMMASPACE = ', ' UEMPTYSTRING = u'' # Helpers def _identity(s): return s def _bdecode(s): if not s: return s # We can't quite use base64.encodestring() since it tacks on a "courtesy # newline". Blech! if not s: return s hasnewline = (s[-1] == '\n') value = base64.decodestring(s) if not hasnewline and value[-1] == '\n': return value[:-1] return value def getaddresses(fieldvalues): """Return a list of (REALNAME, EMAIL) for each fieldvalue.""" all = COMMASPACE.join(fieldvalues) a = _AddrlistClass(all) return a.getaddrlist() ecre = re.compile(r''' =\? # literal =? (?P[^?]*?) # non-greedy up to the next ? is the charset \? # literal ? (?P[qb]) # either a "q" or a "b", case insensitive \? # literal ? (?P.*?) # non-greedy up to the next ?= is the atom \?= # literal ?= ''', re.VERBOSE | re.IGNORECASE) def decode(s): """Return a decoded string according to RFC 2047, as a unicode string.""" rtn = [] parts = ecre.split(s, 1) while parts: # If there are less than 4 parts, it can't be encoded and we're done if len(parts) < 5: rtn.extend(parts) break # The first element is any non-encoded leading text rtn.append(parts[0]) charset = parts[1] encoding = parts[2] atom = parts[3] # The next chunk to decode should be in parts[4] parts = ecre.split(parts[4]) # The encoding must be either `q' or `b', case-insensitive if encoding.lower() == 'q': func = _qdecode elif encoding.lower() == 'b': func = _bdecode else: func = _identity # Decode and get the unicode in the charset rtn.append(unicode(func(atom), charset)) # Now that we've decoded everything, we just need to join all the parts # together into the final string. return UEMPTYSTRING.join(rtn) def encode(s, charset='iso-8859-1', encoding='q'): """Encode a string according to RFC 2047.""" if encoding.lower() == 'q': estr = _qencode(s) elif encoding.lower() == 'b': estr = _bencode(s) else: raise ValueError, 'Illegal encoding code: ' + encoding return '=?%s?%s?%s?=' % (charset.lower(), encoding.lower(), estr) --- NEW FILE: __init__.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """A package for parsing, handling, and generating email messages. """ __version__ = '1.0' __all__ = ['Encoders', 'Errors', 'Generator', 'Image', 'Iterators', 'MIMEBase', 'Message', 'MessageRFC822', 'Parser', 'Text', 'Utils', 'message_from_string', 'message_from_file', ] # Some convenience routines from Parser import Parser as _Parser from Message import Message as _Message def message_from_string(s, _class=_Message): return _Parser(_class).parsestr(s) def message_from_file(fp, _class=_Message): return _Parser(_class).parse(fp) From bwarsaw@users.sourceforge.net Sun Sep 23 04:18:15 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sat, 22 Sep 2001 20:18:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12965 Added Files: test_email.py Log Message: An extensive test suite for the email package. --- NEW FILE: test_email.py --- # Copyright (C) 2001 Python Software Foundation # email package unit tests import os import time import unittest import base64 from cStringIO import StringIO from types import StringType import email from email.Parser import Parser from email.Generator import Generator, DecodedGenerator from email.Message import Message from email.Text import Text from email.Image import Image from email.MIMEBase import MIMEBase from email.MessageRFC822 import MessageRFC822 from email import Utils from email import Errors from email import Encoders from email import Iterators import test.regrtest NL = '\n' EMPTYSTRING = '' def openfile(filename): path = os.path.join(os.path.dirname(test.regrtest.__file__), 'data', filename) return open(path) # Base test class class TestEmailBase(unittest.TestCase): def _msgobj(self, filename): fp = openfile(filename) try: msgobj = email.message_from_file(fp) finally: fp.close() return msgobj # Test various aspects of the Message class's API class TestMessageAPI(TestEmailBase): def test_get_charsets(self): eq = self.assertEqual msgobj = self._msgobj('msg_08.txt') charsets = msgobj.get_charsets() eq(charsets, ['us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r']) msgobj = self._msgobj('msg_09.txt') charsets = msgobj.get_charsets('dingbat') eq(charsets, ['us-ascii', 'iso-8859-1', 'dingbat', 'koi8-r']) msgobj = self._msgobj('msg_12.txt') charsets = msgobj.get_charsets() eq(charsets, ['us-ascii', 'iso-8859-1', 'iso-8859-2', 'iso-8859-3', 'us-ascii', 'koi8-r']) def test_get_filename(self): eq = self.assertEqual msgobj = self._msgobj('msg_04.txt') filenames = [p.get_filename() for p in msgobj.get_payload()] eq(filenames, ['msg.txt', 'msg.txt']) msgobj = self._msgobj('msg_07.txt') subpart = msgobj.get_payload(1) eq(subpart.get_filename(), 'dingusfish.gif') def test_get_boundary(self): eq = self.assertEqual msgobj = self._msgobj('msg_07.txt') # No quotes! eq(msgobj.get_boundary(), 'BOUNDARY') def test_set_boundary(self): eq = self.assertEqual # This one has no existing boundary parameter, but the Content-Type: # header appears fifth. msgobj = self._msgobj('msg_01.txt') msgobj.set_boundary('BOUNDARY') header, value = msgobj.items()[4] eq(header.lower(), 'content-type') eq(value, 'text/plain; charset=us-ascii; boundary="BOUNDARY"') # This one has a Content-Type: header, with a boundary, stuck in the # middle of its headers. Make sure the order is preserved; it should # be fifth. msgobj = self._msgobj('msg_04.txt') msgobj.set_boundary('BOUNDARY') header, value = msgobj.items()[4] eq(header.lower(), 'content-type') eq(value, 'multipart/mixed; boundary="BOUNDARY"') # And this one has no Content-Type: header at all. msgobj = self._msgobj('msg_03.txt') self.assertRaises(Errors.HeaderParseError, msgobj.set_boundary, 'BOUNDARY') def test_get_decoded_payload(self): eq = self.assertEqual msgobj = self._msgobj('msg_10.txt') # The outer message is a multipart eq(msgobj.get_payload(decode=1), None) # Subpart 1 is 7bit encoded eq(msgobj.get_payload(0).get_payload(decode=1), 'This is a 7bit encoded message.\n') # Subpart 2 is quopri eq(msgobj.get_payload(1).get_payload(decode=1), '\xa1This is a Quoted Printable encoded message!\n') # Subpart 3 is base64 eq(msgobj.get_payload(2).get_payload(decode=1), 'This is a Base64 encoded message.') # Subpart 4 has no Content-Transfer-Encoding: header. eq(msgobj.get_payload(3).get_payload(decode=1), 'This has no Content-Transfer-Encoding: header.\n') def test_decoded_generator(self): eq = self.assertEqual msgobj = self._msgobj('msg_07.txt') s = StringIO() g = DecodedGenerator(s) g(msgobj) eq(s.getvalue(), '''\ MIME-Version: 1.0 From: Barry To: Dingus Lovers Subject: Here is your dingus fish Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" Hi there, This is the dingus fish. [Non-text (image/gif) part of message omitted, filename dingusfish.gif] ''') def test__contains__(self): msg = Message() msg['From'] = 'Me' msg['to'] = 'You' # Check for case insensitivity self.failUnless('from' in msg) self.failUnless('From' in msg) self.failUnless('FROM' in msg) self.failUnless('to' in msg) self.failUnless('To' in msg) self.failUnless('TO' in msg) def test_as_string(self): eq = self.assertEqual msgobj = self._msgobj('msg_01.txt') fp = openfile('msg_01.txt') try: text = fp.read() finally: fp.close() eq(text, msgobj.as_string()) fullrepr = str(msgobj) lines = fullrepr.split('\n') self.failUnless(lines[0].startswith('From ')) eq(text, NL.join(lines[1:])) def test_bad_param(self): msg = email.message_from_string("""\ From: foo Content-Type: blarg; baz; boo """) self.assertEqual(msg.get_param('baz'), '') def test_missing_filename(self): msg = email.message_from_string("""\ From: foo """) self.assertEqual(msg.get_filename(), None) def test_bogus_filename(self): msg = email.message_from_string("""\ From: foo Content-Disposition: blarg; filename """) self.assertEqual(msg.get_filename(), '') def test_missing_boundary(self): msg = email.message_from_string("""\ From: foo """) self.assertEqual(msg.get_boundary(), None) # Test the email.Encoders module class TestEncoders(unittest.TestCase): def test_encode_noop(self): eq = self.assertEqual msg = Text('hello world', _encoder=Encoders.encode_noop) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], None) def test_encode_7bit(self): eq = self.assertEqual msg = Text('hello world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], '7bit') msg = Text('hello \x7f world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x7f world\n') eq(msg['content-transfer-encoding'], '7bit') def test_encode_8bit(self): eq = self.assertEqual msg = Text('hello \x80 world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x80 world\n') eq(msg['content-transfer-encoding'], '8bit') def test_encode_base64(self): eq = self.assertEqual msg = Text('hello world', _encoder=Encoders.encode_base64) eq(msg.get_payload(), 'aGVsbG8gd29ybGQK\n') eq(msg['content-transfer-encoding'], 'base64') def test_encode_quoted_printable(self): eq = self.assertEqual msg = Text('hello world', _encoder=Encoders.encode_quopri) eq(msg.get_payload(), 'hello=20world\n') eq(msg['content-transfer-encoding'], 'quoted-printable') class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): msg = Text('') # It'd be great if we could use add_header() here, but that doesn't # guarantee an order of the parameters. msg['X-Foobar-Spoink-Defrobnit'] = ( 'wasnipoop; giraffes="very-long-necked-animals"; ' 'spooge="yummy"; hippos="gargantuan"; marshmallows="gooey"') sfp = StringIO() g = Generator(sfp) g(msg) self.assertEqual(sfp.getvalue(), '''\ Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Foobar-Spoink-Defrobnit: wasnipoop; giraffes="very-long-necked-animals"; spooge="yummy"; hippos="gargantuan"; marshmallows="gooey" ''') class TestFromMangling(unittest.TestCase): def setUp(self): self.msg = Message() self.msg['From'] = 'aaa@bbb.org' self.msg.add_payload("""\ >From the desk of A.A.A.: Blah blah blah """) def test_mangled_from(self): s = StringIO() g = Generator(s, mangle_from_=1) g(self.msg) self.assertEqual(s.getvalue(), """\ From: aaa@bbb.org >From the desk of A.A.A.: Blah blah blah """) def test_dont_mangle_from(self): s = StringIO() g = Generator(s, mangle_from_=0) g(self.msg) self.assertEqual(s.getvalue(), """\ From: aaa@bbb.org >From the desk of A.A.A.: Blah blah blah """) # Test the basic Image class class TestImage(unittest.TestCase): def setUp(self): fp = openfile('PyBanner048.gif') try: self._imgdata = fp.read() finally: fp.close() self._im = Image(self._imgdata) def test_guess_minor_type(self): self.assertEqual(self._im.get_type(), 'image/gif') def test_encoding(self): payload = self._im.get_payload() self.assertEqual(base64.decodestring(payload), self._imgdata) def checkSetMinor(self): im = Image(self._imgdata, 'fish') self.assertEqual(im.get_type(), 'image/fish') def test_custom_encoder(self): eq = self.assertEqual def encoder(msg): orig = msg.get_payload() msg.set_payload(0) msg['Content-Transfer-Encoding'] = 'broken64' im = Image(self._imgdata, _encoder=encoder) eq(im.get_payload(), 0) eq(im['content-transfer-encoding'], 'broken64') def test_add_header(self): eq = self.assertEqual unless = self.failUnless self._im.add_header('Content-Disposition', 'attachment', filename='dingusfish.gif') eq(self._im['content-disposition'], 'attachment; filename="dingusfish.gif"') eq(self._im.get_params(header='content-disposition'), ['filename="dingusfish.gif"']) eq(self._im.get_param('filename', header='content-disposition'), 'dingusfish.gif') missing = [] unless(self._im.get_param('attachment', missing, header='content-disposition') is missing) # Try some missing stuff unless(self._im.get_param('foobar', missing) is missing) unless(self._im.get_param('attachment', missing, header='foobar') is missing) # Test the basic Text class class TestText(unittest.TestCase): def setUp(self): self._msg = Text('hello there') def test_types(self): eq = self.assertEqual unless = self.failUnless eq(self._msg.get_type(), 'text/plain') eq(self._msg.get_param('charset'), 'us-ascii') missing = [] unless(self._msg.get_param('foobar', missing) is missing) unless(self._msg.get_param('charset', missing, header='foobar') is missing) def test_payload(self): self.assertEqual(self._msg.get_payload(), 'hello there\n') self.failUnless(not self._msg.is_multipart()) class TestMultipartMixed(unittest.TestCase): def setUp(self): fp = openfile('PyBanner048.gif') try: data = fp.read() finally: fp.close() container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') image = Image(data, name='dingusfish.gif') image.add_header('content-disposition', 'attachment', filename='dingusfish.gif') intro = Text('''\ Hi there, This is the dingus fish. ''') container.add_payload(intro) container.add_payload(image) container['From'] = 'Barry ' container['To'] = 'Dingus Lovers ' container['Subject'] = 'Here is your dingus fish' now = 987809702.54848599 timetuple = time.localtime(now) if timetuple[-1] == 0: tzsecs = time.timezone else: tzsecs = time.altzone if tzsecs > 0: sign = '-' else: sign = '+' tzoffset = ' %s%04d' % (sign, tzsecs / 36) container['Date'] = time.strftime( '%a, %d %b %Y %H:%M:%S', time.localtime(now)) + tzoffset self._msg = container self._im = image self._txt = intro def test_hierarchy(self): # convenience eq = self.assertEqual unless = self.failUnless raises = self.assertRaises # tests m = self._msg unless(m.is_multipart()) eq(m.get_type(), 'multipart/mixed') eq(len(m.get_payload()), 2) raises(IndexError, m.get_payload, 2) m0 = m.get_payload(0) m1 = m.get_payload(1) unless(m0 is self._txt) unless(m1 is self._im) eq(m.get_payload(), [m0, m1]) unless(not m0.is_multipart()) unless(not m1.is_multipart()) class TestNonConformant(TestEmailBase): def test_parse_missing_minor_type(self): eq = self.assertEqual msg = self._msgobj('msg_14.txt') eq(msg.get_type(), 'text') eq(msg.get_main_type(), 'text') self.failUnless(msg.get_subtype() is None) def test_bogus_boundary(self): fp = openfile('msg_15.txt') try: data = fp.read() finally: fp.close() p = Parser() # Note, under a future non-strict parsing mode, this would parse the # message into the intended message tree. self.assertRaises(Errors.BoundaryError, p.parsestr, data) class TestRFC2047(unittest.TestCase): def test_iso_8859_1(self): eq = self.assertEqual s = '=?iso-8859-1?q?this=20is=20some=20text?=' eq(Utils.decode(s), 'this is some text') s = '=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=' eq(Utils.decode(s), u'Keld_J\xf8rn_Simonsen') s = '=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=' \ '=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=' eq(Utils.decode(s), 'If you can read this you understand the example.') s = '=?iso-8859-8?b?7eXs+SDv4SDp7Oj08A==?=' eq(Utils.decode(s), u'\u05dd\u05d5\u05dc\u05e9 \u05df\u05d1 \u05d9\u05dc\u05d8\u05e4\u05e0') s = '=?iso-8859-1?q?this=20is?= =?iso-8859-1?q?some=20text?=' eq(Utils.decode(s), u'this is some text') def test_encode_header(self): eq = self.assertEqual s = 'this is some text' eq(Utils.encode(s), '=?iso-8859-1?q?this=20is=20some=20text?=') s = 'Keld_J\xf8rn_Simonsen' eq(Utils.encode(s), '=?iso-8859-1?q?Keld_J=F8rn_Simonsen?=') s1 = 'If you can read this yo' s2 = 'u understand the example.' eq(Utils.encode(s1, encoding='b'), '=?iso-8859-1?b?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=') eq(Utils.encode(s2, charset='iso-8859-2', encoding='b'), '=?iso-8859-2?b?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=') class TestMessageRFC822(unittest.TestCase): def setUp(self): fp = openfile('msg_11.txt') self._text = fp.read() fp.close() def test_type_error(self): self.assertRaises(TypeError, MessageRFC822, 'a plain string') def test_valid_argument(self): eq = self.assertEqual subject = 'A sub-message' m = Message() m['Subject'] = subject r = MessageRFC822(m) eq(r.get_type(), 'message/rfc822') self.failUnless(r.get_payload() is m) eq(r.get_payload()['subject'], subject) def test_generate(self): # First craft the message to be encapsulated m = Message() m['Subject'] = 'An enclosed message' m.add_payload('Here is the body of the message.\n') r = MessageRFC822(m) r['Subject'] = 'The enclosing message' s = StringIO() g = Generator(s) g(r) self.assertEqual(s.getvalue(), self._text) class TestIdempotent(unittest.TestCase): def _msgobj(self, filename): fp = openfile(filename) try: data = fp.read() finally: fp.close() msgobj = email.message_from_string(data) return msgobj, data def _idempotent(self, msg, text): eq = self.assertEquals s = StringIO() g = Generator(s, maxheaderlen=0) g(msg) eq(text, s.getvalue()) def test_parse_text_message(self): eq = self.assertEquals msg, text = self._msgobj('msg_01.txt') eq(msg.get_type(), 'text/plain') eq(msg.get_main_type(), 'text') eq(msg.get_subtype(), 'plain') eq(msg.get_params(), ['charset=us-ascii']) eq(msg.get_param('charset'), 'us-ascii') eq(msg.preamble, None) eq(msg.epilogue, None) self._idempotent(msg, text) def test_parse_untyped_message(self): eq = self.assertEquals msg, text = self._msgobj('msg_03.txt') eq(msg.get_type(), None) eq(msg.get_params(), None) eq(msg.get_param('charset'), None) self._idempotent(msg, text) def test_simple_multipart(self): msg, text = self._msgobj('msg_04.txt') self._idempotent(msg, text) def test_MIME_digest(self): msg, text = self._msgobj('msg_02.txt') self._idempotent(msg, text) def test_mixed_with_image(self): msg, text = self._msgobj('msg_06.txt') self._idempotent(msg, text) def test_multipart_report(self): msg, text = self._msgobj('msg_05.txt') self._idempotent(msg, text) def test_content_type(self): eq = self.assertEquals # Get a message object and reset the seek pointer for other tests msg, text = self._msgobj('msg_05.txt') eq(msg.get_type(), 'multipart/report') # Test the Content-Type: parameters params = {} for p in msg.get_params(): pk, pv = p.split('=', 1) params[pk] = pv eq(params['report-type'], 'delivery-status') eq(params['boundary'], '"D1690A7AC1.996856090/mail.example.com"') eq(msg.preamble, 'This is a MIME-encapsulated message.\n\n') eq(msg.epilogue, '\n\n') eq(len(msg.get_payload()), 3) # Make sure the subparts are what we expect msg1 = msg.get_payload(0) eq(msg1.get_type(), 'text/plain') eq(msg1.get_payload(), 'Yadda yadda yadda\n') msg2 = msg.get_payload(1) eq(msg2.get_type(), None) eq(msg2.get_payload(), 'Yadda yadda yadda\n') msg3 = msg.get_payload(2) eq(msg3.get_type(), 'message/rfc822') self.failUnless(isinstance(msg3, Message)) msg4 = msg3.get_payload() self.failUnless(isinstance(msg4, Message)) eq(msg4.get_payload(), 'Yadda yadda yadda\n') def test_parser(self): eq = self.assertEquals msg, text = self._msgobj('msg_06.txt') # Check some of the outer headers eq(msg.get_type(), 'message/rfc822') # Make sure there's exactly one thing in the payload and that's a # sub-Message object of type text/plain msg1 = msg.get_payload() self.failUnless(isinstance(msg1, Message)) eq(msg1.get_type(), 'text/plain') self.failUnless(isinstance(msg1.get_payload(), StringType)) eq(msg1.get_payload(), '\n') class TestMiscellaneous(unittest.TestCase): def test_message_from_string(self): fp = openfile('msg_01.txt') try: text = fp.read() finally: fp.close() msg = email.message_from_string(text) s = StringIO() # Don't wrap/continue long headers since we're trying to test # idempotency. g = Generator(s, maxheaderlen=0) g(msg) self.assertEqual(text, s.getvalue()) def test_message_from_file(self): fp = openfile('msg_01.txt') try: text = fp.read() fp.seek(0) msg = email.message_from_file(fp) s = StringIO() # Don't wrap/continue long headers since we're trying to test # idempotency. g = Generator(s, maxheaderlen=0) g(msg) self.assertEqual(text, s.getvalue()) finally: fp.close() def test_message_from_string_with_class(self): unless = self.failUnless fp = openfile('msg_01.txt') try: text = fp.read() finally: fp.close() # Create a subclass class MyMessage(Message): pass msg = email.message_from_string(text, MyMessage) unless(isinstance(msg, MyMessage)) # Try something more complicated fp = openfile('msg_02.txt') try: text = fp.read() finally: fp.close() msg = email.message_from_string(text, MyMessage) for subpart in msg.walk(): unless(isinstance(subpart, MyMessage)) def test_message_from_file_with_class(self): unless = self.failUnless # Create a subclass class MyMessage(Message): pass fp = openfile('msg_01.txt') try: msg = email.message_from_file(fp, MyMessage) finally: fp.close() unless(isinstance(msg, MyMessage)) # Try something more complicated fp = openfile('msg_02.txt') try: msg = email.message_from_file(fp, MyMessage) finally: fp.close() for subpart in msg.walk(): unless(isinstance(subpart, MyMessage)) class TestIterators(TestEmailBase): def test_body_line_iterator(self): eq = self.assertEqual # First a simple non-multipart message msg = self._msgobj('msg_01.txt') it = Iterators.body_line_iterator(msg) lines = [] for line in it: lines.append(line) eq(len(lines), 6) eq(EMPTYSTRING.join(lines), msg.get_payload()) # Now a more complicated multipart msg = self._msgobj('msg_02.txt') it = Iterators.body_line_iterator(msg) lines = [] for line in it: lines.append(line) eq(len(lines), 43) eq(EMPTYSTRING.join(lines), """\ Send Ppp mailing list submissions to ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ppp-request@zzz.org You can reach the person managing the list at ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Ppp digest..." Today's Topics: 1. testing #1 (Barry A. Warsaw) 2. testing #2 (Barry A. Warsaw) 3. testing #3 (Barry A. Warsaw) 4. testing #4 (Barry A. Warsaw) 5. testing #5 (Barry A. Warsaw) hello hello hello hello hello _______________________________________________ Ppp mailing list Ppp@zzz.org http://www.zzz.org/mailman/listinfo/ppp """) def test_typed_subpart_iterator(self): eq = self.assertEqual msg = self._msgobj('msg_04.txt') it = Iterators.typed_subpart_iterator(msg, 'text') lines = [] subparts = 0 for subpart in it: subparts += 1 lines.append(subpart.get_payload()) eq(subparts, 2) eq(EMPTYSTRING.join(lines), """\ a simple kind of mirror to reflect upon our own a simple kind of mirror to reflect upon our own """) def suite(): suite = unittest.TestSuite() suite.addTest(unittest.makeSuite(TestMessageAPI)) suite.addTest(unittest.makeSuite(TestEncoders)) suite.addTest(unittest.makeSuite(TestLongHeaders)) suite.addTest(unittest.makeSuite(TestFromMangling)) suite.addTest(unittest.makeSuite(TestImage)) suite.addTest(unittest.makeSuite(TestText)) suite.addTest(unittest.makeSuite(TestMultipartMixed)) suite.addTest(unittest.makeSuite(TestNonConformant)) suite.addTest(unittest.makeSuite(TestRFC2047)) suite.addTest(unittest.makeSuite(TestMessageRFC822)) suite.addTest(unittest.makeSuite(TestIdempotent)) suite.addTest(unittest.makeSuite(TestMiscellaneous)) suite.addTest(unittest.makeSuite(TestIterators)) return suite if __name__ == '__main__': unittest.main(defaultTest='suite') else: from test_support import run_suite run_suite(suite()) From bwarsaw@users.sourceforge.net Sun Sep 23 04:18:25 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sat, 22 Sep 2001 20:18:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data - New directory Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv12983/data Log Message: Directory /cvsroot/python/python/dist/src/Lib/test/data added to the repository From bwarsaw@users.sourceforge.net Sun Sep 23 04:19:35 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sat, 22 Sep 2001 20:19:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data PyBanner048.gif,NONE,1.1 msg_01.txt,NONE,1.1 msg_02.txt,NONE,1.1 msg_03.txt,NONE,1.1 msg_04.txt,NONE,1.1 msg_05.txt,NONE,1.1 msg_06.txt,NONE,1.1 msg_07.txt,NONE,1.1 msg_08.txt,NONE,1.1 msg_09.txt,NONE,1.1 msg_10.txt,NONE,1.1 msg_11.txt,NONE,1.1 msg_12.txt,NONE,1.1 msg_13.txt,NONE,1.1 msg_14.txt,NONE,1.1 msg_15.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv13132 Added Files: PyBanner048.gif msg_01.txt msg_02.txt msg_03.txt msg_04.txt msg_05.txt msg_06.txt msg_07.txt msg_08.txt msg_09.txt msg_10.txt msg_11.txt msg_12.txt msg_13.txt msg_14.txt msg_15.txt Log Message: The test data (mostly example messages) for the email package test suite. Note that other tests can put input data in this directory. --- NEW FILE: PyBanner048.gif --- GIF87a– ~)eczw' zj* z  ¦è WTbЀÁyô@1`€@È,#Êÿ9 Delivered-To: bbb@zzz.org Received: by mail.zzz.org (Postfix, from userid 889) id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15090.61304.110929.45684@aaa.zzz.org> From: bbb@ddd.com (John X. Doe) To: bbb@zzz.org Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Hi, Do you like this message? -Me --- NEW FILE: msg_02.txt --- MIME-version: 1.0 From: ppp-request@zzz.org Sender: ppp-admin@zzz.org To: ppp@zzz.org Subject: Ppp digest, Vol 1 #2 - 5 msgs Date: Fri, 20 Apr 2001 20:18:00 -0400 (EDT) X-Mailer: Mailman v2.0.4 X-Mailman-Version: 2.0.4 Content-Type: multipart/mixed; boundary="192.168.1.2.889.32614.987812255.500.21814" --192.168.1.2.889.32614.987812255.500.21814 Content-type: text/plain; charset=us-ascii Content-description: Masthead (Ppp digest, Vol 1 #2) Send Ppp mailing list submissions to ppp@zzz.org To subscribe or unsubscribe via the World Wide Web, visit http://www.zzz.org/mailman/listinfo/ppp or, via email, send a message with subject or body 'help' to ppp-request@zzz.org You can reach the person managing the list at ppp-admin@zzz.org When replying, please edit your Subject line so it is more specific than "Re: Contents of Ppp digest..." --192.168.1.2.889.32614.987812255.500.21814 Content-type: text/plain; charset=us-ascii Content-description: Today's Topics (5 msgs) Today's Topics: 1. testing #1 (Barry A. Warsaw) 2. testing #2 (Barry A. Warsaw) 3. testing #3 (Barry A. Warsaw) 4. testing #4 (Barry A. Warsaw) 5. testing #5 (Barry A. Warsaw) --192.168.1.2.889.32614.987812255.500.21814 Content-Type: multipart/digest; boundary="__--__--" --__--__-- Message: 1 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Fri, 20 Apr 2001 20:16:13 -0400 To: ppp@zzz.org From: barry@digicool.com (Barry A. Warsaw) Subject: [Ppp] testing #1 Precedence: bulk hello --__--__-- Message: 2 Date: Fri, 20 Apr 2001 20:16:21 -0400 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: ppp@zzz.org From: barry@digicool.com (Barry A. Warsaw) Precedence: bulk hello --__--__-- Message: 3 Date: Fri, 20 Apr 2001 20:16:25 -0400 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: ppp@zzz.org From: barry@digicool.com (Barry A. Warsaw) Subject: [Ppp] testing #3 Precedence: bulk hello --__--__-- Message: 4 Date: Fri, 20 Apr 2001 20:16:28 -0400 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: ppp@zzz.org From: barry@digicool.com (Barry A. Warsaw) Subject: [Ppp] testing #4 Precedence: bulk hello --__--__-- Message: 5 Date: Fri, 20 Apr 2001 20:16:32 -0400 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit To: ppp@zzz.org From: barry@digicool.com (Barry A. Warsaw) Subject: [Ppp] testing #5 Precedence: bulk hello --__--__---- --192.168.1.2.889.32614.987812255.500.21814 Content-type: text/plain; charset=us-ascii Content-description: Digest Footer _______________________________________________ Ppp mailing list Ppp@zzz.org http://www.zzz.org/mailman/listinfo/ppp --192.168.1.2.889.32614.987812255.500.21814-- End of Ppp Digest --- NEW FILE: msg_03.txt --- Return-Path: Delivered-To: bbb@zzz.org Received: by mail.zzz.org (Postfix, from userid 889) id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) Message-ID: <15090.61304.110929.45684@aaa.zzz.org> From: bbb@ddd.com (John X. Doe) To: bbb@zzz.org Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Hi, Do you like this message? -Me --- NEW FILE: msg_04.txt --- Return-Path: Delivered-To: barry@python.org Received: by mail.python.org (Postfix, from userid 889) id C2BF0D37C6; Tue, 11 Sep 2001 00:05:05 -0400 (EDT) MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="h90VIIIKmx" Content-Transfer-Encoding: 7bit Message-ID: <15261.36209.358846.118674@anthem.python.org> From: barry@python.org (Barry A. Warsaw) To: barry@python.org Subject: a simple multipart Date: Tue, 11 Sep 2001 00:05:05 -0400 X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid X-Attribution: BAW X-Oblique-Strategy: Make a door into a window --h90VIIIKmx Content-Type: text/plain Content-Disposition: inline; filename="msg.txt" Content-Transfer-Encoding: 7bit a simple kind of mirror to reflect upon our own --h90VIIIKmx Content-Type: text/plain Content-Disposition: inline; filename="msg.txt" Content-Transfer-Encoding: 7bit a simple kind of mirror to reflect upon our own --h90VIIIKmx-- --- NEW FILE: msg_05.txt --- From: foo Subject: bar To: baz MIME-Version: 1.0 Content-Type: multipart/report; report-type=delivery-status; boundary="D1690A7AC1.996856090/mail.example.com" Message-Id: <20010803162810.0CA8AA7ACC@mail.example.com> This is a MIME-encapsulated message. --D1690A7AC1.996856090/mail.example.com Content-Type: text/plain Yadda yadda yadda --D1690A7AC1.996856090/mail.example.com Yadda yadda yadda --D1690A7AC1.996856090/mail.example.com Content-Type: message/rfc822 From: nobody@python.org Yadda yadda yadda --D1690A7AC1.996856090/mail.example.com-- --- NEW FILE: msg_06.txt --- Return-Path: Delivered-To: barry@python.org MIME-Version: 1.0 Content-Type: message/rfc822 Content-Description: forwarded message Content-Transfer-Encoding: 7bit Message-ID: <15265.9482.641338.555352@python.org> From: barry@zope.com (Barry A. Warsaw) Sender: barry@python.org To: barry@python.org Subject: forwarded message from Barry A. Warsaw Date: Thu, 13 Sep 2001 17:28:42 -0400 X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid X-Attribution: BAW X-Oblique-Strategy: Be dirty X-Url: http://barry.wooz.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-Path: Delivered-To: barry@python.org Message-ID: <15265.9468.713530.98441@python.org> From: barry@zope.com (Barry A. Warsaw) Sender: barry@python.org To: barry@python.org Subject: testing Date: Thu, 13 Sep 2001 17:28:28 -0400 X-Mailer: VM 6.95 under 21.4 (patch 4) "Artificial Intelligence" XEmacs Lucid X-Attribution: BAW X-Oblique-Strategy: Spectrum analysis X-Url: http://barry.wooz.org --- NEW FILE: msg_07.txt --- MIME-Version: 1.0 From: Barry To: Dingus Lovers Subject: Here is your dingus fish Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" --BOUNDARY Content-Type: text/plain; charset="us-ascii" Hi there, This is the dingus fish. --BOUNDARY Content-Type: image/gif; name="dingusfish.gif" Content-Transfer-Encoding: base64 content-disposition: attachment; filename="dingusfish.gif" R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2 7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA /obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+ YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb 6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1 ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8 doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/ 1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0 YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0 ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4 cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ 7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb 6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88 9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6 cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs= --BOUNDARY-- --- NEW FILE: msg_08.txt --- MIME-Version: 1.0 From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" --BOUNDARY Content-Type: text/plain; charset="us-ascii" --BOUNDARY Content-Type: text/html; charset="iso-8859-1" --BOUNDARY Content-Type: text/plain; charset="iso-8859-2" --BOUNDARY Content-Type: text/plain; charset="koi8-r" --BOUNDARY-- --- NEW FILE: msg_09.txt --- MIME-Version: 1.0 From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" --BOUNDARY Content-Type: text/plain; charset="us-ascii" --BOUNDARY Content-Type: text/html; charset="iso-8859-1" --BOUNDARY Content-Type: text/plain --BOUNDARY Content-Type: text/plain; charset="koi8-r" --BOUNDARY-- --- NEW FILE: msg_10.txt --- MIME-Version: 1.0 From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" --BOUNDARY Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit This is a 7bit encoded message. --BOUNDARY Content-Type: text/html; charset="iso-8859-1" Content-Transfer-Encoding: Quoted-Printable =A1This is a Quoted Printable encoded message! --BOUNDARY Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: Base64 VGhpcyBpcyBhIEJhc2U2NCBlbmNvZGVkIG1lc3NhZ2Uu --BOUNDARY Content-Type: text/plain; charset="iso-8859-1" This has no Content-Transfer-Encoding: header. --BOUNDARY-- --- NEW FILE: msg_11.txt --- Content-Type: message/rfc822 MIME-Version: 1.0 Subject: The enclosing message Subject: An enclosed message Here is the body of the message. --- NEW FILE: msg_12.txt --- MIME-Version: 1.0 From: Barry Warsaw To: Dingus Lovers Subject: Lyrics Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" --BOUNDARY Content-Type: text/plain; charset="us-ascii" --BOUNDARY Content-Type: text/html; charset="iso-8859-1" --BOUNDARY Content-Type: multipart/mixed; boundary="ANOTHER" --ANOTHER Content-Type: text/plain; charset="iso-8859-2" --ANOTHER Content-Type: text/plain; charset="iso-8859-3" --ANOTHER-- --BOUNDARY Content-Type: text/plain; charset="us-ascii" --BOUNDARY Content-Type: text/plain; charset="koi8-r" --BOUNDARY-- --- NEW FILE: msg_13.txt --- MIME-Version: 1.0 From: Barry To: Dingus Lovers Subject: Here is your dingus fish Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="OUTER" --OUTER Content-Type: text/plain; charset="us-ascii" A text/plain part --OUTER Content-Type: multipart/mixed; boundary=BOUNDARY --BOUNDARY Content-Type: text/plain; charset="us-ascii" Hi there, This is the dingus fish. --BOUNDARY Content-Type: image/gif; name="dingusfish.gif" Content-Transfer-Encoding: base64 content-disposition: attachment; filename="dingusfish.gif" R0lGODdhAAEAAfAAAP///wAAACwAAAAAAAEAAQAC/oSPqcvtD6OctNqLs968+w+G4kiW5omm6sq2 7gvH8kzX9o3n+s73/g8MCofEovGITGICTKbyCV0FDNOo9SqpQqpOrJfXzTQj2vD3TGtqL+NtGQ2f qTXmxzuOd7WXdcc9DyjU53ewFni4s0fGhdiYaEhGBelICTNoV1j5NUnFcrmUqemjNifJVWpaOqaI oFq3SspZsSraE7sHq3jr1MZqWvi662vxV4tD+pvKW6aLDOCLyur8PDwbanyDeq0N3DctbQYeLDvR RY6t95m6UB0d3mwIrV7e2VGNvjjffukeJp4w7F65KecGFsTHQGAygOrgrWs1jt28Rc88KESYcGLA /obvTkH6p+CinWJiJmIMqXGQwH/y4qk0SYjgQTczT3ajKZGfuI0uJ4kkVI/DT5s3/ejkxI0aT4Y+ YTYgWbImUaXk9nlLmnSh1qJiJFl0OpUqRK4oOy7NyRQtHWofhoYVxkwWXKUSn0YsS+fUV6lhqfYb 6ayd3Z5qQdG1B7bvQzaJjwUV2lixMUZ7JVsOlfjWVr/3NB/uFvnySBN6Dcb6rGwaRM3wsormw5cC M9NxWy/bWdufudCvy8bOAjXjVVwta/uO21sE5RHBCzNFXtgq9ORtH4eYjVP4Yryo026nvkFmCeyA B29efV6ravCMK5JwWd5897Qrx7ll38o6iHDZ/rXPR//feevhF4l7wjUGX3xq1eeRfM4RSJGBIV1D z1gKPkfWag3mVBVvva1RlX5bAJTPR/2YqNtw/FkIYYEi/pIZiAdpcxpoHtmnYYoZtvhUftzdx5ZX JSKDW405zkGcZzzGZ6KEv4FI224oDmijlEf+xp6MJK5ojY/ASeVUR+wsKRuJ+XFZ5o7ZeEime8t1 ouUsU6YjF5ZtUihhkGfCdFQLWQFJ3UXxmElfhQnR+eCdcDbkFZp6vTRmj56ApCihn5QGpaToNZmR n3NVSpZcQpZ2KEONusaiCsKAug0wkQbJSFO+PTSjneGxOuFjPlUk3ovWvdIerjUg9ZGIOtGq/qeX eCYrrCX+1UPsgTKGGRSbzd5q156d/gpfbJxe66eD5iQKrXj7RGgruGxs62qebBHUKS32CKluCiqZ qh+pmehmEb71noAUoe5e9Zm17S7773V10pjrtG4CmuurCV/n6zLK5turWNhqOvFXbjhZrMD0YhKe wR0zOyuvsh6MWrGoIuzvyWu5y1WIFAqmJselypxXh6dKLNOKEB98L88bS2rkNqqlKzCNJp9c0G0j Gzh0iRrCbHSXmPR643QS+4rWhgFmnSbSuXCjS0xAOWkU2UdLqyuUNfHSFdUouy3bm5i5GnDM3tG8 doJ4r5tqu3pPbRSVfvs8uJzeNXhp3n4j/tZ42SwH7eaWUUOjc3qFV9453UHTXZfcLH+OeNs5g36x lBnHvTm7EbMbLeuaLncao8vWCXimfo1o+843Ak6y4ChNeGntvAYvfLK4ezmoyNIbNCLTCXO9ZV3A E8/s88RczPzDwI4Ob7XZyl7+9Miban29h+tJZPrE21wgvBphDfrrfPdCTPKJD/y98L1rZwHcV6Jq Zab0metpuNIX/qAFPoz171WUaUb4HAhBSzHuHfjzHb3kha/2Cctis/ORArVHNYfFyYRH2pYIRzic isVOfPWD1b6mRTqpCRBozzof6UZVvFXRxWIr3GGrEviGYgyPMfahheiSaLs/9QeFu7oZ/ndSY8DD ya9x+uPed+7mxN2IzIISBOMLFYWVqC3Pew1T2nFuuCiwZS5/v6II10i4t1OJcUH2U9zxKodHsGGv Oa+zkvNUYUOa/TCCRutF9MzDwdlUMJADTCGSbDQ5OV4PTamDoPEi6Ecc/RF5RWwkcdSXvSOaDWSn I9LlvubFTQpuc6JKXLcKeb+xdbKRBnwREemXyjg6ME65aJiOuBgrktzykfPLJBKR9ClMavJ62/Ff BlNIyod9yX9wcSXexnXFpvkrbXk64xsx5Db7wXKP5fSgsvwIMM/9631VLBfkmtbHRXpqmtei52hG pUwSlo+BASQoeILDOBgREECxBBh5/iYmNsQ9dIv5+OI++QkqdsJPc3uykz5fkM+OraeekcQF7X4n B5S67za5U967PmooGQhUXfF7afXyCD7ONdRe17QogYjVx38uLwtrS6nhTnm15LQUnu9E2uK6CNI/ 1HOABj0ESwOjut4FEpFQpdNAm4K2LHnDWHNcmKB2ioKBogysVZtMO2nSxUdZ8Yk2kJc7URioLVI0 YgmtIwZj4LoeKemgnOnbUdGnzZ4Oa6scqiolBGqS6RgWNLu0RMhcaE6rhhU4hiuqFXPAG8fGwTPW FKeLMtdVmXLSs5YJGF/YeVm7rREMlY3UYE+yCxbaMXX8y15m5zVHq6GOKDMynzII/jdUHdyVqIy0 ifX2+r/EgtZcvRzSb72gU9ui87M2VecjKildW/aFqaYhKoryUjfB/g4qtyVuc60xFDGmCxwjW+qu zjuwl2GkOWn66+3QiiEctvd04OVvcCVzjgT7lrkvjVGKKHmmlDUKowSeikb5kK/mJReuWOxONx+s ULsl+Lqb0CVn0SrVyJ6wt4t6yTeSCafhPhAf0OXn6L60UMxiLolFAtmN35S2Ob1lZpQ1r/n0Qb5D oQ1zJiRVDgF8N3Q8TYfbi3DyWCy3lT1nxyBs6FT3S2GOzWRlxwKvlRP0RPJA9SjxEy0UoEnkA+M4 cnzLMJrBGWLFEaaUb5lvpqbq/loOaU5+DFuHPxo82/OZuM8FXG3oVNZhtWpMpb/0Xu5m/LfLhHZQ 7yuVI0MqZ7NE43imC8jH3IwGZlbPm0xkJYs7+2U48hXTsFSMqgGDvai0kLxyynKNT/waj+q1c1tz GjOpPBgdCSq3UKZxCSsqFIY+O6JbAWGWcV1pwqLyj5sGqCF1xb1F3varUWqrJv6cN3PrUXzijtfZ FshpBL3Xwr4GIPvU2N8EjrJgS1zl21rbXQMXeXc5jjFyrhpCzijSv/RQtyPSzHCFMhlME95fHglt pRsX+dfSQjUeHAlpWzJ5iOo79Ldnaxai6bXTcGO3fp07ri7HLEmXXPlYi8bv/qVxvNcdra6m7Rlb 6JBTb5fd66VhFRjGArh2n7R1rDW4P5NOT9K0I183T2scYkeZ3q/VFyLb09U9ajzXBS8Kgkhc4mBS kYY9cy3Vy9lUnuNJH8HGIclUilwnBtjUOH0gteGOZ4c/XNrhXLSYDyxfnD8z1pDy7rYRvDolhnbe UMzxCZUs40s6s7UIvBnLgc0+vKuOkIXeOrDymlp+Zxra4MZLBbVrqD/jTJ597pDmnw5c4+DbyB88 9Cg9DodYcSuMZT/114pptqc/EuTjRPvH/z5slzI3tluOEBBLqOXLOX+0I5929tO97wkvl/atCz+y xJrdwteW2FNW/NSmBP+f/maYtVs/bYyBC7Ox3jsYZHL05CIrBa/nS+b3bHfiYm4Ueil1YZZSgAUI fFZ1dxUmeA2oQRQ3RuGXNGLFV9/XbGFGPV6kfzk1TBBCd+izc7q1H+OHMJwmaBX2IQNYVAKHYepV SSGCe6CnbYHHETKGNe43EDvFgZr0gB/nVHPHZ80VV1ojOiI3XDvYIkl4ayo4bxQIgrFXWTvBI0nH VElWMuw2aLUWCRHHf8ymVCHjFlJnOSojfevCYyyyZDH0IcvHhrsnQ5O1OsWzONuVVKIxSxiFZ/tR fKDAf6xFTnw4O9Qig2VCfW2hJQrmMOuHW0W3dLQmCMO2ccdUd/xyfflH/olTiHZVdGwb8nIwRzSE J15jFlOJuBZBZ4CiyHyd2IFylFlB+HgHhYabhWOGwYO1ZH/Og1dtQlFMk352CGRSIFTapnWQEUtN l4zv8S0aaCFDyGCBqDUxZYpxGHX01y/JuH1xhn7TOCnNCI4eKDs5WGX4R425F4vF1o3BJ4vO0otq I3rimI7jJY1jISqnBxknCIvruF83mF5wN4X7qGLIhR8A2Vg0yFERSIXn9Vv3GHy3Vj/WIkKddlYi yIMv2I/VMjTLpW7pt05SWIZR0RPyxpB4SIUM9lBPGBl0GC7oSEEwRYLe4pJpZY2P0zbI1n+Oc44w qY3PUnmF0ixjVpDD/mJ9wpOBGTVgXlaCaZiPcIWK5NiKBIiPdGaQ0TWGvAiG7nMchdZb7Vgf8zNi MuMyzRdy/lePe9iC4TRx7WhhOQI/QiSVNAmAa2lT/piFbuh7ofJoYSZzrSZ1bvmWw3eN2nKUPVky uPN5/VRfohRd0VYZoqhKIlU6TXYhJxmPUIloAwc1bPmHEpaZYZORHNlXUJM07hATwHR8MJYqkwWR WaIezFhxSFlc8/Fq82hEnpeRozg3ULhhr9lAGtVEkCg5ZNRuuVleBPaZadhG0ZgkyPmDOTOKzViM YgOcpukKqQcbjAWS0IleQ2ROjdh6A+md1qWdBRSX7iSYgFRTtRmBpJioieXJiHfJiMGIR9fJOn8I MSfXYhspn4ooSa2mSAj4n+8Bmg03fBJZoPOJgsVZRxu1oOMRPXYYjdqjihFaEoZpXBREanuJoRI6 cibFinq4ngUKh/wQd/H5ofYCZ0HJXR62opZFaAT0iFIZo4DIiUojkjeqKiuoZirKo5Y1a7AWckGa BkuYoD5lpDK6eUs6CkDqpETwl1EqpfhJpVeKpVl6EgUAADs= --BOUNDARY-- --OUTER-- --- NEW FILE: msg_14.txt --- Return-Path: Delivered-To: bbb@zzz.org Received: by mail.zzz.org (Postfix, from userid 889) id 27CEAD38CC; Fri, 4 May 2001 14:05:44 -0400 (EDT) MIME-Version: 1.0 Content-Type: text; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <15090.61304.110929.45684@aaa.zzz.org> From: bbb@ddd.com (John X. Doe) To: bbb@zzz.org Subject: This is a test message Date: Fri, 4 May 2001 14:05:44 -0400 Hi, I'm sorry but I'm using a drainbread ISP, which although big and wealthy can't seem to generate standard compliant email. :( This message has a Content-Type: header with no subtype. I hope you can still read it. -Me --- NEW FILE: msg_15.txt --- Return-Path: Received: from fepD.post.tele.dk (195.41.46.149) by mail.groupcare.dk (LSMTP for Windows NT v1.1b) with SMTP id <0.0014F8A2@mail.groupcare.dk>; Mon, 30 Apr 2001 12:17:50 +0200 User-Agent: Microsoft-Outlook-Express-Macintosh-Edition/5.02.2106 Subject: XX From: xx@xx.dk To: XX Message-ID: Mime-version: 1.0 Content-type: multipart/mixed; boundary="MS_Mac_OE_3071477847_720252_MIME_Part" > Denne meddelelse er i MIME-format. Da dit postl¾sningsprogram ikke forstŒr dette format, kan del af eller hele meddelelsen v¾re ul¾selig. --MS_Mac_OE_3071477847_720252_MIME_Part Content-type: multipart/alternative; boundary="MS_Mac_OE_3071477847_720252_MIME_Part" --MS_Mac_OE_3071477847_720252_MIME_Part Content-type: text/plain; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable Some removed test. --MS_Mac_OE_3071477847_720252_MIME_Part Content-type: text/html; charset="ISO-8859-1" Content-transfer-encoding: quoted-printable Some removed HTML Some removed text. --MS_Mac_OE_3071477847_720252_MIME_Part-- --MS_Mac_OE_3071477847_720252_MIME_Part Content-type: image/gif; name="xx.gif"; x-mac-creator="6F676C65"; x-mac-type="47494666" Content-disposition: attachment Content-transfer-encoding: base64 Some removed base64 encoded chars. --MS_Mac_OE_3071477847_720252_MIME_Part-- From tim_one@users.sourceforge.net Sun Sep 23 05:06:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 21:06:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv18490/python/Doc/lib Modified Files: libstdtypes.tex Log Message: Generalize file.writelines() to allow iterable objects. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** libstdtypes.tex 2001/09/22 04:34:48 1.69 --- libstdtypes.tex 2001/09/23 04:06:04 1.70 *************** *** 1313,1318 **** \end{methoddesc} ! \begin{methoddesc}[file]{writelines}{list} ! Write a list of strings to the file. There is no return value. (The name is intended to match \method{readlines()}; \method{writelines()} does not add line separators.) --- 1313,1320 ---- \end{methoddesc} ! \begin{methoddesc}[file]{writelines}{sequence} ! Write a sequence of strings to the file. The sequence can be any ! iterable object producing strings, typically a list of strings. ! There is no return value. (The name is intended to match \method{readlines()}; \method{writelines()} does not add line separators.) From tim_one@users.sourceforge.net Sun Sep 23 05:06:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 21:06:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts ndiff.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv18490/python/Tools/scripts Modified Files: ndiff.py Log Message: Generalize file.writelines() to allow iterable objects. Index: ndiff.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/ndiff.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** ndiff.py 2001/09/22 21:59:18 1.11 --- ndiff.py 2001/09/23 04:06:05 1.12 *************** *** 119,124 **** def restore(which): restored = difflib.restore(sys.stdin.readlines(), which) ! for line in restored: ! print line, if __name__ == '__main__': --- 119,123 ---- def restore(which): restored = difflib.restore(sys.stdin.readlines(), which) ! sys.stdout.writelines(restored) if __name__ == '__main__': From tim_one@users.sourceforge.net Sun Sep 23 05:06:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 21:06:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.251,1.252 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv18490/python/Misc Modified Files: NEWS Log Message: Generalize file.writelines() to allow iterable objects. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.251 retrieving revision 1.252 diff -C2 -d -r1.251 -r1.252 *** NEWS 2001/09/22 21:30:22 1.251 --- NEWS 2001/09/23 04:06:04 1.252 *************** *** 4,7 **** --- 4,9 ---- Core + - file.writelines() now accepts any iterable object producing strings. + - PyUnicode_FromEncodedObject() now works very much like PyObject_Str(obj) in that it tries to use __str__/tp_str From tim_one@users.sourceforge.net Sun Sep 23 05:06:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 21:06:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.130,2.131 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18490/python/Objects Modified Files: fileobject.c Log Message: Generalize file.writelines() to allow iterable objects. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.130 retrieving revision 2.131 diff -C2 -d -r2.130 -r2.131 *** fileobject.c 2001/09/20 21:45:26 2.130 --- fileobject.c 2001/09/23 04:06:05 2.131 *************** *** 1165,1217 **** static PyObject * ! file_writelines(PyFileObject *f, PyObject *args) { #define CHUNKSIZE 1000 PyObject *list, *line; PyObject *result; int i, j, index, len, nwritten, islist; if (f->f_fp == NULL) return err_closed(); - if (args == NULL || !PySequence_Check(args)) { - PyErr_SetString(PyExc_TypeError, - "writelines() argument must be a sequence of strings"); - return NULL; - } - islist = PyList_Check(args); ! /* Strategy: slurp CHUNKSIZE lines into a private list, ! checking that they are all strings, then write that list ! without holding the interpreter lock, then come back for more. */ ! index = 0; ! if (islist) ! list = NULL; else { list = PyList_New(CHUNKSIZE); if (list == NULL) ! return NULL; } - result = NULL; ! for (;;) { if (islist) { Py_XDECREF(list); ! list = PyList_GetSlice(args, index, index+CHUNKSIZE); if (list == NULL) ! return NULL; j = PyList_GET_SIZE(list); } else { for (j = 0; j < CHUNKSIZE; j++) { ! line = PySequence_GetItem(args, index+j); if (line == NULL) { ! if (PyErr_ExceptionMatches( ! PyExc_IndexError)) { ! PyErr_Clear(); ! break; ! } ! /* Some other error occurred. ! XXX We may lose some output. */ ! goto error; } PyList_SetItem(list, j, line); --- 1165,1216 ---- static PyObject * ! file_writelines(PyFileObject *f, PyObject *seq) { #define CHUNKSIZE 1000 PyObject *list, *line; + PyObject *it; /* iter(seq) */ PyObject *result; int i, j, index, len, nwritten, islist; + assert(seq != NULL); if (f->f_fp == NULL) return err_closed(); ! result = NULL; ! list = NULL; ! islist = PyList_Check(seq); ! if (islist) ! it = NULL; else { + it = PyObject_GetIter(seq); + if (it == NULL) { + PyErr_SetString(PyExc_TypeError, + "writelines() requires an iterable argument"); + return NULL; + } + /* From here on, fail by going to error, to reclaim "it". */ list = PyList_New(CHUNKSIZE); if (list == NULL) ! goto error; } ! /* Strategy: slurp CHUNKSIZE lines into a private list, ! checking that they are all strings, then write that list ! without holding the interpreter lock, then come back for more. */ ! for (index = 0; ; index += CHUNKSIZE) { if (islist) { Py_XDECREF(list); ! list = PyList_GetSlice(seq, index, index+CHUNKSIZE); if (list == NULL) ! goto error; j = PyList_GET_SIZE(list); } else { for (j = 0; j < CHUNKSIZE; j++) { ! line = PyIter_Next(it); if (line == NULL) { ! if (PyErr_Occurred()) ! goto error; ! break; } PyList_SetItem(list, j, line); *************** *** 1272,1276 **** if (j < CHUNKSIZE) break; - index += CHUNKSIZE; } --- 1271,1274 ---- *************** *** 1279,1283 **** --- 1277,1283 ---- error: Py_XDECREF(list); + Py_XDECREF(it); return result; + #undef CHUNKSIZE } *************** *** 1343,1350 **** static char writelines_doc[] = ! "writelines(list of strings) -> None. Write the strings to the file.\n" "\n" ! "Note that newlines are not added. This is equivalent to calling write()\n" ! "for each string in the list."; static char flush_doc[] = --- 1343,1350 ---- static char writelines_doc[] = ! "writelines(sequence_of_strings) -> None. Write the strings to the file.\n" "\n" ! "Note that newlines are not added. The sequence can be any iterable object\n" ! "producing strings. This is equivalent to calling write() for each string."; static char flush_doc[] = From tim_one@users.sourceforge.net Sun Sep 23 05:06:07 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 22 Sep 2001 21:06:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_iter.py,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18490/python/Lib/test Modified Files: test_iter.py Log Message: Generalize file.writelines() to allow iterable objects. Index: test_iter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_iter.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** test_iter.py 2001/09/20 21:33:42 1.20 --- test_iter.py 2001/09/23 04:06:04 1.21 *************** *** 642,645 **** --- 642,698 ---- self.assertRaises(ValueError, indexOf, iclass, -1) + # Test iterators with file.writelines(). + def test_writelines(self): + f = file(TESTFN, "w") + + try: + self.assertRaises(TypeError, f.writelines, None) + self.assertRaises(TypeError, f.writelines, 42) + + f.writelines(["1\n", "2\n"]) + f.writelines(("3\n", "4\n")) + f.writelines({'5\n': None}) + f.writelines({}) + + # Try a big chunk too. + class Iterator: + def __init__(self, start, finish): + self.start = start + self.finish = finish + self.i = self.start + + def next(self): + if self.i >= self.finish: + raise StopIteration + result = str(self.i) + '\n' + self.i += 1 + return result + + def __iter__(self): + return self + + class Whatever: + def __init__(self, start, finish): + self.start = start + self.finish = finish + + def __iter__(self): + return Iterator(self.start, self.finish) + + f.writelines(Whatever(6, 6+2000)) + f.close() + + f = file(TESTFN) + expected = [str(i) + "\n" for i in range(1, 2006)] + self.assertEqual(list(f), expected) + + finally: + f.close() + try: + unlink(TESTFN) + except OSError: + pass + + # Test iterators on RHS of unpacking assignments. def test_unpack_iter(self): From tim_one@users.sourceforge.net Sun Sep 23 08:02:31 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 23 Sep 2001 00:02:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv6734/python/dist/src/PCbuild Modified Files: python20.wse Log Message: Install the new Lib/email pkg. Create & populate the new Lib/test/data directory. Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -d -r1.90 -r1.91 *** python20.wse 2001/09/20 04:09:39 1.90 --- python20.wse 2001/09/23 07:02:29 1.91 *************** *** 1898,1901 **** --- 1898,1909 ---- end item: Install File + Source=..\Lib\email\*.py + Destination=%MAINDIR%\Lib\email + Description=Library email package + Flags=0000000000000010 + end + item: Remark + end + item: Install File Source=..\lib\distutils\*.py Destination=%MAINDIR%\Lib\distutils *************** *** 2217,2220 **** --- 2225,2236 ---- Source=..\lib\test\*.out Destination=%MAINDIR%\Lib\test + Description=Python Test files + Flags=0000000000000010 + end + item: Remark + end + item: Install File + Source=..\lib\test\data\*.* + Destination=%MAINDIR%\Lib\test\data Description=Python Test files Flags=0000000000000010 From loewis@users.sourceforge.net Sun Sep 23 11:20:12 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 23 Sep 2001 03:20:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules pyexpat.c,2.50,2.51 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv304 Modified Files: pyexpat.c Log Message: Reactivate participation of expat parsers in GC. Fixes bug #462710. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.50 retrieving revision 2.51 diff -C2 -d -r2.50 -r2.51 *** pyexpat.c 2001/09/19 10:37:50 2.50 --- pyexpat.c 2001/09/23 10:20:10 2.51 *************** *** 978,983 **** new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype); #else ! /* Python versions 1.6 and later */ new_parser = PyObject_New(xmlparseobject, &Xmlparsetype); #endif --- 978,988 ---- new_parser = PyObject_NEW(xmlparseobject, &Xmlparsetype); #else ! #ifndef Py_TPFLAGS_HAVE_GC ! /* Python versions 1.6 to 2.1 */ new_parser = PyObject_New(xmlparseobject, &Xmlparsetype); + #else + /* Python versions 2.2 and later */ + new_parser = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + #endif #endif *************** *** 991,995 **** --- 996,1004 ---- encoding); new_parser->handlers = 0; + #ifdef Py_TPFLAGS_HAVE_GC + PyObject_GC_Track(new_parser); + #else PyObject_GC_Init(new_parser); + #endif if (!new_parser->itself) { *************** *** 1140,1144 **** --- 1149,1158 ---- #else /* Code for versions 1.6 and later */ + #ifdef Py_TPFLAGS_HAVE_GC + /* Code for versions 2.2 and later */ + self = PyObject_GC_New(xmlparseobject, &Xmlparsetype); + #else self = PyObject_New(xmlparseobject, &Xmlparsetype); + #endif if (self == NULL) return NULL; *************** *** 1156,1160 **** --- 1170,1178 ---- self->itself = XML_ParserCreate(encoding); } + #ifdef Py_TPFLAGS_HAVE_GC + PyObject_GC_Track(self); + #else PyObject_GC_Init(self); + #endif if (self->itself == NULL) { PyErr_SetString(PyExc_RuntimeError, *************** *** 1186,1190 **** --- 1204,1212 ---- { int i; + #ifdef Py_TPFLAGS_HAVE_GC + PyObject_GC_UnTrack(self); + #else PyObject_GC_Fini(self); + #endif if (self->itself != NULL) XML_ParserFree(self->itself); *************** *** 1204,1209 **** free(self); #else ! /* Code for versions 1.6 and later */ PyObject_Del(self); #endif } --- 1226,1236 ---- free(self); #else ! #ifndef Py_TPFLAGS_HAVE_GC ! /* Code for versions 1.6 to 2.1 */ PyObject_Del(self); + #else + /* Code for versions 2.2 and later. */ + PyObject_GC_Del(self); + #endif #endif } *************** *** 1371,1375 **** --- 1398,1406 ---- 0, /* tp_setattro */ 0, /* tp_as_buffer */ + #ifdef Py_TPFLAGS_HAVE_GC + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /*tp_flags*/ + #else Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ + #endif Xmlparsetype__doc__, /* Documentation string */ #ifdef WITH_CYCLE_GC From tim_one@users.sourceforge.net Sun Sep 23 22:29:58 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 23 Sep 2001 14:29:58 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19902/python/Lib Modified Files: pydoc.py Log Message: Part of a partial solution to SF bugs 463378, 463381, 463383, 463384. This almost entirely replaces how pydoc pumps out class docs, but only in text mode (like help(whatever) from a Python shell), not in GUI mode. A class C's attrs are now grouped by the class in which they're defined, attrs defined by C first, then inherited attrs grouped by alphabetic order of the defining classes' names. Within each of those groups, the attrs are subgrouped according to whether they're plain methods, class methods, static methods, properties, or data. Note that pydoc never dumped class data attrs before. If a class data attr is implemented via a data descriptor, the data docstring (if any) is also displayed (e.g., file.softspace). Within a subgroup, the attrs are listed alphabetically. This is a friggin' mess, and there are bound to be glitches. Please beat on it and complain! Here are three glitches: 1. __new__ gets classifed as 'data', for some reason. This will have to get fixed in inspect.py, but since the latter is already looking for any clue that something is a method, pydoc will almost certainly not know what to do with it when its classification changes. 2. properties are special-cased to death. Unlike any other kind of function or method, they don't have a __name__ attr, so none of pydoc's usual code can deal with them. Worse, the getter and setter and del'er methods associated with a property don't appear to be discoverable from Python, so there's really nothing I can think of to do here beyond just listing their names. Note that a property can't be given a docstring, either (or at least I've been unable to sneak one in) -- perhaps the property() constructor could take an optional doc argument? 3. In a nested-scopes world, pydoc still doesn't know anything about nesting, so e.g. classes nested in functions are effectively invisible. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -d -r1.43 -r1.44 *** pydoc.py 2001/09/20 06:08:24 1.43 --- pydoc.py 2001/09/23 21:29:55 1.44 *************** *** 129,132 **** --- 129,142 ---- return methods + def _split_class_attrs(attrs, predicate): + yes = [] + no = [] + for tuple in attrs: + if predicate(tuple): + yes.append(tuple) + else: + no.append(tuple) + return yes, no + # ----------------------------------------------------- module manipulation *************** *** 877,887 **** doc = getdoc(object) ! contents = doc and doc + '\n' ! methods = allmethods(object).items() ! methods.sort() ! for key, value in methods: ! contents = contents + '\n' + self.document(value, key, mod, object) ! if not contents: return title + '\n' return title + '\n' + self.indent(rstrip(contents), ' | ') + '\n' --- 887,964 ---- doc = getdoc(object) ! contents = doc and [doc + '\n'] or [] ! push = contents.append ! def spill(msg, attrs, predicate): ! ok, attrs = _split_class_attrs(attrs, predicate) ! if ok: ! push(msg) ! for name, kind, homecls, value in ok: ! push(self.document(getattr(object, name), ! name, mod, object)) ! return attrs ! ! # pydoc can't make any reasonable sense of properties on its own, ! # and it doesn't appear that the getter, setter and del'er methods ! # are discoverable. For now, just pump out their names. ! def spillproperties(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property') ! if ok: ! push(msg) ! for name, kind, homecls, value in ok: ! push(name + '\n') ! return attrs ! ! def spilldata(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') ! if ok: ! push(msg) ! for name, kind, homecls, value in ok: ! doc = getattr(value, "__doc__", None) ! push(self.docother(getattr(object, name), ! name, mod, 70, doc) + '\n') ! return attrs ! ! attrs = inspect.classify_class_attrs(object) ! ! # All attrs defined in this class come first. ! attrs, inherited = _split_class_attrs(attrs, ! lambda t: t[2] is object) ! # Sort inherited attrs by name of defining class. ! inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) ! ! thisclass = object ! while attrs or inherited: ! if thisclass is object: ! tag = "defined here" ! else: ! tag = "inherited from class %s" % classname(thisclass, ! object.__module__) ! ! # Sort attrs by name. ! attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) ! ! # Pump out the attrs, segregated by kind. ! attrs = spill("Methods %s:\n" % tag, attrs, ! lambda t: t[1] == 'method') ! attrs = spill("Class methods %s:\n" % tag, attrs, ! lambda t: t[1] == 'class method') ! attrs = spill("Static methods %s:\n" % tag, attrs, ! lambda t: t[1] == 'static method') ! attrs = spillproperties("Properties %s:\n" % tag, attrs) ! attrs = spilldata("Data %s:\n" % tag, attrs) ! assert attrs == [] ! ! # Split off the attributes inherited from the next class (note ! # that inherited remains sorted by class name). ! if inherited: ! attrs = inherited ! thisclass = attrs[0][2] ! attrs, inherited = _split_class_attrs(attrs, ! lambda t: t[2] is thisclass) ! ! contents = '\n'.join(contents) ! if not contents: ! return title + '\n' return title + '\n' + self.indent(rstrip(contents), ' | ') + '\n' *************** *** 934,938 **** return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n') ! def docother(self, object, name=None, mod=None, maxlen=None): """Produce text documentation for a data object.""" repr = self.repr(object) --- 1011,1015 ---- return decl + '\n' + (doc and rstrip(self.indent(doc)) + '\n') ! def docother(self, object, name=None, mod=None, maxlen=None, doc=None): """Produce text documentation for a data object.""" repr = self.repr(object) *************** *** 942,945 **** --- 1019,1024 ---- if chop < 0: repr = repr[:chop] + '...' line = (name and self.bold(name) + ' = ' or '') + repr + if doc is not None: + line += '\n' + self.indent(str(doc)) return line From bwarsaw@users.sourceforge.net Mon Sep 24 05:28:12 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Sun, 23 Sep 2001 21:28:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.252,1.253 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29689 Modified Files: NEWS Log Message: Added a note about the new email package. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.252 retrieving revision 1.253 diff -C2 -d -r1.252 -r1.253 *** NEWS 2001/09/23 04:06:04 1.252 --- NEWS 2001/09/24 04:28:10 1.253 *************** *** 57,60 **** --- 57,64 ---- Library + - The "email" package has been added. This is basically a port of the + mimelib package with API changes + and some implementations updated to use iterators and generators. + - difflib.ndiff() and difflib.Differ.compare() are generators now. This restores the ability of Tools/scripts/ndiff.py to start producing output From tim_one@users.sourceforge.net Mon Sep 24 05:47:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sun, 23 Sep 2001 21:47:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.44,1.45 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv32147/python/Lib Modified Files: pydoc.py Log Message: Try to do for pydoc's GUI mode what the earlier checkin did for text mode (identify the source class for class attrs; segregate attrs according to source class, and whether class method, static method, property, plain method, or data; display data attrs; display docstrings for data attrs when possible). Alas, this is mondo ugly, and I'm no HTML guy. Part of the problem is that pydoc's GUI mode has always been ugly under IE, largely because under IE renders docstrings unreadably small (while sometimes non-docstring text is painfully large). Another part is that these segregated listings of attrs would *probably* look much better as bulleted lists. Alas, when I tried that, the bullets all ended up on lines by themselves, before the method names; this is apparently because pydoc (ab?)uses definition lists for format effects, and at least under IE if a definition list is the first chunk of a list item, it gets rendered on a line after the
  • bullet. An HTML wizard would certainly be welcomed here. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.44 retrieving revision 1.45 diff -C2 -d -r1.44 -r1.45 *** pydoc.py 2001/09/23 21:29:55 1.44 --- pydoc.py 2001/09/24 04:47:19 1.45 *************** *** 605,618 **** name = name or realname bases = object.__bases__ - contents = '' ! methods, mdict = allmethods(object).items(), {} ! methods.sort() ! for key, value in methods: ! mdict[key] = mdict[value] = '#' + name + '-' + key ! for key, value in methods: ! contents = contents + self.document( ! value, key, mod, funcs, classes, mdict, object) if name == realname: title = 'class %s' % ( --- 605,701 ---- name = name or realname bases = object.__bases__ ! contents = [] ! push = contents.append ! ! def spill(msg, attrs, predicate): ! ok, attrs = _split_class_attrs(attrs, predicate) ! if ok: ! push(msg) ! for name, kind, homecls, value in ok: ! push(self.document(getattr(object, name), name, mod, ! funcs, classes, mdict, object)) ! push('\n') ! return attrs + # pydoc can't make any reasonable sense of properties on its own, + # and it doesn't appear that the getter, setter and del'er methods + # are discoverable. For now, just pump out their names. + def spillproperties(msg, attrs): + ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property') + if ok: + push(msg) + for name, kind, homecls, value in ok: + push('
    %s
    \n' % name) + return attrs + + def spilldata(msg, attrs): + ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') + if ok: + push(msg) + for name, kind, homecls, value in ok: + base = self.docother(getattr(object, name), name, mod) + doc = getattr(value, "__doc__", None) + if doc is None: + push('
    %s
    \n' % base) + else: + doc = self.markup(getdoc(value), self.preformat, + funcs, classes, mdict) + doc = '
    ' + self.small('%s' % doc) + push('
    %s%s
    \n' % (base, doc)) + push('\n') + return attrs + + attrs = inspect.classify_class_attrs(object) + mdict = {} + for key, kind, homecls, value in attrs: + mdict[key] = anchor = '#' + name + '-' + key + value = getattr(object, key) + try: + # The value may not be hashable (e.g., a data attr with + # a dict or list value). + mdict[value] = anchor + except TypeError: + pass + + # All attrs defined in this class come first. + attrs, inherited = _split_class_attrs(attrs, + lambda t: t[2] is object) + # Sort inherited attrs by name of defining class. + inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) + + thisclass = object + while attrs or inherited: + if thisclass is object: + tag = "defined here" + else: + tag = "inherited from class %s" % self.classlink(thisclass, + object.__module__) + tag += ':
    \n' + + # Sort attrs by name. + attrs.sort(lambda t1, t2: cmp(t1[0], t2[0])) + + # Pump out the attrs, segregated by kind. + attrs = spill("Methods %s" % tag, attrs, + lambda t: t[1] == 'method') + attrs = spill("Class methods %s" % tag, attrs, + lambda t: t[1] == 'class method') + attrs = spill("Static methods %s" % tag, attrs, + lambda t: t[1] == 'static method') + attrs = spillproperties("Properties %s" % tag, attrs) + attrs = spilldata("Data %s" % tag, attrs) + assert attrs == [] + + # Split off the attributes inherited from the next class (note + # that inherited remains sorted by class name). + if inherited: + attrs = inherited + thisclass = attrs[0][2] + attrs, inherited = _split_class_attrs(attrs, + lambda t: t[2] is thisclass) + + contents = ''.join(contents) + if name == realname: title = 'class %s' % ( *************** *** 909,913 **** push(name + '\n') return attrs ! def spilldata(msg, attrs): ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') --- 992,996 ---- push(name + '\n') return attrs ! def spilldata(msg, attrs): ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') From tim_one@users.sourceforge.net Mon Sep 24 09:05:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 01:05:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv2025/python/Lib Modified Files: pydoc.py Log Message: More work on class display: + Minor code cleanup, generalization and simplification. + "Do something" to make the attribute aggregation more apparent: - In text mode, stick a "* " at the front of subgroup header lines. - In GUI mode, display a horizontal rule between subgroups. For GUI mode, this is a huge improvement, at least under IE. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -d -r1.45 -r1.46 *** pydoc.py 2001/09/24 04:47:19 1.45 --- pydoc.py 2001/09/24 08:05:11 1.46 *************** *** 129,140 **** return methods ! def _split_class_attrs(attrs, predicate): yes = [] no = [] ! for tuple in attrs: ! if predicate(tuple): ! yes.append(tuple) else: ! no.append(tuple) return yes, no --- 129,147 ---- return methods ! def _split_list(s, predicate): ! """Split sequence s via predicate, and return pair ([true], [false]). ! ! The return value is a 2-tuple of lists, ! ([x for x in s if predicate(x)], ! [x for x in s if not predicate(x)]) ! """ ! yes = [] no = [] ! for x in s: ! if predicate(x): ! yes.append(x) else: ! no.append(x) return yes, no *************** *** 609,615 **** push = contents.append def spill(msg, attrs, predicate): ! ok, attrs = _split_class_attrs(attrs, predicate) if ok: push(msg) for name, kind, homecls, value in ok: --- 616,633 ---- push = contents.append + # Cute little class to pump out a horizontal rule between sections. + class HorizontalRule: + def __init__(self): + self.needone = 0 + def maybe(self): + if self.needone: + push('
    \n') + self.needone = 1 + hr = HorizontalRule() + def spill(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: *************** *** 622,628 **** # and it doesn't appear that the getter, setter and del'er methods # are discoverable. For now, just pump out their names. ! def spillproperties(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property') if ok: push(msg) for name, kind, homecls, value in ok: --- 640,647 ---- # and it doesn't appear that the getter, setter and del'er methods # are discoverable. For now, just pump out their names. ! def spillproperties(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: *************** *** 630,636 **** return attrs ! def spilldata(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') if ok: push(msg) for name, kind, homecls, value in ok: --- 649,656 ---- return attrs ! def spilldata(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: *************** *** 659,674 **** pass ! # All attrs defined in this class come first. ! attrs, inherited = _split_class_attrs(attrs, ! lambda t: t[2] is object) ! # Sort inherited attrs by name of defining class. ! inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) ! thisclass = object ! while attrs or inherited: if thisclass is object: tag = "defined here" else: ! tag = "inherited from class %s" % self.classlink(thisclass, object.__module__) tag += ':
    \n' --- 679,693 ---- pass ! # Sort attrs by name of defining class. ! attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) ! thisclass = object # list attrs defined here first ! while attrs: ! attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) ! if thisclass is object: tag = "defined here" else: ! tag = "inherited from %s" % self.classlink(thisclass, object.__module__) tag += ':
    \n' *************** *** 684,689 **** attrs = spill("Static methods %s" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("Properties %s" % tag, attrs) ! attrs = spilldata("Data %s" % tag, attrs) assert attrs == [] --- 703,710 ---- attrs = spill("Static methods %s" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("Properties %s" % tag, attrs, ! lambda t: t[1] == 'property') ! attrs = spilldata("Data %s" % tag, attrs, ! lambda t: t[1] == 'data') assert attrs == [] *************** *** 693,698 **** attrs = inherited thisclass = attrs[0][2] - attrs, inherited = _split_class_attrs(attrs, - lambda t: t[2] is thisclass) contents = ''.join(contents) --- 714,717 ---- *************** *** 974,978 **** def spill(msg, attrs, predicate): ! ok, attrs = _split_class_attrs(attrs, predicate) if ok: push(msg) --- 993,997 ---- def spill(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: push(msg) *************** *** 985,990 **** # and it doesn't appear that the getter, setter and del'er methods # are discoverable. For now, just pump out their names. ! def spillproperties(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'property') if ok: push(msg) --- 1004,1009 ---- # and it doesn't appear that the getter, setter and del'er methods # are discoverable. For now, just pump out their names. ! def spillproperties(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: push(msg) *************** *** 993,998 **** return attrs ! def spilldata(msg, attrs): ! ok, attrs = _split_class_attrs(attrs, lambda t: t[1] == 'data') if ok: push(msg) --- 1012,1017 ---- return attrs ! def spilldata(msg, attrs, predicate): ! ok, attrs = _split_list(attrs, predicate) if ok: push(msg) *************** *** 1005,1021 **** attrs = inspect.classify_class_attrs(object) ! # All attrs defined in this class come first. ! attrs, inherited = _split_class_attrs(attrs, ! lambda t: t[2] is object) ! # Sort inherited attrs by name of defining class. ! inherited.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) ! thisclass = object ! while attrs or inherited: if thisclass is object: tag = "defined here" else: ! tag = "inherited from class %s" % classname(thisclass, ! object.__module__) # Sort attrs by name. --- 1024,1039 ---- attrs = inspect.classify_class_attrs(object) ! # Sort attrs by name of defining class. ! attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) ! thisclass = object # list attrs defined here first ! while attrs: ! attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) ! if thisclass is object: tag = "defined here" else: ! tag = "inherited from %s" % classname(thisclass, ! object.__module__) # Sort attrs by name. *************** *** 1023,1034 **** # Pump out the attrs, segregated by kind. ! attrs = spill("Methods %s:\n" % tag, attrs, lambda t: t[1] == 'method') ! attrs = spill("Class methods %s:\n" % tag, attrs, lambda t: t[1] == 'class method') ! attrs = spill("Static methods %s:\n" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("Properties %s:\n" % tag, attrs) ! attrs = spilldata("Data %s:\n" % tag, attrs) assert attrs == [] --- 1041,1054 ---- # Pump out the attrs, segregated by kind. ! attrs = spill("* Methods %s:\n" % tag, attrs, lambda t: t[1] == 'method') ! attrs = spill("* Class methods %s:\n" % tag, attrs, lambda t: t[1] == 'class method') ! attrs = spill("* Static methods %s:\n" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("* Properties %s:\n" % tag, attrs, ! lambda t: t[1] == 'property') ! attrs = spilldata("* Data %s:\n" % tag, attrs, ! lambda t: t[1] == 'data') assert attrs == [] *************** *** 1038,1043 **** attrs = inherited thisclass = attrs[0][2] - attrs, inherited = _split_class_attrs(attrs, - lambda t: t[2] is thisclass) contents = '\n'.join(contents) --- 1058,1061 ---- From fdrake@users.sourceforge.net Mon Sep 24 16:29:49 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 24 Sep 2001 08:29:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv15500/api Modified Files: refcounts.dat Log Message: Add more reference count information. Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** refcounts.dat 2001/09/23 02:05:26 1.32 --- refcounts.dat 2001/09/24 15:29:47 1.33 *************** *** 94,97 **** --- 94,114 ---- PyComplex_RealAsDouble:PyObject*:op:0: + PyDescr_NewGetSet:PyObject*::+1: + PyDescr_NewGetSet:PyTypeObject*:type:: + PyDescr_NewGetSet:PyGetSetDef*:getset:: + + PyDescr_NewMember:PyObject*::+1: + PyDescr_NewMember:PyTypeObject*:type:: + PyDescr_NewMember:PyMemberDef*:member:: + + PyDescr_NewMethod:PyObject*::+1: + PyDescr_NewMethod:PyTypeObject*:type:: + PyDescr_NewMethod:PyMethodDef*:meth:: + + PyDescr_NewWrapper:PyObject*::+1: + PyDescr_NewWrapper:PyTypeObject*:type:: + PyDescr_NewWrapper:struct wrapperbase*:base:: + PyDescr_NewWrapper:void*:wrapped:: + PyDict_Check:int::: PyDict_Check:PyObject*:p:0: *************** *** 149,152 **** --- 166,172 ---- PyDict_Values:PyObject*:p:0: + PyDictProxy_New:PyObject*::+1: + PyDictProxy_New:PyObject*:dict:0: + PyErr_BadArgument:int::: *************** *** 926,929 **** --- 946,957 ---- PySequence_Tuple:PyObject*::+1: PySequence_Tuple:PyObject*:o:0: + + PySlice_Check:int::: + PySlice_Check:PyObject*:ob:0: + + PySlice_New:PyObject*::+1: + PySlice_New:PyObject*:start:0: + PySlice_New:PyObject*:stop:0: + PySlice_New:PyObject*:step:0: PyString_AS_STRING:char*::: From fdrake@users.sourceforge.net Mon Sep 24 16:31:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 24 Sep 2001 08:31:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.149,1.150 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv15999/api Modified Files: api.tex Log Message: Add more signature information and some descriptions for the new APIs introduced in Python 2.2. Add documentation for the slice object interface (not complete). Added version annotations for several of the Python 2.2 APIs already documented. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.149 retrieving revision 1.150 diff -C2 -d -r1.149 -r1.150 *** api.tex 2001/09/23 02:05:26 1.149 --- api.tex 2001/09/24 15:31:50 1.150 *************** *** 1691,1694 **** --- 1691,1695 ---- Return true if the object \var{o} is of type \var{type} or a subtype of \var{type}. Both parameters must be non-\NULL. + \versionadded{2.2} \end{cfuncdesc} *************** *** 2340,2351 **** --- 2341,2359 ---- \begin{cfuncdesc}{int}{PyType_IsSubtype}{PyTypeObject *a, PyTypeObject *b} Returns true if \var{a} is a subtype of \var{b}. + \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyType_GenericAlloc}{PyTypeObject *type, int nitems} + \versionadded{2.2} \end{cfuncdesc} \begin{cfuncdesc}{PyObject*}{PyType_GenericNew}{PyTypeObject *type, PyObject *args, PyObject *kwds} + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PyType_Ready}{PyTypeObject *type} + \versionadded{2.2} \end{cfuncdesc} *************** *** 3956,3959 **** --- 3964,3974 ---- \end{cfuncdesc} + \begin{cfuncdesc}{PyObject*}{PyDictProxy_New}{PyObject *dict} + Return a proxy object for a mapping which enforces read-only + behavior. This is normally used to create a proxy to prevent + modification of the dictionary for non-dynamic class types. + \versionadded{2.2} + \end{cfuncdesc} + \begin{cfuncdesc}{void}{PyDict_Clear}{PyObject *p} Empties an existing dictionary of all key-value pairs. *************** *** 4382,4389 **** --- 4397,4406 ---- \cfunction{PySeqIter_New()} and the one-argument form of the \function{iter()} built-in function for built-in sequence types. + \versionadded{2.2} \end{cvardesc} \begin{cfuncdesc}{int}{PySeqIter_Check}{op} Return true if the type of \var{op} is \cdata{PySeqIter_Type}. + \versionadded{2.2} \end{cfuncdesc} *************** *** 4392,4406 **** \var{seq}. The iteration ends when the sequence raises \exception{IndexError} for the subscripting operation. \end{cfuncdesc} - \begin{cvardesc}{PyTypeObject}{PyCallIter_Type} Type object for iterator objects returned by \cfunction{PyCallIter_New()} and the two-argument form of the \function{iter()} built-in function. \end{cvardesc} \begin{cfuncdesc}{int}{PyCallIter_Check}{op} Return true if the type of \var{op} is \cdata{PyCallIter_Type}. \end{cfuncdesc} --- 4409,4425 ---- \var{seq}. The iteration ends when the sequence raises \exception{IndexError} for the subscripting operation. + \versionadded{2.2} \end{cfuncdesc} \begin{cvardesc}{PyTypeObject}{PyCallIter_Type} Type object for iterator objects returned by \cfunction{PyCallIter_New()} and the two-argument form of the \function{iter()} built-in function. + \versionadded{2.2} \end{cvardesc} \begin{cfuncdesc}{int}{PyCallIter_Check}{op} Return true if the type of \var{op} is \cdata{PyCallIter_Type}. + \versionadded{2.2} \end{cfuncdesc} *************** *** 4412,4415 **** --- 4431,4503 ---- \var{callable} returns a value equal to \var{sentinel}, the iteration will be terminated. + \versionadded{2.2} + \end{cfuncdesc} + + + \subsection{Descriptor Objects \label{descriptor-objects}} + + \begin{cvardesc}{PyTypeObject}{PyProperty_Type} + The type object for a descriptor. + \versionadded{2.2} + \end{cvardesc} + + \begin{cfuncdesc}{PyObject*}{PyDescr_NewGetSet}{PyTypeObject *type, + PyGetSetDef *getset} + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyDescr_NewMember}{PyTypeObject *type, + PyMemberDef *meth} + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyDescr_NewMethod}{PyTypeObject *type, + PyMethodDef *meth} + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyDescr_NewWrapper}{PyTypeObject *type, + struct wrapperbase *wrapper, + void *wrapped} + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PyDescr_IsData}{PyObject *descr} + Returns true if the descriptor objects \var{descr} describes a data + attribute, or false if it describes a method. \var{descr} must be a + descriptor object; there is no error checking. + \versionadded{2.2} + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PyWrapper_New}{PyObject *, PyObject *} + \versionadded{2.2} + \end{cfuncdesc} + + + \subsection{Slice Objects \label{slice-objects}} + + \begin{cvardesc}{PyTypeObject}{PySlice_Type} + The type object for slice objects. This is the same as + \code{types.SliceType}. + \withsubitem{(in module types)}{\ttindex{SliceType}} + \end{cvardesc} + + \begin{cfuncdesc}{int}{PySlice_Check}{PyObject *ob} + Returns true if \var{ob} is a slice object; \var{ob} must not be + \NULL. + \end{cfuncdesc} + + \begin{cfuncdesc}{PyObject*}{PySlice_New}{PyObject *start, PyObject *stop, + PyObject *step} + Return a new slice object with the given values. The \var{start}, + \var{stop}, and \var{step} parameters are used as the values of the + slice object attributes of the same names. Any of the values may be + \NULL, in which case the \code{None} will be used for the + corresponding attribute. Returns \NULL{} if the new object could + not be allocated. + \end{cfuncdesc} + + \begin{cfuncdesc}{int}{PySlice_GetIndices}{PySliceObject *slice, int length, + int *start, int *stop, int *step} \end{cfuncdesc} From akuchling@users.sourceforge.net Mon Sep 24 16:37:21 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Mon, 24 Sep 2001 08:37:21 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0247.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv12685 Modified Files: pep-0247.txt Log Message: Clarify description of update() (Boyd Roberts) Clarify description of new (Tim Peters) Index: pep-0247.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0247.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0247.txt 2001/09/20 15:48:02 1.5 --- pep-0247.txt 2001/09/24 15:37:19 1.6 *************** *** 27,39 **** new([key] , [string]) ! Create a new hashing object and return it. You can now feed ! arbitrary strings into the object using its update() method, ! and can ask for the hash value at any time by calling its ! digest() method. ! ! The 'string' parameter, if supplied, will be immediately ! hashed into the object's starting state; an empty string or ! None. For keyed hashes such as HMAC, 'key' is a string ! containing the starting key. Arbitrary additional keyword arguments can be added to this --- 27,41 ---- new([key] , [string]) ! Create a new hashing object and return it. The first form is ! for hashes that are unkeyed; most hashes such as MD5 or SHA ! are unkeyed. For keyed hashes such as HMAC, 'key' is a string ! containing the starting key. The 'string' parameter, if ! supplied, will be immediately hashed into the object's ! starting state, as if obj.update(string) was called. ! ! After creating a hashing object, arbitrary strings can be fed ! into the object using its update() method, and the hash value ! can be obtained at any time by calling the object's digest() ! method. Arbitrary additional keyword arguments can be added to this *************** *** 89,95 **** method mustn't alter the object. ! update(arg) ! Update this hashing object with the string 'arg'. Hashing modules can define additional module-level functions or --- 91,99 ---- method mustn't alter the object. ! update(string) ! Hash 'string' into the current state of the hashing object. ! update() can be called any number of times during a hashing ! object's lifetime. Hashing modules can define additional module-level functions or From gvanrossum@users.sourceforge.net Mon Sep 24 17:04:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 09:04:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.69,2.70 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24518/Objects Modified Files: typeobject.c Log Message: Fix the baffler that Tim reported: sometimes the repr() of an object looks like , sometimes it says . Make this uniformly say . Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.69 retrieving revision 2.70 diff -C2 -d -r2.69 -r2.70 *** typeobject.c 2001/09/21 21:24:49 2.69 --- typeobject.c 2001/09/24 16:03:58 2.70 *************** *** 1158,1167 **** return NULL; if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) ! rtn = PyString_FromFormat("<%s.%s instance at %p>", PyString_AS_STRING(mod), PyString_AS_STRING(name), self); else ! rtn = PyString_FromFormat("<%s instance at %p>", type->tp_name, self); Py_XDECREF(mod); --- 1158,1167 ---- return NULL; if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) ! rtn = PyString_FromFormat("<%s.%s object at %p>", PyString_AS_STRING(mod), PyString_AS_STRING(name), self); else ! rtn = PyString_FromFormat("<%s object at %p>", type->tp_name, self); Py_XDECREF(mod); From gvanrossum@users.sourceforge.net Mon Sep 24 17:04:01 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 09:04:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24518/Lib/test Modified Files: test_descr.py Log Message: Fix the baffler that Tim reported: sometimes the repr() of an object looks like , sometimes it says . Make this uniformly say . Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** test_descr.py 2001/09/21 21:24:49 1.69 --- test_descr.py 2001/09/24 16:03:59 1.70 *************** *** 1194,1198 **** # Note that the module name appears in str/repr, and that varies # depending on whether this test is run standalone or from a framework. ! verify(str(c1).find('C instance at ') >= 0) verify(str(c1) == repr(c1)) verify(-1 not in c1) --- 1194,1198 ---- # Note that the module name appears in str/repr, and that varies # depending on whether this test is run standalone or from a framework. ! verify(str(c1).find('C object at ') >= 0) verify(str(c1) == repr(c1)) verify(-1 not in c1) *************** *** 1217,1221 **** # Note that the module name appears in str/repr, and that varies # depending on whether this test is run standalone or from a framework. ! verify(str(d1).find('D instance at ') >= 0) verify(str(d1) == repr(d1)) verify(-1 not in d1) --- 1217,1221 ---- # Note that the module name appears in str/repr, and that varies # depending on whether this test is run standalone or from a framework. ! verify(str(d1).find('D object at ') >= 0) verify(str(d1) == repr(d1)) verify(-1 not in d1) From gvanrossum@users.sourceforge.net Mon Sep 24 17:51:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 09:51:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects stringobject.c,2.133,2.134 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7513/Objects Modified Files: stringobject.c Log Message: Change string comparison so that it applies even when one (or both) arguments are subclasses of str, as long as they don't override rich comparison. Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.133 retrieving revision 2.134 diff -C2 -d -r2.133 -r2.134 *** stringobject.c 2001/09/12 07:54:51 2.133 --- stringobject.c 2001/09/24 16:51:54 2.134 *************** *** 825,831 **** PyObject *result; ! /* One of the objects is a string object. Make sure the ! other one is one, too. */ ! if (a->ob_type != b->ob_type) { result = Py_NotImplemented; goto out; --- 825,832 ---- PyObject *result; ! /* May sure both arguments use string comparison. ! This implies PyString_Check(a) && PyString_Check(b). */ ! if (a->ob_type->tp_richcompare != (richcmpfunc)string_richcompare || ! b->ob_type->tp_richcompare != (richcmpfunc)string_richcompare) { result = Py_NotImplemented; goto out; From gvanrossum@users.sourceforge.net Mon Sep 24 17:51:56 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 09:51:56 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.70,1.71 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7513/Lib/test Modified Files: test_descr.py Log Message: Change string comparison so that it applies even when one (or both) arguments are subclasses of str, as long as they don't override rich comparison. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** test_descr.py 2001/09/24 16:03:59 1.70 --- test_descr.py 2001/09/24 16:51:54 1.71 *************** *** 1556,1560 **** return self._rev s = madstring("abcdefghijklmnopqrstuvwxyz") ! #XXX verify(s == "abcdefghijklmnopqrstuvwxyz") verify(s.rev() == madstring("zyxwvutsrqponmlkjihgfedcba")) verify(s.rev().rev() == madstring("abcdefghijklmnopqrstuvwxyz")) --- 1556,1560 ---- return self._rev s = madstring("abcdefghijklmnopqrstuvwxyz") ! verify(s == "abcdefghijklmnopqrstuvwxyz") verify(s.rev() == madstring("zyxwvutsrqponmlkjihgfedcba")) verify(s.rev().rev() == madstring("abcdefghijklmnopqrstuvwxyz")) *************** *** 1570,1579 **** base = "\x00" * 5 s = madstring(base) ! #XXX verify(s == base) verify(str(s) == base) verify(str(s).__class__ is str) verify(hash(s) == hash(base)) ! #XXX verify({s: 1}[base] == 1) ! #XXX verify({base: 1}[s] == 1) verify((s + "").__class__ is str) verify(s + "" == base) --- 1570,1579 ---- base = "\x00" * 5 s = madstring(base) ! verify(s == base) verify(str(s) == base) verify(str(s).__class__ is str) verify(hash(s) == hash(base)) ! verify({s: 1}[base] == 1) ! verify({base: 1}[s] == 1) verify((s + "").__class__ is str) verify(s + "" == base) *************** *** 1614,1618 **** s = madstring("x y") ! #XXX verify(s == "x y") verify(intern(s).__class__ is str) verify(intern(s) is intern("x y")) --- 1614,1618 ---- s = madstring("x y") ! verify(s == "x y") verify(intern(s).__class__ is str) verify(intern(s) is intern("x y")) *************** *** 1621,1625 **** i = intern("y x") s = madstring("y x") ! #XXX verify(s == i) verify(intern(s).__class__ is str) verify(intern(s) is i) --- 1621,1625 ---- i = intern("y x") s = madstring("y x") ! verify(s == i) verify(intern(s).__class__ is str) verify(intern(s) is i) From loewis@users.sourceforge.net Mon Sep 24 18:14:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Mon, 24 Sep 2001 10:14:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules md5c.c,2.6,2.7 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13462 Modified Files: md5c.c Log Message: Patch #463421: speed up md5 module with real memcpy/set. Index: md5c.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/md5c.c,v retrieving revision 2.6 retrieving revision 2.7 diff -C2 -d -r2.6 -r2.7 *** md5c.c 2000/09/28 02:54:51 2.6 --- md5c.c 2001/09/24 17:14:40 2.7 *************** *** 49,54 **** static void Encode(unsigned char *, UINT4 *, unsigned int); static void Decode(UINT4 *, unsigned char *, unsigned int); - static void MD5_memcpy(POINTER, POINTER, unsigned int); - static void MD5_memset(POINTER, int, unsigned int); static unsigned char PADDING[64] = { --- 49,52 ---- *************** *** 127,131 **** /* Transform as many times as possible. */ if (inputLen >= partLen) { ! MD5_memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform(context->state, context->buffer); --- 125,129 ---- /* Transform as many times as possible. */ if (inputLen >= partLen) { ! memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen); MD5Transform(context->state, context->buffer); *************** *** 139,143 **** /* Buffer remaining input */ ! MD5_memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); } --- 137,141 ---- /* Buffer remaining input */ ! memcpy((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i); } *************** *** 167,171 **** /* Zeroize sensitive information. */ ! MD5_memset((POINTER)context, 0, sizeof (*context)); } --- 165,169 ---- /* Zeroize sensitive information. */ ! memset((POINTER)context, 0, sizeof (*context)); } *************** *** 257,261 **** /* Zeroize sensitive information. */ ! MD5_memset((POINTER)x, 0, sizeof (x)); } --- 255,259 ---- /* Zeroize sensitive information. */ ! memset((POINTER)x, 0, sizeof (x)); } *************** *** 290,314 **** (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); } - } - - - /* Note: Replace "for loop" with standard memcpy if possible. */ - static void - MD5_memcpy(POINTER output, POINTER input, unsigned int len) - { - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = input[i]; - } - - - /* Note: Replace "for loop" with standard memset if possible. */ - static void - MD5_memset(POINTER output, int value, unsigned int len) - { - unsigned int i; - - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; } --- 288,290 ---- From jvr@users.sourceforge.net Mon Sep 24 18:29:11 2001 From: jvr@users.sourceforge.net (Just van Rossum) Date: Mon, 24 Sep 2001 10:29:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Mac/Tools/CGI BuildCGIApplet.py,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Mac/Tools/CGI In directory usw-pr-cvs1:/tmp/cvs-serv18897 Modified Files: BuildCGIApplet.py Log Message: Fixed old bug (caused by careless Carbonizing) that noone noticed until this week (apparently me and Bob Heeter at more or less the same time). Index: BuildCGIApplet.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Mac/Tools/CGI/BuildCGIApplet.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** BuildCGIApplet.py 2001/08/25 12:01:48 1.4 --- BuildCGIApplet.py 2001/09/24 17:29:09 1.5 *************** *** 65,69 **** buildtools.process(template, wrapper, dst, 1) # write source as a PYC resource into dst ! ref = Res.FSpOpenResFile(dst, 1) try: Res.UseResFile(ref) --- 65,69 ---- buildtools.process(template, wrapper, dst, 1) # write source as a PYC resource into dst ! ref = Res.FSpOpenResFile(dst, 2) try: Res.UseResFile(ref) From lemburg@users.sourceforge.net Mon Sep 24 18:34:54 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Mon, 24 Sep 2001 10:34:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib StringIO.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20159/Lib Modified Files: StringIO.py Log Message: StringIO patch #462596: let's [c]StringIO accept read buffers on input to .write() too. Index: StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/StringIO.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** StringIO.py 2001/09/22 04:34:54 1.18 --- StringIO.py 2001/09/24 17:34:52 1.19 *************** *** 39,43 **** class StringIO: def __init__(self, buf = ''): ! self.buf = buf self.len = len(buf) self.buflist = [] --- 39,44 ---- class StringIO: def __init__(self, buf = ''): ! # Force self.buf to be a string ! self.buf = str(buf) self.len = len(buf) self.buflist = [] *************** *** 135,138 **** --- 136,141 ---- raise ValueError, "I/O operation on closed file" if not s: return + # Force s to be a string + s = str(s) if self.pos > self.len: self.buflist.append('\0'*(self.pos - self.len)) From lemburg@users.sourceforge.net Mon Sep 24 18:34:54 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Mon, 24 Sep 2001 10:34:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_StringIO.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20159/Lib/test Modified Files: test_StringIO.py Log Message: StringIO patch #462596: let's [c]StringIO accept read buffers on input to .write() too. Index: test_StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_StringIO.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_StringIO.py 2001/09/22 04:33:47 1.7 --- test_StringIO.py 2001/09/24 17:34:52 1.8 *************** *** 11,36 **** # use a class variable MODULE to define which module is being tested def setUp(self): ! self._line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' ! self._lines = (self._line + '\n') * 5 self._fp = self.MODULE.StringIO(self._lines) def test_reads(self): eq = self.assertEqual ! eq(self._fp.read(10), 'abcdefghij') ! eq(self._fp.readline(), 'klmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\n') eq(len(self._fp.readlines(60)), 2) def test_writes(self): f = self.MODULE.StringIO() ! f.write('abcdef') f.seek(3) ! f.write('uvwxyz') ! f.write('!') self.assertEqual(f.getvalue(), 'abcuvwxyz!') def test_writelines(self): f = self.MODULE.StringIO() ! f.writelines(['a', 'b', 'c']) f.seek(0) self.assertEqual(f.getvalue(), 'abc') --- 11,43 ---- # use a class variable MODULE to define which module is being tested + # Line of data to test as string + _line = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!' + + # Constructor to use for the test data (._line is passed to this + # constructor) + constructor = str + def setUp(self): ! self._line = self.constructor(self._line) ! self._lines = self.constructor((self._line + '\n') * 5) self._fp = self.MODULE.StringIO(self._lines) def test_reads(self): eq = self.assertEqual ! eq(self._fp.read(10), self._line[:10]) ! eq(self._fp.readline(), self._line[10:] + '\n') eq(len(self._fp.readlines(60)), 2) def test_writes(self): f = self.MODULE.StringIO() ! f.write(self._line[:6]) f.seek(3) ! f.write(self._line[20:26]) ! f.write(self._line[52]) self.assertEqual(f.getvalue(), 'abcuvwxyz!') def test_writelines(self): f = self.MODULE.StringIO() ! f.writelines([self._line[0], self._line[1], self._line[2]]) f.seek(0) self.assertEqual(f.getvalue(), 'abc') *************** *** 65,72 **** --- 72,87 ---- MODULE = cStringIO + class TestBufferStringIO(TestStringIO): + constructor = buffer + + class TestBuffercStringIO(TestcStringIO): + constructor = buffer + def test_main(): test_support.run_unittest(TestStringIO) test_support.run_unittest(TestcStringIO) + test_support.run_unittest(TestBufferStringIO) + test_support.run_unittest(TestBuffercStringIO) if __name__ == '__main__': From lemburg@users.sourceforge.net Mon Sep 24 18:34:55 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Mon, 24 Sep 2001 10:34:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules cStringIO.c,2.29,2.30 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv20159/Modules Modified Files: cStringIO.c Log Message: StringIO patch #462596: let's [c]StringIO accept read buffers on input to .write() too. Index: cStringIO.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/cStringIO.c,v retrieving revision 2.29 retrieving revision 2.30 diff -C2 -d -r2.29 -r2.30 *** cStringIO.c 2001/09/22 04:36:49 2.29 --- cStringIO.c 2001/09/24 17:34:52 2.30 *************** *** 121,125 **** char *buf; int pos, string_size; ! PyObject *pbuf; } Iobject; --- 121,126 ---- char *buf; int pos, string_size; ! /* We store a reference to the object here in order to keep ! the buffer alive during the lifetime of the Iobject. */ PyObject *pbuf; } Iobject; *************** *** 425,436 **** static PyObject * O_write(Oobject *self, PyObject *args) { - PyObject *s; char *c; int l; ! UNLESS (PyArg_ParseTuple(args, "O:write", &s)) return NULL; - UNLESS (-1 != (l=PyString_Size(s))) return NULL; - UNLESS (c=PyString_AsString(s)) return NULL; if (O_cwrite((PyObject*)self,c,l) < 0) return NULL; --- 426,434 ---- static PyObject * O_write(Oobject *self, PyObject *args) { char *c; int l; ! UNLESS (PyArg_ParseTuple(args, "s#:write", &c, &l)) return NULL; if (O_cwrite((PyObject*)self,c,l) < 0) return NULL; *************** *** 714,724 **** int size; ! if (!PyString_Check(s)) { ! PyErr_Format(PyExc_TypeError, "expected string, %.200s found", s->ob_type->tp_name); return NULL; } - buf = PyString_AS_STRING(s); - size = PyString_GET_SIZE(s); UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL; Py_INCREF(s); --- 712,720 ---- int size; ! if (PyObject_AsReadBuffer(s, (const void **)&buf, &size)) { ! PyErr_Format(PyExc_TypeError, "expected read buffer, %.200s found", s->ob_type->tp_name); return NULL; } UNLESS (self = PyObject_New(Iobject, &Itype)) return NULL; Py_INCREF(s); From gvanrossum@users.sourceforge.net Mon Sep 24 18:52:06 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 10:52:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.71,1.72 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24951/Lib/test Modified Files: test_descr.py Log Message: Do the same thing to complex that I did to str: the rich comparison function returns NotImplemented when comparing objects whose tp_richcompare slot is not itself. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -d -r1.71 -r1.72 *** test_descr.py 2001/09/24 16:51:54 1.71 --- test_descr.py 2001/09/24 17:52:04 1.72 *************** *** 1864,1867 **** --- 1864,1882 ---- if verbose: print "Testing rich comparisons..." + class Z(complex): + pass + z = Z(1) + verify(z == 1+0j) + verify(1+0j == z) + class ZZ(complex): + def __eq__(self, other): + try: + return abs(self - other) <= 1e-6 + except: + return NotImplemented + zz = ZZ(1.0000003) + verify(zz == 1+0j) + verify(1+0j == zz) + class classic: pass From gvanrossum@users.sourceforge.net Mon Sep 24 18:52:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 10:52:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.47,2.48 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv24951/Objects Modified Files: complexobject.c Log Message: Do the same thing to complex that I did to str: the rich comparison function returns NotImplemented when comparing objects whose tp_richcompare slot is not itself. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.47 retrieving revision 2.48 diff -C2 -d -r2.47 -r2.48 *** complexobject.c 2001/09/20 20:46:18 2.47 --- complexobject.c 2001/09/24 17:52:04 2.48 *************** *** 554,563 **** PyObject *res; - if (op != Py_EQ && op != Py_NE) { - PyErr_SetString(PyExc_TypeError, - "cannot compare complex numbers using <, <=, >, >="); - return NULL; - } - c = PyNumber_CoerceEx(&v, &w); if (c < 0) --- 554,557 ---- *************** *** 567,571 **** return Py_NotImplemented; } ! if (!PyComplex_Check(v) || !PyComplex_Check(w)) { Py_DECREF(v); Py_DECREF(w); --- 561,568 ---- return Py_NotImplemented; } ! /* May sure both arguments use complex comparison. ! This implies PyComplex_Check(a) && PyComplex_Check(b). */ ! if (v->ob_type->tp_richcompare != complex_richcompare || ! w->ob_type->tp_richcompare != complex_richcompare) { Py_DECREF(v); Py_DECREF(w); *************** *** 578,581 **** --- 575,584 ---- Py_DECREF(v); Py_DECREF(w); + + if (op != Py_EQ && op != Py_NE) { + PyErr_SetString(PyExc_TypeError, + "cannot compare complex numbers using <, <=, >, >="); + return NULL; + } if ((i.real == j.real && i.imag == j.imag) == (op == Py_EQ)) From fdrake@users.sourceforge.net Mon Sep 24 19:44:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 24 Sep 2001 11:44:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22027 Modified Files: test_profilehooks.py Log Message: Add more tests showing the relationship between exceptions raised & caught and the information provided to the profiler. This stuff is a mess! Index: test_profilehooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profilehooks.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_profilehooks.py 2001/09/22 04:28:19 1.1 --- test_profilehooks.py 2001/09/24 18:44:11 1.2 *************** *** 29,36 **** def get_events(self): """Remove calls to add_event().""" ! add_event = self.add_event.im_func.func_code ! disallowed = (add_event.co_firstlineno, add_event.co_name) ! return [item for item in self.events if item[2] != disallowed] --- 29,36 ---- def get_events(self): """Remove calls to add_event().""" ! disallowed = [ident(self.add_event.im_func), ident(ident)] ! self.frames = None ! return [item for item in self.events if item[2] not in disallowed] *************** *** 53,60 **** def test_exception(self): def f(p): ! try: ! 1/0 ! except: ! pass f_ident = ident(f) self.check_events(f, [(0, 'call', f_ident), --- 53,58 ---- def test_exception(self): def f(p): ! try: 1/0 ! except: pass f_ident = ident(f) self.check_events(f, [(0, 'call', f_ident), *************** *** 63,74 **** ]) def test_nested_exception(self): def f(p): 1/0 def g(p): try: f(p) except: ! pass f_ident = ident(f) g_ident = ident(g) --- 61,106 ---- ]) + def test_caught_nested_exception(self): + def f(p): + try: 1/0 + except: pass + def g(p): + f(p) + f_ident = ident(f) + g_ident = ident(g) + self.check_events(g, [(0, 'call', g_ident), + (1, 'call', f_ident), + (1, 'exception', f_ident), + (1, 'return', f_ident), + (0, 'return', g_ident), + ]) + def test_nested_exception(self): def f(p): 1/0 def g(p): + try: f(p) + except: pass + f_ident = ident(f) + g_ident = ident(g) + self.check_events(g, [(0, 'call', g_ident), + (1, 'call', f_ident), + (1, 'exception', f_ident), + # This isn't what I expected: + (0, 'exception', g_ident), + # I expected this again: + # (1, 'exception', f_ident), + (0, 'return', g_ident), + ]) + + def test_exception_in_except_clause(self): + def f(p): + 1/0 + def g(p): try: f(p) except: ! try: f(p) ! except: pass f_ident = ident(f) g_ident = ident(g) *************** *** 76,84 **** (1, 'call', f_ident), (1, 'exception', f_ident), - # This isn't what I expected: (0, 'exception', g_ident), (0, 'return', g_ident), ]) def ident(function): --- 108,139 ---- (1, 'call', f_ident), (1, 'exception', f_ident), (0, 'exception', g_ident), + (2, 'call', f_ident), + (2, 'exception', f_ident), + (0, 'exception', g_ident), (0, 'return', g_ident), ]) + def test_exception_propogation(self): + def f(p): + 1/0 + def g(p): + try: f(p) + finally: p.add_event("falling through") + def h(p): + try: g(p) + except: pass + f_ident = ident(f) + g_ident = ident(g) + h_ident = ident(h) + self.check_events(h, [(0, 'call', h_ident), + (1, 'call', g_ident), + (2, 'call', f_ident), + (2, 'exception', f_ident), + (1, 'exception', g_ident), + (1, 'falling through', g_ident), + (0, 'exception', h_ident), + (0, 'return', h_ident), + ]) def ident(function): From gvanrossum@users.sourceforge.net Mon Sep 24 19:47:42 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 11:47:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.70,2.71 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22870/Objects Modified Files: typeobject.c Log Message: Another comparison patch-up: comparing a type with a dynamic metatype to one with a static metatype raised an obscure error. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -d -r2.70 -r2.71 *** typeobject.c 2001/09/24 16:03:58 2.70 --- typeobject.c 2001/09/24 18:47:39 2.71 *************** *** 2034,2038 **** if (!PyArg_ParseTuple(args, "O", &other)) return NULL; ! if (!PyType_IsSubtype(other->ob_type, self->ob_type)) { PyErr_Format( PyExc_TypeError, --- 2034,2039 ---- if (!PyArg_ParseTuple(args, "O", &other)) return NULL; ! if (other->ob_type->tp_compare != func && ! !PyType_IsSubtype(other->ob_type, self->ob_type)) { PyErr_Format( PyExc_TypeError, From gvanrossum@users.sourceforge.net Mon Sep 24 19:47:42 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 11:47:42 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22870/Lib/test Modified Files: test_descr.py Log Message: Another comparison patch-up: comparing a type with a dynamic metatype to one with a static metatype raised an obscure error. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -d -r1.72 -r1.73 *** test_descr.py 2001/09/24 17:52:04 1.72 --- test_descr.py 2001/09/24 18:47:40 1.73 *************** *** 922,925 **** --- 922,932 ---- verify(L(3)*L(2) == 6) + # Test comparison of classes with dynamic metaclasses + class dynamicmetaclass(type): + __dynamic__ = 1 + class someclass: + __metaclass__ = dynamicmetaclass + verify(someclass != object) + def errors(): if verbose: print "Testing errors..." From twouters@users.sourceforge.net Mon Sep 24 20:32:03 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Mon, 24 Sep 2001 12:32:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.276,2.277 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv1098/Python Modified Files: ceval.c Log Message: Don't swap the arguments to PyFrame_BlockSetup when recreating the recently popped frame-block. What an embarrassing bug! Especially for Jeremy, since he accepted the patch :-) This fixes SF bugs #463359 and #462937, and possibly other, *very* obscure bugs with very deeply nested loops that continue the loop and then break out of it or raise an exception. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.276 retrieving revision 2.277 diff -C2 -d -r2.276 -r2.277 *** ceval.c 2001/09/20 20:46:19 2.276 --- ceval.c 2001/09/24 19:32:01 2.277 *************** *** 2218,2223 **** /* For a continue inside a try block, don't pop the block for the loop. */ ! PyFrame_BlockSetup(f, b->b_type, b->b_level, ! b->b_handler); why = WHY_NOT; JUMPTO(PyInt_AS_LONG(retval)); --- 2218,2223 ---- /* For a continue inside a try block, don't pop the block for the loop. */ ! PyFrame_BlockSetup(f, b->b_type, b->b_handler, ! b->b_level); why = WHY_NOT; JUMPTO(PyInt_AS_LONG(retval)); From fdrake@users.sourceforge.net Mon Sep 24 21:01:31 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Mon, 24 Sep 2001 13:01:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib markupbase.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10713 Added Files: markupbase.py Log Message: New base class for the SGMLParser and HTMLParser classes from the sgmllib and HTMLParser modules (and indirectly for the htmllib.HTMLParser class). This has all the support for scanning over DOCTYPE declarations; it warrants having a base class since this is a fair amount of tedious code (since it's fairly strict), and should be in a separate module to avoid compiling many REs that are not used (which would happen if this were placed in either then sgmllib or HTMLParser module). --- NEW FILE: markupbase.py --- """Shared support for scanning document type declarations in HTML and XHTML.""" import re import string _declname_match = re.compile(r'[a-zA-Z][-_.a-zA-Z0-9]*\s*').match _declstringlit_match = re.compile(r'(\'[^\']*\'|"[^"]*")\s*').match del re class ParserBase: """Parser base class which provides some common support methods used by the SGML/HTML and XHTML parsers.""" def reset(self): self.lineno = 1 self.offset = 0 def getpos(self): """Return current line number and offset.""" return self.lineno, self.offset # Internal -- update line number and offset. This should be # called for each piece of data exactly once, in order -- in other # words the concatenation of all the input strings to this # function should be exactly the entire input. def updatepos(self, i, j): if i >= j: return j rawdata = self.rawdata nlines = string.count(rawdata, "\n", i, j) if nlines: self.lineno = self.lineno + nlines pos = string.rindex(rawdata, "\n", i, j) # Should not fail self.offset = j-(pos+1) else: self.offset = self.offset + j-i return j _decl_otherchars = '' # Internal -- parse declaration (for use by subclasses). def parse_declaration(self, i): # This is some sort of declaration; in "HTML as # deployed," this should only be the document type # declaration (""). rawdata = self.rawdata import sys j = i + 2 assert rawdata[i:j] == "' n = len(rawdata) decltype, j = self._scan_name(j, i) if j < 0: return j if decltype == "doctype": self._decl_otherchars = '' while j < n: c = rawdata[j] if c == ">": # end of declaration syntax data = rawdata[i+2:j] if decltype == "doctype": self.handle_decl(data) else: self.unknown_decl(data) return j + 1 if c in "\"'": m = _declstringlit_match(rawdata, j) if not m: return -1 # incomplete j = m.end() elif c in "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ": name, j = self._scan_name(j, i) elif c in self._decl_otherchars: j = j + 1 elif c == "[": if decltype == "doctype": j = self._parse_doctype_subset(j + 1, i) else: self.error("unexpected '[' char in declaration") else: self.error( "unexpected %s char in declaration" % `rawdata[j]`) if j < 0: return j return -1 # incomplete # Internal -- scan past the internal subset in a n: # end of buffer; incomplete return -1 if rawdata[j:j+4] == " + ]""" + self.check_events(["" % inside], [ + ("decl", inside), + ]) + + def test_doctype_decl_external(self): + inside = "DOCTYPE html PUBLIC '-//W3C//DTD HTML 4.01//EN'" + self.check_events("" % inside, [ + ("decl", inside), + ]) + def test_underscore_in_attrname(self): # SF bug #436621 *************** *** 133,136 **** --- 173,186 ---- ]) + def test_bare_ampersands(self): + self.check_events("this text & contains & ampersands &", [ + ("data", "this text & contains & ampersands &"), + ]) + + def test_bare_pointy_brackets(self): + self.check_events("this < text > contains < bare>pointy< brackets", [ + ("data", "this < text > contains < bare>pointy< brackets"), + ]) + def test_attr_syntax(self): output = [ *************** *** 157,160 **** --- 207,218 ---- ]) + def test_illegal_declarations(self): + s = 'abcdef' + self.check_events(s, [ + ("data", "abc"), + ("unknown decl", 'spacer type="block" height="25"'), + ("data", "def"), + ]) + def test_weird_starttags(self): self.check_events("", [ *************** *** 197,200 **** --- 255,266 ---- ]) + def test_illegal_declarations(self): + s = 'abcdef' + self.check_events(s, [ + ("data", "abc"), + ("unknown decl", 'spacer type="block" height="25"'), + ("data", "def"), + ]) + # XXX These tests have been disabled by prefixing their names with # an underscore. The first two exercise outstanding bugs in the *************** *** 241,243 **** ! test_support.run_unittest(SGMLParserTestCase) --- 307,314 ---- ! def test_main(): ! test_support.run_unittest(SGMLParserTestCase) ! ! ! if __name__ == "__main__": ! test_main() From tim_one@users.sourceforge.net Mon Sep 24 22:17:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 14:17:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.253,1.254 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv32355/python/Misc Modified Files: NEWS Log Message: Make properties discoverable from Python: - property() now takes 4 keyword arguments: fget, fset, fdel, doc. Note that the real purpose of the 'f' prefix is to make fdel fit in ('del' is a keyword, so can't used as a keyword argument name). - These map to visible readonly attributes 'fget', 'fset', 'fdel', and '__doc__' in the property object. - fget/fset/fdel weren't discoverable from Python before. - __doc__ is new, and allows to associate a docstring with a property. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.253 retrieving revision 1.254 diff -C2 -d -r1.253 -r1.254 *** NEWS 2001/09/24 04:28:10 1.253 --- NEWS 2001/09/24 21:17:50 1.254 *************** *** 4,7 **** --- 4,13 ---- Core + - property() now takes 4 keyword arguments: fget, fset, fdel and doc. + These map to readonly attributes 'fget', 'fset', 'fdel', and '__doc__' + in the constructed property object. fget, fset and fdel weren't + discoverable from Python in 2.2a3. __doc__ is new, and allows to + associate a docstring with a property. + - file.writelines() now accepts any iterable object producing strings. From tim_one@users.sourceforge.net Mon Sep 24 22:17:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 14:17:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32355/python/Lib/test Modified Files: test_descr.py Log Message: Make properties discoverable from Python: - property() now takes 4 keyword arguments: fget, fset, fdel, doc. Note that the real purpose of the 'f' prefix is to make fdel fit in ('del' is a keyword, so can't used as a keyword argument name). - These map to visible readonly attributes 'fget', 'fset', 'fdel', and '__doc__' in the property object. - fget/fset/fdel weren't discoverable from Python before. - __doc__ is new, and allows to associate a docstring with a property. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** test_descr.py 2001/09/24 18:47:40 1.73 --- test_descr.py 2001/09/24 21:17:50 1.74 *************** *** 1365,1369 **** def delx(self): del self.__x ! x = property(getx, setx, delx) a = C() verify(not hasattr(a, "x")) --- 1365,1369 ---- def delx(self): del self.__x ! x = property(getx, setx, delx, doc="I'm the x property.") a = C() verify(not hasattr(a, "x")) *************** *** 1379,1382 **** --- 1379,1408 ---- ## verify(not hasattr(a, "x")) + raw = C.__dict__['x'] + verify(isinstance(raw, property)) + + attrs = dir(raw) + verify("__doc__" in attrs) + verify("fget" in attrs) + verify("fset" in attrs) + verify("fdel" in attrs) + + verify(raw.__doc__ == "I'm the x property.") + verify(raw.fget is C.__dict__['getx']) + verify(raw.fset is C.__dict__['setx']) + verify(raw.fdel is C.__dict__['delx']) + + for attr in "__doc__", "fget", "fset", "fdel": + try: + setattr(raw, attr, 42) + except TypeError, msg: + if str(msg).find('readonly') < 0: + raise TestFailed("when setting readonly attr %r on a " + "property, got unexpected TypeError " + "msg %r" % (attr, str(msg))) + else: + raise TestFailed("expected TypeError from trying to set " + "readonly %r attr on a property" % attr) + def supers(): if verbose: print "Testing super..." *************** *** 1885,1889 **** verify(zz == 1+0j) verify(1+0j == zz) ! class classic: pass --- 1911,1915 ---- verify(zz == 1+0j) verify(1+0j == zz) ! class classic: pass From tim_one@users.sourceforge.net Mon Sep 24 22:17:52 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 14:17:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects descrobject.c,2.13,2.14 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv32355/python/Objects Modified Files: descrobject.c Log Message: Make properties discoverable from Python: - property() now takes 4 keyword arguments: fget, fset, fdel, doc. Note that the real purpose of the 'f' prefix is to make fdel fit in ('del' is a keyword, so can't used as a keyword argument name). - These map to visible readonly attributes 'fget', 'fset', 'fdel', and '__doc__' in the property object. - fget/fset/fdel weren't discoverable from Python before. - __doc__ is new, and allows to associate a docstring with a property. Index: descrobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/descrobject.c,v retrieving revision 2.13 retrieving revision 2.14 diff -C2 -d -r2.13 -r2.14 *** descrobject.c 2001/09/20 21:45:26 2.13 --- descrobject.c 2001/09/24 21:17:50 2.14 *************** *** 874,880 **** class property(object): ! def __init__(self, get=None, set=None): ! self.__get = get ! self.__set = set def __get__(self, inst, type=None): --- 874,882 ---- class property(object): ! def __init__(self, fget=None, fset=None, fdel=None, doc=None): ! self.__get = fget ! self.__set = fset ! self.__del = fdel ! self.__doc__ = doc def __get__(self, inst, type=None): *************** *** 886,901 **** def __set__(self, inst, value): ! if self.__set is None: ! raise AttributeError, "unsettable attribute" ! return self.__set(inst, value) */ typedef struct { PyObject_HEAD ! PyObject *get; ! PyObject *set; ! PyObject *del; } propertyobject; static void property_dealloc(PyObject *self) --- 888,918 ---- def __set__(self, inst, value): ! if value is None: ! if self.__del is None: ! raise AttributeError, "can't delete attribute" ! return self.__del(inst) ! else: ! if self.__set is None: ! raise AttributeError, "can't set attribute" ! return self.__set(inst, value) */ typedef struct { PyObject_HEAD ! PyObject *prop_get; ! PyObject *prop_set; ! PyObject *prop_del; ! PyObject *prop_doc; } propertyobject; + static PyMemberDef property_members[] = { + {"fget", T_OBJECT, offsetof(propertyobject, prop_get), READONLY}, + {"fset", T_OBJECT, offsetof(propertyobject, prop_set), READONLY}, + {"fdel", T_OBJECT, offsetof(propertyobject, prop_del), READONLY}, + {"__doc__", T_OBJECT, offsetof(propertyobject, prop_doc), READONLY}, + {0} + }; + + static void property_dealloc(PyObject *self) *************** *** 903,909 **** propertyobject *gs = (propertyobject *)self; ! Py_XDECREF(gs->get); ! Py_XDECREF(gs->set); ! Py_XDECREF(gs->del); self->ob_type->tp_free(self); } --- 920,927 ---- propertyobject *gs = (propertyobject *)self; ! Py_XDECREF(gs->prop_get); ! Py_XDECREF(gs->prop_set); ! Py_XDECREF(gs->prop_del); ! Py_XDECREF(gs->prop_doc); self->ob_type->tp_free(self); } *************** *** 914,918 **** propertyobject *gs = (propertyobject *)self; ! if (gs->get == NULL) { PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; --- 932,936 ---- propertyobject *gs = (propertyobject *)self; ! if (gs->prop_get == NULL) { PyErr_SetString(PyExc_AttributeError, "unreadable attribute"); return NULL; *************** *** 922,926 **** return self; } ! return PyObject_CallFunction(gs->get, "(O)", obj); } --- 940,944 ---- return self; } ! return PyObject_CallFunction(gs->prop_get, "(O)", obj); } *************** *** 932,938 **** if (value == NULL) ! func = gs->del; else ! func = gs->set; if (func == NULL) { PyErr_SetString(PyExc_AttributeError, --- 950,956 ---- if (value == NULL) ! func = gs->prop_del; else ! func = gs->prop_set; if (func == NULL) { PyErr_SetString(PyExc_AttributeError, *************** *** 955,984 **** property_init(PyObject *self, PyObject *args, PyObject *kwds) { ! PyObject *get = NULL, *set = NULL, *del = NULL; propertyobject *gs = (propertyobject *)self; ! if (!PyArg_ParseTuple(args, "|OOO:property", &get, &set, &del)) return -1; if (get == Py_None) get = NULL; if (set == Py_None) set = NULL; Py_XINCREF(get); Py_XINCREF(set); Py_XINCREF(del); ! gs->get = get; ! gs->set = set; ! gs->del = del; return 0; } static char property_doc[] = ! "property([getfunc[, setfunc[, delfunc]]]) -> property attribute\n" ! "Typical use to define a managed attribute x of C instances:\n" "class C(object):\n" " def getx(self): return self.__x\n" " def setx(self, value): self.__x = value\n" " def delx(self): del self.__x\n" ! " x = property(getx, setx, delx)"; PyTypeObject PyProperty_Type = { --- 973,1015 ---- property_init(PyObject *self, PyObject *args, PyObject *kwds) { ! PyObject *get = NULL, *set = NULL, *del = NULL, *doc = NULL; ! static char *kwlist[] = {"fget", "fset", "fdel", "doc", 0}; propertyobject *gs = (propertyobject *)self; ! if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO:property", ! kwlist, &get, &set, &del, &doc)) return -1; + if (get == Py_None) get = NULL; if (set == Py_None) set = NULL; + if (del == Py_None) + del = NULL; + Py_XINCREF(get); Py_XINCREF(set); Py_XINCREF(del); ! Py_XINCREF(doc); ! ! gs->prop_get = get; ! gs->prop_set = set; ! gs->prop_del = del; ! gs->prop_doc = doc; ! return 0; } static char property_doc[] = ! "property(fget=None, fset=None, fdel=None, doc=None) -> property attribute\n" ! "\n" ! "fget is a function to be used for getting an attribute value, and likewise\n" ! "fset is a function for setting, and fdel a function for del'ing, an\n" ! "attribute. Typical use is to define a managed attribute x:\n" "class C(object):\n" " def getx(self): return self.__x\n" " def setx(self, value): self.__x = value\n" " def delx(self): del self.__x\n" ! " x = property(getx, setx, delx, \"I'm the 'x' property.\")"; PyTypeObject PyProperty_Type = { *************** *** 1013,1017 **** 0, /* tp_iternext */ 0, /* tp_methods */ ! 0, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ --- 1044,1048 ---- 0, /* tp_iternext */ 0, /* tp_methods */ ! property_members, /* tp_members */ 0, /* tp_getset */ 0, /* tp_base */ From tim_one@users.sourceforge.net Mon Sep 24 23:40:49 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 15:40:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv18973/python/Lib Modified Files: pydoc.py Log Message: + Text-mode (but not yet GUI mode) pydoc now produces useful stuff for properties: the docstring (if any) is displayed, and the getter, setter and deleter (if any) functions are named. All that is shown indented after the property name. + Text-mode pydoc class display now draws a horizontal line between class attribute groups (similar to GUI mode -- while visually more intrusive in text mode, it's still an improvement). Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -d -r1.46 -r1.47 *** pydoc.py 2001/09/24 08:05:11 1.46 --- pydoc.py 2001/09/24 22:40:47 1.47 *************** *** 992,998 **** --- 992,1009 ---- push = contents.append + # Cute little class to pump out a horizontal rule between sections. + class HorizontalRule: + def __init__(self): + self.needone = 0 + def maybe(self): + if self.needone: + push('-' * 70) + self.needone = 1 + hr = HorizontalRule() + def spill(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: *************** *** 1001,1013 **** return attrs - # pydoc can't make any reasonable sense of properties on its own, - # and it doesn't appear that the getter, setter and del'er methods - # are discoverable. For now, just pump out their names. def spillproperties(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: push(msg) for name, kind, homecls, value in ok: ! push(name + '\n') return attrs --- 1012,1038 ---- return attrs def spillproperties(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: ! push(name) ! need_blank_after_doc = 0 ! doc = getdoc(value) or '' ! if doc: ! push(self.indent(doc)) ! need_blank_after_doc = 1 ! for attr, tag in [("fset", " setter"), ! ("fget", " getter"), ! ("fdel", " deleter")]: ! func = getattr(value, attr) ! if func is not None: ! if need_blank_after_doc: ! push('') ! need_blank_after_doc = 0 ! base = self.docother(func, name + tag, mod, 70) ! push(self.indent(base)) ! push('') return attrs *************** *** 1015,1018 **** --- 1040,1044 ---- ok, attrs = _split_list(attrs, predicate) if ok: + hr.maybe() push(msg) for name, kind, homecls, value in ok: *************** *** 1041,1053 **** # Pump out the attrs, segregated by kind. ! attrs = spill("* Methods %s:\n" % tag, attrs, lambda t: t[1] == 'method') ! attrs = spill("* Class methods %s:\n" % tag, attrs, lambda t: t[1] == 'class method') ! attrs = spill("* Static methods %s:\n" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("* Properties %s:\n" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("* Data %s:\n" % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] --- 1067,1079 ---- # Pump out the attrs, segregated by kind. ! attrs = spill("Methods %s:\n" % tag, attrs, lambda t: t[1] == 'method') ! attrs = spill("Class methods %s:\n" % tag, attrs, lambda t: t[1] == 'class method') ! attrs = spill("Static methods %s:\n" % tag, attrs, lambda t: t[1] == 'static method') ! attrs = spillproperties("Properties %s:\n" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("Data %s:\n" % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] From tim_one@users.sourceforge.net Tue Sep 25 01:01:08 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 17:01:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.47,1.48 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1776/python/Lib Modified Files: pydoc.py Log Message: GUI mode now displays useful stuff for properties. This is usually better than text mode, since here we can hyperlink from the getter etc methods back to their definitions. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.47 retrieving revision 1.48 diff -C2 -d -r1.47 -r1.48 *** pydoc.py 2001/09/24 22:40:47 1.47 --- pydoc.py 2001/09/25 00:01:06 1.48 *************** *** 637,643 **** return attrs - # pydoc can't make any reasonable sense of properties on its own, - # and it doesn't appear that the getter, setter and del'er methods - # are discoverable. For now, just pump out their names. def spillproperties(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) --- 637,640 ---- *************** *** 646,650 **** push(msg) for name, kind, homecls, value in ok: ! push('
    %s
    \n' % name) return attrs --- 643,660 ---- push(msg) for name, kind, homecls, value in ok: ! push('
    %s
    \n' % name) ! if value.__doc__ is not None: ! doc = self.markup(value.__doc__, self.preformat, ! funcs, classes, mdict) ! push('
    %s
    \n' % doc) ! for attr, tag in [("fset", " setter"), ! ("fget", " getter"), ! ("fdel", " deleter")]: ! func = getattr(value, attr) ! if func is not None: ! base = self.document(func, name + tag, mod, ! funcs, classes, mdict, object) ! push('
    %s
    \n' % base) ! push('
    \n') return attrs From tim_one@users.sourceforge.net Tue Sep 25 04:18:34 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 20:18:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.48,1.49 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1374/python/Lib Modified Files: pydoc.py Log Message: + Got rid of all instances of . Under IE5, GUI-mode pydoc has always been close to useless, because the -ified docstrings were too small to read, even after cranking up my default font size just for pydoc. Now it reads fine under my defaults (as does most of the web <0.5 wink>). If it's thought important to play tricks with font size, tough, then someone should rework pydoc to use style sheets, and (more) predictable percentage-of-default size controls. + Tried to ensure that all
    and
    tags are closed. I've read (but don't know) that some browsers get confused if they're not, and esp. when style sheets are in use too. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.48 retrieving revision 1.49 diff -C2 -d -r1.48 -r1.49 *** pydoc.py 2001/09/25 00:01:06 1.48 --- pydoc.py 2001/09/25 03:18:32 1.49 *************** *** 349,354 **** !
     
     
    %s
    %s
    --- 349,354 ---- !
     
    !  
    %s
    %s
    *************** *** 363,368 ****

    ! ''' % (bgcol, fgcol, title) if prelude: --- 363,368 ----

     
    %s
    ! ''' % (bgcol, fgcol, title) if prelude: *************** *** 400,404 **** return '
     
    ! %s
    %s
    ' % result - def small(self, text): return '%s' % text def grey(self, text): return '%s' % text --- 400,403 ---- *************** *** 479,483 **** if type(entry) is type(()): c, bases = entry ! result = result + '

    ' result = result + self.classlink(c, modname) if bases and bases != (parent,): --- 478,482 ---- if type(entry) is type(()): c, bases = entry ! result = result + '
    ' result = result + self.classlink(c, modname) if bases and bases != (parent,): *************** *** 486,490 **** parents.append(self.classlink(base, modname)) result = result + '(' + join(parents, ', ') + ')' ! result = result + '\n
    ' elif type(entry) is type([]): result = result + '
    \n%s
    \n' % self.formattree( --- 485,489 ---- parents.append(self.classlink(base, modname)) result = result + '(' + join(parents, ', ') + ')' ! result = result + '\n
    ' elif type(entry) is type([]): result = result + '
    \n%s
    \n' % self.formattree( *************** *** 553,557 **** doc = self.markup(getdoc(object), self.preformat, fdict, cdict) doc = doc and '%s' % doc ! result = result + '

    %s

    \n' % self.small(doc) if hasattr(object, '__path__'): --- 552,556 ---- doc = self.markup(getdoc(object), self.preformat, fdict, cdict) doc = doc and '%s' % doc ! result = result + '

    %s

    \n' % doc if hasattr(object, '__path__'): *************** *** 647,651 **** doc = self.markup(value.__doc__, self.preformat, funcs, classes, mdict) ! push('
    %s
    \n' % doc) for attr, tag in [("fset", " setter"), ("fget", " getter"), --- 646,650 ---- doc = self.markup(value.__doc__, self.preformat, funcs, classes, mdict) ! push('
    %s
    \n' % doc) for attr, tag in [("fset", " setter"), ("fget", " getter"), *************** *** 672,676 **** doc = self.markup(getdoc(value), self.preformat, funcs, classes, mdict) ! doc = '
    ' + self.small('%s' % doc) push('
    %s%s
    \n' % (base, doc)) push('\n') --- 671,675 ---- doc = self.markup(getdoc(value), self.preformat, funcs, classes, mdict) ! doc = '
    %s' % doc push('
    %s%s
    \n' % (base, doc)) push('\n') *************** *** 738,750 **** parents.append(self.classlink(base, object.__module__)) title = title + '(%s)' % join(parents, ', ') ! doc = self.markup( ! getdoc(object), self.preformat, funcs, classes, mdict) ! doc = self.small(doc and '%s
     
    ' % doc or ! self.small(' ')) return self.section(title, '#000000', '#ffc8d8', contents, 5, doc) def formatvalue(self, object): """Format an argument default value as text.""" ! return self.small(self.grey('=' + self.repr(object))) def docroutine(self, object, name=None, mod=None, --- 737,747 ---- parents.append(self.classlink(base, object.__module__)) title = title + '(%s)' % join(parents, ', ') ! doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict) ! doc = doc and '%s
     
    ' % doc or ' ' return self.section(title, '#000000', '#ffc8d8', contents, 5, doc) def formatvalue(self, object): """Format an argument default value as text.""" ! return self.grey('=' + self.repr(object)) def docroutine(self, object, name=None, mod=None, *************** *** 792,805 **** argspec = '(...)' ! decl = title + argspec + (note and self.small(self.grey( ! '%s' % note))) if skipdocs: ! return '
    %s
    \n' % decl else: doc = self.markup( getdoc(object), self.preformat, funcs, classes, methods) ! doc = doc and '
    ' + self.small('%s' % doc) ! return '
    %s%s
    \n' % (decl, doc) def docother(self, object, name=None, mod=None): --- 789,802 ---- argspec = '(...)' ! decl = title + argspec + (note and self.grey( ! '%s' % note)) if skipdocs: ! return '
    %s
    \n' % decl else: doc = self.markup( getdoc(object), self.preformat, funcs, classes, methods) ! doc = doc and '
    %s
    ' % doc ! return '
    %s
    %s
    \n' % (decl, doc) def docother(self, object, name=None, mod=None): *************** *** 1802,1807 **** indices.append(html.index(dir, seen)) contents = heading + join(indices) + '''

    ! ! pydoc by Ka-Ping Yee <ping@lfw.org>''' self.send_document('Index of Modules', contents) --- 1799,1804 ---- indices.append(html.index(dir, seen)) contents = heading + join(indices) + '''

    ! ! pydoc by Ka-Ping Yee <ping@lfw.org>''' self.send_document('Index of Modules', contents) From gvanrossum@users.sourceforge.net Tue Sep 25 04:43:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 20:43:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv7010/Lib/test Modified Files: test_descr.py Log Message: Make __class__ assignment possible, when the object structures are the same. I hope the test for structural equivalence is stringent enough. It only allows the assignment if the old and new types: - have the same basic size - have the same item size - have the same dict offset - have the same weaklist offset - have the same GC flag bit - have a common base that is the same except for maybe the dict and weaklist (which may have been added separately at the same offsets in both types) Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** test_descr.py 2001/09/24 21:17:50 1.74 --- test_descr.py 2001/09/25 03:43:42 1.75 *************** *** 2006,2009 **** --- 2006,2036 ---- check(file.name, "file name") # member descriptor + def setclass(): + if verbose: print "Testing __class__ assignment..." + class C(object): pass + class D(object): pass + class E(object): pass + class F(D, E): pass + for cls in C, D, E, F: + for cls2 in C, D, E, F: + x = cls() + x.__class__ = cls2 + verify(x.__class__ is cls2) + x.__class__ = cls + verify(x.__class__ is cls) + def cant(x, C): + try: + x.__class__ = C + except TypeError: + pass + else: + raise TestFailed, "shouldn't allow %r.__class__ = %r" % (x, C) + cant(C(), list) + cant(list(), C) + cant(C(), 1) + cant(C(), object) + cant(object(), list) + cant(list(), object) + def test_main(): *************** *** 2048,2051 **** --- 2075,2079 ---- coercions() descrdoc() + setclass() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Tue Sep 25 04:43:44 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 20:43:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.71,2.72 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv7010/Objects Modified Files: typeobject.c Log Message: Make __class__ assignment possible, when the object structures are the same. I hope the test for structural equivalence is stringent enough. It only allows the assignment if the old and new types: - have the same basic size - have the same item size - have the same dict offset - have the same weaklist offset - have the same GC flag bit - have a common base that is the same except for maybe the dict and weaklist (which may have been added separately at the same offsets in both types) Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -d -r2.71 -r2.72 *** typeobject.c 2001/09/24 18:47:39 2.71 --- typeobject.c 2001/09/25 03:43:42 2.72 *************** *** 1193,1198 **** } ! static PyMemberDef object_members[] = { ! {"__class__", T_OBJECT, offsetof(PyObject, ob_type), READONLY}, {0} }; --- 1193,1277 ---- } ! static PyObject * ! object_get_class(PyObject *self, void *closure) ! { ! Py_INCREF(self->ob_type); ! return (PyObject *)(self->ob_type); ! } ! ! static int ! equiv_structs(PyTypeObject *a, PyTypeObject *b) ! { ! return a == b || ! (a != NULL && ! b != NULL && ! a->tp_basicsize == b->tp_basicsize && ! a->tp_itemsize == b->tp_itemsize && ! a->tp_dictoffset == b->tp_dictoffset && ! a->tp_weaklistoffset == b->tp_weaklistoffset && ! ((a->tp_flags & Py_TPFLAGS_HAVE_GC) == ! (b->tp_flags & Py_TPFLAGS_HAVE_GC))); ! } ! ! static int ! same_slots_added(PyTypeObject *a, PyTypeObject *b) ! { ! PyTypeObject *base = a->tp_base; ! int size; ! ! if (base != b->tp_base) ! return 0; ! if (equiv_structs(a, base) && equiv_structs(b, base)) ! return 1; ! size = base->tp_basicsize; ! if (a->tp_dictoffset == size && b->tp_dictoffset == size) ! size += sizeof(PyObject *); ! if (a->tp_weaklistoffset == size && b->tp_weaklistoffset == size) ! size += sizeof(PyObject *); ! return size == a->tp_basicsize && size == b->tp_basicsize; ! } ! ! static int ! object_set_class(PyObject *self, PyObject *value, void *closure) ! { ! PyTypeObject *old = self->ob_type; ! PyTypeObject *new, *newbase, *oldbase; ! ! if (!PyType_Check(value)) { ! PyErr_Format(PyExc_TypeError, ! "__class__ must be set to new-style class, not '%s' object", ! value->ob_type->tp_name); ! return -1; ! } ! new = (PyTypeObject *)value; ! newbase = new; ! oldbase = old; ! while (equiv_structs(newbase, newbase->tp_base)) ! newbase = newbase->tp_base; ! while (equiv_structs(oldbase, oldbase->tp_base)) ! oldbase = oldbase->tp_base; ! if (newbase != oldbase && ! (newbase->tp_base != oldbase->tp_base || ! !same_slots_added(newbase, oldbase))) { ! PyErr_Format(PyExc_TypeError, ! "__class__ assignment: " ! "'%s' object layout differs from '%s'", ! new->tp_name, ! old->tp_name); ! return -1; ! } ! if (new->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! Py_INCREF(new); ! } ! self->ob_type = new; ! if (old->tp_flags & Py_TPFLAGS_HEAPTYPE) { ! Py_DECREF(old); ! } ! return 0; ! } ! ! static PyGetSetDef object_getsets[] = { ! {"__class__", object_get_class, object_set_class, ! "the object's class"}, {0} }; *************** *** 1228,1233 **** 0, /* tp_iternext */ 0, /* tp_methods */ ! object_members, /* tp_members */ ! 0, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ --- 1307,1312 ---- 0, /* tp_iternext */ 0, /* tp_methods */ ! 0, /* tp_members */ ! object_getsets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ From gvanrossum@users.sourceforge.net Tue Sep 25 04:56:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 20:56:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.72,2.73 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9052/Objects Modified Files: typeobject.c Log Message: Change repr() of a new-style class to say rather than . Exception: if it's a built-in type or an extension type, continue to call it . Call me a wimp, but I don't want to break more user code than necessary. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.72 retrieving revision 2.73 diff -C2 -d -r2.72 -r2.73 *** typeobject.c 2001/09/25 03:43:42 2.72 --- typeobject.c 2001/09/25 03:56:29 2.73 *************** *** 115,118 **** --- 115,119 ---- { PyObject *mod, *name, *rtn; + char *kind; mod = type_module(type, NULL); *************** *** 127,137 **** return NULL; if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) { ! rtn = PyString_FromFormat("", PyString_AS_STRING(mod), PyString_AS_STRING(name)); } else ! rtn = PyString_FromFormat("", type->tp_name); Py_XDECREF(mod); --- 128,144 ---- return NULL; + if (type->tp_flags & Py_TPFLAGS_HEAPTYPE) + kind = "class"; + else + kind = "type"; + if (mod != NULL && strcmp(PyString_AS_STRING(mod), "__builtin__")) { ! rtn = PyString_FromFormat("<%s '%s.%s'>", ! kind, PyString_AS_STRING(mod), PyString_AS_STRING(name)); } else ! rtn = PyString_FromFormat("<%s '%s'>", kind, type->tp_name); Py_XDECREF(mod); *************** *** 3366,3375 **** if (su->obj) return PyString_FromFormat( ! ", <%s object>>", su->type ? su->type->tp_name : "NULL", su->obj->ob_type->tp_name); else return PyString_FromFormat( ! ", NULL>", su->type ? su->type->tp_name : "NULL"); } --- 3373,3382 ---- if (su->obj) return PyString_FromFormat( ! ", <%s object>>", su->type ? su->type->tp_name : "NULL", su->obj->ob_type->tp_name); else return PyString_FromFormat( ! ", NULL>", su->type ? su->type->tp_name : "NULL"); } From gvanrossum@users.sourceforge.net Tue Sep 25 04:56:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 20:56:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descrtut.py,1.6,1.7 test_repr.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9052/Lib/test Modified Files: test_descrtut.py test_repr.py Log Message: Change repr() of a new-style class to say rather than . Exception: if it's a built-in type or an extension type, continue to call it . Call me a wimp, but I don't want to break more user code than necessary. Index: test_descrtut.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descrtut.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** test_descrtut.py 2001/09/21 19:29:08 1.6 --- test_descrtut.py 2001/09/25 03:56:29 1.7 *************** *** 38,42 **** >>> print defaultdict # show our type ! >>> print type(defaultdict) # its metatype --- 38,42 ---- >>> print defaultdict # show our type ! >>> print type(defaultdict) # its metatype *************** *** 45,51 **** {} >>> print type(a) # show its type ! >>> print a.__class__ # show its class ! >>> print type(a) is a.__class__ # its type is its class 1 --- 45,51 ---- {} >>> print type(a) # show its type ! >>> print a.__class__ # show its class ! >>> print type(a) is a.__class__ # its type is its class 1 Index: test_repr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_repr.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_repr.py 2001/09/20 21:33:42 1.7 --- test_repr.py 2001/09/25 03:56:29 1.8 *************** *** 209,213 **** from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo eq(repr(foo.foo), ! "") def test_object(self): --- 209,213 ---- from areallylongpackageandmodulenametotestreprtruncation.areallylongpackageandmodulenametotestreprtruncation import foo eq(repr(foo.foo), ! "") def test_object(self): From gvanrossum@users.sourceforge.net Tue Sep 25 05:15:43 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 21:15:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.254,1.255 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv12731 Modified Files: NEWS Log Message: Separate out the type/class-related news and reword some items. Add news items about comparisons, repr(), __class__ assignment. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.254 retrieving revision 1.255 diff -C2 -d -r1.254 -r1.255 *** NEWS 2001/09/24 21:17:50 1.254 --- NEWS 2001/09/25 04:15:41 1.255 *************** *** 2,6 **** =========================== ! Core - property() now takes 4 keyword arguments: fget, fset, fdel and doc. --- 2,18 ---- =========================== ! Type/class unification and new-style classes ! ! - pydoc and inspect are now aware of new-style classes; ! e.g. help(list) at the interactive prompt now shows proper ! documentation for all operations on list objects. ! ! - Applications using Jim Fulton's ExtensionClass module can now safely ! be used with Python 2.2. In particular, Zope 2.4.1 now works with ! Python 2.2 (as well as with Python 2.1.1). The Demo/metaclass ! examples also work again. It is hoped that Gtk and Boost also work ! with 2.2a4 and beyond. (If you can confirm this, please write ! webmaster@python.org; if there are still problems, please open a bug ! report on SourceForge.) - property() now takes 4 keyword arguments: fget, fset, fdel and doc. *************** *** 10,60 **** associate a docstring with a property. ! - file.writelines() now accepts any iterable object producing strings. ! - PyUnicode_FromEncodedObject() now works very much like ! PyObject_Str(obj) in that it tries to use __str__/tp_str ! on the object if the object is not a string or buffer. This ! makes unicode() behave like str() when applied to non-string/buffer ! objects. ! - PyFile_WriteObject now passes Unicode object to the file's write ! method. As a result, all file-like object which may be the target ! of a print statement must support Unicode objects, i.e. they must ! at least convert them into ASCII strings. - The builtin file type can be subclassed now. In the usual pattern, "file" is the name of the builtin type, and file() is a new builtin constructor, with the same signature as the builtin open() function. file() is now the preferred way to open a file. - - - In 2.2a3, *for new-style classes only*, __getattr__ was called for - every attribute access. This was confusing because it differed - significantly from the behavior of classic classes, where it was - only called for missing attributes. Now, __getattr__ is called only - if regular attribute access raises AttributeError; to catch *all* - attribute access, *for new-style classes only*, you can use - __getattribute__. If both are defined, __getattribute__ is called - first, and if it raises AttributeError, __getattr__ is called. ! - In 2.2a3, __new__ would only see sequential arguments passed to the ! type in a constructor call; __init__ would see both sequential and ! keyword arguments. This made no sense whatsoever any more, so now both __new__ and __init__ see all arguments. ! - In 2.2a3, hash() applied to an instance of a subclass of str or unicode ! always returned 0. This has been repaired. ! - In 2.2a3, an operation on an instance of a subclass of an immutable type ! (int, long, float, complex, tuple, str, unicode), where the subtype ! didn't override the operation (and so the operation was handled by the ! builtin type), could return that instance instead a value of the base ! type. For example, if s was of a str sublass type, s[:] returned s ! as-is. Now it returns a str with the same value as s. ! - Applications using Jim Fulton's ExtensionClass module can now safely ! be used with Python 2.2. In particular, Zope 2.4.1 now works with ! Python 2.2 (as well as with Python 2.1.1). The Demo/metaclass ! examples also work again. - Thread scheduling on Solaris should be improved; it is no longer necessary to insert a small sleep at the start of a thread in order --- 22,88 ---- associate a docstring with a property. ! - Comparison overloading is now more completely implemented. For ! example, a str subclass instance can properly be compared to a str ! instance, and it can properly overload comparison. Ditto for most ! other built-in object types. ! - The repr() of new-style classes has changed; instead of a new-style class is now rendered as , ! *except* for built-in types, which are still rendered as (to avoid upsetting existing code that might parse or ! otherwise rely on repr() of certain type objects). ! - The repr() of new-style objects is now always ; ! previously, it was sometimes . + - For new-style classes, what was previously called __getattr__ is now + called __getattribute__. This method, if defined, is called for + *every* attribute access. A new __getattr__ hook mor similar to the + one in classic classes is defined which is called only if regular + attribute access raises AttributeError; to catch *all* attribute + access, you can use __getattribute__ (for new-style classes). If + both are defined, __getattribute__ is called first, and if it raises + AttributeError, __getattr__ is called. + + - The __class__ attribute of new-style objects can be assigned to. + The new class must have the same C-level object layout as the old + class. + - The builtin file type can be subclassed now. In the usual pattern, "file" is the name of the builtin type, and file() is a new builtin constructor, with the same signature as the builtin open() function. file() is now the preferred way to open a file. ! - Previously, __new__ would only see sequential arguments passed to ! the type in a constructor call; __init__ would see both sequential ! and keyword arguments. This made no sense whatsoever any more, so now both __new__ and __init__ see all arguments. ! - Previously, hash() applied to an instance of a subclass of str or ! unicode always returned 0. This has been repaired. ! - Previously, an operation on an instance of a subclass of an ! immutable type (int, long, float, complex, tuple, str, unicode), ! where the subtype didn't override the operation (and so the ! operation was handled by the builtin type), could return that ! instance instead a value of the base type. For example, if s was of ! a str sublass type, s[:] returned s as-is. Now it returns a str ! with the same value as s. ! Core ! ! - file.writelines() now accepts any iterable object producing strings. + - PyUnicode_FromEncodedObject() now works very much like + PyObject_Str(obj) in that it tries to use __str__/tp_str + on the object if the object is not a string or buffer. This + makes unicode() behave like str() when applied to non-string/buffer + objects. + + - PyFile_WriteObject now passes Unicode object to the file's write + method. As a result, all file-like object which may be the target + of a print statement must support Unicode objects, i.e. they must + at least convert them into ASCII strings. + - Thread scheduling on Solaris should be improved; it is no longer necessary to insert a small sleep at the start of a thread in order *************** *** 102,109 **** Tool to a standard library package. (Tools/compiler still exists as a sample driver.) - - - pydoc and inspect are now aware of new-style classes; - e.g. help(list) at the interactive prompt now shows proper - documentation for all operations on list objects. Tools --- 130,133 ---- From gvanrossum@users.sourceforge.net Tue Sep 25 07:20:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Mon, 24 Sep 2001 23:20:54 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv30356 Modified Files: PLAN.txt Log Message: Note a few tasks that are done now. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** PLAN.txt 2001/09/20 05:27:24 1.9 --- PLAN.txt 2001/09/25 06:20:52 1.10 *************** *** 5,13 **** ----------- - Fix comparisons. There's some nasty stuff here: when two types are - not the same, and they're not instances, the fallback code doesn't - account for the possibility that they might be subtypes of a common - base type that defines a comparison. - Check for conflicts between base classes. I fear that the rules used to decide whether multiple bases have conflicting instance variables --- 5,8 ---- *************** *** 22,26 **** implemented. ! Allow __class__ assignment (and __bases__ and __dict__?). Make __dynamic__ the default. --- 17,21 ---- implemented. ! Allow assignment to __bases__ and __dict__? Make __dynamic__ the default. *************** *** 30,42 **** Add __coerce__? ! Support pickling (via __reduce__?) Support mixed multiple inheritance from classic and new-style classes? - Change __getattr__ to be more like classic __getattr__, and introduce - a new name for new-style __getattr__? - Done (mostly) ------------- Make inspect and pydoc do the right thing for new-style classes. *** --- 25,46 ---- Add __coerce__? ! Support pickling (via __reduce__) Support mixed multiple inheritance from classic and new-style classes? Done (mostly) ------------- + + Fix comparisons. There's some nasty stuff here: when two types are + not the same, and they're not instances, the fallback code doesn't + account for the possibility that they might be subtypes of a common + base type that defines a comparison. *** I believe this is now done, + but it's a bit of a mess. *** + + Allow __class__ assignment. *** done *** + + Change __getattr__ to be more like classic __getattr__, and introduce + a new name for new-style __getattr__. *** Done. The new-style method + is called __getattribute__. *** Make inspect and pydoc do the right thing for new-style classes. *** From tim_one@users.sourceforge.net Tue Sep 25 07:30:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Mon, 24 Sep 2001 23:30:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.49,1.50 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30931/python/Lib Modified Files: pydoc.py Log Message: + Display property functions in the same order they're specified to property() (get, set, del; not set, get, del). + Change "Data defined/inherited in ..." header lines to "Data and non-method functions defined/inherited in ...". Things like the value of __class__, and __new__, and class vrbls like the i in class C: i = int show up in this section too. I don't think it's worth a separate section to distinguish them from non-callable attrs, and there's no obvious reliable way to distinguish callable from non-callable attrs anyway. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.49 retrieving revision 1.50 diff -C2 -d -r1.49 -r1.50 *** pydoc.py 2001/09/25 03:18:32 1.49 --- pydoc.py 2001/09/25 06:30:51 1.50 *************** *** 647,652 **** funcs, classes, mdict) push('

    %s
    \n' % doc) ! for attr, tag in [("fset", " setter"), ! ("fget", " getter"), ("fdel", " deleter")]: func = getattr(value, attr) --- 647,652 ---- funcs, classes, mdict) push('
    %s
    \n' % doc) ! for attr, tag in [("fget", " getter"), ! ("fset", " setter"), ("fdel", " deleter")]: func = getattr(value, attr) *************** *** 714,718 **** attrs = spillproperties("Properties %s" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("Data %s" % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] --- 714,718 ---- attrs = spillproperties("Properties %s" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("Data and non-method functions %s" % tag, attrs, lambda t: t[1] == 'data') assert attrs == [] *************** *** 1031,1036 **** push(self.indent(doc)) need_blank_after_doc = 1 ! for attr, tag in [("fset", " setter"), ! ("fget", " getter"), ("fdel", " deleter")]: func = getattr(value, attr) --- 1031,1036 ---- push(self.indent(doc)) need_blank_after_doc = 1 ! for attr, tag in [("fget", " getter"), ! ("fset", " setter"), ("fdel", " deleter")]: func = getattr(value, attr) *************** *** 1082,1087 **** attrs = spillproperties("Properties %s:\n" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("Data %s:\n" % tag, attrs, ! lambda t: t[1] == 'data') assert attrs == [] --- 1082,1087 ---- attrs = spillproperties("Properties %s:\n" % tag, attrs, lambda t: t[1] == 'property') ! attrs = spilldata("Data and non-method functions %s:\n" % tag, ! attrs, lambda t: t[1] == 'data') assert attrs == [] From gvanrossum@users.sourceforge.net Tue Sep 25 14:59:03 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 06:59:03 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules timemodule.c,2.113,2.114 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7427 Modified Files: timemodule.c Log Message: SF patch #459385 (Norman Vine): time.timezone fix for Cygwin. Also did some whitespace normalization. Index: timemodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/timemodule.c,v retrieving revision 2.113 retrieving revision 2.114 diff -C2 -d -r2.113 -r2.114 *** timemodule.c 2001/08/22 12:39:16 2.113 --- timemodule.c 2001/09/25 13:59:01 2.114 *************** *** 89,93 **** static long timezone; ! static void initmactimezone(void) { --- 89,93 ---- static long timezone; ! static void initmactimezone(void) { *************** *** 96,108 **** ReadLocation(&loc); ! if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0) return; ! delta = loc.u.gmtDelta & 0x00FFFFFF; ! if (delta & 0x00800000) delta |= 0xFF000000; ! timezone = -delta; } --- 96,108 ---- ReadLocation(&loc); ! if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0) return; ! delta = loc.u.gmtDelta & 0x00FFFFFF; ! if (delta & 0x00800000) delta |= 0xFF000000; ! timezone = -delta; } *************** *** 163,170 **** if (LargeIntegerEqualToZero(divisor)) { QueryPerformanceCounter(&ctrStart); ! if (!QueryPerformanceFrequency(&divisor) || LargeIntegerEqualToZero(divisor)) { ! /* Unlikely to happen - ! this works on all intel machines at least! Revert to clock() */ return PyFloat_FromDouble(clock()); --- 163,170 ---- if (LargeIntegerEqualToZero(divisor)) { QueryPerformanceCounter(&ctrStart); ! if (!QueryPerformanceFrequency(&divisor) || LargeIntegerEqualToZero(divisor)) { ! /* Unlikely to happen - ! this works on all intel machines at least! Revert to clock() */ return PyFloat_FromDouble(clock()); *************** *** 175,182 **** diff = LargeIntegerDivide(diff, divisor, &rem); /* XXX - we assume both divide results fit in 32 bits. This is ! true on Intels. First person who can afford a machine that doesnt deserves to fix it :-) */ ! return PyFloat_FromDouble((double)diff.LowPart + ((double)rem.LowPart / (double)divisor.LowPart)); } --- 175,182 ---- diff = LargeIntegerDivide(diff, divisor, &rem); /* XXX - we assume both divide results fit in 32 bits. This is ! true on Intels. First person who can afford a machine that doesnt deserves to fix it :-) */ ! return PyFloat_FromDouble((double)diff.LowPart + ((double)rem.LowPart / (double)divisor.LowPart)); } *************** *** 342,346 **** } else if (!gettmarg(tup, &buf)) return NULL; ! fmtlen = strlen(fmt); --- 342,346 ---- } else if (!gettmarg(tup, &buf)) return NULL; ! fmtlen = strlen(fmt); *************** *** 448,452 **** time_t tt; char *p; ! if (PyTuple_Size(args) == 0) tt = time(NULL); --- 448,452 ---- time_t tt; char *p; ! if (PyTuple_Size(args) == 0) tt = time(NULL); *************** *** 492,496 **** if (tt == (time_t)(-1)) { PyErr_SetString(PyExc_OverflowError, ! "mktime argument out of range"); return NULL; } --- 492,496 ---- if (tt == (time_t)(-1)) { PyErr_SetString(PyExc_OverflowError, ! "mktime argument out of range"); return NULL; } *************** *** 585,590 **** strptime() -- parse string to time tuple according to format specification\n\ "; - DL_EXPORT(void) inittime(void) --- 585,590 ---- strptime() -- parse string to time tuple according to format specification\n\ "; + DL_EXPORT(void) inittime(void) *************** *** 600,604 **** Py_INCREF(d); moddict = d; ! #if defined(HAVE_TZNAME) && !defined(__GLIBC__) tzset(); #ifdef PYOS_OS2 --- 600,604 ---- Py_INCREF(d); moddict = d; ! #if defined(HAVE_TZNAME) && !defined(__GLIBC__) && !defined(__CYGWIN__) tzset(); #ifdef PYOS_OS2 *************** *** 618,622 **** ins(d, "daylight", PyInt_FromLong((long)daylight)); ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1])); ! #else /* !HAVE_TZNAME || __GLIBC__ */ #ifdef HAVE_TM_ZONE { --- 618,622 ---- ins(d, "daylight", PyInt_FromLong((long)daylight)); ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1])); ! #else /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ #ifdef HAVE_TM_ZONE { *************** *** 636,640 **** strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); julyname[9] = '\0'; ! if( janzone < julyzone ) { /* DST is reversed in the southern hemisphere */ --- 636,640 ---- strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9); julyname[9] = '\0'; ! if( janzone < julyzone ) { /* DST is reversed in the southern hemisphere */ *************** *** 674,678 **** ins(d, "tzname", Py_BuildValue("(zz)", _tzname[0], _tzname[1])); #endif /* __CYGWIN__ */ ! #endif /* !HAVE_TZNAME || __GLIBC__ */ } --- 674,678 ---- ins(d, "tzname", Py_BuildValue("(zz)", _tzname[0], _tzname[1])); #endif /* __CYGWIN__ */ ! #endif /* !HAVE_TZNAME || __GLIBC__ || __CYGWIN__*/ } *************** *** 821,825 **** return; } ! Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ --- 821,825 ---- return; } ! Py_BEGIN_ALLOW_THREADS /* BeOS snooze() is in microseconds... */ From fdrake@users.sourceforge.net Tue Sep 25 16:12:43 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 08:12:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/inst inst.tex,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/inst In directory usw-pr-cvs1:/tmp/cvs-serv26572/inst Modified Files: inst.tex Log Message: Fix a URL (closing SF patch #462195). Cleaned up a bunch of XXX comments containing links to additional information, replacing them with proper references. Replaced "MacOS" with "Mac OS", since that's what the style guide says. Index: inst.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/inst/inst.tex,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** inst.tex 2001/09/11 15:10:42 1.35 --- inst.tex 2001/09/25 15:12:41 1.36 *************** *** 148,152 **** find them. This document makes no such assumptions, and explains how the Python library is laid out on three major platforms (\UNIX, Windows, ! and MacOS), so that you can understand what happens when the Distutils do their job \emph{and} know how to install modules manually when the module author fails to provide a setup script. --- 148,152 ---- find them. This document makes no such assumptions, and explains how the Python library is laid out on three major platforms (\UNIX, Windows, ! and Mac OS), so that you can understand what happens when the Distutils do their job \emph{and} know how to install modules manually when the module author fails to provide a setup script. *************** *** 178,182 **** On \UNIX, you'd run this command from a shell prompt; on Windows, you have to open a command prompt window (``DOS box'') and do it there; on ! MacOS, things are a tad more complicated (see below). --- 178,182 ---- On \UNIX, you'd run this command from a shell prompt; on Windows, you have to open a command prompt window (``DOS box'') and do it there; on ! Mac OS, things are a tad more complicated (see below). *************** *** 209,213 **** \end{verbatim} ! On MacOS, you have to go through a bit more effort to supply command-line arguments to the setup script: \begin{itemize} --- 209,213 ---- \end{verbatim} ! On Mac OS, you have to go through a bit more effort to supply command-line arguments to the setup script: \begin{itemize} *************** *** 318,322 **** the standard location for third-party Python modules. This location varies by platform and by how you built/installed Python itself. On ! \UNIX{} and MacOS, it also depends on whether the module distribution being installed is pure Python or contains extensions (``non-pure''): \begin{tableiv}{l|l|l|c}{textrm}% --- 318,322 ---- the standard location for third-party Python modules. This location varies by platform and by how you built/installed Python itself. On ! \UNIX{} and Mac OS, it also depends on whether the module distribution being installed is pure Python or contains extensions (``non-pure''): \begin{tableiv}{l|l|l|c}{textrm}% *************** *** 334,342 **** {\filenq{C:\textbackslash{}Python}} {(2)} ! \lineiv{MacOS (pure)} {\filenq{\filevar{prefix}:Lib:site-packages}} {\filenq{Python:Lib:site-packages}} {} ! \lineiv{MacOS (non-pure)} {\filenq{\filevar{prefix}:Lib:site-packages}} {\filenq{Python:Lib:site-packages}} --- 334,342 ---- {\filenq{C:\textbackslash{}Python}} {(2)} ! \lineiv{Mac OS (pure)} {\filenq{\filevar{prefix}:Lib:site-packages}} {\filenq{Python:Lib:site-packages}} {} ! \lineiv{Mac OS (non-pure)} {\filenq{\filevar{prefix}:Lib:site-packages}} {\filenq{Python:Lib:site-packages}} *************** *** 358,362 **** \filevar{prefix} and \filevar{exec-prefix} stand for the directories that Python is installed to, and where it finds its libraries at ! run-time. They are always the same under Windows and MacOS, and very often the same under \UNIX. You can find out what your Python installation uses for \filevar{prefix} and \filevar{exec-prefix} by --- 358,362 ---- \filevar{prefix} and \filevar{exec-prefix} stand for the directories that Python is installed to, and where it finds its libraries at ! run-time. They are always the same under Windows and Mac OS, and very often the same under \UNIX. You can find out what your Python installation uses for \filevar{prefix} and \filevar{exec-prefix} by *************** *** 364,368 **** Under \UNIX, just type \code{python} at the shell prompt. Under Windows, choose \menuselection{Start \sub Programs \sub Python ! 2.1 \sub Python (command line)}. Under MacOS, \XXX{???}. Once the interpreter is started, you type Python code at the prompt. For example, on my Linux system, I type the three Python --- 364,368 ---- Under \UNIX, just type \code{python} at the shell prompt. Under Windows, choose \menuselection{Start \sub Programs \sub Python ! 2.1 \sub Python (command line)}. Under Mac OS, \XXX{???}. Once the interpreter is started, you type Python code at the prompt. For example, on my Linux system, I type the three Python *************** *** 436,441 **** This subsection describes the necessary steps to use Distutils with the ! Borland \Cpp{} compiler version 5.5.\footnote{Check ! \url{http://www.borland.com/bcppbuilder/freecompiler/} for download} %Should we mention that users have to create cfg-files for the compiler %see also http://community.borland.com/article/0,1410,21205,00.html --- 436,440 ---- This subsection describes the necessary steps to use Distutils with the ! Borland \Cpp{} compiler version 5.5. %Should we mention that users have to create cfg-files for the compiler %see also http://community.borland.com/article/0,1410,21205,00.html *************** *** 479,485 **** file for Distutils (see section~\ref{config-files}.) ! \XXX{One place to look: \url{http://www.cyberus.ca/~g_will/pyExtenDL.shtml}} \subsubsection{GNU C / Cygwin / MinGW32} --- 478,494 ---- file for Distutils (see section~\ref{config-files}.) ! \begin{seealso} ! \seetitle[http://www.borland.com/bcppbuilder/freecompiler/] ! {\Cpp{}Builder Compiler} ! {Information about the free \Cpp{} compiler from Borland, ! including links to the download pages.} + \seetitle[http://www.cyberus.ca/~g_will/pyExtenDL.shtml] + {Creating Python Extensions Using Borland's Free Compiler} + {Document describing how to use Borland's free command-line C++ + compiler to build Python.} + \end{seealso} + \subsubsection{GNU C / Cygwin / MinGW32} *************** *** 488,492 **** distributions.\footnote{Check \url{http://sources.redhat.com/cygwin/} and ! \url{http://www.mingw.org} for more information} \XXX{For a Python which was built with Cygwin, all should work without --- 497,501 ---- distributions.\footnote{Check \url{http://sources.redhat.com/cygwin/} and ! \url{http://www.mingw.org/} for more information} \XXX{For a Python which was built with Cygwin, all should work without *************** *** 512,515 **** --- 521,525 ---- dlltool --dllname python20.dll --def python20.def --output-lib libpython20.a \end{verbatim} + The resulting library has to be placed in the same directory as \file{python20.lib}. (Should be the \file{libs} directory under your *************** *** 527,532 **** \end{verbatim} ! and for Cygwin in no-cygwin mode\footnote{Then you have no POSIX emulation ! available, but you also don't need \file{cygwin1.dll}.} or for MinGW32 type \begin{verbatim} --- 537,543 ---- \end{verbatim} ! and for Cygwin in no-cygwin mode\footnote{Then you have no ! \POSIX{} emulation available, but you also don't need ! \file{cygwin1.dll}.} or for MinGW32 type: \begin{verbatim} *************** *** 538,545 **** for Distutils (see section~\ref{config-files}.) ! \XXX{One place to look: \url{http://www.zope.org/Members/als/tips/win32_mingw_modules}} ! \XXX{For converted import libraries in cygwin/mingw32 and bcpp format, ! see \url{ftp://pyopengl.sourceforge.net/pub/pyopengl/win32-stuff/}.} --- 549,563 ---- for Distutils (see section~\ref{config-files}.) ! \begin{seealso} ! \seetitle[http://www.zope.org/Members/als/tips/win32_mingw_modules] ! {Building Python modules on MS Windows platform with MinGW32} ! {Information about building the required libraries for the MinGW32 ! environment.} ! \seeurl{http://pyopengl.sourceforge.net/ftp/win32-stuff/} ! {Converted import libraries in Cygwin/MinGW32 and Borland format, ! and a script to create the registry entries needed for Distutils ! to locate the built Python.} ! \end{seealso} *************** *** 570,574 **** Under \UNIX, there are two ways to perform an alternate installation. The ``prefix scheme'' is similar to how alternate installation works ! under Windows and MacOS, but is not necessarily the most useful way to maintain a personal Python library. Hence, we document the more convenient and commonly useful ``home scheme'' first. --- 588,592 ---- Under \UNIX, there are two ways to perform an alternate installation. The ``prefix scheme'' is similar to how alternate installation works ! under Windows and Mac OS, but is not necessarily the most useful way to maintain a personal Python library. Hence, we document the more convenient and commonly useful ``home scheme'' first. *************** *** 697,704 **** ! \subsection{Alternate installation: MacOS} \label{alt-install-macos} ! Like Windows, MacOS has no notion of home directories (or even of users), and a fairly simple standard Python installation. Thus, only a \longprogramopt{prefix} option is needed. It defines the installation --- 715,722 ---- ! \subsection{Alternate installation: Mac OS} \label{alt-install-macos} ! Like Windows, Mac OS has no notion of home directories (or even of users), and a fairly simple standard Python installation. Thus, only a \longprogramopt{prefix} option is needed. It defines the installation *************** *** 773,777 **** Of course, you also have to ensure that these directories are in Python's module search path, e.g. by putting a \file{.pth} file in ! \filevar{prefix} (\XXX{should have a section describing .pth files and cross-ref it here}). --- 791,795 ---- Of course, you also have to ensure that these directories are in Python's module search path, e.g. by putting a \file{.pth} file in ! \filevar{prefix} (\XXX{should have a section describing \file{.pth} files and cross-ref it here}). *************** *** 853,860 **** \code{\$PLAT}. (And of course, you can only use the configuration variables supplied by the Distutils on systems that don't have ! environment variables, such as MacOS (\XXX{true?}).) See section~\ref{config-files} for details. ! \XXX{need some Windows and MacOS examples---when would custom installation schemes be needed on those platforms?} --- 871,878 ---- \code{\$PLAT}. (And of course, you can only use the configuration variables supplied by the Distutils on systems that don't have ! environment variables, such as Mac OS (\XXX{true?}).) See section~\ref{config-files} for details. ! \XXX{need some Windows and Mac OS examples---when would custom installation schemes be needed on those platforms?} *************** *** 894,898 **** \end{tableiii} ! And on MacOS, they are: \begin{tableiii}{l|l|c}{textrm} {Type of file}{Location and filename}{Notes} --- 912,916 ---- \end{tableiii} ! And on Mac OS, they are: \begin{tableiii}{l|l|c}{textrm} {Type of file}{Location and filename}{Notes} *************** *** 933,937 **** prefix is just \file{Python:}, so under Python 1.6 and later this is normally\file{Python:Lib:distutils:pydistutils.cfg}. (The Distutils ! don't work very well with Python 1.5.2 under MacOS. \XXX{true?}) \end{description} --- 951,955 ---- prefix is just \file{Python:}, so under Python 1.6 and later this is normally\file{Python:Lib:distutils:pydistutils.cfg}. (The Distutils ! don't work very well with Python 1.5.2 under Mac OS. \XXX{true?}) \end{description} From fdrake@users.sourceforge.net Tue Sep 25 16:48:13 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 08:48:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsocket.tex,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv1873/lib Modified Files: libsocket.tex Log Message: Added documentation for the SSL interface, contributed by Gerhard Häring. This closes SF patch #461337. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** libsocket.tex 2001/08/04 22:22:45 1.52 --- libsocket.tex 2001/09/25 15:48:11 1.53 *************** *** 266,269 **** --- 266,278 ---- \end{funcdesc} + \begin{funcdesc}{ssl}{sock, keyfile, certfile} + Initiate a SSL connection over the socket \var{sock}. \var{keyfile} is + the name of a PEM formatted file that contains your private + key. \var{certfile} is a PEM formatted certificate chain file. On + success, a new \class{SSLObject} is returned. + + \strong{Warning:} This does not do any certificate verification! + \end{funcdesc} + \begin{funcdesc}{fromfd}{fd, family, type\optional{, proto}} Build a socket object from an existing file descriptor (an integer as *************** *** 510,513 **** --- 519,536 ---- instead. + + \subsection{SSL Objects \label{ssl-objects}} + + SSL objects have the following methods. + + \begin{methoddesc}{write}{s} + Writes the string \var{s} to the on the object's SSL connection. + The return value is the number of bytes written. + \end{methoddesc} + + \begin{methoddesc}{read}{\optional{n}} + If \var{n} is provided, read \var{n} bytes from the SSL connection, otherwise + read until EOF. The return value is a string of the bytes read. + \end{methoddesc} \subsection{Example \label{socket-example}} From gvanrossum@users.sourceforge.net Tue Sep 25 17:21:41 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 09:21:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_support.py,1.34,1.35 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11517 Modified Files: test_support.py Log Message: Set sys.save_stdout (to sys.stdout), so doctest-using tests can be run standalone. Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.34 retrieving revision 1.35 diff -C2 -d -r1.34 -r1.35 *** test_support.py 2001/09/21 20:45:44 1.34 --- test_support.py 2001/09/25 16:21:39 1.35 *************** *** 3,6 **** --- 3,8 ---- import sys + sys.save_stdout = sys.stdout + class Error(Exception): """Base class for regression test exceptions.""" From gvanrossum@users.sourceforge.net Tue Sep 25 17:26:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 09:26:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib copy_reg.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12467/Lib Modified Files: copy_reg.py Log Message: - Provisional support for pickling new-style objects. (*) - Made cls.__module__ writable. - Ensure that obj.__dict__ is returned as {}, not None, even upon first reference; it simply springs into life when you ask for it. (*) The pickling support is provisional for the following reasons: - It doesn't support classes with __slots__. - It relies on additional support in copy_reg.py: the C method __reduce__, defined in the object class, really calls calling copy_reg._reduce(obj). Eventually the Python code in copy_reg.py needs to be migrated to C, but I'd like to experiment with the Python implementation first. The _reduce() code also relies on an additional helper function, _reconstructor(), defined in copy_reg.py; this should also be reimplemented in C. Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** copy_reg.py 2001/01/20 19:54:20 1.5 --- copy_reg.py 2001/09/25 16:25:58 1.6 *************** *** 34,35 **** --- 34,64 ---- pickle(type(1j), pickle_complex, complex) + + # Support for picking new-style objects + + _dummy_classes = {} + + def _reconstructor(cls, base, state): + dummy = _dummy_classes.get(base) + if dummy is None: + class dummy(base): pass + _dummy_classes[base] = dummy + obj = dummy(state) + obj._foo = 1; del obj._foo # hack to create __dict__ + obj.__class__ = cls + return obj + _reconstructor.__safe_for_unpickling__ = 1 + + _HEAPTYPE = 1<<9 + + def _reduce(self): + for base in self.__class__.__mro__: + if not base.__flags__ & _HEAPTYPE: + break + else: + base = object # not really reachable + if base is object: + state = None + else: + state = base(self) + return _reconstructor, (self.__class__, base, state), self.__dict__ From gvanrossum@users.sourceforge.net Tue Sep 25 17:26:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 09:26:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.75,1.76 test_descrtut.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12467/Lib/test Modified Files: test_descr.py test_descrtut.py Log Message: - Provisional support for pickling new-style objects. (*) - Made cls.__module__ writable. - Ensure that obj.__dict__ is returned as {}, not None, even upon first reference; it simply springs into life when you ask for it. (*) The pickling support is provisional for the following reasons: - It doesn't support classes with __slots__. - It relies on additional support in copy_reg.py: the C method __reduce__, defined in the object class, really calls calling copy_reg._reduce(obj). Eventually the Python code in copy_reg.py needs to be migrated to C, but I'd like to experiment with the Python implementation first. The _reduce() code also relies on an additional helper function, _reconstructor(), defined in copy_reg.py; this should also be reimplemented in C. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.75 retrieving revision 1.76 diff -C2 -d -r1.75 -r1.76 *** test_descr.py 2001/09/25 03:43:42 1.75 --- test_descr.py 2001/09/25 16:25:58 1.76 *************** *** 786,790 **** pass x = Cdict() ! verify(x.__dict__ is None) x.foo = 1 verify(x.foo == 1) --- 786,790 ---- pass x = Cdict() ! verify(x.__dict__ == {}) x.foo = 1 verify(x.foo == 1) *************** *** 2033,2037 **** --- 2033,2097 ---- cant(list(), object) + def pickles(): + if verbose: print "Testing pickling new-style classes and objects..." + import pickle, cPickle + + def sorteditems(d): + L = d.items() + L.sort() + return L + + global C + class C(object): + def __init__(self, a, b): + super(C, self).__init__() + self.a = a + self.b = b + def __repr__(self): + return "C(%r, %r)" % (self.a, self.b) + + global C1 + class C1(list): + def __new__(cls, a, b): + return super(C1, cls).__new__(cls) + def __init__(self, a, b): + self.a = a + self.b = b + def __repr__(self): + return "C1(%r, %r)<%r>" % (self.a, self.b, list(self)) + global C2 + class C2(int): + def __new__(cls, a, b, val=0): + return super(C2, cls).__new__(cls, val) + def __init__(self, a, b, val=0): + self.a = a + self.b = b + def __repr__(self): + return "C2(%r, %r)<%r>" % (self.a, self.b, int(self)) + + for p in pickle, cPickle: + for bin in 0, 1: + + for cls in C, C1, C2: + s = p.dumps(cls, bin) + cls2 = p.loads(s) + verify(cls2 is cls) + + a = C1(1, 2); a.append(42); a.append(24) + b = C2("hello", "world", 42) + s = p.dumps((a, b), bin) + x, y = p.loads(s) + assert x.__class__ == a.__class__ + assert sorteditems(x.__dict__) == sorteditems(a.__dict__) + assert y.__class__ == b.__class__ + assert sorteditems(y.__dict__) == sorteditems(b.__dict__) + assert `x` == `a` + assert `y` == `b` + if verbose: + print "a = x =", a + print "b = y =", b + + def test_main(): lists() *************** *** 2076,2079 **** --- 2136,2140 ---- descrdoc() setclass() + pickles() if verbose: print "All OK" Index: test_descrtut.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descrtut.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** test_descrtut.py 2001/09/25 03:56:29 1.7 --- test_descrtut.py 2001/09/25 16:25:58 1.8 *************** *** 207,210 **** --- 207,211 ---- '__ne__', '__new__', + '__reduce__', '__repr__', '__rmul__', From gvanrossum@users.sourceforge.net Tue Sep 25 17:26:00 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 09:26:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.73,2.74 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv12467/Objects Modified Files: typeobject.c Log Message: - Provisional support for pickling new-style objects. (*) - Made cls.__module__ writable. - Ensure that obj.__dict__ is returned as {}, not None, even upon first reference; it simply springs into life when you ask for it. (*) The pickling support is provisional for the following reasons: - It doesn't support classes with __slots__. - It relies on additional support in copy_reg.py: the C method __reduce__, defined in the object class, really calls calling copy_reg._reduce(obj). Eventually the Python code in copy_reg.py needs to be migrated to C, but I'd like to experiment with the Python implementation first. The _reduce() code also relies on an additional helper function, _reconstructor(), defined in copy_reg.py; this should also be reimplemented in C. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.73 retrieving revision 2.74 diff -C2 -d -r2.73 -r2.74 *** typeobject.c 2001/09/25 03:56:29 2.73 --- typeobject.c 2001/09/25 16:25:58 2.74 *************** *** 54,57 **** --- 54,74 ---- } + static int + type_set_module(PyTypeObject *type, PyObject *value, void *context) + { + if (!(type->tp_flags & Py_TPFLAGS_DYNAMICTYPE) || + strrchr(type->tp_name, '.')) { + PyErr_Format(PyExc_TypeError, + "can't set %s.__module__", type->tp_name); + return -1; + } + if (!value) { + PyErr_Format(PyExc_TypeError, + "can't delete %s.__module__", type->tp_name); + return -1; + } + return PyDict_SetItemString(type->tp_dict, "__module__", value); + } + static PyObject * type_dict(PyTypeObject *type, void *context) *************** *** 94,98 **** PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, ! {"__module__", (getter)type_module, NULL, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__defined__", (getter)type_defined, NULL, NULL}, --- 111,115 ---- PyGetSetDef type_getsets[] = { {"__name__", (getter)type_name, NULL, NULL}, ! {"__module__", (getter)type_module, (setter)type_set_module, NULL}, {"__dict__", (getter)type_dict, NULL, NULL}, {"__defined__", (getter)type_defined, NULL, NULL}, *************** *** 657,668 **** } dict = *dictptr; ! if (dict == NULL) { ! Py_INCREF(Py_None); ! return Py_None; ! } ! else { ! Py_INCREF(dict); ! return dict; ! } } --- 674,681 ---- } dict = *dictptr; ! if (dict == NULL) ! *dictptr = dict = PyDict_New(); ! Py_XINCREF(dict); ! return dict; } *************** *** 1284,1287 **** --- 1297,1325 ---- }; + static PyObject * + object_reduce(PyObject *self, PyObject *args) + { + /* Call copy_reg._reduce(self) */ + static PyObject *copy_reg_str; + PyObject *copy_reg, *res; + + if (!copy_reg_str) { + copy_reg_str = PyString_InternFromString("copy_reg"); + if (copy_reg_str == NULL) + return NULL; + } + copy_reg = PyImport_Import(copy_reg_str); + if (!copy_reg) + return NULL; + res = PyEval_CallMethod(copy_reg, "_reduce", "(O)", self); + Py_DECREF(copy_reg); + return res; + } + + static PyMethodDef object_methods[] = { + {"__reduce__", object_reduce, METH_NOARGS, "helper for pickle"}, + {0} + }; + PyTypeObject PyBaseObject_Type = { PyObject_HEAD_INIT(&PyType_Type) *************** *** 1313,1317 **** 0, /* tp_iter */ 0, /* tp_iternext */ ! 0, /* tp_methods */ 0, /* tp_members */ object_getsets, /* tp_getset */ --- 1351,1355 ---- 0, /* tp_iter */ 0, /* tp_iternext */ ! object_methods, /* tp_methods */ 0, /* tp_members */ object_getsets, /* tp_getset */ *************** *** 3010,3014 **** else res = PyObject_CallFunction(getattribute, "OO", self, name); ! if (res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); res = PyObject_CallFunction(getattr, "OO", self, name); --- 3048,3053 ---- else res = PyObject_CallFunction(getattribute, "OO", self, name); ! if (getattr != NULL && ! res == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Clear(); res = PyObject_CallFunction(getattr, "OO", self, name); From fdrake@users.sourceforge.net Tue Sep 25 17:29:19 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 09:29:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpickle.tex,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13605/lib Modified Files: libpickle.tex Log Message: Revise the example to be more resiliant in the face of continued use after the object has been pickled; don't mutate the instance dict in the __getstate__() method. Other minor changes for style. Broke up the displayed interactive session to get better page-breaking behavior for typeset versions, and to point out an important aspect of the example. This closes SF bug #453914. Index: libpickle.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpickle.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -d -r1.28 -r1.29 *** libpickle.tex 2000/10/18 16:47:52 1.28 --- libpickle.tex 2001/09/25 16:29:17 1.29 *************** *** 306,317 **** \begin{verbatim} - # illustrate __setstate__ and __getstate__ methods - # used in pickling. - class TextReader: ! "Print and number lines in a text file." ! def __init__(self,file): self.file = file ! self.fh = open(file,'r') self.lineno = 0 --- 306,314 ---- \begin{verbatim} class TextReader: ! """Print and number lines in a text file.""" ! def __init__(self, file): self.file = file ! self.fh = open(file) self.lineno = 0 *************** *** 321,342 **** if not line: return None ! return "%d: %s" % (self.lineno,line[:-1]) - # return data representation for pickled object def __getstate__(self): ! odict = self.__dict__ # get attribute dictionary ! del odict['fh'] # remove filehandle entry return odict - # restore object state from data representation generated - # by __getstate__ def __setstate__(self,dict): ! fh = open(dict['file']) # reopen file ! count = dict['lineno'] # read from file... ! while count: # until line count is restored fh.readline() count = count - 1 ! dict['fh'] = fh # create filehandle entry ! self.__dict__ = dict # make dict our attribute dictionary \end{verbatim} --- 318,338 ---- if not line: return None ! if line.endswith("\n"): ! line = line[:-1] ! return "%d: %s" % (self.lineno, line) def __getstate__(self): ! odict = self.__dict__.copy() # copy the dict since we change it ! del odict['fh'] # remove filehandle entry return odict def __setstate__(self,dict): ! fh = open(dict['file']) # reopen file ! count = dict['lineno'] # read from file... ! while count: # until line count is restored fh.readline() count = count - 1 ! self.__dict__.update(dict) # update attributes ! self.fh = fh # save the file object \end{verbatim} *************** *** 353,359 **** >>> import pickle >>> pickle.dump(obj,open('save.p','w')) ! (start another Python session) >>> import pickle >>> reader = pickle.load(open('save.p')) --- 349,359 ---- >>> import pickle >>> pickle.dump(obj,open('save.p','w')) + \end{verbatim} ! If you want to see that \refmodule{pickle} works across Python ! processes, start another Python session, before continuing. What ! follows can happen from either the same process or a new process. + \begin{verbatim} >>> import pickle >>> reader = pickle.load(open('save.p')) From fdrake@users.sourceforge.net Tue Sep 25 17:32:04 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 09:32:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libhttplib.tex,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv14346/lib Modified Files: libhttplib.tex Log Message: Minor changes. Index: libhttplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libhttplib.tex,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** libhttplib.tex 2001/09/01 02:35:23 1.24 --- libhttplib.tex 2001/09/25 16:32:02 1.25 *************** *** 3,14 **** \declaremodule{standard}{httplib} ! \modulesynopsis{HTTP protocol client (requires sockets).} \indexii{HTTP}{protocol} ! This module defines a class which implements the client side of the ! HTTP protocol. It is normally not used directly --- the module ! \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs that ! use HTTP. The module defines one class, \class{HTTP}: --- 3,16 ---- \declaremodule{standard}{httplib} ! \modulesynopsis{HTTP and HTTPS protocol client (requires sockets).} \indexii{HTTP}{protocol} ! This module defines classes which implement the client side of the ! HTTP and HTTPS protocols. It is normally not used directly --- the ! module \refmodule{urllib}\refstmodindex{urllib} uses it to handle URLs ! that use HTTP and HTTPS. \strong{Note:} HTTPS support is only ! available if the \refmodule{socket} module was compiled with SSL ! support. The module defines one class, \class{HTTP}: *************** *** 111,114 **** --- 113,117 ---- \method{readlines()} methods. \end{methoddesc} + \subsection{Examples \label{httplib-examples}} From fdrake@users.sourceforge.net Tue Sep 25 20:00:10 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 12:00:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmmap.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv18307/lib Modified Files: libmmap.tex Log Message: Clarified some points about the interface to the mmap() function. This closes SF bug #448918. Index: libmmap.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmmap.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** libmmap.tex 2001/01/11 22:49:49 1.4 --- libmmap.tex 2001/09/25 19:00:08 1.5 *************** *** 15,20 **** through the file to different positions. ! A memory-mapped file is created by the following function, which is ! different on Unix and on Windows. \begin{funcdesc}{mmap}{fileno, length\optional{, tagname}} --- 15,26 ---- through the file to different positions. ! A memory-mapped file is created by the \function{mmap()} function, ! which is different on \UNIX{} and on Windows. In either case you must ! provide a file descriptor for a file opened for update. ! If you wish to map an existing Python file object, use its ! \method{fileno()} method to obtain the correct value for the ! \var{fileno} parameter. Otherwise, you can open the file using the ! \function{os.open()} function, which returns a file descriptor ! directly (the file still needs to be closed when done). \begin{funcdesc}{mmap}{fileno, length\optional{, tagname}} *************** *** 23,29 **** If \var{length} is \code{0}, the maximum length of the map will be the current size of the file when \function{mmap()} is called. - If you wish to map an existing Python file object, use its - \method{fileno()} method to obtain the correct value for the - \var{fileno} parameter. The file must be opened for update. \var{tagname}, if specified and not \code{None}, is a string giving a --- 29,32 ---- *************** *** 36,45 **** \end{funcdesc} ! \begin{funcdesc}{mmap}{fileno, size\optional{, flags, prot}} \strong{(\UNIX{} version)} Maps \var{length} bytes from the file ! specified by the file handle \var{fileno}, and returns a mmap object. ! If you wish to map an existing Python file object, use its ! \method{fileno()} method to obtain the correct value for the ! \var{fileno} parameter. The file must be opened for update. \var{flags} specifies the nature of the mapping. --- 39,45 ---- \end{funcdesc} ! \begin{funcdesc}{mmap}{fileno, length\optional{, flags\optional{, prot}}} \strong{(\UNIX{} version)} Maps \var{length} bytes from the file ! specified by the file descriptor \var{fileno}, and returns a mmap object. \var{flags} specifies the nature of the mapping. *************** *** 55,58 **** --- 55,59 ---- \var{prot} defaults to \constant{PROT_READ | PROT_WRITE}. \end{funcdesc} + Memory-mapped file objects support the following methods: From tim_one@users.sourceforge.net Tue Sep 25 20:13:22 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 25 Sep 2001 12:13:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.55,1.56 test_support.py,1.35,1.36 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21254/python/Lib/test Modified Files: regrtest.py test_support.py Log Message: Get rid of the increasingly convoluted global tricks w/ sys.stdout, in favor of local save/modify/restore. The test suite should run fine again. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.55 retrieving revision 1.56 diff -C2 -d -r1.55 -r1.56 *** regrtest.py 2001/09/22 05:31:03 1.55 --- regrtest.py 2001/09/25 19:13:20 1.56 *************** *** 288,292 **** cfp = StringIO.StringIO() try: ! sys.save_stdout = sys.stdout try: if cfp: --- 288,292 ---- cfp = StringIO.StringIO() try: ! save_stdout = sys.stdout try: if cfp: *************** *** 302,306 **** indirect_test() finally: ! sys.stdout = sys.save_stdout except (ImportError, test_support.TestSkipped), msg: if not quiet: --- 302,306 ---- indirect_test() finally: ! sys.stdout = save_stdout except (ImportError, test_support.TestSkipped), msg: if not quiet: Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.35 retrieving revision 1.36 diff -C2 -d -r1.35 -r1.36 *** test_support.py 2001/09/25 16:21:39 1.35 --- test_support.py 2001/09/25 19:13:20 1.36 *************** *** 3,8 **** import sys - sys.save_stdout = sys.stdout - class Error(Exception): """Base class for regression test exceptions.""" --- 3,6 ---- *************** *** 24,47 **** use_resources = None # Flag set to [] by regrtest.py - # _output_comparison controls whether regrtest will try to compare stdout - # with an expected-output file. For straight regrtests, it should. - # The doctest driver resets this flag by calling deny_output_comparison(). - # Note that this control is in addition to verbose mode: output will be - # compared if and only if _output_comparison is true and verbose mode is - # not in effect. - _output_comparison = 1 - - def deny_output_comparison(): - global _output_comparison - _output_comparison = 0 - sys.stdout = sys.save_stdout - - # regrtest's interface to _output_comparison. - def output_comparison_denied(): - global _output_comparison - denied = not _output_comparison - _output_comparison = 1 - return denied - def unload(name): try: --- 22,25 ---- *************** *** 202,207 **** verbosity = None ! deny_output_comparison() ! f, t = doctest.testmod(module, verbose=verbosity) ! if f: ! raise TestFailed("%d of %d doctests failed" % (f, t)) --- 180,191 ---- verbosity = None ! # Direct doctest output (normally just errors) to real stdout; doctest ! # output shouldn't be compared by regrtest. ! save_stdout = sys.stdout ! sys.stdout = sys.__stdout__ ! try: ! f, t = doctest.testmod(module, verbose=verbosity) ! if f: ! raise TestFailed("%d of %d doctests failed" % (f, t)) ! finally: ! sys.stdout = save_stdout From tim_one@users.sourceforge.net Tue Sep 25 20:29:37 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 25 Sep 2001 12:29:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_httplib.py,1.1,1.2 test_scope.py,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv25609/python/Lib/test Modified Files: test_httplib.py test_scope.py Log Message: test_support should be imported directly, not via test.test_support. Index: test_httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_httplib.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_httplib.py 2001/04/13 14:57:44 1.1 --- test_httplib.py 2001/09/25 19:29:35 1.2 *************** *** 1,3 **** ! from test.test_support import verify,verbose import httplib import StringIO --- 1,3 ---- ! from test_support import verify,verbose import httplib import StringIO Index: test_scope.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_scope.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** test_scope.py 2001/08/07 16:38:19 1.19 --- test_scope.py 2001/09/25 19:29:35 1.20 *************** *** 1,3 **** ! from test.test_support import verify, TestFailed, check_syntax import warnings --- 1,3 ---- ! from test_support import verify, TestFailed, check_syntax import warnings From gvanrossum@users.sourceforge.net Tue Sep 25 20:46:07 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 12:46:07 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib copy_reg.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29596 Modified Files: copy_reg.py Log Message: _reconstructor(): there's no need for tricks with assignment to __class__. The __new__ protocol is up to this. (Thanks to Tim for pointing this out.) Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** copy_reg.py 2001/09/25 16:25:58 1.6 --- copy_reg.py 2001/09/25 19:46:05 1.7 *************** *** 37,50 **** # Support for picking new-style objects - _dummy_classes = {} - def _reconstructor(cls, base, state): ! dummy = _dummy_classes.get(base) ! if dummy is None: ! class dummy(base): pass ! _dummy_classes[base] = dummy ! obj = dummy(state) ! obj._foo = 1; del obj._foo # hack to create __dict__ ! obj.__class__ = cls return obj _reconstructor.__safe_for_unpickling__ = 1 --- 37,43 ---- # Support for picking new-style objects def _reconstructor(cls, base, state): ! obj = base.__new__(cls, state) ! base.__init__(obj, state) return obj _reconstructor.__safe_for_unpickling__ = 1 From tim_one@users.sourceforge.net Tue Sep 25 21:05:13 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 25 Sep 2001 13:05:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.56,1.57 test_support.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31921/python/Lib/test Modified Files: regrtest.py test_support.py Log Message: Guido points out that sys.__stdout__ is a bit bucket under IDLE. So keep the local save/modify/restore of sys.stdout, but add machinery so that regrtest can tell test_support the value of sys.stdout at the time regrtest.main() started, and test_support can pass that out later to anyone who needs a "visible" stdout. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** regrtest.py 2001/09/25 19:13:20 1.56 --- regrtest.py 2001/09/25 20:05:11 1.57 *************** *** 86,89 **** --- 86,90 ---- """ + test_support.record_original_stdout(sys.stdout) try: opts, args = getopt.getopt(sys.argv[1:], 'hvgqxsrlu:', Index: test_support.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_support.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** test_support.py 2001/09/25 19:13:20 1.36 --- test_support.py 2001/09/25 20:05:11 1.37 *************** *** 22,25 **** --- 22,36 ---- use_resources = None # Flag set to [] by regrtest.py + # _original_stdout is meant to hold stdout at the time regrtest began. + # This may be "the real" stdout, or IDLE's emulation of stdout, or whatever. + # The point is to have some flavor of stdout the user can actually see. + _original_stdout = None + def record_original_stdout(stdout): + global _original_stdout + _original_stdout = stdout + + def get_original_stdout(): + return _original_stdout or sys.stdout + def unload(name): try: *************** *** 183,187 **** # output shouldn't be compared by regrtest. save_stdout = sys.stdout ! sys.stdout = sys.__stdout__ try: f, t = doctest.testmod(module, verbose=verbosity) --- 194,198 ---- # output shouldn't be compared by regrtest. save_stdout = sys.stdout ! sys.stdout = get_original_stdout() try: f, t = doctest.testmod(module, verbose=verbosity) From fdrake@users.sourceforge.net Tue Sep 25 21:48:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 13:48:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12588 Modified Files: test_profilehooks.py Log Message: Factor out the protect-from-exceptions helpers and make capture_events() use it. This simplifies the individual tests a little. Added some new tests related to exception handling. Index: test_profilehooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profilehooks.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_profilehooks.py 2001/09/24 18:44:11 1.2 --- test_profilehooks.py 2001/09/25 20:48:14 1.3 *************** *** 47,62 **** pass f_ident = ident(f) ! self.check_events(f, [(0, 'call', f_ident), ! (0, 'return', f_ident), ]) def test_exception(self): def f(p): try: 1/0 except: pass f_ident = ident(f) ! self.check_events(f, [(0, 'call', f_ident), ! (0, 'exception', f_ident), ! (0, 'return', f_ident), ]) --- 47,71 ---- pass f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), ! (1, 'return', f_ident), ]) def test_exception(self): def f(p): + 1/0 + f_ident = ident(f) + self.check_events(f, [(1, 'call', f_ident), + (1, 'exception', f_ident), + (0, 'exception', protect_ident), + ]) + + def test_caught_exception(self): + def f(p): try: 1/0 except: pass f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (1, 'return', f_ident), ]) *************** *** 65,77 **** try: 1/0 except: pass - def g(p): - f(p) f_ident = ident(f) ! g_ident = ident(g) ! self.check_events(g, [(0, 'call', g_ident), ! (1, 'call', f_ident), (1, 'exception', f_ident), (1, 'return', f_ident), - (0, 'return', g_ident), ]) --- 74,81 ---- try: 1/0 except: pass f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), (1, 'exception', f_ident), (1, 'return', f_ident), ]) *************** *** 79,95 **** def f(p): 1/0 - def g(p): - try: f(p) - except: pass f_ident = ident(f) ! g_ident = ident(g) ! self.check_events(g, [(0, 'call', g_ident), ! (1, 'call', f_ident), (1, 'exception', f_ident), # This isn't what I expected: ! (0, 'exception', g_ident), # I expected this again: # (1, 'exception', f_ident), - (0, 'return', g_ident), ]) --- 83,93 ---- def f(p): 1/0 f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), (1, 'exception', f_ident), # This isn't what I expected: ! (0, 'exception', protect_ident), # I expected this again: # (1, 'exception', f_ident), ]) *************** *** 105,116 **** f_ident = ident(f) g_ident = ident(g) ! self.check_events(g, [(0, 'call', g_ident), ! (1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', g_ident), (2, 'call', f_ident), (2, 'exception', f_ident), ! (0, 'exception', g_ident), ! (0, 'return', g_ident), ]) --- 103,114 ---- f_ident = ident(f) g_ident = ident(g) ! self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), (2, 'exception', f_ident), ! (1, 'exception', g_ident), ! (3, 'call', f_ident), ! (3, 'exception', f_ident), ! (1, 'exception', g_ident), ! (1, 'return', g_ident), ]) *************** *** 121,140 **** try: f(p) finally: p.add_event("falling through") - def h(p): - try: g(p) - except: pass f_ident = ident(f) g_ident = ident(g) ! h_ident = ident(h) ! self.check_events(h, [(0, 'call', h_ident), ! (1, 'call', g_ident), (2, 'call', f_ident), (2, 'exception', f_ident), (1, 'exception', g_ident), (1, 'falling through', g_ident), ! (0, 'exception', h_ident), ! (0, 'return', h_ident), ]) def ident(function): if hasattr(function, "f_code"): --- 119,163 ---- try: f(p) finally: p.add_event("falling through") f_ident = ident(f) g_ident = ident(g) ! self.check_events(g, [(1, 'call', g_ident), (2, 'call', f_ident), (2, 'exception', f_ident), (1, 'exception', g_ident), (1, 'falling through', g_ident), ! (0, 'exception', protect_ident), ! ]) ! ! def test_raise_twice(self): ! def f(p): ! try: 1/0 ! except: 1/0 ! f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ! ]) ! ! def test_raise_reraise(self): ! def f(p): ! try: 1/0 ! except: raise ! f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ! ]) ! ! def test_raise(self): ! def f(p): ! raise Exception() ! f_ident = ident(f) ! self.check_events(f, [(1, 'call', f_ident), ! (1, 'exception', f_ident), ! (0, 'exception', protect_ident) ]) + def ident(function): if hasattr(function, "f_code"): *************** *** 145,154 **** def capture_events(callable): p = HookWatcher() sys.setprofile(p.callback) ! callable(p) sys.setprofile(None) ! return p.get_events() --- 168,184 ---- + def protect(f, p): + try: f(p) + except: pass + + protect_ident = ident(protect) + + def capture_events(callable): p = HookWatcher() sys.setprofile(p.callback) ! protect(callable, p) sys.setprofile(None) ! return p.get_events()[1:-1] From fdrake@users.sourceforge.net Tue Sep 25 21:57:39 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 13:57:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv latex2esis.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv14717 Modified Files: latex2esis.py Log Message: Simplify a helper by returning fewer values. Index: latex2esis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/latex2esis.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -d -r1.24 -r1.25 *** latex2esis.py 2001/07/06 21:01:19 1.24 --- latex2esis.py 2001/09/25 20:57:36 1.25 *************** *** 186,194 **** self.write(")%s\n-\\n\n" % topentry.outputname) # ! if entry.outputname: ! if entry.empty: ! self.write("e\n") # ! params, optional, empty, environ = self.start_macro(macroname) # rip off the macroname if params: --- 186,193 ---- self.write(")%s\n-\\n\n" % topentry.outputname) # ! if entry.outputname and entry.empty: ! self.write("e\n") # ! params, optional, empty = self.start_macro(macroname) # rip off the macroname if params: *************** *** 364,368 **** parameters = conversion.parameters optional = parameters and parameters[0].optional ! return parameters, optional, conversion.empty, conversion.environment def get_entry(self, name): --- 363,367 ---- parameters = conversion.parameters optional = parameters and parameters[0].optional ! return parameters, optional, conversion.empty def get_entry(self, name): From fdrake@users.sourceforge.net Tue Sep 25 21:58:16 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Tue, 25 Sep 2001 13:58:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv14861 Modified Files: conversion.xml Log Message: Update to support \mailheader and 5-column tables. Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** conversion.xml 2001/07/14 03:10:20 1.17 --- conversion.xml 2001/09/25 20:58:13 1.18 *************** *** 561,564 **** --- 561,613 ---- + + 4 + + + + + + + + + + + + + + + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + *************** *** 678,681 **** --- 727,733 ---- + + + From gvanrossum@users.sourceforge.net Tue Sep 25 22:16:35 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Tue, 25 Sep 2001 14:16:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.74,2.75 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19145 Modified Files: typeobject.c Log Message: add_operators(): the __floordiv__ and __truediv__ descriptors (and their 'i' and 'r' variants) were not being generated if the corresponding nb_ slots were present in the type object. I bet this is because floor and true division were introduced after I last looked at that part of the code. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.74 retrieving revision 2.75 diff -C2 -d -r2.74 -r2.75 *** typeobject.c 2001/09/25 16:25:58 2.74 --- typeobject.c 2001/09/25 21:16:33 2.75 *************** *** 1838,1841 **** --- 1838,1843 ---- BINARY(xor, "x^y"); BINARY(or, "x|y"); + BINARY(floordiv, "x//y"); + BINARY(truediv, "x/y # true division"); static PyObject * *************** *** 1916,1919 **** --- 1918,1923 ---- IBINARY(ixor, "x^=y"); IBINARY(ior, "x|=y"); + IBINARY(ifloordiv, "x//=y"); + IBINARY(itruediv, "x/=y # true division"); #undef ITERNARY *************** *** 2587,2590 **** --- 2591,2600 ---- ADD(nb->nb_inplace_xor, tab_ixor); ADD(nb->nb_inplace_or, tab_ior); + if (type->tp_flags & Py_TPFLAGS_CHECKTYPES) { + ADD(nb->nb_floor_divide, tab_floordiv); + ADD(nb->nb_true_divide, tab_truediv); + ADD(nb->nb_inplace_floor_divide, tab_ifloordiv); + ADD(nb->nb_inplace_true_divide, tab_itruediv); + } } From bwarsaw@users.sourceforge.net Tue Sep 25 22:40:06 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 14:40:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_StringIO.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24419 Modified Files: test_StringIO.py Log Message: test_iterator(): Don't do a type comparison to see if it's an iterator, just test to make sure it has the two required iterator protocol methods __iter__() and next() -- actually just test hasattr-ness. Index: test_StringIO.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_StringIO.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** test_StringIO.py 2001/09/24 17:34:52 1.8 --- test_StringIO.py 2001/09/25 21:40:04 1.9 *************** *** 58,63 **** def test_iterator(self): eq = self.assertEqual it = iter(self._fp) ! self.failUnless(isinstance(it, types.FunctionIterType)) i = 0 for line in self._fp: --- 58,66 ---- def test_iterator(self): eq = self.assertEqual + unless = self.failUnless it = iter(self._fp) ! # Does this object support the iteration protocol? ! unless(hasattr(it, '__iter__')) ! unless(hasattr(it, 'next')) i = 0 for line in self._fp: From tim_one@users.sourceforge.net Tue Sep 25 23:02:06 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Tue, 25 Sep 2001 15:02:06 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29611/python/Lib Modified Files: types.py Log Message: SF [#463737] Add types.CallableIterType Rather than add umpteen new obscure internal Iter types, got rid of all of them. See the new comment. Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** types.py 2001/09/13 05:38:55 1.21 --- types.py 2001/09/25 22:02:03 1.22 *************** *** 7,10 **** --- 7,15 ---- import sys + # Iterators in Python aren't a matter of type but of protocol. A large + # and changing number of builtin types implement *some* flavor of + # iterator. Don't check the type! Use hasattr to check for both + # "__iter__" and "next" attributes instead. + NoneType = type(None) TypeType = type *************** *** 77,83 **** EllipsisType = type(Ellipsis) - DictIterType = type(iter({})) - SequenceIterType = type(iter([])) - FunctionIterType = type(iter(lambda: 0, 0)) DictProxyType = type(TypeType.__dict__) --- 82,85 ---- From bwarsaw@users.sourceforge.net Wed Sep 26 06:01:11 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:01:11 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.134,1.135 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv21678 Modified Files: pep-0000.txt Log Message: PEP 271 is withdrawn. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.134 retrieving revision 1.135 diff -C2 -d -r1.134 -r1.135 *** pep-0000.txt 2001/09/20 16:02:29 1.134 --- pep-0000.txt 2001/09/26 05:01:09 1.135 *************** *** 67,71 **** S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone - S 271 Prefixing sys.path by command line option Giacometti Py-in-the-sky PEPs (not considered for Python 2.2) --- 67,70 ---- *************** *** 125,129 **** ID 220 Coroutines, Generators, Continuations McMillan ! Deferred, Abandoned, and Rejected PEPs SR 204 Range Literals Wouters --- 124,128 ---- ID 220 Coroutines, Generators, Continuations McMillan ! Deferred, Abandoned, Withdrawn, and Rejected PEPs SR 204 Range Literals Wouters *************** *** 133,136 **** --- 132,136 ---- SR 244 The `directive' Statement von Loewis SR 259 Omit printing newline after newline van Rossum + SR 271 Prefixing sys.path by command line option Giacometti *************** *** 226,230 **** S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone ! S 271 Prefixing sys.path by command line option Giacometti I 272 API for Secret-Key Encryption Algorithms Kuchling --- 226,230 ---- S 269 Pgen Module for Python Riehl S 270 uniq method for list objects Petrone ! SR 271 Prefixing sys.path by command line option Giacometti I 272 API for Secret-Key Encryption Algorithms Kuchling From bwarsaw@users.sourceforge.net Wed Sep 26 06:01:27 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:01:27 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0271.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv21705 Modified Files: pep-0271.txt Log Message: This PEP has been withdrawn by its author. Index: pep-0271.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0271.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** pep-0271.txt 2001/09/13 18:41:35 1.2 --- pep-0271.txt 2001/09/26 05:01:24 1.3 *************** *** 4,8 **** Last-Modified: $Date$ Author: fred@arakne.com (Frédéric B. Giacometti) ! Status: Draft Type: Standards Track Created: 15-Aug-2001 --- 4,8 ---- Last-Modified: $Date$ Author: fred@arakne.com (Frédéric B. Giacometti) ! Status: Rejected Type: Standards Track Created: 15-Aug-2001 From bwarsaw@users.sourceforge.net Wed Sep 26 06:23:49 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:23:49 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib emailencoders.tex,NONE,1.1 emailexc.tex,NONE,1.1 emailgenerator.tex,NONE,1.1 emailiter.tex,NONE,1.1 emailmessage.tex,NONE,1.1 emailparser.tex,NONE,1.1 email.tex,NONE,1.1 emailutil.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv25736 Added Files: emailencoders.tex emailexc.tex emailgenerator.tex emailiter.tex emailmessage.tex emailparser.tex email.tex emailutil.tex Log Message: The email package documentation, currently organized the way I think Fred prefers. I'm not sure I like this organization, so it may change. --- NEW FILE: emailencoders.tex --- \section{\module{email.Encoders} --- Email message payload encoders} \declaremodule{standard}{email.Encoders} \modulesynopsis{Encoders for email message payloads.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} When creating \class{Message} objects from scratch, you often need to encode the payloads for transport through compliant mail servers. This is especially true for \code{image/*} and \code{text/*} type messages containing binary data. The \module{email} package provides some convenient encodings in its \module{Encoders} module. These encoders are actually used by the \class{MIMEImage} and \class{MIMEText} class constructors to provide default encodings. All encoder functions take exactly one argument, the message object to encode. They usually extract the payload, encode it, and reset the payload to this newly encoded value. They should also set the \code{Content-Transfer-Encoding:} header as appropriate. Here are the encoding functions provided: \begin{funcdesc}{encode_quopri}{msg} Encodes the payload into \emph{Quoted-Printable} form and sets the \code{Content-Transfer-Encoding:} header to \code{quoted-printable}\footnote{Note that encoding with \method{encode_quopri()} also encodes all tabs and space characters in the data.}. This is a good encoding to use when most of your payload is normal printable data, but contains a few unprintable characters. \end{funcdesc} \begin{funcdesc}{encode_base64}{msg} Encodes the payload into \emph{Base64} form and sets the \code{Content-Transfer-Encoding:} header to \code{base64}. This is a good encoding to use when most of your payload is unprintable data since it is a more compact form than Quoted-Printable. The drawback of Base64 encoding is that it renders the text non-human readable. \end{funcdesc} \begin{funcdesc}{encode_7or8bit}{msg} This doesn't actually modify the message's payload, but it does set the \code{Content-Transfer-Encoding:} header to either \code{7bit} or \code{8bit} as appropriate, based on the payload data. \end{funcdesc} \begin{funcdesc}{encode_noop}{msg} This does nothing; it doesn't even set the \code{Content-Transfer-Encoding:} header. \end{funcdesc} --- NEW FILE: emailexc.tex --- \section{\module{email.Errors} --- email package exception classes} \declaremodule{standard}{email.Exceptions} \modulesynopsis{The exception classes used by the email package.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} The following exception classes are defined in the \module{email.Errors} module: \begin{excclassdesc}{MessageError}{} This is the base class for all exceptions that the \module{email} package can raise. It is derived from the standard \exception{Exception} class and defines no additional methods. \end{excclassdesc} \begin{excclassdesc}{MessageParseError}{} This is the base class for exceptions thrown by the \class{Parser} class. It is derived from \exception{MessageError}. \end{excclassdesc} \begin{excclassdesc}{HeaderParseError}{} Raised under some error conditions when parsing the \rfc{2822} headers of a message, this class is derived from \exception{MessageParseError}. It can be raised from the \method{Parser.parse()} or \method{Parser.parsestr()} methods. Situations where it can be raised include finding a \emph{Unix-From} header after the first \rfc{2822} header of the message, finding a continuation line before the first \rfc{2822} header is found, or finding a line in the headers which is neither a header or a continuation line. \end{excclassdesc} \begin{excclassdesc}{BoundaryError}{} Raised under some error conditions when parsing the \rfc{2822} headers of a message, this class is derived from \exception{MessageParseError}. It can be raised from the \method{Parser.parse()} or \method{Parser.parsestr()} methods. Situations where it can be raised include not being able to find the starting or terminating boundary in a \code{multipart/*} message. \end{excclassdesc} \begin{excclassdesc}{MultipartConversionError}{} Raised when a payload is added to a \class{Message} object using \method{add_payload()}, but the payload is already a scalar and the message's \code{Content-Type:} main type is not either \code{multipart} or missing. \exception{MultipartConversionError} multiply inherits from \exception{MessageError} and the built-in \exception{TypeError}. \end{excclassdesc} --- NEW FILE: emailgenerator.tex --- \section{\module{email.Generator} --- Generating flat text from an email message object tree} \declaremodule{standard}{email.Generator} \modulesynopsis{Generate flat text email messages to from a message object tree.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} The \class{Generator} class is used to render a message object model into its flat text representation, including MIME encoding any sub-messages, generating the correct \rfc{2822} headers, etc. Here are the public methods of the \class{Generator} class. \begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{, maxheaderlen}}} The constructor for the \class{Generator} class takes a file-like object called \var{outfp} for an argument. \var{outfp} must support the \method{write()} method and be usable as the output file in a Python 2.0 extended print statement. Optional \var{mangle_from_} is a flag that, when true, puts a ``>'' character in front of any line in the body that starts exactly as \samp{From } (i.e. \code{From} followed by a space at the front of the line). This is the only guaranteed portable way to avoid having such lines be mistaken for \emph{Unix-From} headers (see \url{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} for details). Optional \var{maxheaderlen} specifies the longest length for a non-continued header. When a header line is longer than \var{maxheaderlen} (in characters, with tabs expanded to 8 spaces), the header will be broken on semicolons and continued as per \rfc{2822}. If no semicolon is found, then the header is left alone. Set to zero to disable wrapping headers. Default is 78, as recommended (but not required) by \rfc{2822}. \end{classdesc} The other public \class{Generator} methods are: \begin{methoddesc}[Generator]{__call__}{msg\optional{, unixfrom}} Print the textual representation of the message object tree rooted at \var{msg} to the output file specified when the \class{Generator} instance was created. Sub-objects are visited depth-first and the resulting text will be properly MIME encoded. Optional \var{unixfrom} is a flag that forces the printing of the \emph{Unix-From} (a.k.a. envelope header or \code{From_} header) delimiter before the first \rfc{2822} header of the root message object. If the root object has no \emph{Unix-From} header, a standard one is crafted. By default, this is set to 0 to inhibit the printing of the \emph{Unix-From} delimiter. Note that for sub-objects, no \emph{Unix-From} header is ever printed. \end{methoddesc} \begin{methoddesc}[Generator]{write}{s} Write the string \var{s} to the underlying file object, i.e. \var{outfp} passed to \class{Generator}'s constructor. This provides just enough file-like API for \class{Generator} instances to be used in extended print statements. \end{methoddesc} As a convenience, see the methods \method{Message.as_string()} and \code{str(aMessage)}, a.k.a. \method{Message.__str__()}, which simplify the generation of a formatted string representation of a message object. For more detail, see \refmodule{email.Message}. --- NEW FILE: emailiter.tex --- \section{\module{email.Iterators} --- Message object tree iterators} \declaremodule{standard}{email.Iterators} \modulesynopsis{Iterate over a message object tree.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} Iterating over a message object tree is fairly easy with the \method{Message.walk()} method. The \module{email.Iterators} module provides some useful higher level iterations over message object trees. \begin{funcdesc}{body_line_iterator}{msg} This iterates over all the payloads in all the subparts of \var{msg}, returning the string payloads line-by-line. It skips over all the subpart headers, and it skips over any subpart with a payload that isn't a Python string. This is somewhat equivalent to reading the flat text representation of the message from a file using \method{readline()}, skipping over all the intervening headers. \end{funcdesc} \begin{funcdesc}{typed_subpart_iterator}{msg\optional{, maintype\optional{, subtype}}} This iterates over all the subparts of \var{msg}, returning only those subparts that match the MIME type specified by \var{maintype} and \var{subtype}. Note that \var{subtype} is optional; if omitted, then subpart MIME type matching is done only with the main type. \var{maintype} is optional too; it defaults to \code{text}. Thus, by default \function{typed_subpart_iterator()} returns each subpart that has a MIME type of \code{text/*}. \end{funcdesc} --- NEW FILE: emailmessage.tex --- \section{\module{email.Message} --- The Message class} \declaremodule{standard}{email.Message} \modulesynopsis{The base class representing email messages.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} The \module{Message} module provides a single class, the \class{Message} class. This class is the base class for the \module{email} package object model. It has a fairly extensive set of methods to get and set email headers and email payloads. For an introduction of the \module{email} package, please read the \refmodule{email} package overview. \class{Message} instances can be created either directly, or indirectly by using a \refmodule{email.Parser}. \class{Message} objects provide a mapping style interface for accessing the message headers, and an explicit interface for accessing both the headers and the payload. It provides convenience methods for generating a flat text representation of the message object tree, for accessing commonly used header parameters, and for recursively walking over the object tree. Here are the methods of the \class{Message} class: \begin{methoddesc}[Message]{as_string}{\optional{unixfrom}} Return the entire formatted message as a string. Optional \var{unixfrom}, when true, specifies to include the \emph{Unix-From} envelope header; it defaults to 0. \end{methoddesc} \begin{methoddesc}[Message]{__str__()}{} Equivalent to \method{aMessage.as_string(unixfrom=1)}. \end{methoddesc} \begin{methoddesc}[Message]{is_multipart}{} Return 1 if the message's payload is a list of sub-\class{Message} objects, otherwise return 0. When \method{is_multipart()} returns 0, the payload should either be a string object, or a single \class{Message} instance. \end{methoddesc} \begin{methoddesc}[Message]{set_unixfrom}{unixfrom} Set the \emph{Unix-From} (a.k.a envelope header or \code{From_} header) to \var{unixfrom}, which should be a string. \end{methoddesc} \begin{methoddesc}[Message]{get_unixfrom}{} Return the \emph{Unix-From} header. Defaults to \code{None} if the \emph{Unix-From} header was never set. \end{methoddesc} \begin{methoddesc}[Message]{add_payload}{payload} Add \var{payload} to the message object's existing payload. If, prior to calling this method, the object's payload was \code{None} (i.e. never before set), then after this method is called, the payload will be the argument \var{payload}. If the object's payload was already a list (i.e. \method{is_multipart()} returns 1), then \var{payload} is appended to the end of the existing payload list. For any other type of existing payload, \method{add_payload()} will transform the new payload into a list consisting of the old payload and \var{payload}, but only if the document is already a MIME multipart document. This condition is satisfied if the message's \code{Content-Type:} header's main type is either \var{multipart}, or there is no \code{Content-Type:} header. In any other situation, \exception{MultipartConversionError} is raised. \end{methoddesc} \begin{methoddesc}[Message]{attach}{payload} Synonymous with \method{add_payload()}. \end{methoddesc} \begin{methoddesc}[Message]{get_payload}{\optional{i\optional{, decode}}} Return the current payload, which will be a list of \class{Message} objects when \method{is_multipart()} returns 1, or a scalar (either a string or a single \class{Message} instance) when \method{is_multipart()} returns 0. With optional \var{i}, \method{get_payload()} will return the \var{i}-th element of the payload, counting from zero, if \method{is_multipart()} returns 1. An \code{IndexError} will be raised if \var{i} is less than 0 or greater than or equal to the number of items in the payload. If the payload is scalar (i.e. \method{is_multipart()} returns 0) and \var{i} is given, a \code{TypeError} is raised. Optional \var{decode} is a flag indicating whether the payload should be decoded or not, according to the \code{Content-Transfer-Encoding:} header. When true and the message is not a multipart, the payload will be decoded if this header's value is \samp{quoted-printable} or \samp{base64}. If some other encoding is used, or \code{Content-Transfer-Encoding:} header is missing, the payload is returned as-is (undecoded). If the message is a multipart and the \var{decode} flag is true, then \code{None} is returned. \end{methoddesc} \begin{methoddesc}[Message]{set_payload}{payload} Set the entire message object's payload to \var{payload}. It is the client's responsibility to ensure the payload invariants. \end{methoddesc} The following methods implement a mapping-like interface for accessing the message object's \rfc{2822} headers. Note that there are some semantic differences between these methods and a normal mapping (i.e. dictionary) interface. For example, in a dictionary there are no duplicate keys, but here there may be duplicate message headers. Also, in dictionaries there is no guaranteed order to the keys returned by \method{keys()}, but in a \class{Message} object, there is an explicit order. These semantic differences are intentional and are biased toward maximal convenience. Note that in all cases, any optional \emph{Unix-From} header the message may have is not included in the mapping interface. \begin{methoddesc}[Message]{__len__}{} Return the total number of headers, including duplicates. \end{methoddesc} \begin{methoddesc}[Message]{__contains__}{name} Return true if the message object has a field named \var{name}. Match is done case-insensitively and \var{name} should not include the trailing colon. Used for the \code{in} operator, e.g.: \begin{verbatim} if 'message-id' in myMessage: print 'Message-ID:', myMessage['message-id'] \end{verbatim} \end{methoddesc} \begin{methoddesc}[Message]{__getitem__}{name} Return the value of the named header field. \var{name} should not include the colon field separator. If the header is missing, \code{None} is returned; a \code{KeyError} is never raised. Note that if the named field appears more than once in the message's headers, exactly which of those field values will be returned is undefined. Use the \method{get_all()} method to get the values of all the extant named headers. \end{methoddesc} \begin{methoddesc}[Message]{__setitem__}{name, val} Add a header to the message with field name \var{name} and value \var{val}. The field is appended to the end of the message's existing fields. Note that this does \emph{not} overwrite or delete any existing header with the same name. If you want to ensure that the new header is the only one present in the message with field name \var{name}, first use \method{__delitem__()} to delete all named fields, e.g.: \begin{verbatim} del msg['subject'] msg['subject'] = 'Python roolz!' \end{verbatim} \end{methoddesc} \begin{methoddesc}[Message]{__delitem__}{name} Delete all occurrences of the field with name \var{name} from the message's headers. No exception is raised if the named field isn't present in the headers. \end{methoddesc} \begin{methoddesc}[Message]{has_key}{name} Return 1 if the message contains a header field named \var{name}, otherwise return 0. \end{methoddesc} \begin{methoddesc}[Message]{keys}{} Return a list of all the message's header field names. These keys will be sorted in the order in which they were added to the message via \method{__setitem__()}, and may contain duplicates. Any fields deleted and then subsequently re-added are always appended to the end of the header list. \end{methoddesc} \begin{methoddesc}[Message]{values}{} Return a list of all the message's field values. These will be sorted in the order in which they were added to the message via \method{__setitem__()}, and may contain duplicates. Any fields deleted and then subsequently re-added are always appended to the end of the header list. \end{methoddesc} \begin{methoddesc}[Message]{items}{} Return a list of 2-tuples containing all the message's field headers and values. These will be sorted in the order in which they were added to the message via \method{__setitem__()}, and may contain duplicates. Any fields deleted and then subsequently re-added are always appended to the end of the header list. \end{methoddesc} \begin{methoddesc}[Message]{get}{name\optional{, failobj}} Return the value of the named header field. This is identical to \method{__getitem__()} except that optional \var{failobj} is returned if the named header is missing (defaults to \code{None}). \end{methoddesc} Here are some additional useful methods: \begin{methoddesc}[Message]{get_all}{name\optional{, failobj}} Return a list of all the values for the field named \var{name}. These will be sorted in the order in which they were added to the message via \method{__setitem__()}. Any fields deleted and then subsequently re-added are always appended to the end of the list. If there are no such named headers in the message, \var{failobj} is returned (defaults to \code{None}). \end{methoddesc} \begin{methoddesc}[Message]{add_header}{_name, _value, **_params} Extended header setting. This method is similar to \method{__setitem__()} except that additional header parameters can be provided as keyword arguments. \var{_name} is the header to set and \var{_value} is the \emph{primary} value for the header. For each item in the keyword argument dictionary \var{_params}, the key is taken as the parameter name, with underscores converted to dashes (since dashes are illegal in Python identifiers). Normally, the parameter will be added as \code{key="value"} unless the value is \code{None}, in which case only the key will be added. Here's an example: \begin{verbatim} msg.add_header('Content-Disposition', 'attachment', filename='bud.gif') \end{verbatim} This will add a header that looks like \begin{verbatim} Content-Disposition: attachment; filename="bud.gif" \end{verbatim} \end{methoddesc} \begin{methoddesc}[Message]{get_type}{\optional{failobj}} Return the message's content type, as a string of the form ``maintype/subtype'' as taken from the \code{Content-Type:} header. The returned string is coerced to lowercase. If there is no \code{Content-Type:} header in the message, \var{failobj} is returned (defaults to \code{None}). \end{methoddesc} \begin{methoddesc}[Message]{get_main_type}{\optional{failobj}} Return the message's \emph{main} content type. This essentially returns the \var{maintype} part of the string returned by \method{get_type()}, with the same semantics for \var{failobj}. \end{methoddesc} \begin{methoddesc}[Message]{get_subtype}{\optional{failobj}} Return the message's sub-content type. This essentially returns the \var{subtype} part of the string returned by \method{get_type()}, with the same semantics for \var{failobj}. \end{methoddesc} \begin{methoddesc}[Message]{get_params}{\optional{failobj\optional{, header}}} Return the message's \code{Content-Type:} parameters, as a list. The elements of the returned list are 2-tuples of key/value pairs, as split on the \samp{=} sign. The left hand side of the \samp{=} is the key, while the right hand side is the value. If there is no \samp{=} sign in the parameter the value is the empty string. The value is always unquoted with \method{Utils.unquote()}. Optional \var{failobj} is the object to return if there is no \code{Content-Type:} header. Optional \var{header} is the header to search instead of \code{Content-Type:}. \end{methoddesc} \begin{methoddesc}[Message]{get_param}{param\optional{, failobj\optional{, header}}} Return the value of the \code{Content-Type:} header's parameter \var{param} as a string. If the message has no \code{Content-Type:} header or if there is no such parameter, then \var{failobj} is returned (defaults to \code{None}). Optional \var{header} if given, specifies the message header to use instead of \code{Content-Type:}. \end{methoddesc} \begin{methoddesc}[Message]{get_charsets}{\optional{failobj}} Return a list containing the character set names in the message. If the message is a \code{multipart}, then the list will contain one element for each subpart in the payload, otherwise, it will be a list of length 1. Each item in the list will be a string which is the value of the \code{charset} parameter in the \code{Content-Type:} header for the represented subpart. However, if the subpart has no \code{Content-Type:} header, no \code{charset} parameter, or is not of the \code{text} main MIME type, then that item in the returned list will be \var{failobj}. \end{methoddesc} \begin{methoddesc}[Message]{get_filename}{\optional{failobj}} Return the value of the \code{filename} parameter of the \code{Content-Disposition:} header of the message, or \var{failobj} if either the header is missing, or has no \code{filename} parameter. The returned string will always be unquoted as per \method{Utils.unquote()}. \end{methoddesc} \begin{methoddesc}[Message]{get_boundary}{\optional{failobj}} Return the value of the \code{boundary} parameter of the \code{Content-Type:} header of the message, or \var{failobj} if either the header is missing, or has no \code{boundary} parameter. The returned string will always be unquoted as per \method{Utils.unquote()}. \end{methoddesc} \begin{methoddesc}[Message]{set_boundary}{boundary} Set the \code{boundary} parameter of the \code{Content-Type:} header to \var{boundary}. \method{set_boundary()} will always quote \var{boundary} so you should not quote it yourself. A \code{HeaderParseError} is raised if the message object has no \code{Content-Type:} header. Note that using this method is subtly different than deleting the old \code{Content-Type:} header and adding a new one with the new boundary via \method{add_header()}, because \method{set_boundary()} preserves the order of the \code{Content-Type:} header in the list of headers. However, it does \emph{not} preserve any continuation lines which may have been present in the original \code{Content-Type:} header. \end{methoddesc} \begin{methoddesc}[Message]{walk}{} The \method{walk()} method is an all-purpose generator which can be used to iterate over all the parts and subparts of a message object tree, in depth-first traversal order. You will typically use \method{walk()} as the iterator in a \code{for ... in} loop; each iteration returns the next subpart. Here's an example that prints the MIME type of every part of a message object tree: \begin{verbatim} >>> for part in msg.walk(): >>> print part.get_type('text/plain') multipart/report text/plain message/delivery-status text/plain text/plain message/rfc822 \end{verbatim} \end{methoddesc} \class{Message} objects can also optionally contain two instance attributes, which can be used when generating the plain text of a MIME message. \begin{datadesc}{preamble} The format of a MIME document allows for some text between the blank line following the headers, and the first multipart boundary string. Normally, this text is never visible in a MIME-aware mail reader because it falls outside the standard MIME armor. However, when viewing the raw text of the message, or when viewing the message in a non-MIME aware reader, this text can become visible. The \var{preamble} attribute contains this leading extra-armor text for MIME documents. When the \class{Parser} discovers some text after the headers but before the first boundary string, it assigns this text to the message's \var{preamble} attribute. When the \class{Generator} is writing out the plain text representation of a MIME message, and it finds the message has a \var{preamble} attribute, it will write this text in the area between the headers and the first boundary. Note that if the message object has no preamble, the \var{preamble} attribute will be \code{None}. \end{datadesc} \begin{datadesc}{epilogue} The \var{epilogue} attribute acts the same way as the \var{preamble} attribute, except that it contains text that appears between the last boundary and the end of the message. \end{datadesc} --- NEW FILE: emailparser.tex --- \section{\module{email.Parser} --- Parsing flat text email messages} \declaremodule{standard}{email.Parser} \modulesynopsis{Parse flat text email messages to produce a message object tree.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} The \module{Parser} module provides a single class, the \class{Parser} class, which is used to take a message in flat text form and create the associated object model. The resulting object tree can then be manipulated using the \class{Message} class interface as described in \refmodule{email.Message}, and turned over to a generator (as described in \refmodule{emamil.Generator}) to return the textual representation of the message. It is intended that the \class{Parser} to \class{Generator} path be idempotent if the object model isn't modified in between. \subsection{Parser class API} \begin{classdesc}{Parser}{\optional{_class}} The constructor for the \class{Parser} class takes a single optional argument \var{_class}. This must be callable factory (i.e. a function or a class), and it is used whenever a sub-message object needs to be created. It defaults to \class{Message} (see \refmodule{email.Message}). \var{_class} will be called with zero arguments. \end{classdesc} The other public \class{Parser} methods are: \begin{methoddesc}[Parser]{parse}{fp} Read all the data from the file-like object \var{fp}, parse the resulting text, and return the root message object. \var{fp} must support both the \method{readline()} and the \method{read()} methods on file-like objects. The text contained in \var{fp} must be formatted as a block of \rfc{2822} style headers and header continuation lines, optionally preceeded by a \emph{Unix-From} header. The header block is terminated either by the end of the data or by a blank line. Following the header block is the body of the message (which may contain MIME-encoded subparts). \end{methoddesc} \begin{methoddesc}[Parser]{parsestr}{text} Similar to the \method{parse()} method, except it takes a string object instead of a file-like object. Calling this method on a string is exactly equivalent to wrapping \var{text} in a \class{StringIO} instance first and calling \method{parse()}. \end{methoddesc} Since creating a message object tree from a string or a file object is such a common task, two functions are provided as a convenience. They are available in the top-level \module{email} package namespace. \begin{funcdesc}{message_from_string}{s\optional{, _class}} Return a message object tree from a string. This is exactly equivalent to \code{Parser().parsestr(s)}. Optional \var{_class} is interpreted as with the \class{Parser} class constructor. \end{funcdesc} \begin{funcdesc}{message_from_file}{fp\optional{, _class}} Return a message object tree from an open file object. This is exactly equivalent to \code{Parser().parse(fp)}. Optional \var{_class} is interpreted as with the \class{Parser} class constructor. \end{funcdesc} Here's an example of how you might use this at an interactive Python prompt: \begin{verbatim} >>> import email >>> msg = email.message_from_string(myString) \end{verbatim} \subsection{Additional notes} Here are some notes on the parsing semantics: \begin{itemize} \item Most non-\code{multipart} type messages are parsed as a single message object with a string payload. These objects will return 0 for \method{is_multipart()}. \item One exception is for \code{message/delivery-status} type messages. Because such the body of such messages consist of blocks of headers, \class{Parser} will create a non-multipart object containing non-multipart subobjects for each header block. \item Another exception is for \code{message/*} types (i.e. more general than \code{message/delivery-status}. These are typically \code{message/rfc822} type messages, represented as a non-multipart object containing a singleton payload, another non-multipart \class{Message} instance. \end{itemize} --- NEW FILE: email.tex --- % Copyright (C) 2001 Python Software Foundation % Author: barry@zope.com (Barry Warsaw) \section{\module{email} -- An email and MIME handling package} \declaremodule{standard}{email} \modulesynopsis{Package supporting the parsing, manipulating, and generating email messages, including MIME documents.} \moduleauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} The \module{email} package is a library for managing email messages, including MIME and other \rfc{2822}-based message documents. It subsumes most of the functionality in several older standard modules such as \module{rfc822}, \module{mimetools}, \module{multifile}, and other non-standard packages such as \module{mimecntl}. The primary distinguishing feature of the \module{email} package is that it splits the parsing and generating of email messages from the internal \emph{object model} representation of email. Applications using the \module{email} package deal primarily with objects; you can add sub-objects to messages, remove sub-objects from messages, completely re-arrange the contents, etc. There is a separate parser and a separate generator which handles the transformation from flat text to the object module, and then back to flat text again. There are also handy subclasses for some common MIME object types, and a few miscellaneous utilities that help with such common tasks as extracting and parsing message field values, creating RFC-compliant dates, etc. The following sections describe the functionality of the \module{email} package. The ordering follows a progression that should be common in applications: an email message is read as flat text from a file or other source, the text is parsed to produce an object model representation of the email message, this model is manipulated, and finally the model is rendered back into flat text. It is perfectly feasible to create the object model out of whole cloth -- i.e. completely from scratch. From there, a similar progression can be taken as above. Also included are detailed specifications of all the classes and modules that the \module{email} package provides, the exception classes you might encounter while using the \module{email} package, some auxiliary utilities, and a few examples. For users of the older \module{mimelib} package, from which the \module{email} package is descendent, a section on differences and porting is provided. \subsection{Representing an email message} The primary object in the \module{email} package is the \class{Message} class, provided in the \refmodule{email.Message} module. \class{Message} is the base class for the \module{email} object model. It provides the core functionality for setting and querying header fields, and for accessing message bodies. Conceptually, a \class{Message} object consists of \emph{headers} and \emph{payloads}. Headers are \rfc{2822} style field name and values where the field name and value are separated by a colon. The colon is not part of either the field name or the field value. Headers are stored and returned in case-preserving form but are matched case-insensitively. There may also be a single \emph{Unix-From} header, also known as the envelope header or the \code{From_} header. The payload is either a string in the case of simple message objects, a list of \class{Message} objects for multipart MIME documents, or a single \class{Message} instance for \code{message/rfc822} type objects. \class{Message} objects provide a mapping style interface for accessing the message headers, and an explicit interface for accessing both the headers and the payload. It provides convenience methods for generating a flat text representation of the message object tree, for accessing commonly used header parameters, and for recursively walking over the object tree. \subsection{Parsing email messages} Message object trees can be created in one of two ways: they can be created from whole cloth by instantiating \class{Message} objects and stringing them together via \method{add_payload()} and \method{set_payload()} calls, or they can be created by parsing a flat text representation of the email message. The \module{email} package provides a standard parser that understands most email document structures, including MIME documents. You can pass the parser a string or a file object, and the parser will return to you the root \class{Message} instance of the object tree. For simple, non-MIME messages the payload of this root object will likely be a string (e.g. containing the text of the message). For MIME messages, the root object will return 1 from its \method{is_multipart()} method, and the subparts can be accessed via the \method{get_payload()} and \method{walk()} methods. Note that the parser can be extended in limited ways, and of course you can implement your own parser completely from scratch. There is no magical connection between the \module{email} package's bundled parser and the \class{Message} class, so your custom parser can create message object trees in any way it find necessary. The \module{email} package's parser is described in detail in the \refmodule{email.Parser} module documentation. \subsection{Generating MIME documents} One of the most common tasks is to generate the flat text of the email message represented by a message object tree. You will need to do this if you want to send your message via the \refmodule{smtplib} module or the \refmodule{nntplib} module, or print the message on the console. Taking a message object tree and producing a flat text document is the job of the \refmodule{email.Generator} module. Again, as with the \refmodule{email.Parser} module, you aren't limited to the functionality of the bundled generator; you could write one from scratch yourself. However the bundled generator knows how to generate most email in a standards-compliant way, should handle MIME and non-MIME email messages just fine, and is designed so that the transformation from flat text, to an object tree via the \class{Parser} class, and back to flat text, be idempotent (the input is identical to the output). \subsection{Creating email and MIME objects from scratch} Ordinarily, you get a message object tree by passing some text to a parser, which parses the text and returns the root of the message object tree. However you can also build a complete object tree from scratch, or even individual \class{Message} objects by hand. In fact, you can also take an existing tree and add new \class{Message} objects, move them around, etc. This makes a very convenient interface for slicing-and-dicing MIME messages. You can create a new object tree by creating \class{Message} instances, adding payloads and all the appropriate headers manually. For MIME messages though, the \module{email} package provides some convenient classes to make things easier. Each of these classes should be imported from a module with the same name as the class, from within the \module{email} package. E.g.: \begin{verbatim} import email.MIMEImage.MIMEImage \end{verbatim} or \begin{verbatim} from email.MIMEText import MIMEText \end{verbatim} Here are the classes: \begin{classdesc}{MIMEBase}{_maintype, _subtype, **_params} This is the base class for all the MIME-specific subclasses of \class{Message}. Ordinarily you won't create instances specifically of \class{MIMEBase}, although you could. \class{MIMEBase} is provided primarily as a convenient base class for more specific MIME-aware subclasses. \var{_maintype} is the \code{Content-Type:} major type (e.g. \code{text} or \code{image}), and \var{_subtype} is the \code{Content-Type:} minor type (e.g. \code{plain} or \code{gif}). \var{_params} is a parameter key/value dictionary and is passed directly to \method{Message.add_header()}. The \class{MIMEBase} class always adds a \code{Content-Type:} header (based on \var{_maintype}, \var{_subtype}, and \var{_params}), and a \code{MIME-Version:} header (always set to \code{1.0}). \end{classdesc} \begin{classdesc}{MIMEImage}{_imagedata\optional{, _subtype\optional{, _encoder\optional{, **_params}}}} A subclass of \class{MIMEBase}, the \class{MIMEImage} class is used to create MIME message objects of major type \code{image}. \var{_imagedata} is a string containing the raw image data. If this data can be decoded by the standard Python module \refmodule{imghdr}, then the subtype will be automatically included in the \code{Content-Type:} header. Otherwise you can explicitly specify the image subtype via the \var{_subtype} parameter. If the minor type could not be guessed and \var{_subtype} was not given, then \code{TypeError} is raised. Optional \var{_encoder} is a callable (i.e. function) which will perform the actual encoding of the image data for transport. This callable takes one argument, which is the \class{MIMEImage} instance. It should use \method{get_payload()} and \method{set_payload()} to change the payload to encoded form. It should also add any \code{Content-Transfer-Encoding:} or other headers to the message object as necessary. The default encoding is \emph{Base64}. See the \refmodule{email.Encoders} module for a list of the built-in encoders. \var{_params} are passed straight through to the \class{MIMEBase} constructor. \end{classdesc} \begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{, _charset\optional{, _encoder}}}} A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to create MIME objects of major type \code{text}. \var{_text} is the string for the payload. \var{_subtype} is the minor type and defaults to \code{plain}. \var{_charset} is the character set of the text and is passed as a parameter to the \class{MIMEBase} constructor; it defaults to \code{us-ascii}. No guessing or encoding is performed on the text data, but a newline is appended to \var{_text} if it doesn't already end with a newline. The \var{_encoding} argument is as with the \class{MIMEImage} class constructor, except that the default encoding for \class{MIMEText} objects is one that doesn't actually modify the payload, but does set the \code{Content-Transfer-Encoding:} header to \code{7bit} or \code{8bit} as appropriate. \end{classdesc} \begin{classdesc}{MIMEMessage}{_msg\optional{, _subtype}} A subclass of \class{MIMEBase}, the \class{MIMEMessage} class is used to create MIME objects of main type \code{message}. \var{_msg} is used as the payload, and must be an instance of class \class{Message} (or a subclass thereof), otherwise a \exception{TypeError} is raised. Optional \var{_subtype} sets the subtype of the message; it defaults to \code{rfc822}. \end{classdesc} \subsection{Encoders, Exceptions, Utilities, and Iterators} The \module{email} package provides various encoders for safe transport of binary payloads in \class{MIMEImage} and \class{MIMEText} instances. See the \refmodule{email.Encoders} module for more details. All of the class exceptions that the \module{email} package can raise are available in the \refmodule{email.Errors} module. Some miscellaneous utility functions are available in the \refmodule{email.Utils} module. Iterating over a message object tree is easy with the \method{Message.walk()} method; some additional helper iterators are available in the \refmodule{email.Iterators} module. \subsection{Differences from \module{mimelib}} The \module{email} package was originally prototyped as a separate library called \module{mimelib}. Changes have been made so that method names are more consistent, and some methods or modules have either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in \module{mimelib} is still available in the \module{email} package, albeit often in a different way. Here is a brief description of the differences between the \module{mimelib} and the \module{email} packages, along with hints on how to port your applications. Of course, the most visible difference between the two packages is that the package name has been changed to \module{email}. In addition, the top-level package has the following differences: \begin{itemize} \item \function{messageFromString()} has been renamed to \function{message_from_string()}. \item \function{messageFromFile()} has been renamed to \function{message_from_file()}. \end{itemize} The \class{Message} class has the following differences: \begin{itemize} \item The method \method{asString()} was renamed to \method{as_string()}. \item The method \method{ismultipart()} was renamed to \method{is_multipart()}. \item The \method{get_payload()} method has grown a \var{decode} optional argument. \item The method \method{getall()} was renamed to \method{get_all()}. \item The method \method{addheader()} was renamed to \method{add_header()}. \item The method \method{gettype()} was renamed to \method{get_type()}. \item The method\method{getmaintype()} was renamed to \method{get_main_type()}. \item The method \method{getsubtype()} was renamed to \method{get_subtype()}. \item The method \method{getparams()} was renamed to \method{get_params()}. Also, whereas \method{getparams()} returned a list of strings, \method{get_params()} returns a list of 2-tuples, effectively the key/value pairs of the parameters, split on the \samp{=} sign. \item The method \method{getparam()} was renamed to \method{get_param()}. \item The method \method{getcharsets()} was renamed to \method{get_charsets()}. \item The method \method{getfilename()} was renamed to \method{get_filename()}. \item The method \method{getboundary()} was renamed to \method{get_boundary()}. \item The method \method{setboundary()} was renamed to \method{set_boundary()}. \item The method \method{getdecodedpayload()} was removed. To get similar functionality, pass the value 1 to the \var{decode} flag of the {get_payload()} method. \item The method \method{getpayloadastext()} was removed. Similar functionality is supported by the \class{DecodedGenerator} class in the \refmodule{email.Generator} module. \item The method \method{getbodyastext()} was removed. You can get similar functionality by creating an iterator with \function{typed_subpart_iterator()} in the \refmodule{email.Iterators} module. \end{itemize} The \class{Parser} class has no differences in its public interface. It does have some additional smarts to recognize \code{message/delivery-status} type messages, which it represents as a \class{Message} instance containing separate \class{Message} subparts for each header block in the delivery status notification\footnote{Delivery Status Notifications (DSN) are defined in \rfc{1894}}. The \class{Generator} class has no differences in its public interface. There is a new class in the \refmodule{email.Generator} module though, called \class{DecodedGenerator} which provides most of the functionality previously available in the \method{Message.getpayloadastext()} method. The following modules and classes have been changed: \begin{itemize} \item The \class{MIMEBase} class constructor arguments \var{_major} and \var{_minor} have changed to \var{_maintype} and \var{_subtype} respectively. \item The \code{Image} class/module has been renamed to \code{MIMEImage}. The \var{_minor} argument has been renamed to \var{_subtype}. \item The \code{Text} class/module has been renamed to \code{MIMEText}. The \var{_minor} argument has been renamed to \var{_subtype}. \item The \code{MessageRFC822} class/module has been renamed to \code{MIMEMessage}. Note that an earlier version of \module{mimelib} called this class/module \code{RFC822}, but that clashed with the Python standard library module \refmodule{rfc822} on some case-insensitive file systems. Also, the \class{MIMEMessage} class now represents any kind of MIME message with main type \code{message}. It takes an optional argument \var{_subtype} which is used to set the MIME subtype. \var{_subtype} defaults to \code{rfc822}. \end{itemize} \module{mimelib} provided some utility functions in its \module{address} and \module{date} modules. All of these functions have been moved to the \refmodule{email.Utils} module. The \code{MsgReader} class/module has been removed. Its functionality is most closely supported in the \function{body_line_iterator()} function in the \refmodule{email.Iterators} module. \subsection{Examples} Coming soon... --- NEW FILE: emailutil.tex --- \section{\module{email.Utils} --- Miscellaneous email package utilities} \declaremodule{standard}{email.Utils} \modulesynopsis{Miscellaneous email package utilities.} \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} There are several useful utilities provided with the \module{email} package. \begin{funcdesc}{quote}{str} Return a new string with backslashes in \var{str} replaced by two backslashes and double quotes replaced by backslash-double quote. \end{funcdesc} \begin{funcdesc}{unquote}{str} Return a new string which is an \emph{unquoted} version of \var{str}. If \var{str} ends and begins with double quotes, they are stripped off. Likewise if \var{str} ends and begins with angle brackets, they are stripped off. \end{funcdesc} \begin{funcdesc}{parseaddr}{address} Parse address -- which should be the value of some address-containing field such as \code{To:} or \code{Cc:} -- into its constituent ``realname'' and ``email address'' parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of \code{(None, None)} is returned. \end{funcdesc} \begin{funcdesc}{dump_address_pair}{pair} The inverse of \method{parseaddr()}, this takes a 2-tuple of the form \code{(realname, email_address)} and returns the string value suitable for a \code{To:} or \code{Cc:} header. If the first element of \var{pair} is false, then the second element is returned unmodified. \end{funcdesc} \begin{funcdesc}{getaddresses}{fieldvalues} This method returns a list of 2-tuples of the form returned by \code{parseaddr()}. \var{fieldvalues} is a sequence of header field values as might be returned by \method{Message.getall()}. Here's a simple example that gets all the recipients of a message: \begin{verbatim} from email.Utils import getaddresses tos = msg.get_all('to') ccs = msg.get_all('cc') resent_tos = msg.get_all('resent-to') resent_ccs = msg.get_all('resent-cc') all_recipients = getaddresses(tos + ccs + resent_tos + resent_ccs) \end{verbatim} \end{funcdesc} \begin{funcdesc}{decode}{s} This method decodes a string according to the rules in \rfc{2047}. It returns the decoded string as a Python unicode string. \end{funcdesc} \begin{funcdesc}{encode}{s\optional{, charset\optional{, encoding}}} This method encodes a string according to the rules in \rfc{2047}. It is not actually the inverse of \function{decode()} since it doesn't handle multiple character sets or multiple string parts needing encoding. In fact, the input string \var{s} must already be encoded in the \var{charset} character set (Python can't reliably guess what character set a string might be encoded in). The default \var{charset} is \samp{iso-8859-1}. \var{encoding} must be either the letter \samp{q} for Quoted-Printable or \samp{b} for Base64 encoding. If neither, a \code{ValueError} is raised. Both the \var{charset} and the \var{encoding} strings are case-insensitive, and coerced to lower case in the returned string. \end{funcdesc} \begin{funcdesc}{parsedate}{date} Attempts to parse a date according to the rules in \rfc{2822}. however, some mailers don't follow that format as specified, so \function{parsedate()} tries to guess correctly in such cases. \var{date} is a string containing an \rfc{2822} date, such as \code{"Mon, 20 Nov 1995 19:12:08 -0500"}. If it succeeds in parsing the date, \function{parsedate()} returns a 9-tuple that can be passed directly to \function{time.mktime()}; otherwise \code{None} will be returned. Note that fields 6, 7, and 8 of the result tuple are not usable. \end{funcdesc} \begin{funcdesc}{parsedate_tz}{date} Performs the same function as \function{parsedate()}, but returns either \code{None} or a 10-tuple; the first 9 elements make up a tuple that can be passed directly to \function{time.mktime()}, and the tenth is the offset of the date's timezone from UTC (which is the official term for Greenwich Mean Time)\footnote{Note that the sign of the timezone offset is the opposite of the sign of the \code{time.timezone} variable for the same timezone; the latter variable follows the \POSIX{} standard while this module follows \rfc{2822}.}. If the input string has no timezone, the last element of the tuple returned is \code{None}. Note that fields 6, 7, and 8 of the result tuple are not usable. \end{funcdesc} \begin{funcdesc}{mktime_tz}{tuple} Turn a 10-tuple as returned by \function{parsedate_tz()} into a UTC timestamp. It the timezone item in the tuple is \code{None}, assume local time. Minor deficiency: \function{mktime_tz()} interprets the first 8 elements of \var{tuple} as a local time and then compensates for the timezone difference. This may yield a slight error around changes in daylight savings time, though not worth worring about for common use. \end{funcdesc} \begin{funcdesc}{formatdate}{\optional{timeval}} Returns the time formatted as per Internet standards \rfc{2822} and updated by \rfc{1123}. If \var{timeval} is provided, then it should be a floating point time value as expected by \method{time.gmtime()}, otherwise the current time is used. \end{funcdesc} From bwarsaw@users.sourceforge.net Wed Sep 26 06:26:24 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:26:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Encoders.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv26257 Modified Files: Encoders.py Log Message: cosmetic Index: Encoders.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Encoders.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Encoders.py 2001/09/23 03:17:28 1.1 --- Encoders.py 2001/09/26 05:26:22 1.2 *************** *** 14,17 **** --- 14,18 ---- return _encodestring(s, quotetabs=1) + def _bencode(s): # We can't quite use base64.encodestring() since it tacks on a "courtesy From bwarsaw@users.sourceforge.net Wed Sep 26 06:32:43 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:32:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Generator.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv27105 Modified Files: Generator.py Log Message: In class Generator: _handle_text(): If the payload is None, then just return (i.e. don't write anything). Subparts of message/delivery-status types will have this property since they are just blocks of headers. Also, when raising the TypeError, include the type of the payload in the error message. _handle_multipart(), _handle_message(): When creating a clone of self, pass in our _mangle_from_ and maxheaderlen flags so the clone has the same behavior. _handle_message_delivery_status(): New method to do the proper printing of message/delivery-status type messages. These have to be handled differently than other message/* types because their payloads are subparts containing just blocks of headers. In class DecodedGenerator: _dispatch(): Skip over multipart/* messages since we don't care about them, and don't want the non-text format to appear in the printed results. Index: Generator.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Generator.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Generator.py 2001/09/23 03:17:28 1.1 --- Generator.py 2001/09/26 05:32:41 1.2 *************** *** 191,196 **** def _handle_text(self, msg): payload = msg.get_payload() if not isinstance(payload, StringType): ! raise TypeError, 'string payload expected' if self._mangle_from_: payload = fcre.sub('>From ', payload) --- 191,198 ---- def _handle_text(self, msg): payload = msg.get_payload() + if payload is None: + return if not isinstance(payload, StringType): ! raise TypeError, 'string payload expected: %s' % type(payload) if self._mangle_from_: payload = fcre.sub('>From ', payload) *************** *** 207,211 **** for part in msg.get_payload(): s = StringIO() ! g = self.__class__(s) g(part, unixfrom=0) msgtexts.append(s.getvalue()) --- 209,213 ---- for part in msg.get_payload(): s = StringIO() ! g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) g(part, unixfrom=0) msgtexts.append(s.getvalue()) *************** *** 246,252 **** self._handle_multipart(msg, isdigest=1) ! def _handle_message_rfc822(self, msg): s = StringIO() ! g = self.__class__(s) # A message/rfc822 should contain a scalar payload which is another # Message object. Extract that object, stringify it, and write that --- 248,275 ---- self._handle_multipart(msg, isdigest=1) ! def _handle_message_delivery_status(self, msg): ! # We can't just write the headers directly to self's file object ! # because this will leave an extra newline between the last header ! # block and the boundary. Sigh. ! blocks = [] ! for part in msg.get_payload(): ! s = StringIO() ! g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) ! g(part, unixfrom=0) ! text = s.getvalue() ! lines = text.split('\n') ! # Strip off the unnecessary trailing empty line ! if lines and lines[-1] == '': ! blocks.append(NL.join(lines[:-1])) ! else: ! blocks.append(text) ! # Now join all the blocks with an empty line. This has the lovely ! # effect of separating each block with an empty line, but not adding ! # an extra one after the last one. ! self._fp.write(NL.join(blocks)) ! ! def _handle_message(self, msg): s = StringIO() ! g = self.__class__(s, self._mangle_from_, self.__maxheaderlen) # A message/rfc822 should contain a scalar payload which is another # Message object. Extract that object, stringify it, and write that *************** *** 293,298 **** def _dispatch(self, msg): for part in msg.walk(): ! if part.get_main_type('text') == 'text': print >> self, part.get_payload(decode=1) else: print >> self, self._fmt % { --- 316,325 ---- def _dispatch(self, msg): for part in msg.walk(): ! maintype = part.get_main_type('text') ! if maintype == 'text': print >> self, part.get_payload(decode=1) + elif maintype == 'multipart': + # Just skip this + pass else: print >> self, self._fmt % { From bwarsaw@users.sourceforge.net Wed Sep 26 06:34:32 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:34:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email MIMEImage.py,NONE,1.1 MIMEMessage.py,NONE,1.1 MIMEText.py,NONE,1.1 Image.py,1.1,NONE MessageRFC822.py,1.1,NONE Text.py,1.1,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv27400 Added Files: MIMEImage.py MIMEMessage.py MIMEText.py Removed Files: Image.py MessageRFC822.py Text.py Log Message: Image.py and class Image => MIMEImage.py and MIMEImage Text.py and class Text => MIMEText.py and MIMEText MessageRFC822.py and class MessageRFC822 => MIMEMessage.py and MIMEMessage These are renamed so as to be more consistent; these are MIME specific derived classes for when creating the object model out of whole cloth. --- NEW FILE: MIMEImage.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class representing image/* type MIME documents. """ import imghdr # Intrapackage imports import MIMEBase import Errors import Encoders class MIMEImage(MIMEBase.MIMEBase): """Class for generating image/* type MIME documents.""" def __init__(self, _imagedata, _subtype=None, _encoder=Encoders.encode_base64, **_params): """Create an image/* type MIME document. _imagedata is a string containing the raw image data. If this data can be decoded by the standard Python `imghdr' module, then the subtype will be automatically included in the Content-Type: header. Otherwise, you can specify the specific image subtype via the _subtype parameter. _encoder is a function which will perform the actual encoding for transport of the image data. It takes one argument, which is this Image instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding: or other headers to the message as necessary. The default encoding is Base64. Any additional keyword arguments are passed to the base class constructor, which turns them into parameters on the Content-Type: header. """ if _subtype is None: _subtype = imghdr.what(None, _imagedata) if _subtype is None: raise TypeError, 'Could not guess image MIME subtype' MIMEBase.MIMEBase.__init__(self, 'image', _subtype, **_params) self.set_payload(_imagedata) _encoder(self) --- NEW FILE: MIMEMessage.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class representing message/* MIME documents. """ import Message import MIMEBase class MIMEMessage(MIMEBase.MIMEBase): """Class representing message/* MIME documents.""" def __init__(self, _msg, _subtype='rfc822'): """Create a message/* type MIME document. _msg is a message object and must be an instance of Message, or a derived class of Message, otherwise a TypeError is raised. Optional _subtype defines the subtype of the contained message. The default is "rfc822" (this is defined by the MIME standard, even though the term "rfc822" is technically outdated by RFC 2822). """ MIMEBase.MIMEBase.__init__(self, 'message', _subtype) if not isinstance(_msg, Message.Message): raise TypeError, 'Argument is not an instance of Message' self.set_payload(_msg) --- NEW FILE: MIMEText.py --- # Copyright (C) 2001 Python Software Foundation # Author: barry@zope.com (Barry Warsaw) """Class representing text/* type MIME documents. """ import MIMEBase from Encoders import encode_7or8bit class MIMEText(MIMEBase.MIMEBase): """Class for generating text/* type MIME documents.""" def __init__(self, _text, _subtype='plain', _charset='us-ascii', _encoder=encode_7or8bit): """Create a text/* type MIME document. _text is the string for this message object. If the text does not end in a newline, one is added. _subtype is the MIME sub content type, defaulting to "plain". _charset is the character set parameter added to the Content-Type: header. This defaults to "us-ascii". _encoder is a function which will perform the actual encoding for transport of the text data. It takes one argument, which is this Text instance. It should use get_payload() and set_payload() to change the payload to the encoded form. It should also add any Content-Transfer-Encoding: or other headers to the message as necessary. The default encoding doesn't actually modify the payload, but it does set Content-Transfer-Encoding: to either `7bit' or `8bit' as appropriate. """ MIMEBase.MIMEBase.__init__(self, 'text', _subtype, **{'charset': _charset}) if _text and _text[-1] <> '\n': _text += '\n' self.set_payload(_text) _encoder(self) --- Image.py DELETED --- --- MessageRFC822.py DELETED --- --- Text.py DELETED --- From bwarsaw@users.sourceforge.net Wed Sep 26 06:35:50 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:35:50 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Iterators.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv27576 Modified Files: Iterators.py Log Message: Updated docstrings. Also, typed_subpart_iterator(): Arguments major renamed to maintype and minor renamed to subtype for consistency with the rest of the package. Index: Iterators.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Iterators.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Iterators.py 2001/09/23 03:17:28 1.1 --- Iterators.py 2001/09/26 05:35:47 1.2 *************** *** 12,16 **** def body_line_iterator(msg): ! """Iterator over the parts, returning the lines in a string payload.""" for subpart in msg.walk(): payload = subpart.get_payload() --- 12,16 ---- def body_line_iterator(msg): ! """Iterate over the parts, returning string payloads line-by-line.""" for subpart in msg.walk(): payload = subpart.get_payload() *************** *** 21,33 **** ! def typed_subpart_iterator(msg, major='text', minor=None): ! """Iterator over the subparts with a given MIME type. ! Use `major' as the main MIME type to match against; this defaults to ! "text". Optional `minor' is the MIME subtype to match against; if omitted, only the main type is matched. """ for subpart in msg.walk(): ! if subpart.get_main_type() == major: ! if minor is None or subpart.get_subtype() == minor: yield subpart --- 21,33 ---- ! def typed_subpart_iterator(msg, maintype='text', subtype=None): ! """Iterate over the subparts with a given MIME type. ! Use `maintype' as the main MIME type to match against; this defaults to ! "text". Optional `subtype' is the MIME subtype to match against; if omitted, only the main type is matched. """ for subpart in msg.walk(): ! if subpart.get_main_type() == maintype: ! if subtype is None or subpart.get_subtype() == subtype: yield subpart From bwarsaw@users.sourceforge.net Wed Sep 26 06:36:38 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:36:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email MIMEBase.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv27710 Modified Files: MIMEBase.py Log Message: __init__(): Arguments major renamed to maintype and minor renamed to subtype for consistency with the rest of the package. Index: MIMEBase.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/MIMEBase.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** MIMEBase.py 2001/09/23 03:17:28 1.1 --- MIMEBase.py 2001/09/26 05:36:36 1.2 *************** *** 12,24 **** """Base class for MIME specializations.""" ! def __init__(self, _major, _minor, **_params): """This constructor adds a Content-Type: and a MIME-Version: header. ! The Content-Type: header is taken from the _major and _minor arguments. Additional parameters for this header are taken from the keyword arguments. """ Message.Message.__init__(self) ! ctype = '%s/%s' % (_major, _minor) self.add_header('Content-Type', ctype, **_params) self['MIME-Version'] = '1.0' --- 12,24 ---- """Base class for MIME specializations.""" ! def __init__(self, _maintype, _subtype, **_params): """This constructor adds a Content-Type: and a MIME-Version: header. ! The Content-Type: header is taken from the _maintype and _subtype arguments. Additional parameters for this header are taken from the keyword arguments. """ Message.Message.__init__(self) ! ctype = '%s/%s' % (_maintype, _subtype) self.add_header('Content-Type', ctype, **_params) self['MIME-Version'] = '1.0' From bwarsaw@users.sourceforge.net Wed Sep 26 06:41:54 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:41:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Message.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv28509 Modified Files: Message.py Log Message: has_key(): Implement in terms of get(). get_type(): Use a compiled regular expression, which can be shared. _get_params_preserve(): A helper method which extracts the header's parameter list preserving value quoting. I'm not sure that this needs to be a public method. It's necessary because we want get_param() and friends to return the unquoted parameter value, however we want the quote-preserved form for set_boundary(). get_params(), get_param(), set_boundary(): Implement in terms of _get_params_preserve(). walk(): Yield ourself first, then recurse over our subparts (if any). Index: Message.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Message.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Message.py 2001/09/23 03:17:28 1.1 --- Message.py 2001/09/26 05:41:51 1.2 *************** *** 13,22 **** from types import ListType - SEMISPACE = '; ' - # Intrapackage imports import Errors import Utils --- 13,23 ---- from types import ListType # Intrapackage imports import Errors import Utils + SEMISPACE = '; ' + paramre = re.compile(r';\s*') + *************** *** 136,140 **** # def __len__(self): ! """Get the total number of headers, including duplicates.""" return len(self._headers) --- 137,141 ---- # def __len__(self): ! """Return the total number of headers, including duplicates.""" return len(self._headers) *************** *** 175,179 **** def has_key(self, name): """Return true if the message contains the header.""" ! return self[name] <> None def keys(self): --- 176,181 ---- def has_key(self, name): """Return true if the message contains the header.""" ! missing = [] ! return self.get(name, missing) is not missing def keys(self): *************** *** 268,272 **** if value is missing: return failobj ! return re.split(r';\s+', value)[0].lower() def get_main_type(self, failobj=None): --- 270,274 ---- if value is missing: return failobj ! return paramre.split(value)[0].lower() def get_main_type(self, failobj=None): *************** *** 292,298 **** --- 294,324 ---- return failobj + def _get_params_preserve(self, failobj, header): + # Like get_params() but preserves the quoting of values. BAW: + # should this be part of the public interface? + missing = [] + value = self.get(header, missing) + if value is missing: + return failobj + params = [] + for p in paramre.split(value): + try: + name, val = p.split('=', 1) + except ValueError: + # Must have been a bare attribute + name = p + val = '' + params.append((name, val)) + return params + def get_params(self, failobj=None, header='content-type'): """Return the message's Content-Type: parameters, as a list. + The elements of the returned list are 2-tuples of key/value pairs, as + split on the `=' sign. The left hand side of the `=' is the key, + while the right hand side is the value. If there is no `=' sign in + the parameter the value is the empty string. The value is always + unquoted. + Optional failobj is the object to return if there is no Content-Type: header. Optional header is the header to search instead of *************** *** 300,307 **** """ missing = [] ! value = self.get(header, missing) ! if value is missing: return failobj ! return re.split(r';\s+', value)[1:] def get_param(self, param, failobj=None, header='content-type'): --- 326,333 ---- """ missing = [] ! params = self._get_params_preserve(missing, header) ! if params is missing: return failobj ! return [(k, Utils.unquote(v)) for k, v in params] def get_param(self, param, failobj=None, header='content-type'): *************** *** 311,329 **** header. Optional header is the header to search instead of Content-Type: """ ! param = param.lower() ! missing = [] ! params = self.get_params(missing, header=header) ! if params is missing: return failobj ! for p in params: ! try: ! name, val = p.split('=', 1) ! except ValueError: ! # Must have been a bare attribute ! name = p ! val = '' ! if name.lower() == param: ! return Utils.unquote(val) return failobj --- 337,349 ---- header. Optional header is the header to search instead of Content-Type: + + Parameter keys are always compared case insensitively. Values are + always unquoted. """ ! if not self.has_key(header): return failobj ! for k, v in self._get_params_preserve(failobj, header): ! if k.lower() == param.lower(): ! return Utils.unquote(v) return failobj *************** *** 362,367 **** HeaderParseError is raised if the message has no Content-Type: header. """ ! params = self.get_params() ! if not params: # There was no Content-Type: header, and we don't know what type # to set it to, so raise an exception. --- 382,388 ---- HeaderParseError is raised if the message has no Content-Type: header. """ ! missing = [] ! params = self._get_params_preserve(missing, 'content-type') ! if params is missing: # There was no Content-Type: header, and we don't know what type # to set it to, so raise an exception. *************** *** 369,390 **** newparams = [] foundp = 0 ! for p in params: ! if p.lower().startswith('boundary='): ! newparams.append('boundary="%s"' % boundary) foundp = 1 else: ! newparams.append(p) if not foundp: # The original Content-Type: header had no boundary attribute. # Tack one one the end. BAW: should we raise an exception # instead??? ! newparams.append('boundary="%s"' % boundary) # Replace the existing Content-Type: header with the new value newheaders = [] for h, v in self._headers: if h.lower() == 'content-type': ! value = v.split(';', 1)[0] ! newparams.insert(0, value) ! newheaders.append((h, SEMISPACE.join(newparams))) else: newheaders.append((h, v)) --- 390,416 ---- newparams = [] foundp = 0 ! for pk, pv in params: ! if pk.lower() == 'boundary': ! newparams.append(('boundary', '"%s"' % boundary)) foundp = 1 else: ! newparams.append((pk, pv)) if not foundp: # The original Content-Type: header had no boundary attribute. # Tack one one the end. BAW: should we raise an exception # instead??? ! newparams.append(('boundary', '"%s"' % boundary)) # Replace the existing Content-Type: header with the new value newheaders = [] for h, v in self._headers: if h.lower() == 'content-type': ! parts = [] ! for k, v in newparams: ! if v == '': ! parts.append(k) ! else: ! parts.append('%s=%s' % (k, v)) ! newheaders.append((h, SEMISPACE.join(parts))) ! else: newheaders.append((h, v)) *************** *** 397,406 **** generator. """ if self.is_multipart(): for subpart in self.get_payload(): for subsubpart in subpart.walk(): yield subsubpart - else: - yield self def get_charsets(self, failobj=None): --- 423,431 ---- generator. """ + yield self if self.is_multipart(): for subpart in self.get_payload(): for subsubpart in subpart.walk(): yield subsubpart def get_charsets(self, failobj=None): From bwarsaw@users.sourceforge.net Wed Sep 26 06:44:11 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:44:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/email Parser.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/email In directory usw-pr-cvs1:/tmp/cvs-serv28784 Modified Files: Parser.py Log Message: _parsebody(): Use get_boundary() and get_type(). Also, add a clause to the big-if to handle message/delivery-status content types. These create a message with subparts that are Message instances, which best represent the header blocks of this content type. Index: Parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/email/Parser.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** Parser.py 2001/09/23 03:17:28 1.1 --- Parser.py 2001/09/26 05:44:09 1.2 *************** *** 5,9 **** """ - import re from cStringIO import StringIO --- 5,8 ---- *************** *** 12,16 **** import Message - bcre = re.compile('boundary="?([^"]+)"?', re.IGNORECASE) EMPTYSTRING = '' NL = '\n' --- 11,14 ---- *************** *** 93,103 **** # Parse the body, but first split the payload on the content-type # boundary if present. ! boundary = isdigest = None ! ctype = container['content-type'] ! if ctype: ! mo = bcre.search(ctype) ! if mo: ! boundary = mo.group(1) ! isdigest = container.get_type() == 'multipart/digest' # If there's a boundary, split the payload text into its constituent # parts and parse each separately. Otherwise, just parse the rest of --- 91,96 ---- # Parse the body, but first split the payload on the content-type # boundary if present. ! boundary = container.get_boundary() ! isdigest = (container.get_type() == 'multipart/digest') # If there's a boundary, split the payload text into its constituent # parts and parse each separately. Otherwise, just parse the rest of *************** *** 142,146 **** container.epilogue = epilogue container.add_payload(msgobj) ! elif ctype == 'message/rfc822': # Create a container for the payload, but watch out for there not # being any headers left --- 135,152 ---- container.epilogue = epilogue container.add_payload(msgobj) ! elif container.get_type() == 'message/delivery-status': ! # This special kind of type contains blocks of headers separated ! # by a blank line. We'll represent each header block as a ! # separate Message object ! blocks = [] ! while 1: ! blockmsg = self._class() ! self._parseheaders(blockmsg, fp) ! if not len(blockmsg): ! # No more header blocks left ! break ! blocks.append(blockmsg) ! container.set_payload(blocks) ! elif container.get_main_type() == 'message': # Create a container for the payload, but watch out for there not # being any headers left From bwarsaw@users.sourceforge.net Wed Sep 26 06:45:19 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:45:19 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/data msg_16.txt,NONE,1.1 msg_17.txt,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/data In directory usw-pr-cvs1:/tmp/cvs-serv28899 Added Files: msg_16.txt msg_17.txt Log Message: More test messages for test_email.py --- NEW FILE: msg_16.txt --- Return-Path: <> Delivered-To: scr-admin@socal-raves.org Received: from cougar.noc.ucla.edu (cougar.noc.ucla.edu [169.232.10.18]) by babylon.socal-raves.org (Postfix) with ESMTP id CCC2C51B84 for ; Sun, 23 Sep 2001 20:13:54 -0700 (PDT) Received: from sims-ms-daemon by cougar.noc.ucla.edu (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10) id <0GK500B01D0B8Y@cougar.noc.ucla.edu> for scr-admin@socal-raves.org; Sun, 23 Sep 2001 20:14:35 -0700 (PDT) Received: from cougar.noc.ucla.edu (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10) id <0GK500B01D0B8X@cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT) Date: Sun, 23 Sep 2001 20:14:35 -0700 (PDT) From: Internet Mail Delivery Subject: Delivery Notification: Delivery has failed To: scr-admin@socal-raves.org Message-id: <0GK500B04D0B8X@cougar.noc.ucla.edu> MIME-version: 1.0 Sender: scr-owner@socal-raves.org Errors-To: scr-owner@socal-raves.org X-BeenThere: scr@socal-raves.org X-Mailman-Version: 2.1a3 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: SoCal-Raves List-Unsubscribe: , List-Archive: Content-Type: multipart/report; boundary="Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)" --Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA) Content-type: text/plain; charset=ISO-8859-1 This report relates to a message you sent with the following header fields: Message-id: <002001c144a6$8752e060$56104586@oxy.edu> Date: Sun, 23 Sep 2001 20:10:55 -0700 From: "Ian T. Henry" To: SoCal Raves Subject: [scr] yeah for Ians!! Your message cannot be delivered to the following recipients: Recipient address: jangel1@cougar.noc.ucla.edu Reason: recipient reached disk quota --Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA) Content-type: message/DELIVERY-STATUS Original-envelope-id: 0GK500B4HD0888@cougar.noc.ucla.edu Reporting-MTA: dns; cougar.noc.ucla.edu Action: failed Status: 5.0.0 (recipient reached disk quota) Original-recipient: rfc822;jangel1@cougar.noc.ucla.edu Final-recipient: rfc822;jangel1@cougar.noc.ucla.edu --Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA) Content-type: MESSAGE/RFC822 Return-path: scr-admin@socal-raves.org Received: from sims-ms-daemon by cougar.noc.ucla.edu (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10) id <0GK500B01D0B8X@cougar.noc.ucla.edu>; Sun, 23 Sep 2001 20:14:35 -0700 (PDT) Received: from panther.noc.ucla.edu by cougar.noc.ucla.edu (Sun Internet Mail Server sims.3.5.2000.03.23.18.03.p10) with ESMTP id <0GK500B4GD0888@cougar.noc.ucla.edu> for jangel1@sims-ms-daemon; Sun, 23 Sep 2001 20:14:33 -0700 (PDT) Received: from babylon.socal-raves.org (ip-209-85-222-117.dreamhost.com [209.85.222.117]) by panther.noc.ucla.edu (8.9.1a/8.9.1) with ESMTP id UAA09793 for ; Sun, 23 Sep 2001 20:14:32 -0700 (PDT) Received: from babylon (localhost [127.0.0.1]) by babylon.socal-raves.org (Postfix) with ESMTP id D3B2951B70; Sun, 23 Sep 2001 20:13:47 -0700 (PDT) Received: by babylon.socal-raves.org (Postfix, from userid 60001) id A611F51B82; Sun, 23 Sep 2001 20:13:46 -0700 (PDT) Received: from tiger.cc.oxy.edu (tiger.cc.oxy.edu [134.69.3.112]) by babylon.socal-raves.org (Postfix) with ESMTP id ADA7351B70 for ; Sun, 23 Sep 2001 20:13:44 -0700 (PDT) Received: from ent (n16h86.dhcp.oxy.edu [134.69.16.86]) by tiger.cc.oxy.edu (8.8.8/8.8.8) with SMTP id UAA08100 for ; Sun, 23 Sep 2001 20:14:24 -0700 (PDT) Date: Sun, 23 Sep 2001 20:10:55 -0700 From: "Ian T. Henry" Subject: [scr] yeah for Ians!! Sender: scr-admin@socal-raves.org To: SoCal Raves Errors-to: scr-admin@socal-raves.org Message-id: <002001c144a6$8752e060$56104586@oxy.edu> MIME-version: 1.0 X-Mailer: Microsoft Outlook Express 5.50.4522.1200 Content-type: text/plain; charset=us-ascii Precedence: bulk Delivered-to: scr-post@babylon.socal-raves.org Delivered-to: scr@socal-raves.org X-Converted-To-Plain-Text: from multipart/alternative by demime 0.98e X-Converted-To-Plain-Text: Alternative section used was text/plain X-BeenThere: scr@socal-raves.org X-Mailman-Version: 2.1a3 List-Help: List-Post: List-Subscribe: , List-Id: SoCal-Raves List-Unsubscribe: , List-Archive: I always love to find more Ian's that are over 3 years old!! Ian _______________________________________________ For event info, list questions, or to unsubscribe, see http://www.socal-raves.org/ --Boundary_(ID_PGS2F2a+z+/jL7hupKgRhA)-- --- NEW FILE: msg_17.txt --- MIME-Version: 1.0 From: Barry To: Dingus Lovers Subject: Here is your dingus fish Date: Fri, 20 Apr 2001 19:35:02 -0400 Content-Type: multipart/mixed; boundary="BOUNDARY" Hi there, This is the dingus fish. [Non-text (image/gif) part of message omitted, filename dingusfish.gif] From bwarsaw@users.sourceforge.net Wed Sep 26 06:47:10 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Tue, 25 Sep 2001 22:47:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_email.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29310 Modified Files: test_email.py Log Message: Update the tests for the current incarnation of the email package, and added some new tests of message/delivery-status content type messages. Index: test_email.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_email.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** test_email.py 2001/09/23 03:18:13 1.1 --- test_email.py 2001/09/26 05:47:08 1.2 *************** *** 14,21 **** from email.Generator import Generator, DecodedGenerator from email.Message import Message ! from email.Text import Text ! from email.Image import Image from email.MIMEBase import MIMEBase ! from email.MessageRFC822 import MessageRFC822 from email import Utils from email import Errors --- 14,21 ---- from email.Generator import Generator, DecodedGenerator from email.Message import Message ! from email.MIMEText import MIMEText ! from email.MIMEImage import MIMEImage from email.MIMEBase import MIMEBase ! from email.MIMEMessage import MIMEMessage from email import Utils from email import Errors *************** *** 42,49 **** fp = openfile(filename) try: ! msgobj = email.message_from_file(fp) finally: fp.close() ! return msgobj --- 42,49 ---- fp = openfile(filename) try: ! msg = email.message_from_file(fp) finally: fp.close() ! return msg *************** *** 54,86 **** eq = self.assertEqual ! msgobj = self._msgobj('msg_08.txt') ! charsets = msgobj.get_charsets() ! eq(charsets, ['us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r']) ! msgobj = self._msgobj('msg_09.txt') ! charsets = msgobj.get_charsets('dingbat') ! eq(charsets, ['us-ascii', 'iso-8859-1', 'dingbat', 'koi8-r']) ! msgobj = self._msgobj('msg_12.txt') ! charsets = msgobj.get_charsets() ! eq(charsets, ['us-ascii', 'iso-8859-1', 'iso-8859-2', 'iso-8859-3', ! 'us-ascii', 'koi8-r']) def test_get_filename(self): eq = self.assertEqual ! msgobj = self._msgobj('msg_04.txt') ! filenames = [p.get_filename() for p in msgobj.get_payload()] eq(filenames, ['msg.txt', 'msg.txt']) ! msgobj = self._msgobj('msg_07.txt') ! subpart = msgobj.get_payload(1) eq(subpart.get_filename(), 'dingusfish.gif') def test_get_boundary(self): eq = self.assertEqual ! msgobj = self._msgobj('msg_07.txt') # No quotes! ! eq(msgobj.get_boundary(), 'BOUNDARY') def test_set_boundary(self): --- 54,87 ---- eq = self.assertEqual ! msg = self._msgobj('msg_08.txt') ! charsets = msg.get_charsets() ! eq(charsets, [None, 'us-ascii', 'iso-8859-1', 'iso-8859-2', 'koi8-r']) ! msg = self._msgobj('msg_09.txt') ! charsets = msg.get_charsets('dingbat') ! eq(charsets, ['dingbat', 'us-ascii', 'iso-8859-1', 'dingbat', ! 'koi8-r']) ! msg = self._msgobj('msg_12.txt') ! charsets = msg.get_charsets() ! eq(charsets, [None, 'us-ascii', 'iso-8859-1', None, 'iso-8859-2', ! 'iso-8859-3', 'us-ascii', 'koi8-r']) def test_get_filename(self): eq = self.assertEqual ! msg = self._msgobj('msg_04.txt') ! filenames = [p.get_filename() for p in msg.get_payload()] eq(filenames, ['msg.txt', 'msg.txt']) ! msg = self._msgobj('msg_07.txt') ! subpart = msg.get_payload(1) eq(subpart.get_filename(), 'dingusfish.gif') def test_get_boundary(self): eq = self.assertEqual ! msg = self._msgobj('msg_07.txt') # No quotes! ! eq(msg.get_boundary(), 'BOUNDARY') def test_set_boundary(self): *************** *** 88,94 **** # This one has no existing boundary parameter, but the Content-Type: # header appears fifth. ! msgobj = self._msgobj('msg_01.txt') ! msgobj.set_boundary('BOUNDARY') ! header, value = msgobj.items()[4] eq(header.lower(), 'content-type') eq(value, 'text/plain; charset=us-ascii; boundary="BOUNDARY"') --- 89,95 ---- # This one has no existing boundary parameter, but the Content-Type: # header appears fifth. ! msg = self._msgobj('msg_01.txt') ! msg.set_boundary('BOUNDARY') ! header, value = msg.items()[4] eq(header.lower(), 'content-type') eq(value, 'text/plain; charset=us-ascii; boundary="BOUNDARY"') *************** *** 96,147 **** # middle of its headers. Make sure the order is preserved; it should # be fifth. ! msgobj = self._msgobj('msg_04.txt') ! msgobj.set_boundary('BOUNDARY') ! header, value = msgobj.items()[4] eq(header.lower(), 'content-type') eq(value, 'multipart/mixed; boundary="BOUNDARY"') # And this one has no Content-Type: header at all. ! msgobj = self._msgobj('msg_03.txt') self.assertRaises(Errors.HeaderParseError, ! msgobj.set_boundary, 'BOUNDARY') def test_get_decoded_payload(self): eq = self.assertEqual ! msgobj = self._msgobj('msg_10.txt') # The outer message is a multipart ! eq(msgobj.get_payload(decode=1), None) # Subpart 1 is 7bit encoded ! eq(msgobj.get_payload(0).get_payload(decode=1), 'This is a 7bit encoded message.\n') # Subpart 2 is quopri ! eq(msgobj.get_payload(1).get_payload(decode=1), '\xa1This is a Quoted Printable encoded message!\n') # Subpart 3 is base64 ! eq(msgobj.get_payload(2).get_payload(decode=1), 'This is a Base64 encoded message.') # Subpart 4 has no Content-Transfer-Encoding: header. ! eq(msgobj.get_payload(3).get_payload(decode=1), 'This has no Content-Transfer-Encoding: header.\n') def test_decoded_generator(self): eq = self.assertEqual ! msgobj = self._msgobj('msg_07.txt') s = StringIO() g = DecodedGenerator(s) ! g(msgobj) ! eq(s.getvalue(), '''\ ! MIME-Version: 1.0 ! From: Barry ! To: Dingus Lovers ! Subject: Here is your dingus fish ! Date: Fri, 20 Apr 2001 19:35:02 -0400 ! Content-Type: multipart/mixed; boundary="BOUNDARY" ! ! Hi there, ! ! This is the dingus fish. ! ! [Non-text (image/gif) part of message omitted, filename dingusfish.gif] ! ''') def test__contains__(self): --- 97,140 ---- # middle of its headers. Make sure the order is preserved; it should # be fifth. ! msg = self._msgobj('msg_04.txt') ! msg.set_boundary('BOUNDARY') ! header, value = msg.items()[4] eq(header.lower(), 'content-type') eq(value, 'multipart/mixed; boundary="BOUNDARY"') # And this one has no Content-Type: header at all. ! msg = self._msgobj('msg_03.txt') self.assertRaises(Errors.HeaderParseError, ! msg.set_boundary, 'BOUNDARY') def test_get_decoded_payload(self): eq = self.assertEqual ! msg = self._msgobj('msg_10.txt') # The outer message is a multipart ! eq(msg.get_payload(decode=1), None) # Subpart 1 is 7bit encoded ! eq(msg.get_payload(0).get_payload(decode=1), 'This is a 7bit encoded message.\n') # Subpart 2 is quopri ! eq(msg.get_payload(1).get_payload(decode=1), '\xa1This is a Quoted Printable encoded message!\n') # Subpart 3 is base64 ! eq(msg.get_payload(2).get_payload(decode=1), 'This is a Base64 encoded message.') # Subpart 4 has no Content-Transfer-Encoding: header. ! eq(msg.get_payload(3).get_payload(decode=1), 'This has no Content-Transfer-Encoding: header.\n') def test_decoded_generator(self): eq = self.assertEqual ! msg = self._msgobj('msg_07.txt') ! fp = openfile('msg_17.txt') ! try: ! text = fp.read() ! finally: ! fp.close() s = StringIO() g = DecodedGenerator(s) ! g(msg) ! eq(s.getvalue(), text) def test__contains__(self): *************** *** 159,163 **** def test_as_string(self): eq = self.assertEqual ! msgobj = self._msgobj('msg_01.txt') fp = openfile('msg_01.txt') try: --- 152,156 ---- def test_as_string(self): eq = self.assertEqual ! msg = self._msgobj('msg_01.txt') fp = openfile('msg_01.txt') try: *************** *** 165,170 **** finally: fp.close() ! eq(text, msgobj.as_string()) ! fullrepr = str(msgobj) lines = fullrepr.split('\n') self.failUnless(lines[0].startswith('From ')) --- 158,163 ---- finally: fp.close() ! eq(text, msg.as_string()) ! fullrepr = str(msg) lines = fullrepr.split('\n') self.failUnless(lines[0].startswith('From ')) *************** *** 172,205 **** def test_bad_param(self): ! msg = email.message_from_string("""\ ! From: foo ! Content-Type: blarg; baz; boo ! ! """) self.assertEqual(msg.get_param('baz'), '') def test_missing_filename(self): ! msg = email.message_from_string("""\ ! From: foo ! ! """) self.assertEqual(msg.get_filename(), None) def test_bogus_filename(self): ! msg = email.message_from_string("""\ ! From: foo ! Content-Disposition: blarg; filename ! ! """) self.assertEqual(msg.get_filename(), '') def test_missing_boundary(self): ! msg = email.message_from_string("""\ ! From: foo ! ! """) self.assertEqual(msg.get_boundary(), None) # Test the email.Encoders module --- 165,221 ---- def test_bad_param(self): ! msg = email.message_from_string("Content-Type: blarg; baz; boo\n") self.assertEqual(msg.get_param('baz'), '') def test_missing_filename(self): ! msg = email.message_from_string("From: foo\n") self.assertEqual(msg.get_filename(), None) def test_bogus_filename(self): ! msg = email.message_from_string( ! "Content-Disposition: blarg; filename\n") self.assertEqual(msg.get_filename(), '') def test_missing_boundary(self): ! msg = email.message_from_string("From: foo\n") self.assertEqual(msg.get_boundary(), None) + def test_get_params(self): + eq = self.assertEqual + msg = email.message_from_string( + 'X-Header: foo=one; bar=two; baz=three\n') + eq(msg.get_params(header='x-header'), + [('foo', 'one'), ('bar', 'two'), ('baz', 'three')]) + msg = email.message_from_string( + 'X-Header: foo; bar=one; baz=two\n') + eq(msg.get_params(header='x-header'), + [('foo', ''), ('bar', 'one'), ('baz', 'two')]) + eq(msg.get_params(), None) + msg = email.message_from_string( + 'X-Header: foo; bar="one"; baz=two\n') + eq(msg.get_params(header='x-header'), + [('foo', ''), ('bar', 'one'), ('baz', 'two')]) + + def test_get_param(self): + eq = self.assertEqual + msg = email.message_from_string( + "X-Header: foo=one; bar=two; baz=three\n") + eq(msg.get_param('bar', header='x-header'), 'two') + eq(msg.get_param('quuz', header='x-header'), None) + eq(msg.get_param('quuz'), None) + msg = email.message_from_string( + 'X-Header: foo; bar="one"; baz=two\n') + eq(msg.get_param('foo', header='x-header'), '') + eq(msg.get_param('bar', header='x-header'), 'one') + eq(msg.get_param('baz', header='x-header'), 'two') + def test_has_key(self): + msg = email.message_from_string('Header: exists') + self.failUnless(msg.has_key('header')) + self.failUnless(msg.has_key('Header')) + self.failUnless(msg.has_key('HEADER')) + self.failIf(msg.has_key('headeri')) + + # Test the email.Encoders module *************** *** 207,211 **** def test_encode_noop(self): eq = self.assertEqual ! msg = Text('hello world', _encoder=Encoders.encode_noop) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], None) --- 223,227 ---- def test_encode_noop(self): eq = self.assertEqual ! msg = MIMEText('hello world', _encoder=Encoders.encode_noop) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], None) *************** *** 213,220 **** def test_encode_7bit(self): eq = self.assertEqual ! msg = Text('hello world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], '7bit') ! msg = Text('hello \x7f world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x7f world\n') eq(msg['content-transfer-encoding'], '7bit') --- 229,236 ---- def test_encode_7bit(self): eq = self.assertEqual ! msg = MIMEText('hello world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello world\n') eq(msg['content-transfer-encoding'], '7bit') ! msg = MIMEText('hello \x7f world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x7f world\n') eq(msg['content-transfer-encoding'], '7bit') *************** *** 222,226 **** def test_encode_8bit(self): eq = self.assertEqual ! msg = Text('hello \x80 world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x80 world\n') eq(msg['content-transfer-encoding'], '8bit') --- 238,242 ---- def test_encode_8bit(self): eq = self.assertEqual ! msg = MIMEText('hello \x80 world', _encoder=Encoders.encode_7or8bit) eq(msg.get_payload(), 'hello \x80 world\n') eq(msg['content-transfer-encoding'], '8bit') *************** *** 228,232 **** def test_encode_base64(self): eq = self.assertEqual ! msg = Text('hello world', _encoder=Encoders.encode_base64) eq(msg.get_payload(), 'aGVsbG8gd29ybGQK\n') eq(msg['content-transfer-encoding'], 'base64') --- 244,248 ---- def test_encode_base64(self): eq = self.assertEqual ! msg = MIMEText('hello world', _encoder=Encoders.encode_base64) eq(msg.get_payload(), 'aGVsbG8gd29ybGQK\n') eq(msg['content-transfer-encoding'], 'base64') *************** *** 234,238 **** def test_encode_quoted_printable(self): eq = self.assertEqual ! msg = Text('hello world', _encoder=Encoders.encode_quopri) eq(msg.get_payload(), 'hello=20world\n') eq(msg['content-transfer-encoding'], 'quoted-printable') --- 250,254 ---- def test_encode_quoted_printable(self): eq = self.assertEqual ! msg = MIMEText('hello world', _encoder=Encoders.encode_quopri) eq(msg.get_payload(), 'hello=20world\n') eq(msg['content-transfer-encoding'], 'quoted-printable') *************** *** 242,246 **** class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): ! msg = Text('') # It'd be great if we could use add_header() here, but that doesn't # guarantee an order of the parameters. --- 258,262 ---- class TestLongHeaders(unittest.TestCase): def test_header_splitter(self): ! msg = MIMEText('') # It'd be great if we could use add_header() here, but that doesn't # guarantee an order of the parameters. *************** *** 295,300 **** ! # Test the basic Image class ! class TestImage(unittest.TestCase): def setUp(self): fp = openfile('PyBanner048.gif') --- 311,316 ---- ! # Test the basic MIMEImage class ! class TestMIMEImage(unittest.TestCase): def setUp(self): fp = openfile('PyBanner048.gif') *************** *** 303,307 **** finally: fp.close() ! self._im = Image(self._imgdata) def test_guess_minor_type(self): --- 319,323 ---- finally: fp.close() ! self._im = MIMEImage(self._imgdata) def test_guess_minor_type(self): *************** *** 313,317 **** def checkSetMinor(self): ! im = Image(self._imgdata, 'fish') self.assertEqual(im.get_type(), 'image/fish') --- 329,333 ---- def checkSetMinor(self): ! im = MIMEImage(self._imgdata, 'fish') self.assertEqual(im.get_type(), 'image/fish') *************** *** 322,326 **** msg.set_payload(0) msg['Content-Transfer-Encoding'] = 'broken64' ! im = Image(self._imgdata, _encoder=encoder) eq(im.get_payload(), 0) eq(im['content-transfer-encoding'], 'broken64') --- 338,342 ---- msg.set_payload(0) msg['Content-Transfer-Encoding'] = 'broken64' ! im = MIMEImage(self._imgdata, _encoder=encoder) eq(im.get_payload(), 0) eq(im['content-transfer-encoding'], 'broken64') *************** *** 334,342 **** 'attachment; filename="dingusfish.gif"') eq(self._im.get_params(header='content-disposition'), ! ['filename="dingusfish.gif"']) eq(self._im.get_param('filename', header='content-disposition'), 'dingusfish.gif') missing = [] ! unless(self._im.get_param('attachment', missing, header='content-disposition') is missing) # Try some missing stuff --- 350,359 ---- 'attachment; filename="dingusfish.gif"') eq(self._im.get_params(header='content-disposition'), ! [('attachment', ''), ('filename', 'dingusfish.gif')]) eq(self._im.get_param('filename', header='content-disposition'), 'dingusfish.gif') missing = [] ! eq(self._im.get_param('attachment', header='content-disposition'), '') ! unless(self._im.get_param('foo', failobj=missing, header='content-disposition') is missing) # Try some missing stuff *************** *** 347,354 **** ! # Test the basic Text class ! class TestText(unittest.TestCase): def setUp(self): ! self._msg = Text('hello there') def test_types(self): --- 364,371 ---- ! # Test the basic MIMEText class ! class TestMIMEText(unittest.TestCase): def setUp(self): ! self._msg = MIMEText('hello there') def test_types(self): *************** *** 377,384 **** container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') ! image = Image(data, name='dingusfish.gif') image.add_header('content-disposition', 'attachment', filename='dingusfish.gif') ! intro = Text('''\ Hi there, --- 394,401 ---- container = MIMEBase('multipart', 'mixed', boundary='BOUNDARY') ! image = MIMEImage(data, name='dingusfish.gif') image.add_header('content-disposition', 'attachment', filename='dingusfish.gif') ! intro = MIMEText('''\ Hi there, *************** *** 482,486 **** ! class TestMessageRFC822(unittest.TestCase): def setUp(self): fp = openfile('msg_11.txt') --- 499,503 ---- ! class TestMIMEMessage(TestEmailBase): def setUp(self): fp = openfile('msg_11.txt') *************** *** 489,493 **** def test_type_error(self): ! self.assertRaises(TypeError, MessageRFC822, 'a plain string') def test_valid_argument(self): --- 506,510 ---- def test_type_error(self): ! self.assertRaises(TypeError, MIMEMessage, 'a plain string') def test_valid_argument(self): *************** *** 496,500 **** m = Message() m['Subject'] = subject ! r = MessageRFC822(m) eq(r.get_type(), 'message/rfc822') self.failUnless(r.get_payload() is m) --- 513,517 ---- m = Message() m['Subject'] = subject ! r = MIMEMessage(m) eq(r.get_type(), 'message/rfc822') self.failUnless(r.get_payload() is m) *************** *** 506,517 **** m['Subject'] = 'An enclosed message' m.add_payload('Here is the body of the message.\n') ! r = MessageRFC822(m) r['Subject'] = 'The enclosing message' s = StringIO() g = Generator(s) g(r) ! self.assertEqual(s.getvalue(), self._text) class TestIdempotent(unittest.TestCase): --- 523,607 ---- m['Subject'] = 'An enclosed message' m.add_payload('Here is the body of the message.\n') ! r = MIMEMessage(m) r['Subject'] = 'The enclosing message' s = StringIO() g = Generator(s) g(r) ! self.assertEqual(s.getvalue(), """\ ! Content-Type: message/rfc822 ! MIME-Version: 1.0 ! Subject: The enclosing message ! ! Subject: An enclosed message + Here is the body of the message. + """) + def test_parse_message_rfc822(self): + eq = self.assertEqual + msg = self._msgobj('msg_11.txt') + eq(msg.get_type(), 'message/rfc822') + eq(len(msg.get_payload()), 1) + submsg = msg.get_payload() + self.failUnless(isinstance(submsg, Message)) + eq(submsg['subject'], 'An enclosed message') + eq(submsg.get_payload(), 'Here is the body of the message.\n') + + def test_dsn(self): + eq = self.assertEqual + unless = self.failUnless + # msg 16 is a Delivery Status Notification, see RFC XXXX + msg = self._msgobj('msg_16.txt') + eq(msg.get_type(), 'multipart/report') + unless(msg.is_multipart()) + eq(len(msg.get_payload()), 3) + # Subpart 1 is a text/plain, human readable section + subpart = msg.get_payload(0) + eq(subpart.get_type(), 'text/plain') + eq(subpart.get_payload(), """\ + This report relates to a message you sent with the following header fields: + + Message-id: <002001c144a6$8752e060$56104586@oxy.edu> + Date: Sun, 23 Sep 2001 20:10:55 -0700 + From: "Ian T. Henry" + To: SoCal Raves + Subject: [scr] yeah for Ians!! + + Your message cannot be delivered to the following recipients: + + Recipient address: jangel1@cougar.noc.ucla.edu + Reason: recipient reached disk quota + + """) + # Subpart 2 contains the machine parsable DSN information. It + # consists of two blocks of headers, represented by two nested Message + # objects. + subpart = msg.get_payload(1) + eq(subpart.get_type(), 'message/delivery-status') + eq(len(subpart.get_payload()), 2) + # message/delivery-status should treat each block as a bunch of + # headers, i.e. a bunch of Message objects. + dsn1 = subpart.get_payload(0) + unless(isinstance(dsn1, Message)) + eq(dsn1['original-envelope-id'], '0GK500B4HD0888@cougar.noc.ucla.edu') + eq(dsn1.get_param('dns', header='reporting-mta'), '') + # Try a missing one + eq(dsn1.get_param('nsd', header='reporting-mta'), None) + dsn2 = subpart.get_payload(1) + unless(isinstance(dsn2, Message)) + eq(dsn2['action'], 'failed') + eq(dsn2.get_params(header='original-recipient'), + [('rfc822', ''), ('jangel1@cougar.noc.ucla.edu', '')]) + eq(dsn2.get_param('rfc822', header='final-recipient'), '') + # Subpart 3 is the original message + subpart = msg.get_payload(2) + eq(subpart.get_type(), 'message/rfc822') + subsubpart = subpart.get_payload() + unless(isinstance(subsubpart, Message)) + eq(subsubpart.get_type(), 'text/plain') + eq(subsubpart['message-id'], + '<002001c144a6$8752e060$56104586@oxy.edu>') + + class TestIdempotent(unittest.TestCase): *************** *** 522,527 **** finally: fp.close() ! msgobj = email.message_from_string(data) ! return msgobj, data def _idempotent(self, msg, text): --- 612,617 ---- finally: fp.close() ! msg = email.message_from_string(data) ! return msg, data def _idempotent(self, msg, text): *************** *** 538,542 **** eq(msg.get_main_type(), 'text') eq(msg.get_subtype(), 'plain') ! eq(msg.get_params(), ['charset=us-ascii']) eq(msg.get_param('charset'), 'us-ascii') eq(msg.preamble, None) --- 628,632 ---- eq(msg.get_main_type(), 'text') eq(msg.get_subtype(), 'plain') ! eq(msg.get_params()[1], ('charset', 'us-ascii')) eq(msg.get_param('charset'), 'us-ascii') eq(msg.preamble, None) *************** *** 567,570 **** --- 657,664 ---- msg, text = self._msgobj('msg_05.txt') self._idempotent(msg, text) + + def test_dsn(self): + msg, text = self._msgobj('msg_16.txt') + self._idempotent(msg, text) def test_content_type(self): *************** *** 575,583 **** # Test the Content-Type: parameters params = {} ! for p in msg.get_params(): ! pk, pv = p.split('=', 1) params[pk] = pv eq(params['report-type'], 'delivery-status') ! eq(params['boundary'], '"D1690A7AC1.996856090/mail.example.com"') eq(msg.preamble, 'This is a MIME-encapsulated message.\n\n') eq(msg.epilogue, '\n\n') --- 669,676 ---- # Test the Content-Type: parameters params = {} ! for pk, pv in msg.get_params(): params[pk] = pv eq(params['report-type'], 'delivery-status') ! eq(params['boundary'], 'D1690A7AC1.996856090/mail.example.com') eq(msg.preamble, 'This is a MIME-encapsulated message.\n\n') eq(msg.epilogue, '\n\n') *************** *** 778,787 **** suite.addTest(unittest.makeSuite(TestLongHeaders)) suite.addTest(unittest.makeSuite(TestFromMangling)) ! suite.addTest(unittest.makeSuite(TestImage)) ! suite.addTest(unittest.makeSuite(TestText)) suite.addTest(unittest.makeSuite(TestMultipartMixed)) suite.addTest(unittest.makeSuite(TestNonConformant)) suite.addTest(unittest.makeSuite(TestRFC2047)) ! suite.addTest(unittest.makeSuite(TestMessageRFC822)) suite.addTest(unittest.makeSuite(TestIdempotent)) suite.addTest(unittest.makeSuite(TestMiscellaneous)) --- 871,880 ---- suite.addTest(unittest.makeSuite(TestLongHeaders)) suite.addTest(unittest.makeSuite(TestFromMangling)) ! suite.addTest(unittest.makeSuite(TestMIMEImage)) ! suite.addTest(unittest.makeSuite(TestMIMEText)) suite.addTest(unittest.makeSuite(TestMultipartMixed)) suite.addTest(unittest.makeSuite(TestNonConformant)) suite.addTest(unittest.makeSuite(TestRFC2047)) ! suite.addTest(unittest.makeSuite(TestMIMEMessage)) suite.addTest(unittest.makeSuite(TestIdempotent)) suite.addTest(unittest.makeSuite(TestMiscellaneous)) From twouters@users.sourceforge.net Wed Sep 26 13:43:41 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 26 Sep 2001 05:43:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_grammar.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv27695/Lib/test Modified Files: test_grammar.py Log Message: Test case for SF bugs #463359 and #462937, added to test_grammar for lack of a better place. Excessively fragile code, but at least it breaks when something in this area changes! Index: test_grammar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_grammar.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** test_grammar.py 2001/09/21 19:22:34 1.37 --- test_grammar.py 2001/09/26 12:43:38 1.38 *************** *** 359,362 **** --- 359,389 ---- print msg + + # This test warrants an explanation. It is a test specifically for SF bugs + # #463359 and #462937. The bug is that a 'break' statement executed or + # exception raised inside a try/except inside a loop, *after* a continue + # statement has been executed in that loop, will cause the wrong number of + # arguments to be popped off the stack and the instruction pointer reset to + # a very small number (usually 0.) Because of this, the following test + # *must* written as a function, and the tracking vars *must* be function + # arguments with default values. Otherwise, the test will loop and loop. + + print "testing continue and break in try/except in loop" + def test_break_continue_loop(extra_burning_oil = 1, count=0): + big_hippo = 2 + while big_hippo: + count += 1 + try: + if extra_burning_oil and big_hippo == 1: + extra_burning_oil -= 1 + break + big_hippo -= 1 + continue + except: + raise + if count > 2 or big_hippo <> 1: + print "continue then break in try/except in loop broken!" + test_break_continue_loop() + print 'return_stmt' # 'return' [testlist] def g1(): return From twouters@users.sourceforge.net Wed Sep 26 13:43:41 2001 From: twouters@users.sourceforge.net (Thomas Wouters) Date: Wed, 26 Sep 2001 05:43:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_grammar,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv27695/Lib/test/output Modified Files: test_grammar Log Message: Test case for SF bugs #463359 and #462937, added to test_grammar for lack of a better place. Excessively fragile code, but at least it breaks when something in this area changes! Index: test_grammar =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_grammar,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -d -r1.17 -r1.18 *** test_grammar 2001/03/19 20:42:11 1.17 --- test_grammar 2001/09/26 12:43:39 1.18 *************** *** 33,36 **** --- 33,37 ---- continue + try/except ok continue + try/finally ok + testing continue and break in try/except in loop return_stmt raise_stmt From fdrake@users.sourceforge.net Wed Sep 26 17:52:20 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 09:52:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib email.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv27613 Modified Files: email.tex Log Message: Start making some markup adjustments; Barry has indicated he will work on this before we finish the integration, along with some restructuring. Index: email.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/email.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** email.tex 2001/09/26 05:23:47 1.1 --- email.tex 2001/09/26 16:52:18 1.2 *************** *** 2,6 **** % Author: barry@zope.com (Barry Warsaw) ! \section{\module{email} -- An email and MIME handling package} --- 2,6 ---- % Author: barry@zope.com (Barry Warsaw) ! \section{\module{email} --- An email and MIME handling package} *************** *** 65,72 **** matched case-insensitively. There may also be a single \emph{Unix-From} header, also known as the envelope header or the ! \code{From_} header. The payload is either a string in the case of simple message objects, a list of \class{Message} objects for multipart MIME documents, or a single \class{Message} instance for ! \code{message/rfc822} type objects. \class{Message} objects provide a mapping style interface for --- 65,72 ---- matched case-insensitively. There may also be a single \emph{Unix-From} header, also known as the envelope header or the ! \mailheader{From_} header. The payload is either a string in the case of simple message objects, a list of \class{Message} objects for multipart MIME documents, or a single \class{Message} instance for ! \mimetype{message/rfc822} type objects. \class{Message} objects provide a mapping style interface for *************** *** 163,169 **** \method{Message.add_header()}. ! The \class{MIMEBase} class always adds a \code{Content-Type:} header (based on \var{_maintype}, \var{_subtype}, and \var{_params}), and a ! \code{MIME-Version:} header (always set to \code{1.0}). \end{classdesc} --- 163,169 ---- \method{Message.add_header()}. ! The \class{MIMEBase} class always adds a \mailheader{Content-Type} header (based on \var{_maintype}, \var{_subtype}, and \var{_params}), and a ! \mailheader{MIME-Version} header (always set to \code{1.0}). \end{classdesc} *************** *** 172,182 **** A subclass of \class{MIMEBase}, the \class{MIMEImage} class is used to ! create MIME message objects of major type \code{image}. \var{_imagedata} is a string containing the raw image data. If this data can be decoded by the standard Python module \refmodule{imghdr}, then the subtype will be automatically included in the ! \code{Content-Type:} header. Otherwise you can explicitly specify the image subtype via the \var{_subtype} parameter. If the minor type could ! not be guessed and \var{_subtype} was not given, then \code{TypeError} is raised. --- 172,182 ---- A subclass of \class{MIMEBase}, the \class{MIMEImage} class is used to ! create MIME message objects of major type \mimetype{image}. \var{_imagedata} is a string containing the raw image data. If this data can be decoded by the standard Python module \refmodule{imghdr}, then the subtype will be automatically included in the ! \mailheader{Content-Type} header. Otherwise you can explicitly specify the image subtype via the \var{_subtype} parameter. If the minor type could ! not be guessed and \var{_subtype} was not given, then \exception{TypeError} is raised. *************** *** 186,190 **** It should use \method{get_payload()} and \method{set_payload()} to change the payload to encoded form. It should also add any ! \code{Content-Transfer-Encoding:} or other headers to the message object as necessary. The default encoding is \emph{Base64}. See the \refmodule{email.Encoders} module for a list of the built-in encoders. --- 186,190 ---- It should use \method{get_payload()} and \method{set_payload()} to change the payload to encoded form. It should also add any ! \mailheader{Content-Transfer-Encoding} or other headers to the message object as necessary. The default encoding is \emph{Base64}. See the \refmodule{email.Encoders} module for a list of the built-in encoders. *************** *** 197,203 **** _charset\optional{, _encoder}}}} A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to ! create MIME objects of major type \code{text}. \var{_text} is the string for the payload. \var{_subtype} is the minor type and defaults to ! \code{plain}. \var{_charset} is the character set of the text and is passed as a parameter to the \class{MIMEBase} constructor; it defaults to \code{us-ascii}. No guessing or encoding is performed on the text --- 197,203 ---- _charset\optional{, _encoder}}}} A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to ! create MIME objects of major type \mimetype{text}. \var{_text} is the string for the payload. \var{_subtype} is the minor type and defaults to ! \mimetype{plain}. \var{_charset} is the character set of the text and is passed as a parameter to the \class{MIMEBase} constructor; it defaults to \code{us-ascii}. No guessing or encoding is performed on the text *************** *** 208,212 **** constructor, except that the default encoding for \class{MIMEText} objects is one that doesn't actually modify the payload, but does set ! the \code{Content-Transfer-Encoding:} header to \code{7bit} or \code{8bit} as appropriate. \end{classdesc} --- 208,212 ---- constructor, except that the default encoding for \class{MIMEText} objects is one that doesn't actually modify the payload, but does set ! the \mailheader{Content-Transfer-Encoding} header to \code{7bit} or \code{8bit} as appropriate. \end{classdesc} *************** *** 214,223 **** \begin{classdesc}{MIMEMessage}{_msg\optional{, _subtype}} A subclass of \class{MIMEBase}, the \class{MIMEMessage} class is used to ! create MIME objects of main type \code{message}. \var{_msg} is used as the payload, and must be an instance of class \class{Message} (or a subclass thereof), otherwise a \exception{TypeError} is raised. Optional \var{_subtype} sets the subtype of the message; it defaults ! to \code{rfc822}. \end{classdesc} --- 214,223 ---- \begin{classdesc}{MIMEMessage}{_msg\optional{, _subtype}} A subclass of \class{MIMEBase}, the \class{MIMEMessage} class is used to ! create MIME objects of main type \mimetype{message}. \var{_msg} is used as the payload, and must be an instance of class \class{Message} (or a subclass thereof), otherwise a \exception{TypeError} is raised. Optional \var{_subtype} sets the subtype of the message; it defaults ! to \mimetype{rfc822}. \end{classdesc} *************** *** 309,313 **** The \class{Parser} class has no differences in its public interface. It does have some additional smarts to recognize ! \code{message/delivery-status} type messages, which it represents as a \class{Message} instance containing separate \class{Message} subparts for each header block in the delivery status --- 309,313 ---- The \class{Parser} class has no differences in its public interface. It does have some additional smarts to recognize ! \mimetype{message/delivery-status} type messages, which it represents as a \class{Message} instance containing separate \class{Message} subparts for each header block in the delivery status *************** *** 340,346 **** Also, the \class{MIMEMessage} class now represents any kind of ! MIME message with main type \code{message}. It takes an optional argument \var{_subtype} which is used to set the MIME ! subtype. \var{_subtype} defaults to \code{rfc822}. \end{itemize} --- 340,346 ---- Also, the \class{MIMEMessage} class now represents any kind of ! MIME message with main type \mimetype{message}. It takes an optional argument \var{_subtype} which is used to set the MIME ! subtype. \var{_subtype} defaults to \mimetype{rfc822}. \end{itemize} From fdrake@users.sourceforge.net Wed Sep 26 18:02:00 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 10:02:00 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv30991/Doc/doc Modified Files: doc.tex Log Message: Move the \mailheader description to the right place. Clarify the \mimetype description; it can be used to refer to a part of a MIME type name, so \mimetype{text} or \mimetype{plain} can be used, not just \mimetype{text/plain}. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** doc.tex 2001/08/29 02:34:10 1.52 --- doc.tex 2001/09/26 17:01:58 1.53 *************** *** 817,820 **** --- 817,831 ---- \end{macrodesc} + \begin{macrodesc}{mailheader}{\p{name}} + The name of an \rfc{822}-style mail header. This markup does + not imply that the header is being used in an email message, but + can be used to refer to any header of the same ``style.'' This + is also used for headers defined by the various MIME + specifications. The header name should be entered in the same + way it would normally be found in practice, with the + camel-casing conventions being preferred where there is more + than one common usage. For example: \mailheader{Content-Type}. + \end{macrodesc} + \begin{macrodesc}{makevar}{\p{name}} The name of a \program{make} variable. *************** *** 835,851 **** \end{macrodesc} - \begin{macrodesc}{mailheader}{\p{name}} - The name of an \rfc{822}-style mail header. This markup does - not imply that the header is being used in an email message, but - can be used to refer to any header of the same ``style.'' This - is also used for headers defined by the various MIME - specifications. The header name should be entered in the same - way it would normally be found in practice, with the - camel-casing conventions being preferred where there is more - than one common usage. For example: \mailheader{Content-Type}. - \end{macrodesc} - \begin{macrodesc}{mimetype}{\p{name}} ! The name of a MIME type. \end{macrodesc} --- 846,852 ---- \end{macrodesc} \begin{macrodesc}{mimetype}{\p{name}} ! The name of a MIME type, or a component of a MIME type (the ! major or minor portion, taken alone). \end{macrodesc} From gward@users.sourceforge.net Wed Sep 26 19:12:51 2001 From: gward@users.sourceforge.net (Greg Ward) Date: Wed, 26 Sep 2001 11:12:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.150,1.151 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv20165 Modified Files: api.tex Log Message: Typo fix. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.150 retrieving revision 1.151 diff -C2 -d -r1.150 -r1.151 *** api.tex 2001/09/24 15:31:50 1.150 --- api.tex 2001/09/26 18:12:49 1.151 *************** *** 1403,1407 **** ! \section{Parsing arguements and building values \label{arg-parsing}} --- 1403,1407 ---- ! \section{Parsing arguments and building values \label{arg-parsing}} From fdrake@users.sourceforge.net Wed Sep 26 19:43:23 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 11:43:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/doc doc.tex,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/doc In directory usw-pr-cvs1:/tmp/cvs-serv32122/doc Modified Files: doc.tex Log Message: Note that the colon following a mail header name should not be included when using the \mailheader markup. Change a couple of inline examples to show the markup rather than the result. Index: doc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/doc/doc.tex,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** doc.tex 2001/09/26 17:01:58 1.53 --- doc.tex 2001/09/26 18:43:20 1.54 *************** *** 463,468 **** document is an example) and for shorter reference manuals for small, fairly cohesive module libraries. Examples of the later use include - the standard \citetitle[../mac/mac.html]{Macintosh Library Modules} - and \citetitle[http://starship.python.net/crew/fdrake/manuals/krb5py/krb5py.html]{Using Kerberos from Python}, which contains reference material for an --- 463,466 ---- *************** *** 825,829 **** way it would normally be found in practice, with the camel-casing conventions being preferred where there is more ! than one common usage. For example: \mailheader{Content-Type}. \end{macrodesc} --- 823,829 ---- way it would normally be found in practice, with the camel-casing conventions being preferred where there is more ! than one common usage. The colon which follows the name of the ! header should not be included. ! For example: \code{\e mailheader\{Content-Type\}}. \end{macrodesc} *************** *** 871,875 **** negative value of a specified magnitude, typically represented by a plus sign placed over a minus sign. For example: ! \emph{The lateral movement has a tolerance of \plusminus 3\%{}}. \end{macrodesc} --- 871,875 ---- negative value of a specified magnitude, typically represented by a plus sign placed over a minus sign. For example: ! \code{\e plusminus 3\%{}}. \end{macrodesc} *************** *** 1013,1017 **** ``fully qualified'' form (it should include the package name). For example, a module ``foo'' in package ``bar'' should be marked as ! \samp{\e module\{bar.foo\}}, and the beginning of the reference section would appear as: --- 1013,1017 ---- ``fully qualified'' form (it should include the package name). For example, a module ``foo'' in package ``bar'' should be marked as ! \code{\e module\{bar.foo\}}, and the beginning of the reference section would appear as: From fdrake@users.sourceforge.net Wed Sep 26 19:46:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 11:46:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs python.sty,1.81,1.82 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv1837/texinputs Modified Files: python.sty Log Message: Move the styling for the HTML version of \mailheader into the CSS file. In both the HTML and typeset versions of the documentation, add a colon after the name of a mail header so that it is more easily distinguished from other text. Index: python.sty =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/python.sty,v retrieving revision 1.81 retrieving revision 1.82 diff -C2 -d -r1.81 -r1.82 *** python.sty 2001/08/20 21:36:38 1.81 --- python.sty 2001/09/26 18:46:36 1.82 *************** *** 834,838 **** \newcommand{\cdata}[1]{\texttt{#1}} % C variable, typically global ! \newcommand{\mailheader}[1]{\texttt{#1}} \newcommand{\mimetype}[1]{{\small\textsf{#1}}} % The \! is a "negative thin space" in math mode. --- 834,838 ---- \newcommand{\cdata}[1]{\texttt{#1}} % C variable, typically global ! \newcommand{\mailheader}[1]{{\small\textsf{#1:}}} \newcommand{\mimetype}[1]{{\small\textsf{#1}}} % The \! is a "negative thin space" in math mode. From fdrake@users.sourceforge.net Wed Sep 26 19:46:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 11:46:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/html style.css,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory usw-pr-cvs1:/tmp/cvs-serv1837/html Modified Files: style.css Log Message: Move the styling for the HTML version of \mailheader into the CSS file. In both the HTML and typeset versions of the documentation, add a colon after the name of a mail header so that it is more easily distinguished from other text. Index: style.css =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/style.css,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** style.css 2001/07/06 22:37:36 1.16 --- style.css 2001/09/26 18:46:36 1.17 *************** *** 73,76 **** --- 73,77 ---- .email { font-family: avantgarde, sans-serif; } + .mailheader { font-family: avantgarde, sans-serif; } .mimetype { font-family: avantgarde, sans-serif; } .newsgroup { font-family: avantgarde, sans-serif; } From fdrake@users.sourceforge.net Wed Sep 26 19:46:38 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 11:46:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl python.perl,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv1837/perl Modified Files: python.perl Log Message: Move the styling for the HTML version of \mailheader into the CSS file. In both the HTML and typeset versions of the documentation, add a colon after the name of a mail header so that it is more easily distinguished from other text. Index: python.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/python.perl,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** python.perl 2001/08/20 21:36:38 1.109 --- python.perl 2001/09/26 18:46:36 1.110 *************** *** 214,218 **** return use_wrappers(@_[0], ''); } sub do_cmd_mailheader{ ! return use_wrappers(@_[0], '', ''); } sub do_cmd_mimetype{ return use_wrappers(@_[0], '', ''); } --- 214,218 ---- return use_wrappers(@_[0], ''); } sub do_cmd_mailheader{ ! return use_wrappers(@_[0], '', ':'); } sub do_cmd_mimetype{ return use_wrappers(@_[0], '', ''); } From jhylton@users.sourceforge.net Wed Sep 26 20:24:47 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 26 Sep 2001 12:24:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.277,2.278 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv19695 Modified Files: ceval.c Log Message: Prevent a NULL pointer from being pushed onto the stack. It's possible for PyErr_NormalizeException() to set the traceback pointer to NULL. I'm not sure how to provoke this directly from Python, although it may be possible. The error occurs when an exception is set using PyErr_SetObject() and another exception occurs while PyErr_NormalizeException() is creating the exception instance. XXX As a result of this change, it's possible for an exception to occur but sys.last_traceback to be left undefined. Not sure if this is a problem. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.277 retrieving revision 2.278 diff -C2 -d -r2.277 -r2.278 *** ceval.c 2001/09/24 19:32:01 2.277 --- ceval.c 2001/09/26 19:24:45 2.278 *************** *** 2256,2260 **** exc, val, tb); } ! PUSH(tb); PUSH(val); PUSH(exc); --- 2256,2264 ---- exc, val, tb); } ! if (tb == NULL) { ! Py_INCREF(Py_None); ! PUSH(Py_None); ! } else ! PUSH(tb); PUSH(val); PUSH(exc); From jhylton@users.sourceforge.net Wed Sep 26 20:54:11 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 26 Sep 2001 12:54:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib types.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv1760 Modified Files: types.py Log Message: Don't export generators future info Index: types.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/types.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** types.py 2001/09/25 22:02:03 1.22 --- types.py 2001/09/26 19:54:08 1.23 *************** *** 84,86 **** DictProxyType = type(TypeType.__dict__) ! del sys, _f, _C, _x # Not for export --- 84,86 ---- DictProxyType = type(TypeType.__dict__) ! del sys, _f, _C, _x, generators # Not for export From jhylton@users.sourceforge.net Wed Sep 26 20:58:41 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 26 Sep 2001 12:58:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python errors.c,2.64,2.65 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3911 Modified Files: errors.c Log Message: PyErr_NormalizeException() If a new exception occurs while an exception instance is being created, try harder to make sure there is a traceback. If the original exception had a traceback associated with it and the new exception does not, keep the old exception. Of course, callers to PyErr_NormalizeException() must still be prepared to have tb set to NULL. XXX This isn't an ideal solution, but it's better than no traceback at all. It occurs if, for example, the exception occurs when the call to the constructor fails before any Python code is executed. Guido suggests that it there is Python code that was about to be executed -- but wasn't, say, because it was called with the wrong number of arguments -- then we should point at the first line of the code object anyway. Index: errors.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/errors.c,v retrieving revision 2.64 retrieving revision 2.65 diff -C2 -d -r2.64 -r2.65 *** errors.c 2001/08/24 18:35:23 2.64 --- errors.c 2001/09/26 19:58:38 2.65 *************** *** 129,132 **** --- 129,133 ---- PyObject *value = *val; PyObject *inclass = NULL; + PyObject *initial_tb = NULL; if (type == NULL) { *************** *** 192,197 **** Py_DECREF(type); Py_DECREF(value); ! Py_XDECREF(*tb); PyErr_Fetch(exc, val, tb); /* normalize recursively */ PyErr_NormalizeException(exc, val, tb); --- 193,208 ---- Py_DECREF(type); Py_DECREF(value); ! /* If the new exception doesn't set a traceback and the old ! exception had a traceback, use the old traceback for the ! new exception. It's better than nothing. ! */ ! initial_tb = *tb; PyErr_Fetch(exc, val, tb); + if (initial_tb != NULL) { + if (*tb == NULL) + *tb = initial_tb; + else + Py_DECREF(initial_tb); + } /* normalize recursively */ PyErr_NormalizeException(exc, val, tb); From jhylton@users.sourceforge.net Wed Sep 26 21:01:11 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 26 Sep 2001 13:01:11 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_exceptions.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5478 Modified Files: test_exceptions.py Log Message: Add tests for new PyErr_NormalizeException() behavior Add raise_exception() to the _testcapi module. It isn't a test, but the C API exists only to support test_exceptions. raise_exception() takes two arguments -- an exception class and an integer specifying how many arguments it should be called with. test_exceptions uses BadException() to test the interpreter's behavior when there is a problem instantiating the exception. test_capi1() calls it with too many arguments. test_capi2() causes an exception to be raised in the Python code of the constructor. Index: test_exceptions.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_exceptions.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -d -r1.14 -r1.15 *** test_exceptions.py 2001/08/23 03:23:03 1.14 --- test_exceptions.py 2001/09/26 20:01:09 1.15 *************** *** 4,7 **** --- 4,9 ---- from types import ClassType import warnings + import sys, traceback + import _testcapi warnings.filterwarnings("error", "", OverflowWarning, __name__) *************** *** 161,164 **** --- 163,199 ---- try: x = 1/0 except Exception, e: pass + + # test that setting an exception at the C level works even if the + # exception object can't be constructed. + + class BadException: + def __init__(self): + raise RuntimeError, "can't instantiate BadException" + + def test_capi1(): + try: + _testcapi.raise_exception(BadException, 1) + except TypeError, err: + exc, err, tb = sys.exc_info() + co = tb.tb_frame.f_code + assert co.co_name == "test_capi1" + assert co.co_filename.endswith('test_exceptions.py') + else: + print "Expected exception" + test_capi1() + + def test_capi2(): + try: + _testcapi.raise_exception(BadException, 0) + except RuntimeError, err: + exc, err, tb = sys.exc_info() + co = tb.tb_frame.f_code + assert co.co_name == "__init__" + assert co.co_filename.endswith('test_exceptions.py') + co2 = tb.tb_frame.f_back.f_code + assert co2.co_name == "test_capi2" + else: + print "Expected exception" + test_capi2() unlink(TESTFN) From jhylton@users.sourceforge.net Wed Sep 26 21:01:15 2001 From: jhylton@users.sourceforge.net (Jeremy Hylton) Date: Wed, 26 Sep 2001 13:01:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv5515 Modified Files: _testcapimodule.c Log Message: Add tests for new PyErr_NormalizeException() behavior Add raise_exception() to the _testcapi module. It isn't a test, but the C API exists only to support test_exceptions. raise_exception() takes two arguments -- an exception class and an integer specifying how many arguments it should be called with. test_exceptions uses BadException() to test the interpreter's behavior when there is a problem instantiating the exception. test_capi1() calls it with too many arguments. test_capi2() causes an exception to be raised in the Python code of the constructor. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** _testcapimodule.c 2001/07/26 13:41:05 1.10 --- _testcapimodule.c 2001/09/26 20:01:13 1.11 *************** *** 258,263 **** --- 258,289 ---- #endif /* ifdef HAVE_LONG_LONG */ + static PyObject * + raise_exception(PyObject *self, PyObject *args) + { + PyObject *exc; + PyObject *exc_args, *v; + int num_args, i; + + if (!PyArg_ParseTuple(args, "Oi:raise_exception", + &exc, &num_args)) + return NULL; + + exc_args = PyTuple_New(num_args); + if (exc_args == NULL) + return NULL; + for (i = 0; i < num_args; ++i) { + v = PyInt_FromLong(i); + if (v == NULL) { + Py_DECREF(exc_args); + return NULL; + } + PyTuple_SET_ITEM(exc_args, i, v); + } + PyErr_SetObject(exc, exc_args); + return NULL; + } static PyMethodDef TestMethods[] = { + {"raise_exception", raise_exception, METH_VARARGS}, {"test_config", test_config, METH_VARARGS}, {"test_list_api", test_list_api, METH_VARARGS}, From tim_one@users.sourceforge.net Wed Sep 26 21:31:54 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 26 Sep 2001 13:31:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test pydocfodder.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19470 Added Files: pydocfodder.py Log Message: A file just to look at (using pydoc). --- NEW FILE: pydocfodder.py --- """Something just to look at via pydoc.""" class A_classic: "A classic class." def A_method(self): "Method defined in A." def AB_method(self): "Method defined in A and B." def AC_method(self): "Method defined in A and C." def AD_method(self): "Method defined in A and D." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." class B_classic(A_classic): "A classic class, derived from A_classic." def AB_method(self): "Method defined in A and B." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ABCD_method(self): "Method defined in A, B, C and D." def B_method(self): "Method defined in B." def BC_method(self): "Method defined in B and C." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." class C_classic(A_classic): "A classic class, derived from A_classic." def AC_method(self): "Method defined in A and C." def ABC_method(self): "Method defined in A, B and C." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BC_method(self): "Method defined in B and C." def BCD_method(self): "Method defined in B, C and D." def C_method(self): "Method defined in C." def CD_method(self): "Method defined in C and D." class D_classic(B_classic, C_classic): "A classic class, derived from B_classic and C_classic." def AD_method(self): "Method defined in A and D." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." def CD_method(self): "Method defined in C and D." def D_method(self): "Method defined in D." class A_new_dynamic(object): "A new-style dynamic class." __dynamic__ = 1 def A_method(self): "Method defined in A." def AB_method(self): "Method defined in A and B." def AC_method(self): "Method defined in A and C." def AD_method(self): "Method defined in A and D." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def A_classmethod(cls, x): "A class method defined in A." A_classmethod = classmethod(A_classmethod) def A_staticmethod(): "A static method defined in A." A_staticmethod = staticmethod(A_staticmethod) def _getx(self): "A property getter function." def _setx(self, value): "A property setter function." def _delx(self): "A property deleter function." A_property = property(fdel=_delx, fget=_getx, fset=_setx, doc="A sample property defined in A.") A_int_alias = int class B_new_dynamic(A_new_dynamic): "A new-style dynamic class, derived from A_new_dynamic." __dynamic__ = 1 def AB_method(self): "Method defined in A and B." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ABCD_method(self): "Method defined in A, B, C and D." def B_method(self): "Method defined in B." def BC_method(self): "Method defined in B and C." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." class C_new_dynamic(A_new_dynamic): "A new-style dynamic class, derived from A_new_dynamic." __dynamic__ = 1 def AC_method(self): "Method defined in A and C." def ABC_method(self): "Method defined in A, B and C." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BC_method(self): "Method defined in B and C." def BCD_method(self): "Method defined in B, C and D." def C_method(self): "Method defined in C." def CD_method(self): "Method defined in C and D." class D_new_dynamic(B_new_dynamic, C_new_dynamic): """A new-style dynamic class, derived from B_new_dynamic and C_new_dynamic. """ __dynamic__ = 1 def AD_method(self): "Method defined in A and D." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." def CD_method(self): "Method defined in C and D." def D_method(self): "Method defined in D." class A_new_static(object): "A new-style static class." __dynamic__ = 0 def A_method(self): "Method defined in A." def AB_method(self): "Method defined in A and B." def AC_method(self): "Method defined in A and C." def AD_method(self): "Method defined in A and D." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def A_classmethod(cls, x): "A class method defined in A." A_classmethod = classmethod(A_classmethod) def A_staticmethod(): "A static method defined in A." A_staticmethod = staticmethod(A_staticmethod) def _getx(self): "A property getter function." def _setx(self, value): "A property setter function." def _delx(self): "A property deleter function." A_property = property(fdel=_delx, fget=_getx, fset=_setx, doc="A sample property defined in A.") A_int_alias = int class B_new_static(A_new_static): "A new-style static class, derived from A_new_static." __dynamic__ = 0 def AB_method(self): "Method defined in A and B." def ABC_method(self): "Method defined in A, B and C." def ABD_method(self): "Method defined in A, B and D." def ABCD_method(self): "Method defined in A, B, C and D." def B_method(self): "Method defined in B." def BC_method(self): "Method defined in B and C." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." class C_new_static(A_new_static): "A new-style static class, derived from A_new_static." __dynamic__ = 0 def AC_method(self): "Method defined in A and C." def ABC_method(self): "Method defined in A, B and C." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BC_method(self): "Method defined in B and C." def BCD_method(self): "Method defined in B, C and D." def C_method(self): "Method defined in C." def CD_method(self): "Method defined in C and D." class D_new_static(B_new_static, C_new_static): "A new-style static class, derived from B_new_static and C_new_static." __dynamic__ = 0 def AD_method(self): "Method defined in A and D." def ABD_method(self): "Method defined in A, B and D." def ACD_method(self): "Method defined in A, C and D." def ABCD_method(self): "Method defined in A, B, C and D." def BD_method(self): "Method defined in B and D." def BCD_method(self): "Method defined in B, C and D." def CD_method(self): "Method defined in C and D." def D_method(self): "Method defined in D." From akuchling@users.sourceforge.net Wed Sep 26 21:37:04 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Wed, 26 Sep 2001 13:37:04 -0700 Subject: [Python-checkins] CVS: python/nondist/sandbox/parrot - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/parrot In directory usw-pr-cvs1:/tmp/cvs-serv21832/parrot Log Message: Directory /cvsroot/python/python/nondist/sandbox/parrot added to the repository From akuchling@users.sourceforge.net Wed Sep 26 21:37:45 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Wed, 26 Sep 2001 13:37:45 -0700 Subject: [Python-checkins] CVS: python/nondist/sandbox/parrot README,NONE,1.1 euclid.py,NONE,1.1 parrot-gen.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/parrot In directory usw-pr-cvs1:/tmp/cvs-serv22033 Added Files: README euclid.py parrot-gen.py Log Message: Initial checkin of Python->Parrot compiler --- NEW FILE: README --- This is a simple compiler that turns Python source into Parrot bytecode. By default, it will generate both a .pasm file (containing Parrot assembly source) and a compiled .pdbc file. -S will make it only write the .pasm file, and -r will try to execute the code by running Parrot's test_prog on the .pdbc file. Limitations: * Currently this only understands a *really* limited subset of Python: simple expressions, integer variables, and the 'while' and 'if' statements (with no 'else' suites). * The only allowable type is integer; strings, floats, long ints, &c., aren't supported at all. * It will die with an assertion if you feed it a language construct it doesn't handle (def, class, most operators). * The code structure is suboptimal; this is just a quick-and-dirty hack. Example usage: ute parrot>python euclid.py # Run code with Python 96 64 32 ute parrot>python parrot-gen.py -r euclid.py # -r to run generated bytecode 96 64 32 ute parrot>cat euclid.pasm main: set I3, 96 set I10, 64 set I9, 0 add I0, I3, I9 ... ... Currently the Parrot interpreter only supports integer, floating point, and string registers. There's no way to store the contents of a register in memory as far as I can tell, and PMCs -- Parrot Magic Cookies, the polymorphic objects that would correspond to PyObjects -- aren't implemented either. This means it's not possible to handle general variables, and therefore we'll have to wait for PMCs before general Python programs can be handled. Scalar PMCs are supposed to be implemented for Parrot 0.0.3, and dictionary/list PMCs in 0.0.4. You can discuss this code on either python-dev@python.org or perl6-internals@perl.org. --amk --- NEW FILE: euclid.py --- # Python implementation of Euclid's algorithm m = 96 n = 64 print m,n r = m % n while r != 0: m = n n = r r = m % n print n --- NEW FILE: parrot-gen.py --- """parrot-gen.py Parses a Python file and outputs a Parrot assembly file. Currently this only understands a *really* limited subset of Python. The only allowable type is integer; strings, floats, long ints, &c., aren't supported at all. It will die with an assertion if you feed it a language construct it doesn't handle (def, class, most operators). """ # created 2001/09/21, AMK __revision__ = "$Id: parrot-gen.py,v 1.1 2001/09/26 20:37:43 akuchling Exp $" import sys, os, types import getopt, random __doc__ = """%s: convert Python source to Parrot bytecode -r Run Parrot assembler and interpreter on output -S Only produce assembly source code (.pasm file) """ from compiler import ast, transformer, visitor, walk from compiler.pycodegen import LocalNameFinder # List 31 of the 32 integer registers as being available FREE_REGISTERS = [] for i in range(1, 32): FREE_REGISTERS.append('I' + str(i)) # Global variable: maps local variable names to their assigned register LOCAL_REGS = {} symcount = 1 # Counter for symbols def gensym (): """gensym() -> string Return a unique string that can be used as a label in the generated assembly code. """ global symcount sym = 'sym%i' % symcount symcount += 1 return sym class ParrotVisitor: """Visitor class that outputs Parrot bytecode. Attributes: lines : list of strings, each one a line of output. """ def __init__ (self): self.lines = [] self.symcount = 0 def add_line (self, line): """add_line(line:string) Add a line of output to the generated code. The line is modified slightly to ensure that it ends with a newline and is indented properly. """ line = line.rstrip() + '\n' # Indent mnemonics # XXX this logic is obviously far too simple, but it'll do for now if ':' not in line: line = '\t' + line self.lines.append(line) def add_lines (self, lines): """add_lines(line:[string]) Add several lines of output to the generated code. """ for line in lines: self.add_line(line) # Visitor methods. Most of the def visitAssign (self, node): a_name = node.nodes[0].name reg = LOCAL_REGS[a_name] lines = compile_expr(node.expr, reg, FREE_REGISTERS) self.add_lines(lines) # XXX assign result to 'a_name.name' def visitClass (self, node): assert 0, "class statement not supported" def visitIf (self, node): assert len(node.tests) == 1, "Only one test supported" test_expr, body = node.tests[0] sym = gensym() sym2 = gensym() lines = (compile_expr(test_expr, 'I0', FREE_REGISTERS) + ["if I0, %s" % sym, "branch %s" % sym2, "%s:" % sym]) self.add_lines(lines) self.visit(body) self.add_line("%s:" % sym2) def visitPrint (self, node): assert node.dest is None, "print without trailing newline not yet handled" def visitPrintnl (self, node): assert node.dest is None, "print>> not yet handled" lines = [] for n in node.nodes: lines += compile_expr(n, 'I0', FREE_REGISTERS) lines += ["print I0", 'print " "'] lines += ['print "\\n"'] self.add_lines(lines) ## def visitAnd(self, node): ## assert 0, "not implemented" ## def visitAssAttr(self, node): ## assert 0, "not implemented" ## def visitAssList(self, node): ## assert 0, "not implemented" ## def visitAssName(self, node): ## assert 0, "not implemented" ## def visitAssName(self, node): ## assert 0, "not implemented" ## def visitAssName(self, node): ## assert 0, "not implemented" ## def visitAssTuple(self, node): ## assert 0, "not implemented" def visitAssert(self, node): assert 0, "not implemented" ## def visitAugAssign(self, node): ## assert 0, "not implemented" ## def visitAugGetattr(self, node, mode): ## assert 0, "not implemented" ## def visitAugName(self, node, mode): ## assert 0, "not implemented" ## def visitAugSlice(self, node, mode): ## assert 0, "not implemented" ## def visitAugSubscript(self, node, mode): ## assert 0, "not implemented" ## def visitBackquote(self, node): ## assert 0, "not implemented" ## def visitBitand(self, node): ## assert 0, "not implemented" ## def visitBitor(self, node): ## assert 0, "not implemented" ## def visitBitxor(self, node): ## assert 0, "not implemented" def visitBreak(self, node): assert 0, "not implemented" def visitCallFunc(self, node): assert 0, "not implemented" def visitClass(self, node): assert 0, "not implemented" ## def visitCompare(self, node): ## assert 0, "not implemented" ## def visitConst(self, node): ## assert 0, "not implemented" ## def visitContinue(self, node): ## assert 0, "not implemented" ## def visitDict(self, node): ## assert 0, "not implemented" ## def visitDict(self, node): ## assert 0, "not implemented" def visitDiscard(self, node): lines = compile_expr(node.expr, 'I0', FREE_REGISTERS) self.add_lines(lines) ## def visitEllipsis(self, node): ## assert 0, "not implemented" def visitExec(self, node): assert 0, "not implemented" def visitFor(self, node): assert 0, "not implemented" ## def visitFrom(self, node): ## assert 0, "not implemented" ## def visitFrom(self, node): ## assert 0, "not implemented" ## def visitFunction(self, node): ## assert 0, "not implemented" ## def visitFunction(self, node): ## assert 0, "not implemented" ## def visitGetattr(self, node): ## assert 0, "not implemented" ## def visitGlobal(self, node): ## assert 0, "not implemented" ## def visitGlobal(self, node): ## assert 0, "not implemented" ## def visitImport(self, node): ## assert 0, "not implemented" def visitImport(self, node): assert 0, "not implemented" ## def visitInvert(self, node): ## assert 0, "not implemented" ## def visitKeyword(self, node): ## assert 0, "not implemented" ## def visitLambda(self, node): ## assert 0, "not implemented" ## def visitLambda(self, node): ## assert 0, "not implemented" ## def visitLeftShift(self, node): ## assert 0, "not implemented" ## def visitList(self, node): ## assert 0, "not implemented" ## def visitListComp(self, node): ## assert 0, "not implemented" ## def visitListCompFor(self, node): ## assert 0, "not implemented" ## def visitListCompIf(self, node, branch): ## assert 0, "not implemented" ## def visitModule(self, node): ## pass ## #assert 0, "not implemented" ## def visitMul(self, node): ## assert 0, "not implemented" ## def visitName(self, node): ## assert 0, "not implemented" ## def visitNot(self, node): ## assert 0, "not implemented" ## def visitOr(self, node): ## assert 0, "not implemented" ## def visitPass(self, node): ## assert 0, "not implemented" ## def visitPower(self, node): ## assert 0, "not implemented" ## def visitRaise(self, node): ## assert 0, "not implemented" ## def visitReturn(self, node): ## assert 0, "not implemented" ## def visitRightShift(self, node): ## assert 0, "not implemented" ## def visitSlice(self, node, aug_flag=None): ## assert 0, "not implemented" ## def visitSliceobj(self, node): ## assert 0, "not implemented" ## def visitSub(self, node): ## assert 0, "not implemented" ## def visitSubscript(self, node, aug_flag=None): ## assert 0, "not implemented" ## def visitTest(self, node, jump): ## assert 0, "not implemented" ## def visitTryExcept(self, node): ## assert 0, "not implemented" ## def visitTryFinally(self, node): ## assert 0, "not implemented" ## def visitTuple(self, node): ## assert 0, "not implemented" ## def visitUnaryAdd(self, node): ## assert 0, "not implemented" ## def visitUnaryInvert(self, node): ## assert 0, "not implemented" ## def visitUnarySub(self, node): ## assert 0, "not implemented" def visitWhile(self, node): assert node.else_ is None, "while...else not supported" start = gensym() end = gensym() self.add_line("%s:" % start) self.add_lines(compile_expr(node.test, 'I0', FREE_REGISTERS)) self.add_line('EQ I0, 0, %s' % end) self.visit(node.body) self.add_line('BRANCH %s' % start) self.add_line("%s:" % end) def compile_expr (expr, dest_register, avail_registers): """compile_expr(expr:Node, dest_register:string, avail_registers:[string]) -> [string] Generate bytecode to evaluate the resulting expression. The result is left in the register named by 'dest_register'; 'avail_registers' is a list of unused registers. XXX This handles registers really stupidly, and always leaves its result in I0; it should allocate registers more efficiently. XXX how to handle string constants, or constants of other types? """ # Copy avail_registers, because we'll be mutating it later avail_registers = avail_registers[:] lines = [] # Ensure destination register isn't listed among available regs if dest_register in avail_registers: avail_registers.remove(dest_register) if isinstance(expr, ast.Const): assert type(expr.value) == types.IntType, "Only int type is supported" return ["set %s, %r" % (dest_register, expr.value)] elif isinstance(expr, ast.Name): reg = LOCAL_REGS[expr.name] temp = random.choice(FREE_REGISTERS) return ["set %s, 0" % temp, "add %s, %s, %s" % (dest_register, reg, temp)] elif (isinstance(expr, ast.Add) or isinstance(expr, ast.Sub) or isinstance(expr, ast.Mul) or isinstance(expr, ast.Div) or isinstance(expr, ast.Mod) ): dict = {ast.Add: "add", ast.Sub: "sub", ast.Mul: "mul", ast.Div: "div", ast.Mod: "mod"} opcode = dict[expr.__class__] temp1 = random.choice(avail_registers) avail_registers.remove(temp1) temp2 = random.choice(avail_registers) avail_registers.remove(temp2) lines = (compile_expr(expr.left, temp1, avail_registers) + compile_expr(expr.right, temp2, avail_registers) + # perform operation ["%s %s, %s, %s" % (opcode, dest_register, temp1, temp2)] ) elif isinstance(expr, ast.Compare): dict = {'<':'lt', '>':'gt', '==':'eq', '>=':'ge', '=>':'ge', '<=':'le', '=>':'le', '!=':'ne', '<>':'ne'} temp1 = random.choice(avail_registers) avail_registers.remove(temp1) temp2 = random.choice(avail_registers) avail_registers.remove(temp2) # XXX this code generation is doubtless wrong when there # are multiple comparison operators (as in 1<2<3). lines = compile_expr(expr.expr, temp1, avail_registers) for op, expr2 in expr.ops: lines += compile_expr(expr2, temp2, avail_registers) sym = 'true' + gensym() sym2 = 'done' + gensym() lines += ["%s %s, %s, %s" % (dict[op], temp1, temp2, sym), "set %s, 0" % dest_register, # False branch "eq %s, %s, %s" % (dest_register, dest_register, sym2), "%s:" % sym, "set %s, 1" % dest_register, # True branch "%s:" % sym2] else: raise RuntimeError, "Unexpected node in expression: %r" % expr return lines def generate_assembly (input_name, output_name): ast = transformer.parseFile(input_name) ## print ast # Determine locals and assign them to registers lnf = walk(ast, LocalNameFinder(), 0) for name in lnf.getLocals().elements(): reg = LOCAL_REGS[name] = random.choice(FREE_REGISTERS) FREE_REGISTERS.remove(reg) ## print LOCAL_REGS # Walk tree and generate bytecode vtor = visitor.ASTVisitor() pv = ParrotVisitor() vtor.preorder(ast, pv) # Write the generated assembly code lines = ["main:\n"] + pv.lines output = open(output_name, 'w') output.writelines(lines) output.close() def main(): opts, args = getopt.getopt(sys.argv[1:], 'hrS', ['help']) do_run = 0 do_assemble = 1 for opt, param in opts: if opt in ['-h', '--help']: print __doc__ % sys.argv[0] sys.exit(0) elif opt == '-r': do_run = 1 elif opt == '-S': do_assemble = 0 if len(args) != 1: print __doc__ % sys.argv[0] sys.exit(0) for filename in args: root, ext = os.path.splitext(filename) asm_filename = root + '.pasm' bytecode_filename = root + '.pdbc' generate_assembly(filename, asm_filename) if do_assemble: err = os.system('perl assemble.pl %s > %s' % (asm_filename, bytecode_filename) ) if err: sys.exit(err) if do_run: err = os.system('./test_prog %s' % bytecode_filename) if err: sys.exit(err) if __name__ == '__main__': main() From fdrake@users.sourceforge.net Wed Sep 26 22:00:35 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 14:00:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_profilehooks.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32382 Modified Files: test_profilehooks.py Log Message: More test cases, including something that simulates what the profiler probably *should* be doing. Index: test_profilehooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_profilehooks.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_profilehooks.py 2001/09/25 20:48:14 1.3 --- test_profilehooks.py 2001/09/26 21:00:33 1.4 *************** *** 35,46 **** ! class ProfileHookTestCase(unittest.TestCase): def check_events(self, callable, expected): ! events = capture_events(callable) if events != expected: self.fail("Expected events:\n%s\nReceived events:\n%s" % (pprint.pformat(expected), pprint.pformat(events))) def test_simple(self): def f(p): --- 35,80 ---- ! class ProfileSimulator(HookWatcher): ! def __init__(self): ! self.stack = [] ! HookWatcher.__init__(self) ! ! def callback(self, frame, event, arg): ! self.dispatch[event](self, frame) ! ! def trace_call(self, frame): ! self.add_event('call', frame) ! self.stack.append(frame) ! ! def trace_return(self, frame): ! self.add_event('return', frame) ! self.stack.pop() ! ! def trace_exception(self, frame): ! if len(self.stack) >= 2 and frame is self.stack[-2]: ! self.add_event('propogate-from', self.stack[-1]) ! self.stack.pop() ! else: ! self.add_event('ignore', frame) ! ! dispatch = { ! 'call': trace_call, ! 'exception': trace_exception, ! 'return': trace_return, ! } ! + class TestCaseBase(unittest.TestCase): def check_events(self, callable, expected): ! events = capture_events(callable, self.new_watcher()) if events != expected: self.fail("Expected events:\n%s\nReceived events:\n%s" % (pprint.pformat(expected), pprint.pformat(events))) + + class ProfileHookTestCase(TestCaseBase): + def new_watcher(self): + return HookWatcher() + def test_simple(self): def f(p): *************** *** 160,163 **** --- 194,219 ---- + class ProfileSimulatorTestCase(TestCaseBase): + def new_watcher(self): + return ProfileSimulator() + + def test_simple(self): + def f(p): + pass + f_ident = ident(f) + self.check_events(f, [(1, 'call', f_ident), + (1, 'return', f_ident), + ]) + + def test_basic_exception(self): + def f(p): + 1/0 + f_ident = ident(f) + self.check_events(f, [(1, 'call', f_ident), + (1, 'ignore', f_ident), + (1, 'propogate-from', f_ident), + ]) + + def ident(function): if hasattr(function, "f_code"): *************** *** 175,180 **** ! def capture_events(callable): ! p = HookWatcher() sys.setprofile(p.callback) protect(callable, p) --- 231,237 ---- ! def capture_events(callable, p=None): ! if p is None: ! p = HookWatcher() sys.setprofile(p.callback) protect(callable, p) *************** *** 189,193 **** def test_main(): ! test_support.run_unittest(ProfileHookTestCase) --- 246,254 ---- def test_main(): ! loader = unittest.TestLoader() ! suite = unittest.TestSuite() ! suite.addTest(loader.loadTestsFromTestCase(ProfileHookTestCase)) ! suite.addTest(loader.loadTestsFromTestCase(ProfileSimulatorTestCase)) ! test_support.run_suite(suite) From tim_one@users.sourceforge.net Wed Sep 26 22:31:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 26 Sep 2001 14:31:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10730/python/Lib Modified Files: pydoc.py Log Message: Display a class's method resolution order, if it's non-trivial. "Trivial" here means it has no more than one base class to rummage through (in which cases there's no potential confusion about resolution order). Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** pydoc.py 2001/09/25 06:30:51 1.50 --- pydoc.py 2001/09/26 21:31:51 1.51 *************** *** 625,628 **** --- 625,638 ---- hr = HorizontalRule() + # List the mro, if non-trivial. + mro = inspect.getmro(object) + if len(mro) > 2: + hr.maybe() + push('
    Method resolution order:
    \n') + for base in mro: + push('
    %s
    \n' % self.classlink(base, + object.__module__)) + push('
    \n') + def spill(msg, attrs, predicate): ok, attrs = _split_list(attrs, predicate) *************** *** 739,742 **** --- 749,753 ---- doc = self.markup(getdoc(object), self.preformat, funcs, classes, mdict) doc = doc and '%s
     
    ' % doc or ' ' + return self.section(title, '#000000', '#ffc8d8', contents, 5, doc) *************** *** 986,989 **** --- 997,1003 ---- bases = object.__bases__ + def makename(c, m=object.__module__): + return classname(c, m) + if name == realname: title = 'class ' + self.bold(realname) *************** *** 991,995 **** title = self.bold(name) + ' = class ' + realname if bases: - def makename(c, m=object.__module__): return classname(c, m) parents = map(makename, bases) title = title + '(%s)' % join(parents, ', ') --- 1005,1008 ---- *************** *** 998,1001 **** --- 1011,1022 ---- contents = doc and [doc + '\n'] or [] push = contents.append + + # List the mro, if non-trivial. + mro = inspect.getmro(object) + if len(mro) > 2: + push("Method resolution order:") + for base in mro: + push(' ' + makename(base)) + push('') # Cute little class to pump out a horizontal rule between sections. From bwarsaw@users.sourceforge.net Wed Sep 26 23:21:55 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Wed, 26 Sep 2001 15:21:55 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib email.tex,1.2,1.3 emailencoders.tex,1.1,1.2 emailexc.tex,1.1,1.2 emailgenerator.tex,1.1,1.2 emailiter.tex,1.1,1.2 emailmessage.tex,1.1,1.2 emailparser.tex,1.1,1.2 emailutil.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23832/Doc/lib Modified Files: email.tex emailencoders.tex emailexc.tex emailgenerator.tex emailiter.tex emailmessage.tex emailparser.tex emailutil.tex Log Message: Updates do email package documentation for markup, style, and organization. Index: email.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/email.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** email.tex 2001/09/26 16:52:18 1.2 --- email.tex 2001/09/26 22:21:52 1.3 *************** *** 15,20 **** including MIME and other \rfc{2822}-based message documents. It subsumes most of the functionality in several older standard modules ! such as \module{rfc822}, \module{mimetools}, \module{multifile}, and ! other non-standard packages such as \module{mimecntl}. The primary distinguishing feature of the \module{email} package is --- 15,21 ---- including MIME and other \rfc{2822}-based message documents. It subsumes most of the functionality in several older standard modules ! such as \refmodule{rfc822}, \refmodule{mimetools}, ! \refmodule{multifile}, and other non-standard packages such as ! \module{mimecntl}. The primary distinguishing feature of the \module{email} package is *************** *** 39,44 **** It is perfectly feasible to create the object model out of whole cloth ! -- i.e. completely from scratch. From there, a similar progression can ! be taken as above. Also included are detailed specifications of all the classes and --- 40,45 ---- It is perfectly feasible to create the object model out of whole cloth ! --- i.e. completely from scratch. From there, a similar progression ! can be taken as above. Also included are detailed specifications of all the classes and *************** *** 50,123 **** \subsection{Representing an email message} ! ! The primary object in the \module{email} package is the ! \class{Message} class, provided in the \refmodule{email.Message} ! module. \class{Message} is the base class for the \module{email} ! object model. It provides the core functionality for setting and ! querying header fields, and for accessing message bodies. ! ! Conceptually, a \class{Message} object consists of \emph{headers} and ! \emph{payloads}. Headers are \rfc{2822} style field name and ! values where the field name and value are separated by a colon. The ! colon is not part of either the field name or the field value. ! ! Headers are stored and returned in case-preserving form but are ! matched case-insensitively. There may also be a single ! \emph{Unix-From} header, also known as the envelope header or the ! \mailheader{From_} header. The payload is either a string in the case of ! simple message objects, a list of \class{Message} objects for ! multipart MIME documents, or a single \class{Message} instance for ! \mimetype{message/rfc822} type objects. ! ! \class{Message} objects provide a mapping style interface for ! accessing the message headers, and an explicit interface for accessing ! both the headers and the payload. It provides convenience methods for ! generating a flat text representation of the message object tree, for ! accessing commonly used header parameters, and for recursively walking ! over the object tree. \subsection{Parsing email messages} ! Message object trees can be created in one of two ways: they can be ! created from whole cloth by instantiating \class{Message} objects and ! stringing them together via \method{add_payload()} and ! \method{set_payload()} calls, or they can be created by parsing a flat text ! representation of the email message. ! ! The \module{email} package provides a standard parser that understands ! most email document structures, including MIME documents. You can ! pass the parser a string or a file object, and the parser will return ! to you the root \class{Message} instance of the object tree. For ! simple, non-MIME messages the payload of this root object will likely ! be a string (e.g. containing the text of the message). For MIME ! messages, the root object will return 1 from its ! \method{is_multipart()} method, and the subparts can be accessed via ! the \method{get_payload()} and \method{walk()} methods. ! ! Note that the parser can be extended in limited ways, and of course ! you can implement your own parser completely from scratch. There is ! no magical connection between the \module{email} package's bundled ! parser and the ! \class{Message} class, so your custom parser can create message object ! trees in any way it find necessary. The \module{email} package's ! parser is described in detail in the \refmodule{email.Parser} module ! documentation. \subsection{Generating MIME documents} ! One of the most common tasks is to generate the flat text of the email ! message represented by a message object tree. You will need to do ! this if you want to send your message via the \refmodule{smtplib} ! module or the \refmodule{nntplib} module, or print the message on the ! console. Taking a message object tree and producing a flat text ! document is the job of the \refmodule{email.Generator} module. ! ! Again, as with the \refmodule{email.Parser} module, you aren't limited ! to the functionality of the bundled generator; you could write one ! from scratch yourself. However the bundled generator knows how to ! generate most email in a standards-compliant way, should handle MIME ! and non-MIME email messages just fine, and is designed so that the ! transformation from flat text, to an object tree via the ! \class{Parser} class, ! and back to flat text, be idempotent (the input is identical to the ! output). \subsection{Creating email and MIME objects from scratch} --- 51,61 ---- \subsection{Representing an email message} ! \input{emailmessage} \subsection{Parsing email messages} ! \input{emailparser} \subsection{Generating MIME documents} ! \input{emailgenerator} \subsection{Creating email and MIME objects from scratch} *************** *** 157,163 **** subclasses. ! \var{_maintype} is the \code{Content-Type:} major type (e.g. \code{text} or ! \code{image}), and \var{_subtype} is the \code{Content-Type:} minor type ! (e.g. \code{plain} or \code{gif}). \var{_params} is a parameter key/value dictionary and is passed directly to \method{Message.add_header()}. --- 95,102 ---- subclasses. ! \var{_maintype} is the \mailheader{Content-Type} major type ! (e.g. \mimetype{text} or \mimetype{image}), and \var{_subtype} is the ! \mailheader{Content-Type} minor type ! (e.g. \mimetype{plain} or \mimetype{gif}). \var{_params} is a parameter key/value dictionary and is passed directly to \method{Message.add_header()}. *************** *** 196,203 **** \begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{, _charset\optional{, _encoder}}}} A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to ! create MIME objects of major type \mimetype{text}. \var{_text} is the string ! for the payload. \var{_subtype} is the minor type and defaults to ! \mimetype{plain}. \var{_charset} is the character set of the text and is passed as a parameter to the \class{MIMEBase} constructor; it defaults to \code{us-ascii}. No guessing or encoding is performed on the text --- 135,143 ---- \begin{classdesc}{MIMEText}{_text\optional{, _subtype\optional{, _charset\optional{, _encoder}}}} + A subclass of \class{MIMEBase}, the \class{MIMEText} class is used to ! create MIME objects of major type \mimetype{text}. \var{_text} is the ! string for the payload. \var{_subtype} is the minor type and defaults ! to \mimetype{plain}. \var{_charset} is the character set of the text and is passed as a parameter to the \class{MIMEBase} constructor; it defaults to \code{us-ascii}. No guessing or encoding is performed on the text *************** *** 221,246 **** to \mimetype{rfc822}. \end{classdesc} - - \subsection{Encoders, Exceptions, Utilities, and Iterators} ! The \module{email} package provides various encoders for safe ! transport of binary payloads in \class{MIMEImage} and \class{MIMEText} ! instances. See the \refmodule{email.Encoders} module for more ! details. ! All of the class exceptions that the \module{email} package can raise ! are available in the \refmodule{email.Errors} module. ! Some miscellaneous utility functions are available in the ! \refmodule{email.Utils} module. ! Iterating over a message object tree is easy with the ! \method{Message.walk()} method; some additional helper iterators are ! available in the \refmodule{email.Iterators} module. \subsection{Differences from \module{mimelib}} The \module{email} package was originally prototyped as a separate ! library called \module{mimelib}. Changes have been made so that method names are more consistent, and some methods or modules have either been added or removed. The semantics of some of the methods --- 161,183 ---- to \mimetype{rfc822}. \end{classdesc} ! \subsection{Encoders} ! \input{emailencoders} ! \subsection{Exception classes} ! \input{emailexc} ! \subsection{Miscellaneous utilities} ! \input{emailutil} ! \subsection{Iterators} ! \input{emailiter} \subsection{Differences from \module{mimelib}} The \module{email} package was originally prototyped as a separate ! library called ! \ulink{\module{mimelib}}{http://mimelib.sf.net/}. ! Changes have been made so that method names are more consistent, and some methods or modules have either been added or removed. The semantics of some of the methods *************** *** 283,287 **** Also, whereas \method{getparams()} returned a list of strings, \method{get_params()} returns a list of 2-tuples, effectively ! the key/value pairs of the parameters, split on the \samp{=} sign. \item The method \method{getparam()} was renamed to \method{get_param()}. --- 220,224 ---- Also, whereas \method{getparams()} returned a list of strings, \method{get_params()} returns a list of 2-tuples, effectively ! the key/value pairs of the parameters, split on the \character{=} sign. \item The method \method{getparam()} was renamed to \method{get_param()}. *************** *** 356,358 **** Coming soon... - --- 293,294 ---- Index: emailencoders.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailencoders.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailencoders.tex 2001/09/26 05:23:47 1.1 --- emailencoders.tex 2001/09/26 22:21:52 1.2 *************** *** 1,15 **** - \section{\module{email.Encoders} --- - Email message payload encoders} - \declaremodule{standard}{email.Encoders} \modulesynopsis{Encoders for email message payloads.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} - \versionadded{2.2} - When creating \class{Message} objects from scratch, you often need to encode the payloads for transport through compliant mail servers. ! This is especially true for \code{image/*} and \code{text/*} type ! messages containing binary data. The \module{email} package provides some convenient encodings in its --- 1,9 ---- \declaremodule{standard}{email.Encoders} \modulesynopsis{Encoders for email message payloads.} When creating \class{Message} objects from scratch, you often need to encode the payloads for transport through compliant mail servers. ! This is especially true for \mimetype{image/*} and \mimetype{text/*} ! type messages containing binary data. The \module{email} package provides some convenient encodings in its *************** *** 19,23 **** message object to encode. They usually extract the payload, encode it, and reset the payload to this newly encoded value. They should also ! set the \code{Content-Transfer-Encoding:} header as appropriate. Here are the encoding functions provided: --- 13,17 ---- message object to encode. They usually extract the payload, encode it, and reset the payload to this newly encoded value. They should also ! set the \mailheader{Content-Transfer-Encoding} header as appropriate. Here are the encoding functions provided: *************** *** 35,39 **** \begin{funcdesc}{encode_base64}{msg} Encodes the payload into \emph{Base64} form and sets the ! \code{Content-Transfer-Encoding:} header to \code{base64}. This is a good encoding to use when most of your payload is unprintable data since it is a more compact form than --- 29,33 ---- \begin{funcdesc}{encode_base64}{msg} Encodes the payload into \emph{Base64} form and sets the ! \mailheader{Content-Transfer-Encoding} header to \code{base64}. This is a good encoding to use when most of your payload is unprintable data since it is a more compact form than *************** *** 44,48 **** \begin{funcdesc}{encode_7or8bit}{msg} This doesn't actually modify the message's payload, but it does set ! the \code{Content-Transfer-Encoding:} header to either \code{7bit} or \code{8bit} as appropriate, based on the payload data. \end{funcdesc} --- 38,42 ---- \begin{funcdesc}{encode_7or8bit}{msg} This doesn't actually modify the message's payload, but it does set ! the \mailheader{Content-Transfer-Encoding} header to either \code{7bit} or \code{8bit} as appropriate, based on the payload data. \end{funcdesc} *************** *** 50,53 **** \begin{funcdesc}{encode_noop}{msg} This does nothing; it doesn't even set the ! \code{Content-Transfer-Encoding:} header. \end{funcdesc} --- 44,47 ---- \begin{funcdesc}{encode_noop}{msg} This does nothing; it doesn't even set the ! \mailheader{Content-Transfer-Encoding} header. \end{funcdesc} Index: emailexc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailexc.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailexc.tex 2001/09/26 05:23:47 1.1 --- emailexc.tex 2001/09/26 22:21:52 1.2 *************** *** 1,10 **** ! \section{\module{email.Errors} --- ! email package exception classes} ! ! \declaremodule{standard}{email.Exceptions} \modulesynopsis{The exception classes used by the email package.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} - - \versionadded{2.2} The following exception classes are defined in the --- 1,4 ---- ! \declaremodule{standard}{email.Errors} \modulesynopsis{The exception classes used by the email package.} The following exception classes are defined in the *************** *** 42,46 **** Situations where it can be raised include not being able to find the ! starting or terminating boundary in a \code{multipart/*} message. \end{excclassdesc} --- 36,40 ---- Situations where it can be raised include not being able to find the ! starting or terminating boundary in a \mimetype{multipart/*} message. \end{excclassdesc} *************** *** 48,53 **** Raised when a payload is added to a \class{Message} object using \method{add_payload()}, but the payload is already a scalar and the ! message's \code{Content-Type:} main type is not either \code{multipart} ! or missing. \exception{MultipartConversionError} multiply inherits ! from \exception{MessageError} and the built-in \exception{TypeError}. \end{excclassdesc} --- 42,48 ---- Raised when a payload is added to a \class{Message} object using \method{add_payload()}, but the payload is already a scalar and the ! message's \mailheader{Content-Type} main type is not either ! \mimetype{multipart} or missing. \exception{MultipartConversionError} ! multiply inherits from \exception{MessageError} and the built-in ! \exception{TypeError}. \end{excclassdesc} Index: emailgenerator.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailgenerator.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailgenerator.tex 2001/09/26 05:23:47 1.1 --- emailgenerator.tex 2001/09/26 22:21:52 1.2 *************** *** 1,16 **** - \section{\module{email.Generator} --- - Generating flat text from an email message object tree} - \declaremodule{standard}{email.Generator} ! \modulesynopsis{Generate flat text email messages to from a message ! object tree.} ! \sectionauthor{Barry A. Warsaw}{barry@zope.com} ! \versionadded{2.2} ! The \class{Generator} class is used to render a message object model ! into its flat text representation, including MIME encoding any ! sub-messages, generating the correct \rfc{2822} headers, etc. Here ! are the public methods of the \class{Generator} class. \begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{, --- 1,23 ---- \declaremodule{standard}{email.Generator} ! \modulesynopsis{Generate flat text email messages from a message object tree.} ! One of the most common tasks is to generate the flat text of the email ! message represented by a message object tree. You will need to do ! this if you want to send your message via the \refmodule{smtplib} ! module or the \refmodule{nntplib} module, or print the message on the ! console. Taking a message object tree and producing a flat text ! document is the job of the \class{Generator} class. ! Again, as with the \refmodule{email.Parser} module, you aren't limited ! to the functionality of the bundled generator; you could write one ! from scratch yourself. However the bundled generator knows how to ! generate most email in a standards-compliant way, should handle MIME ! and non-MIME email messages just fine, and is designed so that the ! transformation from flat text, to an object tree via the ! \class{Parser} class, ! and back to flat text, be idempotent (the input is identical to the ! output). ! ! Here are the public methods of the \class{Generator} class: \begin{classdesc}{Generator}{outfp\optional{, mangle_from_\optional{, *************** *** 26,31 **** line). This is the only guaranteed portable way to avoid having such lines be mistaken for \emph{Unix-From} headers (see ! \url{http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} ! for details). Optional \var{maxheaderlen} specifies the longest length for a --- 33,39 ---- line). This is the only guaranteed portable way to avoid having such lines be mistaken for \emph{Unix-From} headers (see ! \ulink{WHY THE CONTENT-LENGTH FORMAT IS BAD} ! {http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html} ! for details). Optional \var{maxheaderlen} specifies the longest length for a Index: emailiter.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailiter.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailiter.tex 2001/09/26 05:23:47 1.1 --- emailiter.tex 2001/09/26 22:21:52 1.2 *************** *** 1,10 **** - \section{\module{email.Iterators} --- - Message object tree iterators} - \declaremodule{standard}{email.Iterators} \modulesynopsis{Iterate over a message object tree.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} - - \versionadded{2.2} Iterating over a message object tree is fairly easy with the --- 1,4 ---- *************** *** 30,37 **** Note that \var{subtype} is optional; if omitted, then subpart MIME type matching is done only with the main type. \var{maintype} is ! optional too; it defaults to \code{text}. Thus, by default \function{typed_subpart_iterator()} returns each ! subpart that has a MIME type of \code{text/*}. \end{funcdesc} --- 24,31 ---- Note that \var{subtype} is optional; if omitted, then subpart MIME type matching is done only with the main type. \var{maintype} is ! optional too; it defaults to \mimetype{text}. Thus, by default \function{typed_subpart_iterator()} returns each ! subpart that has a MIME type of \mimetype{text/*}. \end{funcdesc} Index: emailmessage.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailmessage.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailmessage.tex 2001/09/26 05:23:47 1.1 --- emailmessage.tex 2001/09/26 22:21:52 1.2 *************** *** 1,29 **** - \section{\module{email.Message} --- - The Message class} - \declaremodule{standard}{email.Message} \modulesynopsis{The base class representing email messages.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} ! \versionadded{2.2} ! The \module{Message} module provides a single class, the ! \class{Message} class. This class is the base class for the ! \module{email} package object model. It has a fairly extensive set of ! methods to get and set email headers and email payloads. For an ! introduction of the \module{email} package, please read the ! \refmodule{email} package overview. ! \class{Message} instances can be created either directly, or ! indirectly by using a \refmodule{email.Parser}. \class{Message} ! objects provide a mapping style interface for accessing the message ! headers, and an explicit interface for accessing both the headers and ! the payload. It provides convenience methods for generating a flat ! text representation of the message object tree, for accessing commonly ! used header parameters, and for recursively walking over the object ! tree. Here are the methods of the \class{Message} class: \begin{methoddesc}[Message]{as_string}{\optional{unixfrom}} Return the entire formatted message as a string. Optional --- 1,36 ---- \declaremodule{standard}{email.Message} \modulesynopsis{The base class representing email messages.} ! The central class in the \module{email} package is the ! \class{Message} class; it is the base class for the \module{email} ! object model. \class{Message} provides the core functionality for ! setting and querying header fields, and for accessing message bodies. ! Conceptually, a \class{Message} object consists of \emph{headers} and ! \emph{payloads}. Headers are \rfc{2822} style field names and ! values where the field name and value are separated by a colon. The ! colon is not part of either the field name or the field value. ! Headers are stored and returned in case-preserving form but are ! matched case-insensitively. There may also be a single ! \emph{Unix-From} header, also known as the envelope header or the ! \code{From_} header. The payload is either a string in the case of ! simple message objects, a list of \class{Message} objects for ! multipart MIME documents, or a single \class{Message} instance for ! \mimetype{message/rfc822} type objects. ! ! \class{Message} objects provide a mapping style interface for ! accessing the message headers, and an explicit interface for accessing ! both the headers and the payload. It provides convenience methods for ! generating a flat text representation of the message object tree, for ! accessing commonly used header parameters, and for recursively walking ! over the object tree. Here are the methods of the \class{Message} class: + \begin{classdesc}{Message}{} + The constructor takes no arguments. + \end{classdesc} + \begin{methoddesc}[Message]{as_string}{\optional{unixfrom}} Return the entire formatted message as a string. Optional *************** *** 67,72 **** and \var{payload}, but only if the document is already a MIME multipart document. This condition is satisfied if the message's ! \code{Content-Type:} header's main type is either \var{multipart}, or ! there is no \code{Content-Type:} header. In any other situation, \exception{MultipartConversionError} is raised. \end{methoddesc} --- 74,80 ---- and \var{payload}, but only if the document is already a MIME multipart document. This condition is satisfied if the message's ! \mailheader{Content-Type} header's main type is either ! \mimetype{multipart}, or there is no \mailheader{Content-Type} ! header. In any other situation, \exception{MultipartConversionError} is raised. \end{methoddesc} *************** *** 84,99 **** With optional \var{i}, \method{get_payload()} will return the \var{i}-th element of the payload, counting from zero, if ! \method{is_multipart()} returns 1. An \code{IndexError} will be raised if \var{i} is less than 0 or greater than or equal to the number of items in the payload. If the payload is scalar (i.e. \method{is_multipart()} returns 0) and \var{i} is given, a ! \code{TypeError} is raised. Optional \var{decode} is a flag indicating whether the payload should be ! decoded or not, according to the \code{Content-Transfer-Encoding:} header. When true and the message is not a multipart, the payload will be decoded if this header's value is \samp{quoted-printable} or \samp{base64}. If some other encoding is used, or ! \code{Content-Transfer-Encoding:} header is missing, the payload is returned as-is (undecoded). If the message is a multipart and the \var{decode} flag is true, then \code{None} is --- 92,107 ---- With optional \var{i}, \method{get_payload()} will return the \var{i}-th element of the payload, counting from zero, if ! \method{is_multipart()} returns 1. An \exception{IndexError} will be raised if \var{i} is less than 0 or greater than or equal to the number of items in the payload. If the payload is scalar (i.e. \method{is_multipart()} returns 0) and \var{i} is given, a ! \exception{TypeError} is raised. Optional \var{decode} is a flag indicating whether the payload should be ! decoded or not, according to the \mailheader{Content-Transfer-Encoding} header. When true and the message is not a multipart, the payload will be decoded if this header's value is \samp{quoted-printable} or \samp{base64}. If some other encoding is used, or ! \mailheader{Content-Transfer-Encoding} header is missing, the payload is returned as-is (undecoded). If the message is a multipart and the \var{decode} flag is true, then \code{None} is *************** *** 138,142 **** Return the value of the named header field. \var{name} should not include the colon field separator. If the header is missing, ! \code{None} is returned; a \code{KeyError} is never raised. Note that if the named field appears more than once in the message's --- 146,150 ---- Return the value of the named header field. \var{name} should not include the colon field separator. If the header is missing, ! \code{None} is returned; a \exception{KeyError} is never raised. Note that if the named field appears more than once in the message's *************** *** 244,251 **** \begin{methoddesc}[Message]{get_type}{\optional{failobj}} Return the message's content type, as a string of the form ! ``maintype/subtype'' as taken from the \code{Content-Type:} header. The returned string is coerced to lowercase. ! If there is no \code{Content-Type:} header in the message, \var{failobj} is returned (defaults to \code{None}). \end{methoddesc} --- 252,260 ---- \begin{methoddesc}[Message]{get_type}{\optional{failobj}} Return the message's content type, as a string of the form ! \mimetype{maintype/subtype} as taken from the ! \mailheader{Content-Type} header. The returned string is coerced to lowercase. ! If there is no \mailheader{Content-Type} header in the message, \var{failobj} is returned (defaults to \code{None}). \end{methoddesc} *************** *** 264,301 **** \begin{methoddesc}[Message]{get_params}{\optional{failobj\optional{, header}}} ! Return the message's \code{Content-Type:} parameters, as a list. The elements of the returned list are 2-tuples of key/value pairs, as ! split on the \samp{=} sign. The left hand side of the \samp{=} is the ! key, while the right hand side is the value. If there is no \samp{=} ! sign in the parameter the value is the empty string. The value is ! always unquoted with \method{Utils.unquote()}. Optional \var{failobj} is the object to return if there is no ! \code{Content-Type:} header. Optional \var{header} is the header to ! search instead of \code{Content-Type:}. \end{methoddesc} \begin{methoddesc}[Message]{get_param}{param\optional{, failobj\optional{, header}}} ! Return the value of the \code{Content-Type:} header's parameter ! \var{param} as a string. If the message has no \code{Content-Type:} header or if there is no such parameter, then \var{failobj} is returned (defaults to \code{None}). Optional \var{header} if given, specifies the message header to use ! instead of \code{Content-Type:}. \end{methoddesc} \begin{methoddesc}[Message]{get_charsets}{\optional{failobj}} Return a list containing the character set names in the message. If ! the message is a \code{multipart}, then the list will contain one element for each subpart in the payload, otherwise, it will be a list of length 1. Each item in the list will be a string which is the value of the ! \code{charset} parameter in the \code{Content-Type:} header for the represented subpart. However, if the subpart has no ! \code{Content-Type:} header, no \code{charset} parameter, or is not of ! the \code{text} main MIME type, then that item in the returned list will be \var{failobj}. \end{methoddesc} --- 273,310 ---- \begin{methoddesc}[Message]{get_params}{\optional{failobj\optional{, header}}} ! Return the message's \mailheader{Content-Type} parameters, as a list. The elements of the returned list are 2-tuples of key/value pairs, as ! split on the \character{=} sign. The left hand side of the ! \character{=} is the key, while the right hand side is the value. If ! there is no \character{=} sign in the parameter the value is the empty ! string. The value is always unquoted with \method{Utils.unquote()}. Optional \var{failobj} is the object to return if there is no ! \mailheader{Content-Type} header. Optional \var{header} is the header to ! search instead of \mailheader{Content-Type}. \end{methoddesc} \begin{methoddesc}[Message]{get_param}{param\optional{, failobj\optional{, header}}} ! Return the value of the \mailheader{Content-Type} header's parameter ! \var{param} as a string. If the message has no \mailheader{Content-Type} header or if there is no such parameter, then \var{failobj} is returned (defaults to \code{None}). Optional \var{header} if given, specifies the message header to use ! instead of \mailheader{Content-Type}. \end{methoddesc} \begin{methoddesc}[Message]{get_charsets}{\optional{failobj}} Return a list containing the character set names in the message. If ! the message is a \mimetype{multipart}, then the list will contain one element for each subpart in the payload, otherwise, it will be a list of length 1. Each item in the list will be a string which is the value of the ! \code{charset} parameter in the \mailheader{Content-Type} header for the represented subpart. However, if the subpart has no ! \mailheader{Content-Type} header, no \code{charset} parameter, or is not of ! the \mimetype{text} main MIME type, then that item in the returned list will be \var{failobj}. \end{methoddesc} *************** *** 303,307 **** \begin{methoddesc}[Message]{get_filename}{\optional{failobj}} Return the value of the \code{filename} parameter of the ! \code{Content-Disposition:} header of the message, or \var{failobj} if either the header is missing, or has no \code{filename} parameter. The returned string will always be unquoted as per --- 312,316 ---- \begin{methoddesc}[Message]{get_filename}{\optional{failobj}} Return the value of the \code{filename} parameter of the ! \mailheader{Content-Disposition} header of the message, or \var{failobj} if either the header is missing, or has no \code{filename} parameter. The returned string will always be unquoted as per *************** *** 311,315 **** \begin{methoddesc}[Message]{get_boundary}{\optional{failobj}} Return the value of the \code{boundary} parameter of the ! \code{Content-Type:} header of the message, or \var{failobj} if either the header is missing, or has no \code{boundary} parameter. The returned string will always be unquoted as per --- 320,324 ---- \begin{methoddesc}[Message]{get_boundary}{\optional{failobj}} Return the value of the \code{boundary} parameter of the ! \mailheader{Content-Type} header of the message, or \var{failobj} if either the header is missing, or has no \code{boundary} parameter. The returned string will always be unquoted as per *************** *** 318,333 **** \begin{methoddesc}[Message]{set_boundary}{boundary} ! Set the \code{boundary} parameter of the \code{Content-Type:} header to \var{boundary}. \method{set_boundary()} will always quote \var{boundary} so you should not quote it yourself. A ! \code{HeaderParseError} is raised if the message object has no ! \code{Content-Type:} header. Note that using this method is subtly different than deleting the old ! \code{Content-Type:} header and adding a new one with the new boundary via \method{add_header()}, because \method{set_boundary()} preserves the ! order of the \code{Content-Type:} header in the list of headers. However, it does \emph{not} preserve any continuation lines which may ! have been present in the original \code{Content-Type:} header. \end{methoddesc} --- 327,342 ---- \begin{methoddesc}[Message]{set_boundary}{boundary} ! Set the \code{boundary} parameter of the \mailheader{Content-Type} header to \var{boundary}. \method{set_boundary()} will always quote \var{boundary} so you should not quote it yourself. A ! \exception{HeaderParseError} is raised if the message object has no ! \mailheader{Content-Type} header. Note that using this method is subtly different than deleting the old ! \mailheader{Content-Type} header and adding a new one with the new boundary via \method{add_header()}, because \method{set_boundary()} preserves the ! order of the \mailheader{Content-Type} header in the list of headers. However, it does \emph{not} preserve any continuation lines which may ! have been present in the original \mailheader{Content-Type} header. \end{methoddesc} Index: emailparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailparser.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailparser.tex 2001/09/26 05:23:47 1.1 --- emailparser.tex 2001/09/26 22:21:52 1.2 *************** *** 1,23 **** - \section{\module{email.Parser} --- - Parsing flat text email messages} - \declaremodule{standard}{email.Parser} \modulesynopsis{Parse flat text email messages to produce a message object tree.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} ! \versionadded{2.2} ! The \module{Parser} module provides a single class, the \class{Parser} ! class, which is used to take a message in flat text form and create ! the associated object model. The resulting object tree can then be ! manipulated using the \class{Message} class interface as described in ! \refmodule{email.Message}, and turned over ! to a generator (as described in \refmodule{emamil.Generator}) to ! return the textual representation of the message. It is intended that ! the \class{Parser} to \class{Generator} path be idempotent if the ! object model isn't modified in between. ! \subsection{Parser class API} \begin{classdesc}{Parser}{\optional{_class}} --- 1,29 ---- \declaremodule{standard}{email.Parser} \modulesynopsis{Parse flat text email messages to produce a message object tree.} ! Message object trees can be created in one of two ways: they can be ! created from whole cloth by instantiating \class{Message} objects and ! stringing them together via \method{add_payload()} and ! \method{set_payload()} calls, or they can be created by parsing a flat text ! representation of the email message. ! The \module{email} package provides a standard parser that understands ! most email document structures, including MIME documents. You can ! pass the parser a string or a file object, and the parser will return ! to you the root \class{Message} instance of the object tree. For ! simple, non-MIME messages the payload of this root object will likely ! be a string (e.g. containing the text of the message). For MIME ! messages, the root object will return 1 from its ! \method{is_multipart()} method, and the subparts can be accessed via ! the \method{get_payload()} and \method{walk()} methods. ! Note that the parser can be extended in limited ways, and of course ! you can implement your own parser completely from scratch. There is ! no magical connection between the \module{email} package's bundled ! parser and the \class{Message} class, so your custom parser can create ! message object trees in any way it find necessary. ! ! \subsubsection{Parser class API} \begin{classdesc}{Parser}{\optional{_class}} *************** *** 76,95 **** \end{verbatim} ! \subsection{Additional notes} Here are some notes on the parsing semantics: \begin{itemize} ! \item Most non-\code{multipart} type messages are parsed as a single message object with a string payload. These objects will return 0 for \method{is_multipart()}. ! \item One exception is for \code{message/delivery-status} type ! messages. Because such the body of such messages consist of blocks of headers, \class{Parser} will create a non-multipart object containing non-multipart subobjects for each header block. ! \item Another exception is for \code{message/*} types (i.e. more ! general than \code{message/delivery-status}. These are ! typically \code{message/rfc822} type messages, represented as a non-multipart object containing a singleton payload, another non-multipart \class{Message} instance. --- 82,101 ---- \end{verbatim} ! \subsubsection{Additional notes} Here are some notes on the parsing semantics: \begin{itemize} ! \item Most non-\mimetype{multipart} type messages are parsed as a single message object with a string payload. These objects will return 0 for \method{is_multipart()}. ! \item One exception is for \mimetype{message/delivery-status} type ! messages. Because the body of such messages consist of blocks of headers, \class{Parser} will create a non-multipart object containing non-multipart subobjects for each header block. ! \item Another exception is for \mimetype{message/*} types (i.e. more ! general than \mimetype{message/delivery-status}). These are ! typically \mimetype{message/rfc822} type messages, represented as a non-multipart object containing a singleton payload, another non-multipart \class{Message} instance. Index: emailutil.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/emailutil.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** emailutil.tex 2001/09/26 05:23:47 1.1 --- emailutil.tex 2001/09/26 22:21:52 1.2 *************** *** 1,11 **** - \section{\module{email.Utils} --- - Miscellaneous email package utilities} - \declaremodule{standard}{email.Utils} \modulesynopsis{Miscellaneous email package utilities.} - \sectionauthor{Barry A. Warsaw}{barry@zope.com} - \versionadded{2.2} - There are several useful utilities provided with the \module{email} package. --- 1,5 ---- *************** *** 25,30 **** \begin{funcdesc}{parseaddr}{address} Parse address -- which should be the value of some address-containing ! field such as \code{To:} or \code{Cc:} -- into its constituent ! ``realname'' and ``email address'' parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of \code{(None, None)} is returned. --- 19,24 ---- \begin{funcdesc}{parseaddr}{address} Parse address -- which should be the value of some address-containing ! field such as \mailheader{To} or \mailheader{Cc} -- into its constituent ! \emph{realname} and \emph{email address} parts. Returns a tuple of that information, unless the parse fails, in which case a 2-tuple of \code{(None, None)} is returned. *************** *** 34,38 **** The inverse of \method{parseaddr()}, this takes a 2-tuple of the form \code{(realname, email_address)} and returns the string value suitable ! for a \code{To:} or \code{Cc:} header. If the first element of \var{pair} is false, then the second element is returned unmodified. \end{funcdesc} --- 28,32 ---- The inverse of \method{parseaddr()}, this takes a 2-tuple of the form \code{(realname, email_address)} and returns the string value suitable ! for a \mailheader{To} or \mailheader{Cc} header. If the first element of \var{pair} is false, then the second element is returned unmodified. \end{funcdesc} *************** *** 69,75 **** \var{charset} is \samp{iso-8859-1}. ! \var{encoding} must be either the letter \samp{q} for ! Quoted-Printable or \samp{b} for Base64 encoding. If ! neither, a \code{ValueError} is raised. Both the \var{charset} and the \var{encoding} strings are case-insensitive, and coerced to lower case in the returned string. --- 63,69 ---- \var{charset} is \samp{iso-8859-1}. ! \var{encoding} must be either the letter \character{q} for ! Quoted-Printable or \character{b} for Base64 encoding. If ! neither, a \exception{ValueError} is raised. Both the \var{charset} and the \var{encoding} strings are case-insensitive, and coerced to lower case in the returned string. From fdrake@users.sourceforge.net Wed Sep 26 23:26:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 15:26:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext newtypes.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv24946/ext Modified Files: newtypes.tex Log Message: Remove comment that no longer applies. Index: newtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/newtypes.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** newtypes.tex 2001/08/29 01:41:58 1.2 --- newtypes.tex 2001/09/26 22:26:45 1.3 *************** *** 786,790 **** } \end{verbatim} - - %For a reasonably extensive example, from which most of the snippits - %above were taken, see \file{newdatatype.c} and \file{newdatatype.h}. --- 786,787 ---- From tim_one@users.sourceforge.net Wed Sep 26 23:39:24 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 26 Sep 2001 15:39:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27561/python/Lib Modified Files: pydoc.py Log Message: Removed no-longer-true comment about pydoc working under all versions of Python since 1.5 (virtually everything I changed over the last week relies on "modern" features, particularly nested scopes). Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** pydoc.py 2001/09/26 21:31:51 1.51 --- pydoc.py 2001/09/26 22:39:22 1.52 *************** *** 36,43 **** Mynd you, møøse bites Kan be pretty nasti...""" - # Note: this module is designed to deploy instantly and run under any - # version of Python from 1.5 and up. That's why it's a single file and - # some 2.0 features (like string methods) are conspicuously absent. - # Known bugs that can't be fixed here: # - imp.load_module() cannot be prevented from clobbering existing --- 36,39 ---- From tim_one@users.sourceforge.net Thu Sep 27 04:29:53 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 26 Sep 2001 20:29:53 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv23454/python/Lib Modified Files: pydoc.py Log Message: List class attrs in MRO order of defining class instead of by alphabetic order of defining class's name. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -d -r1.52 -r1.53 *** pydoc.py 2001/09/26 22:39:22 1.52 --- pydoc.py 2001/09/27 03:29:51 1.53 *************** *** 622,626 **** # List the mro, if non-trivial. ! mro = inspect.getmro(object) if len(mro) > 2: hr.maybe() --- 622,626 ---- # List the mro, if non-trivial. ! mro = list(inspect.getmro(object)) if len(mro) > 2: hr.maybe() *************** *** 694,702 **** pass - # Sort attrs by name of defining class. - attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) - - thisclass = object # list attrs defined here first while attrs: attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) --- 694,702 ---- pass while attrs: + if mro: + thisclass = mro.pop(0) + else: + thisclass = attrs[0][2] attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) *************** *** 723,732 **** lambda t: t[1] == 'data') assert attrs == [] ! ! # Split off the attributes inherited from the next class (note ! # that inherited remains sorted by class name). ! if inherited: ! attrs = inherited ! thisclass = attrs[0][2] contents = ''.join(contents) --- 723,727 ---- lambda t: t[1] == 'data') assert attrs == [] ! attrs = inherited contents = ''.join(contents) *************** *** 1009,1013 **** # List the mro, if non-trivial. ! mro = inspect.getmro(object) if len(mro) > 2: push("Method resolution order:") --- 1004,1008 ---- # List the mro, if non-trivial. ! mro = list(inspect.getmro(object)) if len(mro) > 2: push("Method resolution order:") *************** *** 1073,1082 **** attrs = inspect.classify_class_attrs(object) - - # Sort attrs by name of defining class. - attrs.sort(lambda t1, t2: cmp(t1[2].__name__, t2[2].__name__)) - - thisclass = object # list attrs defined here first while attrs: attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) --- 1068,1076 ---- attrs = inspect.classify_class_attrs(object) while attrs: + if mro: + thisclass = mro.pop(0) + else: + thisclass = attrs[0][2] attrs, inherited = _split_list(attrs, lambda t: t[2] is thisclass) *************** *** 1102,1111 **** attrs, lambda t: t[1] == 'data') assert attrs == [] ! ! # Split off the attributes inherited from the next class (note ! # that inherited remains sorted by class name). ! if inherited: ! attrs = inherited ! thisclass = attrs[0][2] contents = '\n'.join(contents) --- 1096,1100 ---- attrs, lambda t: t[1] == 'data') assert attrs == [] ! attrs = inherited contents = '\n'.join(contents) From tim_one@users.sourceforge.net Thu Sep 27 05:08:18 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Wed, 26 Sep 2001 21:08:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib pydoc.py,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28135/python/Lib Modified Files: pydoc.py Log Message: docroutine() (both instances): Docstrings for class methods weren't getting displayed, due to a special case here whose purpose I didn't understand. So just disabled the doc suppression here. Another special case here skips the docs when picking apart a method and finding that the im_func is also in the class __dict__ under the same name. That one I understood. It has a curious consequence, though, wrt inherited properties: a static class copies inherited stuff into the inheriting class's dict, and that affects whether or not this special case triggers. The upshoot is that pydoc doesn't show the function docstrings of getter/setter/deleter functions of inherited properties in the property section when the class is static, but does when the class is dynamic (bring up Lib/test/pydocfodder.py under GUI pydoc to see this). Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pydoc.py,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** pydoc.py 2001/09/27 03:29:51 1.53 --- pydoc.py 2001/09/27 04:08:16 1.54 *************** *** 760,764 **** if imclass is not cl: note = ' from ' + self.classlink(imclass, mod) - skipdocs = 1 else: if object.im_self: --- 760,763 ---- *************** *** 1118,1122 **** if imclass is not cl: note = ' from ' + classname(imclass, mod) - skipdocs = 1 else: if object.im_self: --- 1117,1120 ---- From fdrake@users.sourceforge.net Thu Sep 27 05:16:29 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 21:16:29 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib liblocale.tex,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv31989 Modified Files: liblocale.tex Log Message: Markup adjustment: \[...\] is math markup and does not translate well when used with text as was done here. Fixed so that the typeset version wraps the warning text and the HTML version does not create images of the warning text. Index: liblocale.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/liblocale.tex,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** liblocale.tex 2001/08/10 13:58:50 1.25 --- liblocale.tex 2001/09/27 04:16:27 1.26 *************** *** 299,305 **** \begin{datadesc}{DAY_1 ... DAY_7} ! Return name of the n-th day of the week. \[Warning: this follows the US ! convention DAY_1 = Sunday, not the international convention (ISO 8601) ! that Monday is the first day of the week.\] \end{datadesc} --- 299,306 ---- \begin{datadesc}{DAY_1 ... DAY_7} ! Return name of the n-th day of the week. \strong{Warning:} this ! follows the US convention of \constant{DAY_1} being Sunday, not the ! international convention (ISO 8601) that Monday is the first day of ! the week. \end{datadesc} *************** *** 327,333 **** Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. ! \[Warning: the expression is in the syntax suitable for the ! regex C library function, which might differ from the syntax ! used in \module{re}\] \end{datadesc} --- 328,334 ---- Return a regular expression that can be used with the regex function to recognize a positive response to a yes/no question. ! \strong{Warning:} the expression is in the syntax suitable for the ! \cfunction{regex()} function from the C library, which might differ ! from the syntax used in \refmodule{re}. \end{datadesc} From fdrake@users.sourceforge.net Thu Sep 27 05:17:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 21:17:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsocket.tex,1.53,1.54 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv32107 Modified Files: libsocket.tex Log Message: Fix some markup errors. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -d -r1.53 -r1.54 *** libsocket.tex 2001/09/25 15:48:11 1.53 --- libsocket.tex 2001/09/27 04:17:20 1.54 *************** *** 20,25 **** to the manual pages; for Windows, see the WinSock (or Winsock 2) specification. ! For IPv6-ready APIs, readers may want to refer to RFC2553 titled ! \cite{Basic Socket Interface Extensions for IPv6}. The Python interface is a straightforward transliteration of the --- 20,25 ---- to the manual pages; for Windows, see the WinSock (or Winsock 2) specification. ! For IPv6-ready APIs, readers may want to refer to \rfc{2553} titled ! \citetitle{Basic Socket Interface Extensions for IPv6}. The Python interface is a straightforward transliteration of the From akuchling@users.sourceforge.net Thu Sep 27 05:18:38 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Wed, 26 Sep 2001 21:18:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/compiler __init__.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/compiler In directory usw-pr-cvs1:/tmp/cvs-serv32270 Modified Files: __init__.py Log Message: Fix comment typo Index: __init__.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/compiler/__init__.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** __init__.py 2001/09/17 21:02:51 1.5 --- __init__.py 2001/09/27 04:18:36 1.6 *************** *** 19,23 **** compileFile(filename) ! Generates a .pyc file by compilining filename. """ --- 19,23 ---- compileFile(filename) ! Generates a .pyc file by compiling filename. """ From fdrake@users.sourceforge.net Thu Sep 27 05:18:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Wed, 26 Sep 2001 21:18:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv32292/tools/sgmlconv Modified Files: conversion.xml Log Message: Add support for some more markup that had slipped in. Fixed a typo in a comment. Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** conversion.xml 2001/09/25 20:58:13 1.18 --- conversion.xml 2001/09/27 04:18:39 1.19 *************** *** 39,42 **** --- 39,45 ---- + + + *************** *** 456,459 **** --- 459,466 ---- visible + + yes + + *************** *** 659,665 **** ! --- 666,675 ---- ! + + + *************** *** 767,771 **** --- 777,781 ---- *************** *** 831,834 **** --- 841,847 ---- ~ + + + \ From lemburg@users.sourceforge.net Thu Sep 27 15:17:36 2001 From: lemburg@users.sourceforge.net (M.-A. Lemburg) Date: Thu, 27 Sep 2001 07:17:36 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.255,1.256 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv31161/Misc Modified Files: NEWS Log Message: Added note about new StringIO/cStringIO feature. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.255 retrieving revision 1.256 diff -C2 -d -r1.255 -r1.256 *** NEWS 2001/09/25 04:15:41 1.255 --- NEWS 2001/09/27 14:17:33 1.256 *************** *** 91,94 **** --- 91,99 ---- Library + - StringIO.StringIO instances and cStringIO.StringIO instances support + read character buffer compatible objects for their .write() methods. + These objects are converted to strings and then handled as such + by the instances. + - The "email" package has been added. This is basically a port of the mimelib package with API changes From fdrake@users.sourceforge.net Thu Sep 27 16:49:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 08:49:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.19,1.20 docfixer.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv27642 Modified Files: conversion.xml docfixer.py Log Message: Turn \input, \include, and \verbatiminput into XInclude elements instead of something ad-hoc. Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** conversion.xml 2001/09/27 04:18:39 1.19 --- conversion.xml 2001/09/27 15:49:23 1.20 *************** *** 185,189 **** ! --- 185,189 ---- ! *************** *** 280,288 **** ! ! ! ! --- 280,288 ---- ! ! ! ! *************** *** 301,305 **** subsection subsection* subsubsection subsubsection* ! paragraph paragraph* subparagraph subparagraph*"/> ! http://www.w3.org/2001/XInclude ! visible ! ! yes ! --- 463,469 ---- visible ! ! text ! Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -d -r1.29 -r1.30 *** docfixer.py 2001/07/06 21:03:30 1.29 --- docfixer.py 2001/09/27 15:49:23 1.30 *************** *** 616,620 **** PARA_LEVEL_PRECEEDERS = ( "setindexsubitem", "author", ! "stindex", "obindex", "COMMENT", "label", "input", "title", "versionadded", "versionchanged", "declaremodule", "modulesynopsis", "moduleauthor", "indexterm", "leader", --- 616,620 ---- PARA_LEVEL_PRECEEDERS = ( "setindexsubitem", "author", ! "stindex", "obindex", "COMMENT", "label", "xi:include", "title", "versionadded", "versionchanged", "declaremodule", "modulesynopsis", "moduleauthor", "indexterm", "leader", From tim_one@users.sourceforge.net Thu Sep 27 17:28:17 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Thu, 27 Sep 2001 09:28:17 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild BUILDno.txt,1.21,1.22 pythoncore.dsp,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv6806/python/PCbuild Modified Files: BUILDno.txt pythoncore.dsp Log Message: Bump Windows build numbers for 2.2a4; installer changes were done earlier. Index: BUILDno.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/BUILDno.txt,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** BUILDno.txt 2001/09/06 16:33:17 1.21 --- BUILDno.txt 2001/09/27 16:28:15 1.22 *************** *** 34,37 **** --- 34,39 ---- Windows Python BUILD numbers ---------------------------- + 24 2.2a4 + 28-Sep-2001 23 2.2a3 07-Sep-2001 Index: pythoncore.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/pythoncore.dsp,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -d -r1.22 -r1.23 *** pythoncore.dsp 2001/09/06 16:33:17 1.22 --- pythoncore.dsp 2001/09/27 16:28:15 1.23 *************** *** 725,733 **** !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=23 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=23 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" --- 725,733 ---- !IF "$(CFG)" == "pythoncore - Win32 Release" ! # ADD CPP /D BUILD=24 !ELSEIF "$(CFG)" == "pythoncore - Win32 Debug" ! # ADD CPP /D BUILD=24 !ELSEIF "$(CFG)" == "pythoncore - Win32 Alpha Debug" From fdrake@users.sourceforge.net Thu Sep 27 17:28:44 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 09:28:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib profile.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7008 Modified Files: profile.py Log Message: Change the sense of a test in how the profiler interprets exception events. This should fix a bug in how time is allocated during exception propogation (esp. in the presence of finally clauses). Index: profile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/profile.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** profile.py 2001/08/09 21:22:15 1.30 --- profile.py 2001/09/27 16:28:42 1.31 *************** *** 242,246 **** def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (not rframe is frame) and rcur: return self.trace_dispatch_return(rframe, t) return 0 --- 242,246 ---- def trace_dispatch_exception(self, frame, t): rt, rtt, rct, rfn, rframe, rcur = self.cur ! if (rframe is frame) and rcur: return self.trace_dispatch_return(rframe, t) return 0 From gvanrossum@users.sourceforge.net Thu Sep 27 17:41:30 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 27 Sep 2001 09:41:30 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.54,2.54.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv9729 Modified Files: Tag: r22a4-branch patchlevel.h Log Message: Update version to 2.2a4. Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.54 retrieving revision 2.54.2.1 diff -C2 -d -r2.54 -r2.54.2.1 *** patchlevel.h 2001/09/07 18:23:30 2.54 --- patchlevel.h 2001/09/27 16:41:28 2.54.2.1 *************** *** 24,31 **** #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 3 /* Version as a string */ ! #define PY_VERSION "2.2a3+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 24,31 ---- #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 4 /* Version as a string */ ! #define PY_VERSION "2.2a4" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From fdrake@users.sourceforge.net Thu Sep 27 17:52:25 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 09:52:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv docfixer.py,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv13507/tools/sgmlconv Modified Files: docfixer.py Log Message: Re-write elements as described in the conversion spec. Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -d -r1.30 -r1.31 *** docfixer.py 2001/09/27 15:49:23 1.30 --- docfixer.py 2001/09/27 16:52:22 1.31 *************** *** 811,814 **** --- 811,832 ---- + def fixup_ulink(doc, fragment): + for ulink in find_all_elements(fragment, "ulink"): + children = ulink.childNodes + assert len(children) == 2 + text = children[0] + href = children[1] + href.normalize() + assert len(href.childNodes) == 1 + assert href.childNodes[0].nodeType == TEXT + url = href.childNodes[0].data + ulink.setAttribute("href", url) + ulink.removeChild(href) + content = text.childNodes + while len(content): + ulink.appendChild(content[0]) + ulink.removeChild(text) + + REFMODINDEX_ELEMENTS = ('refmodindex', 'refbimodindex', 'refexmodindex', 'refstmodindex') *************** *** 977,980 **** --- 995,999 ---- fixup_rfc_references(doc, fragment) fixup_signatures(doc, fragment) + fixup_ulink(doc, fragment) add_node_ids(fragment) fixup_refmodindexes(fragment) From fdrake@users.sourceforge.net Thu Sep 27 18:02:01 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 10:02:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv conversion.xml,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv17551/tools/sgmlconv Modified Files: conversion.xml Log Message: Do not distinguish \refmodule from \module in the generated output; whether or not a link will be generated will depend on the link database. Add a couple of explanatory comments for one of the stranger constructs (giving input an empty name). Index: conversion.xml =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/conversion.xml,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** conversion.xml 2001/09/27 15:49:23 1.20 --- conversion.xml 2001/09/27 17:01:59 1.21 *************** *** 71,76 **** - yes --- 71,77 ---- + *************** *** 185,188 **** --- 186,191 ---- + From fdrake@users.sourceforge.net Thu Sep 27 21:06:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:06:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib compiler.tex,NONE,1.1 asttable.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv10935 Added Files: compiler.tex asttable.tex Log Message: Migrate the compiler documentation from the Tools/compiler/doc/ directory. Changes made to make it work in the new location. --- NEW FILE: compiler.tex --- \chapter{Python compiler package \label{compiler}} \sectionauthor{Jeremy Hylton}{jeremy@zope.com} The Python compiler package is a tool for analyzing Python source code and generating Python bytecode. The compiler contains libraries to generate an abstract syntax tree from Python source code and to generate Python bytecode from the tree. The \refmodule{compiler} package is a Python source to bytecode translator written in Python. It uses the built-in parser and standard \refmodule{parser} module to generated a concrete syntax tree. This tree is used to generate an abstract syntax tree (AST) and then Python bytecode. The full functionality of the package duplicates the builtin compiler provided with the Python interpreter. It is intended to match its behavior almost exactly. Why implement another compiler that does the same thing? The package is useful for a variety of purposes. It can be modified more easily than the builtin compiler. The AST it generates is useful for analyzing Python source code. This chapter explains how the various components of the \refmodule{compiler} package work. It blends reference material with a tutorial. The following modules are part of the \refmodule{compiler} package: \localmoduletable \subsection{The basic interface} \declaremodule{}{compiler} The top-level of the package defines four functions. If you import \module{compiler}, you will get these functions and a collection of modules contained in the package. \begin{funcdesc}{parse}{buf} Returns an abstract syntax tree for the Python source code in \var{buf}. The function raises SyntaxError if there is an error in the source code. The return value is a \class{compiler.ast.Module} instance that contains the tree. \end{funcdesc} \begin{funcdesc}{parseFile}{path} Return an abstract syntax tree for the Python source code in the file specified by \var{path}. It is equivalent to \code{parse(open(\var{path}).read())}. \end{funcdesc} \begin{funcdesc}{walk}{ast, visitor\optional{, verbose}} Do a pre-order walk over the abstract syntax tree \var{ast}. Call the appropriate method on the \var{visitor} instance for each node encountered. \end{funcdesc} \begin{funcdesc}{compile}{path} Compile the file \var{path} and generate the corresponding \file{.pyc} file. \end{funcdesc} The \module{compiler} package contains the following modules: \refmodule[compiler.ast]{ast}, \module{consts}, \module{future}, \module{misc}, \module{pyassem}, \module{pycodegen}, \module{symbols}, \module{transformer}, and \refmodule[compiler.visitor]{visitor}. \subsection{Limitations} There are some problems with the error checking of the compiler package. The interpreter detects syntax errors in two distinct phases. One set of errors is detected by the interpreter's parser, the other set by the compiler. The compiler package relies on the interpreter's parser, so it get the first phases of error checking for free. It implements the second phase itself, and that implement is incomplete. For example, the compiler package does not raise an error if a name appears more than once in an argument list: \code{def f(x, x): ...} A future version of the compiler should fix these problems. \section{Python Abstract Syntax} The \module{compiler.ast} module defines an abstract syntax for Python. In the abstract syntax tree, each node represents a syntactic construct. The root of the tree is \class{Module} object. The abstract syntax offers a higher level interface to parsed Python source code. The \ulink{\module{parser}} {http://www.python.org/doc/current/lib/module-parser.html} module and the compiler written in C for the Python interpreter use a concrete syntax tree. The concrete syntax is tied closely to the grammar description used for the Python parser. Instead of a single node for a construct, there are often several levels of nested nodes that are introduced by Python's precedence rules. The abstract syntax tree is created by the \module{compiler.transformer} module. The transformer relies on the builtin Python parser to generate a concrete syntax tree. It generates an abstract syntax tree from the concrete tree. The \module{transformer} module was created by Greg Stein\index{Stein, Greg} and Bill Tutt\index{Tutt, Bill} for an experimental Python-to-C compiler. The current version contains a number of modifications and improvements, but the basic form of the abstract syntax and of the transformer are due to Stein and Tutt. \subsection{AST Nodes} \declaremodule{}{compiler.ast} The \module{compiler.ast} module is generated from a text file that describes each node type and its elements. Each node type is represented as a class that inherits from the abstract base class \class{compiler.ast.Node} and defines a set of named attributes for child nodes. \begin{classdesc}{Node}{} The \class{Node} instances are created automatically by the parser generator. The recommended interface for specific \class{Node} instances is to use the public attributes to access child nodes. A public attribute may be bound to a single node or to a sequence of nodes, depending on the \class{Node} type. For example, the \member{bases} attribute of the \class{Class} node, is bound to a list of base class nodes, and the \member{doc} attribute is bound to a single node. Each \class{Node} instance has a \member{lineno} attribute which may be \code{None}. XXX Not sure what the rules are for which nodes will have a useful lineno. \end{classdesc} All \class{Node} objects offer the following methods: \begin{methoddesc}{getChildren}{} Returns a flattened list of the child nodes and objects in the order they occur. Specifically, the order of the nodes is the order in which they appear in the Python grammar. Not all of the children are \class{Node} instances. The names of functions and classes, for example, are plain strings. \end{methoddesc} \begin{methoddesc}{getChildNodes}{} Returns a flattened list of the child nodes in the order they occur. This method is like \method{getChildren()}, except that it only returns those children that are \class{Node} instances. \end{methoddesc} Two examples illustrate the general structure of \class{Node} classes. The \keyword{while} statement is defined by the following grammar production: \begin{verbatim} while_stmt: "while" expression ":" suite ["else" ":" suite] \end{verbatim} The \class{While} node has three attributes: \member{test}, \member{body}, and \member{else_}. (If the natural name for an attribute is also a Python reserved word, it can't be used as an attribute name. An underscore is appended to the word to make it a legal identifier, hence \member{else_} instead of \keyword{else}.) The \keyword{if} statement is more complicated because it can include several tests. \begin{verbatim} if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite] \end{verbatim} The \class{If} node only defines two attributes: \member{tests} and \member{else_}. The \member{tests} attribute is a sequence of test expression, consequent body pairs. There is one pair for each \keyword{if}/\keyword{elif} clause. The first element of the pair is the test expression. The second elements is a \class{Stmt} node that contains the code to execute if the test is true. The \method{getChildren()} method of \class{If} returns a flat list of child nodes. If there are three \keyword{if}/\keyword{elif} clauses and no \keyword{else} clause, then \method{getChildren()} will return a list of six elements: the first test expression, the first \class{Stmt}, the second text expression, etc. The following table lists each of the \class{Node} subclasses defined in \module{compiler.ast} and each of the public attributes available on their instances. The values of most of the attributes are themselves \class{Node} instances or sequences of instances. When the value is something other than an instance, the type is noted in the comment. The attributes are listed in the order in which they are returned by \method{getChildren()} and \method{getChildNodes()}. \input{asttable} \subsection{Assignment nodes} There is a collection of nodes used to represent assignments. Each assignment statement in the source code becomes a single \class{Assign} node in the AST. The \member{nodes} attribute is a list that contains a node for each assignment target. This is necessary because assignment can be chained, e.g. \code{a = b = 2}. Each \class{Node} in the list will be one of the following classes: \class{AssAttr}, \class{AssList}, \class{AssName}, or \class{AssTuple}. Each target assignment node will describe the kind of object being assigned to: \class{AssName} for a simple name, e.g. \code{a = 1}. \class{AssAttr} for an attribute assigned, e.g. \code{a.x = 1}. \class{AssList} and \class{AssTuple} for list and tuple expansion respectively, e.g. \code{a, b, c = a_tuple}. The target assignment nodes also have a \member{flags} attribute that indicates whether the node is being used for assignment or in a delete statement. The \class{AssName} is also used to represent a delete statement, e.g. \class{del x}. When an expression contains several attribute references, an assignment or delete statement will contain only one \class{AssAttr} node -- for the final attribute reference. The other attribute references will be represented as \class{Getattr} nodes in the \member{expr} attribute of the \class{AssAttr} instance. \subsection{Examples} This section shows several simple examples of ASTs for Python source code. The examples demonstrate how to use the \function{parse()} function, what the repr of an AST looks like, and how to access attributes of an AST node. The first module defines a single function. Assume it is stored in \file{/tmp/doublelib.py}. \begin{verbatim} """This is an example module. This is the docstring. """ def double(x): "Return twice the argument" return x * 2 \end{verbatim} In the interactive interpreter session below, I have reformatted the long AST reprs for readability. The AST reprs use unqualified class names. If you want to create an instance from a repr, you must import the class names from the \module{compiler.ast} module. \begin{verbatim} >>> import compiler >>> mod = compiler.parseFile("/tmp/doublelib.py") >>> mod Module('This is an example module.\n\nThis is the docstring.\n', Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', Stmt([Return(Mul((Name('x'), Const(2))))]))])) >>> from compiler.ast import * >>> Module('This is an example module.\n\nThis is the docstring.\n', ... Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', ... Stmt([Return(Mul((Name('x'), Const(2))))]))])) Module('This is an example module.\n\nThis is the docstring.\n', Stmt([Function('double', ['x'], [], 0, 'Return twice the argument', Stmt([Return(Mul((Name('x'), Const(2))))]))])) >>> mod.doc 'This is an example module.\n\nThis is the docstring.\n' >>> for node in mod.node.nodes: ... print node ... Function('double', ['x'], [], 0, 'Return twice the argument', Stmt([Return(Mul((Name('x'), Const(2))))])) >>> func = mod.node.nodes[0] >>> func.code Stmt([Return(Mul((Name('x'), Const(2))))]) \end{verbatim} \section{Using Visitors to Walk ASTs} \declaremodule{}{compiler.visitor} The visitor pattern is ... The \refmodule{compiler} package uses a variant on the visitor pattern that takes advantage of Python's introspection features to elminiate the need for much of the visitor's infrastructure. The classes being visited do not need to be programmed to accept visitors. The visitor need only define visit methods for classes it is specifically interested in; a default visit method can handle the rest. XXX The magic \method{visit()} method for visitors. \begin{funcdesc}{walk}{tree, visitor\optional{, verbose}} \end{funcdesc} \begin{classdesc}{ASTVisitor}{} The \class{ASTVisitor} is responsible for walking over the tree in the correct order. A walk begins with a call to \method{preorder()}. For each node, it checks the \var{visitor} argument to \method{preorder()} for a method named `visitNodeType,' where NodeType is the name of the node's class, e.g. for a \class{While} node a \method{visitWhile()} would be called. If the method exists, it is called with the node as its first argument. The visitor method for a particular node type can control how child nodes are visited during the walk. The \class{ASTVisitor} modifies the visitor argument by adding a visit method to the visitor; this method can be used to visit a particular child node. If no visitor is found for a particular node type, the \method{default()} method is called. \end{classdesc} \class{ASTVisitor} objects have the following methods: XXX describe extra arguments \begin{methoddesc}{default}{node\optional{, \moreargs}} \end{methoddesc} \begin{methoddesc}{dispatch}{node\optional{, \moreargs}} \end{methoddesc} \begin{methoddesc}{preorder}{tree, visitor} \end{methoddesc} \section{Bytecode Generation} The code generator is a visitor that emits bytecodes. Each visit method can call the \method{emit()} method to emit a new bytecode. The basic code generator is specialized for modules, classes, and functions. An assembler converts that emitted instructions to the low-level bytecode format. It handles things like generator of constant lists of code objects and calculation of jump offsets. --- NEW FILE: asttable.tex --- \begin{longtableiii}{lll}{class}{Node type}{Attribute}{Value} \lineiii{Add}{\member{left}}{left operand} \lineiii{}{\member{right}}{right operand} \hline \lineiii{And}{\member{nodes}}{list of operands} \hline \lineiii{AssAttr}{}{\emph{attribute as target of assignment}} \lineiii{}{\member{expr}}{expression on the left-hand side of the dot} \lineiii{}{\member{attrname}}{the attribute name, a string} \lineiii{}{\member{flags}}{XXX} \hline \lineiii{AssList}{\member{nodes}}{list of list elements being assigned to} \hline \lineiii{AssName}{\member{name}}{name being assigned to} \lineiii{}{\member{flags}}{XXX} \hline \lineiii{AssTuple}{\member{nodes}}{list of tuple elements being assigned to} \hline \lineiii{Assert}{\member{test}}{the expression to be tested} \lineiii{}{\member{fail}}{the value of the \exception{AssertionError}} \hline \lineiii{Assign}{\member{nodes}}{a list of assignment targets, one per equal sign} \lineiii{}{\member{expr}}{the value being assigned} \hline \lineiii{AugAssign}{\member{node}}{} \lineiii{}{\member{op}}{} \lineiii{}{\member{expr}}{} \hline \lineiii{Backquote}{\member{expr}}{} \hline \lineiii{Bitand}{\member{nodes}}{} \hline \lineiii{Bitor}{\member{nodes}}{} \hline \lineiii{Bitxor}{\member{nodes}}{} \hline \lineiii{Break}{}{} \hline \lineiii{CallFunc}{\member{node}}{expression for the callee} \lineiii{}{\member{args}}{a list of arguments} \lineiii{}{\member{star_args}}{the extended *-arg value} \lineiii{}{\member{dstar_args}}{the extended **-arg value} \hline \lineiii{Class}{\member{name}}{the name of the class, a string} \lineiii{}{\member{bases}}{a list of base classes} \lineiii{}{\member{doc}}{doc string, a string or \code{None}} \lineiii{}{\member{code}}{the body of the class statement} \hline \lineiii{Compare}{\member{expr}}{} \lineiii{}{\member{ops}}{} \hline \lineiii{Const}{\member{value}}{} \hline \lineiii{Continue}{}{} \hline \lineiii{Dict}{\member{items}}{} \hline \lineiii{Discard}{\member{expr}}{} \hline \lineiii{Div}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Ellipsis}{}{} \hline \lineiii{Exec}{\member{expr}}{} \lineiii{}{\member{locals}}{} \lineiii{}{\member{globals}}{} \hline \lineiii{For}{\member{assign}}{} \lineiii{}{\member{list}}{} \lineiii{}{\member{body}}{} \lineiii{}{\member{else_}}{} \hline \lineiii{From}{\member{modname}}{} \lineiii{}{\member{names}}{} \hline \lineiii{Function}{\member{name}}{name used in def, a string} \lineiii{}{\member{argnames}}{list of argument names, as strings} \lineiii{}{\member{defaults}}{list of default values} \lineiii{}{\member{flags}}{xxx} \lineiii{}{\member{doc}}{doc string, a string or \code{None}} \lineiii{}{\member{code}}{the body of the function} \hline \lineiii{Getattr}{\member{expr}}{} \lineiii{}{\member{attrname}}{} \hline \lineiii{Global}{\member{names}}{} \hline \lineiii{If}{\member{tests}}{} \lineiii{}{\member{else_}}{} \hline \lineiii{Import}{\member{names}}{} \hline \lineiii{Invert}{\member{expr}}{} \hline \lineiii{Keyword}{\member{name}}{} \lineiii{}{\member{expr}}{} \hline \lineiii{Lambda}{\member{argnames}}{} \lineiii{}{\member{defaults}}{} \lineiii{}{\member{flags}}{} \lineiii{}{\member{code}}{} \hline \lineiii{LeftShift}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{List}{\member{nodes}}{} \hline \lineiii{ListComp}{\member{expr}}{} \lineiii{}{\member{quals}}{} \hline \lineiii{ListCompFor}{\member{assign}}{} \lineiii{}{\member{list}}{} \lineiii{}{\member{ifs}}{} \hline \lineiii{ListCompIf}{\member{test}}{} \hline \lineiii{Mod}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Module}{\member{doc}}{doc string, a string or \code{None}} \lineiii{}{\member{node}}{body of the module, a \class{Stmt}} \hline \lineiii{Mul}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Name}{\member{name}}{} \hline \lineiii{Not}{\member{expr}}{} \hline \lineiii{Or}{\member{nodes}}{} \hline \lineiii{Pass}{}{} \hline \lineiii{Power}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Print}{\member{nodes}}{} \lineiii{}{\member{dest}}{} \hline \lineiii{Printnl}{\member{nodes}}{} \lineiii{}{\member{dest}}{} \hline \lineiii{Raise}{\member{expr1}}{} \lineiii{}{\member{expr2}}{} \lineiii{}{\member{expr3}}{} \hline \lineiii{Return}{\member{value}}{} \hline \lineiii{RightShift}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Slice}{\member{expr}}{} \lineiii{}{\member{flags}}{} \lineiii{}{\member{lower}}{} \lineiii{}{\member{upper}}{} \hline \lineiii{Sliceobj}{\member{nodes}}{list of statements} \hline \lineiii{Stmt}{\member{nodes}}{} \hline \lineiii{Sub}{\member{left}}{} \lineiii{}{\member{right}}{} \hline \lineiii{Subscript}{\member{expr}}{} \lineiii{}{\member{flags}}{} \lineiii{}{\member{subs}}{} \hline \lineiii{TryExcept}{\member{body}}{} \lineiii{}{\member{handlers}}{} \lineiii{}{\member{else_}}{} \hline \lineiii{TryFinally}{\member{body}}{} \lineiii{}{\member{final}}{} \hline \lineiii{Tuple}{\member{nodes}}{} \hline \lineiii{UnaryAdd}{\member{expr}}{} \hline \lineiii{UnarySub}{\member{expr}}{} \hline \lineiii{While}{\member{test}}{} \lineiii{}{\member{body}}{} \lineiii{}{\member{else_}}{} \hline \lineiii{Yield}{\member{value}}{} \hline \end{longtableiii} From fdrake@users.sourceforge.net Thu Sep 27 21:08:22 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:08:22 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.73,1.74 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv11692 Modified Files: Makefile.deps Log Message: Added dependencies for the compiler and email packages. (Migrate to branch, along with new files compiler.tex and asttable.tex.) Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.73 retrieving revision 1.74 diff -C2 -d -r1.73 -r1.74 *** Makefile.deps 2001/09/11 16:59:42 1.73 --- Makefile.deps 2001/09/27 20:08:20 1.74 *************** *** 52,56 **** --- 52,66 ---- LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ lib/lib.tex \ + lib/asttable.tex \ + lib/compiler.tex \ lib/distutils.tex \ + lib/email.tex \ + lib/emailencoders.tex \ + lib/emailexc.tex \ + lib/emailgenerator.tex \ + lib/emailiter.tex \ + lib/emailmessage.tex \ + lib/emailparser.tex \ + lib/emailutil.tex \ texinputs/reportingbugs.tex \ lib/libintro.tex \ From fdrake@users.sourceforge.net Thu Sep 27 21:09:41 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:09:41 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib email.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12106/lib Modified Files: email.tex Log Message: Markup adjustments. Index: email.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/email.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** email.tex 2001/09/26 22:21:52 1.3 --- email.tex 2001/09/27 20:09:39 1.4 *************** *** 9,12 **** --- 9,13 ---- generating email messages, including MIME documents.} \moduleauthor{Barry A. Warsaw}{barry@zope.com} + \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} *************** *** 183,195 **** either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in ! \module{mimelib} is still available in the \module{email} package, albeit often in a different way. Here is a brief description of the differences between the ! \module{mimelib} and the \module{email} packages, along with hints on how to port your applications. Of course, the most visible difference between the two packages is ! that the package name has been changed to \module{email}. In addition, the top-level package has the following differences: --- 184,196 ---- either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in ! \module{mimelib} is still available in the \refmodule{email} package, albeit often in a different way. Here is a brief description of the differences between the ! \module{mimelib} and the \refmodule{email} packages, along with hints on how to port your applications. Of course, the most visible difference between the two packages is ! that the package name has been changed to \refmodule{email}. In addition, the top-level package has the following differences: *************** *** 250,254 **** subparts for each header block in the delivery status notification\footnote{Delivery Status Notifications (DSN) are defined ! in \rfc{1894}}. The \class{Generator} class has no differences in its public --- 251,255 ---- subparts for each header block in the delivery status notification\footnote{Delivery Status Notifications (DSN) are defined ! in \rfc{1894}.}. The \class{Generator} class has no differences in its public From fdrake@users.sourceforge.net Thu Sep 27 21:11:09 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:11:09 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.191,1.192 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv12719/lib Modified Files: lib.tex Log Message: Add entries for the email and compiler packages. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.191 retrieving revision 1.192 diff -C2 -d -r1.191 -r1.192 *** lib.tex 2001/09/11 16:59:42 1.191 --- lib.tex 2001/09/27 20:11:07 1.192 *************** *** 216,219 **** --- 216,227 ---- \input{netdata} % Internet Data Handling \input{libformatter} + \input{email} + \input{emailencoders} + \input{emailexc} + \input{emailgenerator} + \input{emailiter} + \input{emailmessage} + \input{emailparser} + \input{emailutil} \input{librfc822} \input{libmimetools} *************** *** 284,287 **** --- 292,297 ---- \input{libdis} \input{distutils} + + \input{compiler} % compiler package %\input{libamoeba} % AMOEBA ONLY From gvanrossum@users.sourceforge.net Thu Sep 27 21:13:37 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 27 Sep 2001 13:13:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.75,2.75.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13594 Modified Files: Tag: r22a4-branch typeobject.c Log Message: Add support for __coerce__. We'll need it once __dynamic__ is the default. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.75 retrieving revision 2.75.2.1 diff -C2 -d -r2.75 -r2.75.2.1 *** typeobject.c 2001/09/25 21:16:33 2.75 --- typeobject.c 2001/09/27 20:13:35 2.75.2.1 *************** *** 1838,1841 **** --- 1838,1875 ---- BINARY(xor, "x^y"); BINARY(or, "x|y"); + + static PyObject * + wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped) + { + coercion func = (coercion)wrapped; + PyObject *other, *res; + int ok; + + if (!PyArg_ParseTuple(args, "O", &other)) + return NULL; + ok = func(&self, &other); + if (ok < 0) + return NULL; + if (ok > 0) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + res = PyTuple_New(2); + if (res == NULL) { + Py_DECREF(self); + Py_DECREF(other); + return NULL; + } + PyTuple_SET_ITEM(res, 0, self); + PyTuple_SET_ITEM(res, 1, other); + return res; + } + + static struct wrapperbase tab_coerce[] = { + {"__coerce__", (wrapperfunc)wrap_coercefunc, + "x.__coerce__(y) <==> coerce(x, y)"}, + {0} + }; + BINARY(floordiv, "x//y"); BINARY(truediv, "x/y # true division"); *************** *** 2574,2578 **** ADD(nb->nb_xor, tab_xor); ADD(nb->nb_or, tab_or); ! /* We don't support coerce() -- see above comment */ ADD(nb->nb_int, tab_int); ADD(nb->nb_long, tab_long); --- 2608,2612 ---- ADD(nb->nb_xor, tab_xor); ADD(nb->nb_or, tab_or); ! ADD(nb->nb_coerce, tab_coerce); ADD(nb->nb_int, tab_int); ADD(nb->nb_long, tab_long); *************** *** 2841,2845 **** SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") ! /* Not coerce() */ SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") --- 2875,2936 ---- SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") ! ! static int ! slot_nb_coerce(PyObject **a, PyObject **b) ! { ! static PyObject *coerce_str; ! PyObject *self = *a, *other = *b; ! ! if (self->ob_type->tp_as_number != NULL && ! self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { ! PyObject *r; ! r = call_maybe( ! self, "__coerce__", &coerce_str, "(O)", other); ! if (r == NULL) ! return -1; ! if (r == Py_NotImplemented) { ! Py_DECREF(r); ! return 1; ! } ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, ! "__coerce__ didn't return a 2-tuple"); ! Py_DECREF(r); ! return -1; ! } ! *a = PyTuple_GET_ITEM(r, 0); ! Py_INCREF(*a); ! *b = PyTuple_GET_ITEM(r, 1); ! Py_INCREF(*b); ! Py_DECREF(r); ! return 0; ! } ! if (other->ob_type->tp_as_number != NULL && ! other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { ! PyObject *r; ! r = call_maybe( ! other, "__coerce__", &coerce_str, "(O)", self); ! if (r == NULL) ! return -1; ! if (r == Py_NotImplemented) { ! Py_DECREF(r); ! return 1; ! } ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, ! "__coerce__ didn't return a 2-tuple"); ! Py_DECREF(r); ! return -1; ! } ! *a = PyTuple_GET_ITEM(r, 1); ! Py_INCREF(*a); ! *b = PyTuple_GET_ITEM(r, 0); ! Py_INCREF(*b); ! Py_DECREF(r); ! return 0; ! } ! return 1; ! } ! SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") *************** *** 3337,3341 **** NBSLOT("__xor__", nb_xor, slot_nb_xor); NBSLOT("__or__", nb_or, slot_nb_or); ! /* Not coerce() */ NBSLOT("__int__", nb_int, slot_nb_int); NBSLOT("__long__", nb_long, slot_nb_long); --- 3428,3432 ---- NBSLOT("__xor__", nb_xor, slot_nb_xor); NBSLOT("__or__", nb_or, slot_nb_or); ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce); NBSLOT("__int__", nb_int, slot_nb_int); NBSLOT("__long__", nb_long, slot_nb_long); From gvanrossum@users.sourceforge.net Thu Sep 27 21:21:13 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 27 Sep 2001 13:21:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.48,2.48.2.1 object.c,2.151,2.151.2.1 stringobject.c,2.134,2.134.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv14426/Objects Modified Files: Tag: r22a4-branch complexobject.c object.c stringobject.c Log Message: Policy change for rich comparison: if the second operand's type is a subtype of the first operand's type, try its comparison *before* trying the first operand. This removes the need for hacks in string and complex rich comparisons that test whether the operands have the proper comparison slot; instead, we can use a straightforward typecheck. This solves some issues related to make __dynamic__ the default: the test failed if the comparison slot was slot_tp_richcompare. It also solves the situation where a derived class overrides a base class's rich comparison but wants to call the base class's rich comparison implementation: class C(complex): def __eq__(self, other): print "Comparing", self, "to", other return complex.__eq__(self, other) Here the base class implementation would refuse the explicit call because of the test for a specific slot function. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.48 retrieving revision 2.48.2.1 diff -C2 -d -r2.48 -r2.48.2.1 *** complexobject.c 2001/09/24 17:52:04 2.48 --- complexobject.c 2001/09/27 20:21:11 2.48.2.1 *************** *** 561,568 **** return Py_NotImplemented; } ! /* May sure both arguments use complex comparison. ! This implies PyComplex_Check(a) && PyComplex_Check(b). */ ! if (v->ob_type->tp_richcompare != complex_richcompare || ! w->ob_type->tp_richcompare != complex_richcompare) { Py_DECREF(v); Py_DECREF(w); --- 561,566 ---- return Py_NotImplemented; } ! /* Make sure both arguments are complex. */ ! if (!(PyComplex_Check(v) && PyComplex_Check(w))) { Py_DECREF(v); Py_DECREF(w); Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.151 retrieving revision 2.151.2.1 diff -C2 -d -r2.151 -r2.151.2.1 *** object.c 2001/09/20 13:38:22 2.151 --- object.c 2001/09/27 20:21:11 2.151.2.1 *************** *** 366,369 **** --- 366,377 ---- PyObject *res; + if (v->ob_type != w->ob_type && + PyType_IsSubtype(w->ob_type, v->ob_type) && + (f = RICHCOMPARE(w->ob_type)) != NULL) { + res = (*f)(w, v, swapped_op[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } if ((f = RICHCOMPARE(v->ob_type)) != NULL) { res = (*f)(v, w, op); Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.134 retrieving revision 2.134.2.1 diff -C2 -d -r2.134 -r2.134.2.1 *** stringobject.c 2001/09/24 16:51:54 2.134 --- stringobject.c 2001/09/27 20:21:11 2.134.2.1 *************** *** 825,832 **** PyObject *result; ! /* May sure both arguments use string comparison. ! This implies PyString_Check(a) && PyString_Check(b). */ ! if (a->ob_type->tp_richcompare != (richcmpfunc)string_richcompare || ! b->ob_type->tp_richcompare != (richcmpfunc)string_richcompare) { result = Py_NotImplemented; goto out; --- 825,830 ---- PyObject *result; ! /* Make sure both arguments are strings. */ ! if (!(PyString_Check(a) && PyString_Check(b))) { result = Py_NotImplemented; goto out; From gvanrossum@users.sourceforge.net Thu Sep 27 21:30:10 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Thu, 27 Sep 2001 13:30:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects complexobject.c,2.48,2.49 object.c,2.151,2.152 stringobject.c,2.134,2.135 typeobject.c,2.75,2.76 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19849 Modified Files: complexobject.c object.c stringobject.c typeobject.c Log Message: Merge branch changes (coercion, rich comparisons) into trunk. Index: complexobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/complexobject.c,v retrieving revision 2.48 retrieving revision 2.49 diff -C2 -d -r2.48 -r2.49 *** complexobject.c 2001/09/24 17:52:04 2.48 --- complexobject.c 2001/09/27 20:30:07 2.49 *************** *** 561,568 **** return Py_NotImplemented; } ! /* May sure both arguments use complex comparison. ! This implies PyComplex_Check(a) && PyComplex_Check(b). */ ! if (v->ob_type->tp_richcompare != complex_richcompare || ! w->ob_type->tp_richcompare != complex_richcompare) { Py_DECREF(v); Py_DECREF(w); --- 561,566 ---- return Py_NotImplemented; } ! /* Make sure both arguments are complex. */ ! if (!(PyComplex_Check(v) && PyComplex_Check(w))) { Py_DECREF(v); Py_DECREF(w); Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.151 retrieving revision 2.152 diff -C2 -d -r2.151 -r2.152 *** object.c 2001/09/20 13:38:22 2.151 --- object.c 2001/09/27 20:30:07 2.152 *************** *** 366,369 **** --- 366,377 ---- PyObject *res; + if (v->ob_type != w->ob_type && + PyType_IsSubtype(w->ob_type, v->ob_type) && + (f = RICHCOMPARE(w->ob_type)) != NULL) { + res = (*f)(w, v, swapped_op[op]); + if (res != Py_NotImplemented) + return res; + Py_DECREF(res); + } if ((f = RICHCOMPARE(v->ob_type)) != NULL) { res = (*f)(v, w, op); Index: stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.134 retrieving revision 2.135 diff -C2 -d -r2.134 -r2.135 *** stringobject.c 2001/09/24 16:51:54 2.134 --- stringobject.c 2001/09/27 20:30:07 2.135 *************** *** 825,832 **** PyObject *result; ! /* May sure both arguments use string comparison. ! This implies PyString_Check(a) && PyString_Check(b). */ ! if (a->ob_type->tp_richcompare != (richcmpfunc)string_richcompare || ! b->ob_type->tp_richcompare != (richcmpfunc)string_richcompare) { result = Py_NotImplemented; goto out; --- 825,830 ---- PyObject *result; ! /* Make sure both arguments are strings. */ ! if (!(PyString_Check(a) && PyString_Check(b))) { result = Py_NotImplemented; goto out; Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.75 retrieving revision 2.76 diff -C2 -d -r2.75 -r2.76 *** typeobject.c 2001/09/25 21:16:33 2.75 --- typeobject.c 2001/09/27 20:30:07 2.76 *************** *** 1838,1841 **** --- 1838,1875 ---- BINARY(xor, "x^y"); BINARY(or, "x|y"); + + static PyObject * + wrap_coercefunc(PyObject *self, PyObject *args, void *wrapped) + { + coercion func = (coercion)wrapped; + PyObject *other, *res; + int ok; + + if (!PyArg_ParseTuple(args, "O", &other)) + return NULL; + ok = func(&self, &other); + if (ok < 0) + return NULL; + if (ok > 0) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + res = PyTuple_New(2); + if (res == NULL) { + Py_DECREF(self); + Py_DECREF(other); + return NULL; + } + PyTuple_SET_ITEM(res, 0, self); + PyTuple_SET_ITEM(res, 1, other); + return res; + } + + static struct wrapperbase tab_coerce[] = { + {"__coerce__", (wrapperfunc)wrap_coercefunc, + "x.__coerce__(y) <==> coerce(x, y)"}, + {0} + }; + BINARY(floordiv, "x//y"); BINARY(truediv, "x/y # true division"); *************** *** 2574,2578 **** ADD(nb->nb_xor, tab_xor); ADD(nb->nb_or, tab_or); ! /* We don't support coerce() -- see above comment */ ADD(nb->nb_int, tab_int); ADD(nb->nb_long, tab_long); --- 2608,2612 ---- ADD(nb->nb_xor, tab_xor); ADD(nb->nb_or, tab_or); ! ADD(nb->nb_coerce, tab_coerce); ADD(nb->nb_int, tab_int); ADD(nb->nb_long, tab_long); *************** *** 2841,2845 **** SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") ! /* Not coerce() */ SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") --- 2875,2936 ---- SLOT1BIN(slot_nb_xor, nb_xor, "__xor__", "__rxor__") SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") ! ! static int ! slot_nb_coerce(PyObject **a, PyObject **b) ! { ! static PyObject *coerce_str; ! PyObject *self = *a, *other = *b; ! ! if (self->ob_type->tp_as_number != NULL && ! self->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { ! PyObject *r; ! r = call_maybe( ! self, "__coerce__", &coerce_str, "(O)", other); ! if (r == NULL) ! return -1; ! if (r == Py_NotImplemented) { ! Py_DECREF(r); ! return 1; ! } ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, ! "__coerce__ didn't return a 2-tuple"); ! Py_DECREF(r); ! return -1; ! } ! *a = PyTuple_GET_ITEM(r, 0); ! Py_INCREF(*a); ! *b = PyTuple_GET_ITEM(r, 1); ! Py_INCREF(*b); ! Py_DECREF(r); ! return 0; ! } ! if (other->ob_type->tp_as_number != NULL && ! other->ob_type->tp_as_number->nb_coerce == slot_nb_coerce) { ! PyObject *r; ! r = call_maybe( ! other, "__coerce__", &coerce_str, "(O)", self); ! if (r == NULL) ! return -1; ! if (r == Py_NotImplemented) { ! Py_DECREF(r); ! return 1; ! } ! if (!PyTuple_Check(r) || PyTuple_GET_SIZE(r) != 2) { ! PyErr_SetString(PyExc_TypeError, ! "__coerce__ didn't return a 2-tuple"); ! Py_DECREF(r); ! return -1; ! } ! *a = PyTuple_GET_ITEM(r, 1); ! Py_INCREF(*a); ! *b = PyTuple_GET_ITEM(r, 0); ! Py_INCREF(*b); ! Py_DECREF(r); ! return 0; ! } ! return 1; ! } ! SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_long, "__long__") *************** *** 3337,3341 **** NBSLOT("__xor__", nb_xor, slot_nb_xor); NBSLOT("__or__", nb_or, slot_nb_or); ! /* Not coerce() */ NBSLOT("__int__", nb_int, slot_nb_int); NBSLOT("__long__", nb_long, slot_nb_long); --- 3428,3432 ---- NBSLOT("__xor__", nb_xor, slot_nb_xor); NBSLOT("__or__", nb_or, slot_nb_or); ! NBSLOT("__coerce__", nb_coerce, slot_nb_coerce); NBSLOT("__int__", nb_int, slot_nb_int); NBSLOT("__long__", nb_long, slot_nb_long); From fdrake@users.sourceforge.net Thu Sep 27 21:41:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:41:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.73,1.73.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv22923 Modified Files: Tag: r22a4-branch Makefile.deps Log Message: Sync with documentation head. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.73 retrieving revision 1.73.2.1 diff -C2 -d -r1.73 -r1.73.2.1 *** Makefile.deps 2001/09/11 16:59:42 1.73 --- Makefile.deps 2001/09/27 20:41:06 1.73.2.1 *************** *** 52,56 **** --- 52,66 ---- LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \ lib/lib.tex \ + lib/asttable.tex \ + lib/compiler.tex \ lib/distutils.tex \ + lib/email.tex \ + lib/emailencoders.tex \ + lib/emailexc.tex \ + lib/emailgenerator.tex \ + lib/emailiter.tex \ + lib/emailmessage.tex \ + lib/emailparser.tex \ + lib/emailutil.tex \ texinputs/reportingbugs.tex \ lib/libintro.tex \ From fdrake@users.sourceforge.net Thu Sep 27 21:41:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 13:41:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib email.tex,1.3,1.3.2.1 lib.tex,1.191,1.191.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22923/lib Modified Files: Tag: r22a4-branch email.tex lib.tex Log Message: Sync with documentation head. Index: email.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/email.tex,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -C2 -d -r1.3 -r1.3.2.1 *** email.tex 2001/09/26 22:21:52 1.3 --- email.tex 2001/09/27 20:41:06 1.3.2.1 *************** *** 9,12 **** --- 9,13 ---- generating email messages, including MIME documents.} \moduleauthor{Barry A. Warsaw}{barry@zope.com} + \sectionauthor{Barry A. Warsaw}{barry@zope.com} \versionadded{2.2} *************** *** 183,195 **** either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in ! \module{mimelib} is still available in the \module{email} package, albeit often in a different way. Here is a brief description of the differences between the ! \module{mimelib} and the \module{email} packages, along with hints on how to port your applications. Of course, the most visible difference between the two packages is ! that the package name has been changed to \module{email}. In addition, the top-level package has the following differences: --- 184,196 ---- either been added or removed. The semantics of some of the methods have also changed. For the most part, any functionality available in ! \module{mimelib} is still available in the \refmodule{email} package, albeit often in a different way. Here is a brief description of the differences between the ! \module{mimelib} and the \refmodule{email} packages, along with hints on how to port your applications. Of course, the most visible difference between the two packages is ! that the package name has been changed to \refmodule{email}. In addition, the top-level package has the following differences: *************** *** 250,254 **** subparts for each header block in the delivery status notification\footnote{Delivery Status Notifications (DSN) are defined ! in \rfc{1894}}. The \class{Generator} class has no differences in its public --- 251,255 ---- subparts for each header block in the delivery status notification\footnote{Delivery Status Notifications (DSN) are defined ! in \rfc{1894}.}. The \class{Generator} class has no differences in its public Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.191 retrieving revision 1.191.2.1 diff -C2 -d -r1.191 -r1.191.2.1 *** lib.tex 2001/09/11 16:59:42 1.191 --- lib.tex 2001/09/27 20:41:06 1.191.2.1 *************** *** 216,219 **** --- 216,227 ---- \input{netdata} % Internet Data Handling \input{libformatter} + \input{email} + \input{emailencoders} + \input{emailexc} + \input{emailgenerator} + \input{emailiter} + \input{emailmessage} + \input{emailparser} + \input{emailutil} \input{librfc822} \input{libmimetools} *************** *** 284,287 **** --- 292,297 ---- \input{libdis} \input{distutils} + + \input{compiler} % compiler package %\input{libamoeba} % AMOEBA ONLY From fdrake@users.sourceforge.net Fri Sep 28 05:33:08 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Thu, 27 Sep 2001 21:33:08 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.36,1.37 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv6065 Modified Files: minidom.py Log Message: For Python 2.2 and newer, actually support the full NodeList interface by subclassing list to add the length and item() attributes. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.36 retrieving revision 1.37 diff -C2 -d -r1.36 -r1.37 *** minidom.py 2001/09/19 13:28:25 1.36 --- minidom.py 2001/09/28 04:33:06 1.37 *************** *** 33,36 **** --- 33,53 ---- _Node = xml.dom.Node + + if list is type([]): + class NodeList(list): + def item(self, index): + if 0 <= index < len(self): + return self[index] + + def __getattr__(self, name): + if name == "length": + return len(self) + raise AttributeError, name + + else: + def NodeList(): + return [] + + class Node(_Node): allnodes = {} *************** *** 42,46 **** def __init__(self): ! self.childNodes = [] self.parentNode = self.ownerDocument = None if Node._debug: --- 59,63 ---- def __init__(self): ! self.childNodes = NodeList() self.parentNode = self.ownerDocument = None if Node._debug: *************** *** 235,239 **** if self._makeParentNodes: clone.parentNode = None ! clone.childNodes = [] if deep: for child in self.childNodes: --- 252,256 ---- if self._makeParentNodes: clone.parentNode = None ! clone.childNodes = NodeList() if deep: for child in self.childNodes: From bwarsaw@users.sourceforge.net Fri Sep 28 16:24:10 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 28 Sep 2001 08:24:10 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.256,1.256.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17014 Modified Files: Tag: r22a4-branch NEWS Log Message: A couple of minor updates (plus I think it would be nice to have the release dates right under the "What's New" bit). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.256 retrieving revision 1.256.2.1 diff -C2 -d -r1.256 -r1.256.2.1 *** NEWS 2001/09/27 14:17:33 1.256 --- NEWS 2001/09/28 15:24:08 1.256.2.1 *************** *** 1,3 **** --- 1,4 ---- What's New in Python 2.2a4? + Release date: 28-Sep-2001 =========================== *************** *** 70,73 **** --- 71,76 ---- with the same value as s. + - Provisional support for pickling new-style objects has been added. + Core *************** *** 192,195 **** --- 195,199 ---- What's New in Python 2.2a3? + Release Date: 07-Sep-2001 =========================== *************** *** 380,383 **** --- 384,388 ---- What's New in Python 2.2a2? + Release Date: 22-Aug-2001 =========================== From bwarsaw@users.sourceforge.net Fri Sep 28 16:26:14 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 28 Sep 2001 08:26:14 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.256,1.257 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv17424 Modified Files: NEWS Log Message: Merged changes from 22a4 branch. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.256 retrieving revision 1.257 diff -C2 -d -r1.256 -r1.257 *** NEWS 2001/09/27 14:17:33 1.256 --- NEWS 2001/09/28 15:26:12 1.257 *************** *** 1,3 **** --- 1,4 ---- What's New in Python 2.2a4? + Release date: 28-Sep-2001 =========================== *************** *** 70,73 **** --- 71,76 ---- with the same value as s. + - Provisional support for pickling new-style objects has been added. + Core *************** *** 192,195 **** --- 195,199 ---- What's New in Python 2.2a3? + Release Date: 07-Sep-2001 =========================== *************** *** 380,383 **** --- 384,388 ---- What's New in Python 2.2a2? + Release Date: 22-Aug-2001 =========================== From gvanrossum@users.sourceforge.net Fri Sep 28 16:59:40 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 08:59:40 -0700 Subject: [Python-checkins] CVS: python/dist/src configure,1.252,1.253 configure.in,1.260,1.261 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv25488 Modified Files: configure configure.in Log Message: Fix SF bug 419062: building pbs on AIX 4.3.2 Apply patch from "china@thewrittenword.com" to put the correct location for ld_so_aix in BLDSHARED. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.252 retrieving revision 1.253 diff -C2 -d -r1.252 -r1.253 *** configure 2001/09/17 04:03:14 1.252 --- configure 2001/09/28 15:59:37 1.253 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.260 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.261 # Guess values for system-dependent variables and create Makefiles. *************** *** 3048,3056 **** AIX*) BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" ! LDSHARED="\$(BINLIBDEST)/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/python.exp" ;; BeOS*) BLDSHARED="\$(srcdir)/Modules/ld_so_beos $LDLIBRARY" ! LDSHARED="\$(BINLIBDEST)/ld_so_beos \$(LIBDIR)/$LDLIBRARY" ;; IRIX/5*) LDSHARED="ld -shared";; --- 3048,3056 ---- AIX*) BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" ! LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp" ;; BeOS*) BLDSHARED="\$(srcdir)/Modules/ld_so_beos $LDLIBRARY" ! LDSHARED="\$(BINLIBDEST)/config/ld_so_beos \$(LIBDIR)/$LDLIBRARY" ;; IRIX/5*) LDSHARED="ld -shared";; Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.260 retrieving revision 1.261 diff -C2 -d -r1.260 -r1.261 *** configure.in 2001/09/17 04:03:14 1.260 --- configure.in 2001/09/28 15:59:38 1.261 *************** *** 678,686 **** AIX*) BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" ! LDSHARED="\$(BINLIBDEST)/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/python.exp" ;; BeOS*) BLDSHARED="\$(srcdir)/Modules/ld_so_beos $LDLIBRARY" ! LDSHARED="\$(BINLIBDEST)/ld_so_beos \$(LIBDIR)/$LDLIBRARY" ;; IRIX/5*) LDSHARED="ld -shared";; --- 678,686 ---- AIX*) BLDSHARED="\$(srcdir)/Modules/ld_so_aix \$(CC) -bI:Modules/python.exp" ! LDSHARED="\$(BINLIBDEST)/config/ld_so_aix \$(CC) -bI:\$(BINLIBDEST)/config/python.exp" ;; BeOS*) BLDSHARED="\$(srcdir)/Modules/ld_so_beos $LDLIBRARY" ! LDSHARED="\$(BINLIBDEST)/config/ld_so_beos \$(LIBDIR)/$LDLIBRARY" ;; IRIX/5*) LDSHARED="ld -shared";; From fdrake@users.sourceforge.net Fri Sep 28 17:01:48 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 09:01:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbase64.tex,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26538/lib Modified Files: libbase64.tex Log Message: State that encode() and encodestring() append a newline to the input data if it does not already end with a newline. This fixes SF bug #463330. Index: libbase64.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbase64.tex,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -d -r1.18 -r1.19 *** libbase64.tex 2001/07/14 02:50:55 1.18 --- libbase64.tex 2001/09/28 16:01:46 1.19 *************** *** 41,45 **** \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.read()} returns an empty string. \end{funcdesc} --- 41,47 ---- \var{input} and \var{output} must either be file objects or objects that mimic the file object interface. \var{input} will be read until ! \code{\var{input}.read()} returns an empty string. If the last input ! character is not a newline (\code{'\e n'}), a newline will be added to ! the input data. \end{funcdesc} *************** *** 47,51 **** Encode the string \var{s}, which can contain arbitrary binary data, and return a string containing one or more lines of ! base64 encoded data. \end{funcdesc} --- 49,56 ---- Encode the string \var{s}, which can contain arbitrary binary data, and return a string containing one or more lines of ! base64-encoded data. If the last character of \var{s} is not a ! newline (\code{'\e n'}), a newline will be added. This causes ! \code{encodestring('hello!')} to return the same value as ! \code{encodestring('hello!\e n')}. \end{funcdesc} From fdrake@users.sourceforge.net Fri Sep 28 17:14:20 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 09:14:20 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libos.tex,1.64,1.65 libposixpath.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv30006/lib Modified Files: libos.tex libposixpath.tex Log Message: Added note about non-support of UNC paths on Windows. This fixes SF bug #465447. Index: libos.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libos.tex,v retrieving revision 1.64 retrieving revision 1.65 diff -C2 -d -r1.64 -r1.65 *** libos.tex 2001/09/11 19:56:51 1.64 --- libos.tex 2001/09/28 16:14:18 1.65 *************** *** 635,639 **** leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} ! is \code{0777} (octal). \versionadded{1.5.2} \end{funcdesc} --- 635,640 ---- leaf directory. Throws an \exception{error} exception if the leaf directory already exists or cannot be created. The default \var{mode} ! is \code{0777} (octal). This function does not properly handle UNC ! paths (only relevant on Windows systems). \versionadded{1.5.2} \end{funcdesc} Index: libposixpath.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libposixpath.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -d -r1.19 -r1.20 *** libposixpath.tex 2001/09/17 15:16:09 1.19 --- libposixpath.tex 2001/09/28 16:14:18 1.20 *************** *** 8,11 **** --- 8,15 ---- \index{path!operations} + \strong{Warning:} On Windows, many of these functions do not properly + support UNC pathnames. \function{splitunc()} and \function{ismount()} + do handle them correctly. + \begin{funcdesc}{abspath}{path} From fdrake@users.sourceforge.net Fri Sep 28 17:25:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 09:25:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv esis2sgml.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv32657 Modified Files: esis2sgml.py Log Message: Convert most uses of the string module to string methods. (string.join() lives!) Index: esis2sgml.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/esis2sgml.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** esis2sgml.py 2001/03/23 17:09:02 1.15 --- esis2sgml.py 2001/09/28 16:25:00 1.16 *************** *** 98,102 **** data = escape(data) if not inverbatim: ! data = string.replace(data, "---", "—") ofp.write(data) if "\n" in data: --- 98,102 ---- data = escape(data) if not inverbatim: ! data = data.replace("---", "—") ofp.write(data) if "\n" in data: *************** *** 140,144 **** inverbatim = 0 elif type == "A": ! name, type, value = string.split(data, " ", 2) name = map_gi(name, _attr_map) attrs[name] = esistools.decode(value) --- 140,144 ---- inverbatim = 0 elif type == "A": ! name, type, value = data.split(" ", 2) name = map_gi(name, _attr_map) attrs[name] = esistools.decode(value) *************** *** 166,170 **** if not line: break ! gi = string.strip(line) if gi: d[gi] = gi --- 166,170 ---- if not line: break ! gi = line.strip() if gi: d[gi] = gi *************** *** 178,184 **** def update_gi_map(map, names, fromsgml=1): ! for name in string.split(names, ","): if fromsgml: ! uncased = string.lower(name) else: uncased = name --- 178,184 ---- def update_gi_map(map, names, fromsgml=1): ! for name in names.split(","): if fromsgml: ! uncased = name.lower() else: uncased = name *************** *** 212,216 **** xml = 1 elif opt in ("-a", "--autoclose"): ! autoclose = string.split(arg, ",") elif opt == "--elements-map": elem_names = ("%s,%s" % (elem_names, arg))[1:] --- 212,216 ---- xml = 1 elif opt in ("-a", "--autoclose"): ! autoclose = arg.split(",") elif opt == "--elements-map": elem_names = ("%s,%s" % (elem_names, arg))[1:] *************** *** 242,248 **** global _normalize_case _normalize_case = string.lower ! update_gi_map(_elem_map, string.split(elem_names, ",")) ! update_gi_map(_attr_map, string.split(attr_names, ",")) ! update_gi_map(_values_map, string.split(value_names, ",")) else: global map_gi --- 242,248 ---- global _normalize_case _normalize_case = string.lower ! update_gi_map(_elem_map, elem_names.split(",")) ! update_gi_map(_attr_map, attr_names.split(",")) ! update_gi_map(_values_map, value_names.split(",")) else: global map_gi From fdrake@users.sourceforge.net Fri Sep 28 17:26:15 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 09:26:15 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv esistools.py,1.7,1.8 latex2esis.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv462 Modified Files: esistools.py latex2esis.py Log Message: Convert most uses of the string module to string methods. (string.join() lives!) Index: esistools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/esistools.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** esistools.py 2001/04/21 06:01:53 1.7 --- esistools.py 2001/09/28 16:26:13 1.8 *************** *** 2,6 **** import re - import string import xml.dom.pulldom --- 2,5 ---- *************** *** 183,187 **** if handler: if ' ' in data: ! target, data = string.split(data, None, 1) else: target, data = data, "" --- 182,186 ---- if handler: if ' ' in data: ! target, data = data.split(None, 1) else: target, data = data, "" Index: latex2esis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/latex2esis.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -d -r1.25 -r1.26 *** latex2esis.py 2001/09/25 20:57:36 1.25 --- latex2esis.py 2001/09/28 16:26:13 1.26 *************** *** 110,114 **** self.ofp = ofp self.table = table ! self.line = string.join(map(string.rstrip, ifp.readlines()), "\n") self.preamble = 1 --- 110,114 ---- self.ofp = ofp self.table = table ! self.line = string.join([s.rstrip() for s in ifp.readlines()], "\n") self.preamble = 1 *************** *** 171,175 **** if entry.verbatim: # magic case! ! pos = string.find(line, "\\end{%s}" % macroname) text = line[m.end(1):pos] stack.append(entry.name) --- 171,175 ---- if entry.verbatim: # magic case! ! pos = line.find("\\end{%s}" % macroname) text = line[m.end(1):pos] stack.append(entry.name) *************** *** 411,415 **** def skip_white(line): while line and line[0] in " %\n\t\r": ! line = string.lstrip(line[1:]) return line --- 411,415 ---- def skip_white(line): while line and line[0] in " %\n\t\r": ! line = line[1:].lstrip() return line *************** *** 462,466 **** if attrs.has_key("outputname"): self.__current.outputname = attrs.get("outputname") ! self.__current.endcloses = string.split(attrs.get("endcloses", "")) def end_environment(self): self.end_macro() --- 462,466 ---- if attrs.has_key("outputname"): self.__current.outputname = attrs.get("outputname") ! self.__current.endcloses = attrs.get("endcloses", "").split() def end_environment(self): self.end_macro() *************** *** 469,473 **** name = attrs["name"] self.__current = TableEntry(name) ! self.__current.closes = string.split(attrs.get("closes", "")) if attrs.has_key("outputname"): self.__current.outputname = attrs.get("outputname") --- 469,473 ---- name = attrs["name"] self.__current = TableEntry(name) ! self.__current.closes = attrs.get("closes", "").split() if attrs.has_key("outputname"): self.__current.outputname = attrs.get("outputname") From fdrake@users.sourceforge.net Fri Sep 28 17:57:18 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 09:57:18 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcfgparser.tex,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7815/lib Modified Files: libcfgparser.tex Log Message: Use consistent version annotations instead of something ad hoc. Index: libcfgparser.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcfgparser.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -d -r1.16 -r1.17 *** libcfgparser.tex 2001/02/19 22:37:24 1.16 --- libcfgparser.tex 2001/09/28 16:57:16 1.17 *************** *** 129,133 **** \begin{methoddesc}{has_option}{section, option} If the given section exists, and contains the given option. return 1; ! otherwise return 0. (New in 1.6) \end{methoddesc} --- 129,134 ---- \begin{methoddesc}{has_option}{section, option} If the given section exists, and contains the given option. return 1; ! otherwise return 0. ! \versionadded{1.6} \end{methoddesc} *************** *** 170,174 **** \begin{methoddesc}{set}{section, option, value} If the given section exists, set the given option to the specified value; ! otherwise raise \exception{NoSectionError}. (New in 1.6) \end{methoddesc} --- 171,176 ---- \begin{methoddesc}{set}{section, option, value} If the given section exists, set the given option to the specified value; ! otherwise raise \exception{NoSectionError}. ! \versionadded{1.6} \end{methoddesc} *************** *** 176,180 **** Write a representation of the configuration to the specified file object. This representation can be parsed by a future \method{read()} ! call. (New in 1.6) \end{methoddesc} --- 178,183 ---- Write a representation of the configuration to the specified file object. This representation can be parsed by a future \method{read()} ! call. ! \versionadded{1.6} \end{methoddesc} *************** *** 183,187 **** If the section does not exist, raise \exception{NoSectionError}. If the option existed to be removed, return 1; otherwise return 0. ! (New in 1.6) \end{methoddesc} --- 186,190 ---- If the section does not exist, raise \exception{NoSectionError}. If the option existed to be removed, return 1; otherwise return 0. ! \versionadded{1.6} \end{methoddesc} From bwarsaw@users.sourceforge.net Fri Sep 28 18:01:04 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 28 Sep 2001 10:01:04 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.257,1.258 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv9002 Modified Files: NEWS Log Message: Fixed a minor typo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.257 retrieving revision 1.258 diff -C2 -d -r1.257 -r1.258 *** NEWS 2001/09/28 15:26:12 1.257 --- NEWS 2001/09/28 17:01:02 1.258 *************** *** 118,122 **** simplifies writing XML RPC servers. ! - os.path.realpath(): a new function that returns the absoute pathname after interpretation of symbolic links. On non-Unix systems, this is an alias for os.path.abspath(). --- 118,122 ---- simplifies writing XML RPC servers. ! - os.path.realpath(): a new function that returns the absolute pathname after interpretation of symbolic links. On non-Unix systems, this is an alias for os.path.abspath(). From fdrake@users.sourceforge.net Fri Sep 28 18:14:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 10:14:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv docfixer.py,1.31,1.32 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv12067/tools/sgmlconv Modified Files: docfixer.py Log Message: Convert to string methods. For the real document element, make sure the prolog is migrated into the document element so it isn't left stranded. Make fixup_trailing_whitespace() whitespace do what was really intended. Add the *desc environments used in the C API manual to the list of things that can exist at the paragraph level so they don't get wrapped in .... Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -d -r1.31 -r1.32 *** docfixer.py 2001/09/27 16:52:22 1.31 --- docfixer.py 2001/09/28 17:14:35 1.32 *************** *** 9,13 **** import esistools import re - import string import sys import xml.dom --- 9,12 ---- *************** *** 120,123 **** --- 119,128 ---- if node is not None: set_tagName(node, documentclass) + # Move everything that comes before this node into this node; + # this will be the document element. + nodelist = fragment.childNodes + point = node.firstChild + while not nodelist[0].isSameNode(node): + node.insertBefore(nodelist[0], point) while 1: node = extract_first_element(fragment, "input") *************** *** 252,256 **** last = description.childNodes[-1] if last.nodeType == TEXT: ! last.data = string.rstrip(last.data) + "\n " # 6. # should have nothing but whitespace and signature lines in ; --- 257,261 ---- last = description.childNodes[-1] if last.nodeType == TEXT: ! last.data = last.data.rstrip() + "\n " # 6. # should have nothing but whitespace and signature lines in ; *************** *** 311,315 **** back.appendChild(doc.createTextNode("\n")) while nodes and nodes[0].nodeType == TEXT \ ! and not string.strip(nodes[0].data): del nodes[0] map(back.appendChild, nodes) --- 316,320 ---- back.appendChild(doc.createTextNode("\n")) while nodes and nodes[0].nodeType == TEXT \ ! and not nodes[0].data.strip(): del nodes[0] map(back.appendChild, nodes) *************** *** 334,363 **** children = parent.childNodes if children[-1].nodeType == TEXT: ! children[-1].data = string.rstrip(children[-1].data) ! def fixup_trailing_whitespace(doc, wsmap): ! queue = [doc] while queue: node = queue[0] del queue[0] if wsmap.has_key(node.nodeName): ! ws = wsmap[node.tagName] ! children = node.childNodes ! children.reverse() ! if children[0].nodeType == TEXT: ! data = string.rstrip(children[0].data) + ws ! children[0].data = data ! children.reverse() ! # hack to get the title in place: ! if node.tagName == "title" \ ! and node.parentNode.firstChild.nodeType == ELEMENT: ! node.parentNode.insertBefore(doc.createText("\n "), ! node.parentNode.firstChild) for child in node.childNodes: if child.nodeType == ELEMENT: queue.append(child) def normalize(doc): for node in doc.childNodes: --- 339,382 ---- children = parent.childNodes if children[-1].nodeType == TEXT: ! children[-1].data = children[-1].data.rstrip() ! def fixup_trailing_whitespace(doc, fragment, wsmap): ! queue = [fragment] ! fixups = [] while queue: node = queue[0] del queue[0] if wsmap.has_key(node.nodeName): ! fixups.append(node) for child in node.childNodes: if child.nodeType == ELEMENT: queue.append(child) + # reverse the list to process from the inside out + fixups.reverse() + for node in fixups: + node.parentNode.normalize() + lastchild = node.lastChild + before, after = wsmap[node.tagName] + if lastchild.nodeType == TEXT: + data = lastchild.data.rstrip() + before + lastchild.data = data + norm = 0 + if wsmap[node.tagName]: + nextnode = node.nextSibling + if nextnode and nextnode.nodeType == TEXT: + nextnode.data = after + nextnode.data.lstrip() + else: + wsnode = doc.createTextNode(after) + node.parentNode.insertBefore(wsnode, nextnode) + # hack to get the title in place: + if node.tagName == "title" \ + and node.parentNode.firstChild.nodeType == ELEMENT: + node.parentNode.insertBefore(doc.createTextNode("\n "), + node.parentNode.firstChild) + node.parentNode.normalize() + def normalize(doc): for node in doc.childNodes: *************** *** 462,466 **** first_data = children[1] if first_data.data[:4] == " ---": ! first_data.data = string.lstrip(first_data.data[4:]) set_tagName(title, "short-synopsis") if children[-1].nodeType == TEXT \ --- 481,485 ---- first_data = children[1] if first_data.data[:4] == " ---": ! first_data.data = first_data.data[4:].lstrip() set_tagName(title, "short-synopsis") if children[-1].nodeType == TEXT \ *************** *** 505,510 **** if nextnode.nodeType == TEXT: data = nextnode.data ! if len(string.lstrip(data)) < (len(data) - 4): ! nextnode.data = "\n\n\n" + string.lstrip(data) --- 524,530 ---- if nextnode.nodeType == TEXT: data = nextnode.data ! s = data.lstrip() ! if len(s) < (len(data) - 4): ! nextnode.data = "\n\n\n" + s *************** *** 547,551 **** nodeType = child.nodeType if nodeType == TEXT: ! if string.strip(child.data): raise ConversionError("unexpected free data in <%s>: %r" % (table.tagName, child.data)) --- 567,571 ---- nodeType = child.nodeType if nodeType == TEXT: ! if child.data.strip(): raise ConversionError("unexpected free data in <%s>: %r" % (table.tagName, child.data)) *************** *** 606,609 **** --- 626,630 ---- "interpreter-session", "back-matter", "interactive-session", "opcodedesc", "classdesc", "datadesc", + "cfuncdesc", "ctypedesc", "cvardesc", "funcdesc", "methoddesc", "excdesc", "memberdesc", "membderdescni", "funcdescni", "methoddescni", "excdescni", *************** *** 663,667 **** break elif nodeType == TEXT: ! pos = string.find(child.data, "\n\n") if pos == 0: after = j --- 684,688 ---- break elif nodeType == TEXT: ! pos = child.data.find("\n\n") if pos == 0: after = j *************** *** 679,685 **** child = children[after - 1] data = child.data ! if string.rstrip(data) != data: have_last = 0 ! child.splitText(len(string.rstrip(data))) para = doc.createElement(PARA_ELEMENT) prev = None --- 700,706 ---- child = children[after - 1] data = child.data ! if data.rstrip() != data: have_last = 0 ! child.splitText(len(data.rstrip())) para = doc.createElement(PARA_ELEMENT) prev = None *************** *** 724,728 **** if nodeType == TEXT: data = child.data ! shortened = string.lstrip(data) if shortened: if data != shortened: --- 745,749 ---- if nodeType == TEXT: data = child.data ! shortened = data.lstrip() if shortened: if data != shortened: *************** *** 796,800 **** child = verbatim.childNodes[0] if child.nodeType == TEXT \ ! and string.lstrip(child.data)[:3] == ">>>": set_tagName(verbatim, "interactive-session") --- 817,821 ---- child = verbatim.childNodes[0] if child.nodeType == TEXT \ ! and child.data.lstrip().startswith(">>>"): set_tagName(verbatim, "interactive-session") *************** *** 974,986 **** handle_labels(doc, fragment) handle_appendix(doc, fragment) ! fixup_trailing_whitespace(doc, { ! "abstract": "\n", ! "title": "", ! "chapter": "\n\n", ! "section": "\n\n", ! "subsection": "\n\n", ! "subsubsection": "\n\n", ! "paragraph": "\n\n", ! "subparagraph": "\n\n", }) cleanup_root_text(doc) --- 995,1009 ---- handle_labels(doc, fragment) handle_appendix(doc, fragment) ! fixup_trailing_whitespace(doc, fragment, { ! # element -> (before-end-tag, after-end-tag) ! "abstract": ("\n", "\n"), ! "title": ("", "\n"), ! "chapter": ("\n", "\n\n\n"), ! "section": ("\n", "\n\n\n"), ! "subsection": ("\n", "\n\n"), ! "subsubsection": ("\n", "\n\n"), ! "paragraph": ("\n", "\n\n"), ! "subparagraph": ("\n", "\n\n"), ! "enumeration": ("\n", "\n\n"), }) cleanup_root_text(doc) From bwarsaw@users.sourceforge.net Fri Sep 28 18:15:25 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 28 Sep 2001 10:15:25 -0700 Subject: [Python-checkins] CVS: python/dist/src/Include patchlevel.h,2.54,2.55 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv12228 Modified Files: patchlevel.h Log Message: PY_RELEASE_SERIAL => 4 PY_VERSION => "2.2a4+" Index: patchlevel.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/patchlevel.h,v retrieving revision 2.54 retrieving revision 2.55 diff -C2 -d -r2.54 -r2.55 *** patchlevel.h 2001/09/07 18:23:30 2.54 --- patchlevel.h 2001/09/28 17:15:23 2.55 *************** *** 24,31 **** #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 3 /* Version as a string */ ! #define PY_VERSION "2.2a3+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. --- 24,31 ---- #define PY_MICRO_VERSION 0 #define PY_RELEASE_LEVEL PY_RELEASE_LEVEL_ALPHA ! #define PY_RELEASE_SERIAL 4 /* Version as a string */ ! #define PY_VERSION "2.2a4+" /* Version as a single 4-byte hex number, e.g. 0x010502B2 == 1.5.2b2. From bwarsaw@users.sourceforge.net Fri Sep 28 18:16:39 2001 From: bwarsaw@users.sourceforge.net (Barry Warsaw) Date: Fri, 28 Sep 2001 10:16:39 -0700 Subject: [Python-checkins] CVS: python/nondist/peps pep-0101.txt,1.5,1.6 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv12465 Modified Files: pep-0101.txt Log Message: A couple of minor corrections based on 2.2a4 experience. For the most part, this looks darn good! Index: pep-0101.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0101.txt,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** pep-0101.txt 2001/09/08 05:17:56 1.5 --- pep-0101.txt 2001/09/28 17:16:35 1.6 *************** *** 68,72 **** You'll be doing a lot of work in this directory and you want to keep it straight from your trunk working directory. E.g. ! % cvs -d -q co -d python-22a3 -r 22a3-branch python/dist/src - Send an email to python-dev@python.org indicating the fork and --- 68,72 ---- You'll be doing a lot of work in this directory and you want to keep it straight from your trunk working directory. E.g. ! % cvs -d -q co -d python-22a3 -r r22a3-branch python/dist/src - Send an email to python-dev@python.org indicating the fork and *************** *** 433,437 **** #define PY_VERSION "2.2a2+" ! Commit this change. * Now test your clean, merged trunk by doing --- 433,438 ---- #define PY_VERSION "2.2a2+" ! Make sure that the other PY_ version macros contain the ! correct values. Commit this change. * Now test your clean, merged trunk by doing From fdrake@users.sourceforge.net Fri Sep 28 18:22:37 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 10:22:37 -0700 Subject: [Python-checkins] CVS: python/dist/src/Tools/compiler/doc astdocgen.py,1.2,NONE asttable.tex,1.2,NONE compiler.tex,1.6,NONE Message-ID: Update of /cvsroot/python/python/dist/src/Tools/compiler/doc In directory usw-pr-cvs1:/tmp/cvs-serv13847 Removed Files: astdocgen.py asttable.tex compiler.tex Log Message: Removed files no longer needed. --- astdocgen.py DELETED --- --- asttable.tex DELETED --- --- compiler.tex DELETED --- From gvanrossum@users.sourceforge.net Fri Sep 28 19:13:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 11:13:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib copy.py,1.20,1.21 copy_reg.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv22311/Lib Modified Files: copy.py copy_reg.py Log Message: Changes to copy() and deepcopy() in copy.py to support __reduce__ as a fallback for objects that are neither supported by our dispatch table nor have a __copy__ or __deepcopy__ method. Changes to _reduce() in copy_reg.py to support reducing objects that don't have a __dict__ -- copy.copy(complex()) now invokes _reduce(). Add tests for copy.copy() and copy.deepcopy() to test_regrtest.py. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** copy.py 2001/08/17 18:39:24 1.20 --- copy.py 2001/09/28 18:13:29 1.21 *************** *** 62,66 **** PyStringMap = None ! __all__ = ["Error","error","copy","deepcopy"] def copy(x): --- 62,66 ---- PyStringMap = None ! __all__ = ["Error", "error", "copy", "deepcopy"] def copy(x): *************** *** 76,82 **** copier = x.__copy__ except AttributeError: ! raise error, \ ! "un(shallow)copyable object of type %s" % type(x) ! y = copier() else: y = copierfunction(x) --- 76,88 ---- copier = x.__copy__ except AttributeError: ! try: ! reductor = x.__reduce__ ! except AttributeError: ! raise error, \ ! "un(shallow)copyable object of type %s" % type(x) ! else: ! y = _reconstruct(x, reductor(), 0) ! else: ! y = copier() else: y = copierfunction(x) *************** *** 157,163 **** copier = x.__deepcopy__ except AttributeError: ! raise error, \ ! "un-deep-copyable object of type %s" % type(x) ! y = copier(memo) else: y = copierfunction(x, memo) --- 163,175 ---- copier = x.__deepcopy__ except AttributeError: ! try: ! reductor = x.__reduce__ ! except AttributeError: ! raise error, \ ! "un-deep-copyable object of type %s" % type(x) ! else: ! y = _reconstruct(x, reductor(), 1) ! else: ! y = copier(memo) else: y = copierfunction(x, memo) *************** *** 259,262 **** --- 271,294 ---- return y d[types.InstanceType] = _deepcopy_inst + + def _reconstruct(x, info, deep): + if isinstance(info, str): + return x + assert isinstance(info, tuple) + n = len(info) + assert n in (2, 3) + callable, args = info[:2] + if n > 2: + state = info[2] + else: + state = {} + if deep: + args = deepcopy(args) + y = callable(*args) + if state: + if deep: + state = deepcopy(state) + y.__dict__.update(state) + return y del d Index: copy_reg.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy_reg.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** copy_reg.py 2001/09/25 19:46:05 1.7 --- copy_reg.py 2001/09/28 18:13:29 1.8 *************** *** 55,57 **** else: state = base(self) ! return _reconstructor, (self.__class__, base, state), self.__dict__ --- 55,65 ---- else: state = base(self) ! args = (self.__class__, base, state) ! try: ! dict = self.__dict__ ! except AttributeError: ! dict = None ! if dict: ! return _reconstructor, args, dict ! else: ! return _reconstructor, args From gvanrossum@users.sourceforge.net Fri Sep 28 19:13:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 11:13:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.76,1.77 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22311/Lib/test Modified Files: test_descr.py Log Message: Changes to copy() and deepcopy() in copy.py to support __reduce__ as a fallback for objects that are neither supported by our dispatch table nor have a __copy__ or __deepcopy__ method. Changes to _reduce() in copy_reg.py to support reducing objects that don't have a __dict__ -- copy.copy(complex()) now invokes _reduce(). Add tests for copy.copy() and copy.deepcopy() to test_regrtest.py. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.76 retrieving revision 1.77 diff -C2 -d -r1.76 -r1.77 *** test_descr.py 2001/09/25 16:25:58 1.76 --- test_descr.py 2001/09/28 18:13:29 1.77 *************** *** 2034,2038 **** def pickles(): ! if verbose: print "Testing pickling new-style classes and objects..." import pickle, cPickle --- 2034,2039 ---- def pickles(): ! if verbose: ! print "Testing pickling and copying new-style classes and objects..." import pickle, cPickle *************** *** 2093,2097 **** --- 2094,2138 ---- print "b = y =", b + # Testing copy.deepcopy() + import copy + for cls in C, C1, C2: + cls2 = copy.deepcopy(cls) + verify(cls2 is cls) + + a = C1(1, 2); a.append(42); a.append(24) + b = C2("hello", "world", 42) + x, y = copy.deepcopy((a, b)) + assert x.__class__ == a.__class__ + assert sorteditems(x.__dict__) == sorteditems(a.__dict__) + assert y.__class__ == b.__class__ + assert sorteditems(y.__dict__) == sorteditems(b.__dict__) + assert `x` == `a` + assert `y` == `b` + if verbose: + print "a = x =", a + print "b = y =", b + + def copies(): + if verbose: print "Testing copy.copy() and copy.deepcopy()..." + import copy + class C(object): + pass + + a = C() + a.foo = 12 + b = copy.copy(a) + verify(b.__dict__ == a.__dict__) + + a.bar = [1,2,3] + c = copy.copy(a) + verify(c.bar == a.bar) + verify(c.bar is a.bar) + d = copy.deepcopy(a) + verify(d.__dict__ == a.__dict__) + a.bar.append(4) + verify(d.bar == [1,2,3]) + + def test_main(): lists() *************** *** 2137,2140 **** --- 2178,2182 ---- setclass() pickles() + copies() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Fri Sep 28 19:16:16 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 11:16:16 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib copy.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25906 Modified Files: copy.py Log Message: Add complex to the dispatch tables, to avoid going through the whole rigmarole of __reduce__. Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -d -r1.21 -r1.22 *** copy.py 2001/09/28 18:13:29 1.21 --- copy.py 2001/09/28 18:16:13 1.22 *************** *** 97,100 **** --- 97,104 ---- d[types.LongType] = _copy_atomic d[types.FloatType] = _copy_atomic + try: + d[types.ComplexType] = _copy_atomic + except AttributeError: + pass d[types.StringType] = _copy_atomic try: *************** *** 185,188 **** --- 189,196 ---- d[types.LongType] = _deepcopy_atomic d[types.FloatType] = _deepcopy_atomic + try: + d[types.ComplexType] = _deepcopy_atomic + except AttributeError: + pass d[types.StringType] = _deepcopy_atomic try: From gvanrossum@users.sourceforge.net Fri Sep 28 19:19:24 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 11:19:24 -0700 Subject: [Python-checkins] CVS: python/dist/src PLAN.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv26504 Modified Files: PLAN.txt Log Message: Reorder Still To Do items (highest priority on top), add one. Index: PLAN.txt =================================================================== RCS file: /cvsroot/python/python/dist/src/PLAN.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -d -r1.10 -r1.11 *** PLAN.txt 2001/09/25 06:20:52 1.10 --- PLAN.txt 2001/09/28 18:19:21 1.11 *************** *** 5,8 **** --- 5,22 ---- ----------- + Treat all binary operators the same way as I just did for rich + comparison: in a b, if isinstance(b, type(a)), try b.__rop__(a) + before trying a.__op__(b). + + Make __dynamic__ the default (this requires more performance work -- + one particular test, test_descr.inherits(), is about 10x slower when + __dynamic__ is 1. :-( + + Add __del__ handlers. + + Allow assignment to __bases__ and __dict__? + + Support mixed multiple inheritance from classic and new-style classes? + Check for conflicts between base classes. I fear that the rules used to decide whether multiple bases have conflicting instance variables *************** *** 16,31 **** conflict, and should be disallowed; currently the test for this is not implemented. - - Allow assignment to __bases__ and __dict__? - - Make __dynamic__ the default. - - Add __del__ handlers. - - Add __coerce__? - - Support pickling (via __reduce__) - - Support mixed multiple inheritance from classic and new-style classes? Done (mostly) --- 30,33 ---- From fdrake@users.sourceforge.net Fri Sep 28 20:01:28 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 12:01:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib weakref.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4234 Modified Files: weakref.py Log Message: Clean up circular references in the Weak*Dictionary classes; this avoids depending on the cycle detector code in the library implementation. This is a *slightly* different patch than SF patch #417795, but takes the same approach. (This version avoids calling the __len__() method of the dict in the remove() functions.) This closes SF patch #417795. Index: weakref.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/weakref.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -d -r1.12 -r1.13 *** weakref.py 2001/09/06 14:51:01 1.12 --- weakref.py 2001/09/28 19:01:26 1.13 *************** *** 52,58 **** def __setitem__(self, key, value): ! def remove(o, data=self.data, key=key): ! del data[key] ! self.data[key] = ref(value, remove) def copy(self): --- 52,56 ---- def __setitem__(self, key, value): ! self.data[key] = ref(value, self.__makeremove(key)) def copy(self): *************** *** 106,112 **** wr = self.data[key] except KeyError: ! def remove(o, data=self.data, key=key): ! del data[key] ! self.data[key] = ref(default, remove) return default else: --- 104,108 ---- wr = self.data[key] except KeyError: ! self.data[key] = ref(default, self.__makeremove(key)) return default else: *************** *** 116,122 **** d = self.data for key, o in dict.items(): ! def remove(o, data=d, key=key): ! del data[key] ! d[key] = ref(o, remove) def values(self): --- 112,116 ---- d = self.data for key, o in dict.items(): ! d[key] = ref(o, self.__makeremove(key)) def values(self): *************** *** 128,131 **** --- 122,132 ---- return L + def __makeremove(self, key): + def remove(o, selfref=ref(self), key=key): + self = selfref() + if self is not None: + del self.data[key] + return remove + class WeakKeyDictionary(UserDict.UserDict): *************** *** 143,148 **** self.data = {} if dict is not None: self.update(dict) ! def remove(k, data=self.data): ! del data[k] self._remove = remove --- 144,151 ---- self.data = {} if dict is not None: self.update(dict) ! def remove(k, selfref=ref(self)): ! self = selfref() ! if self is not None: ! del self.data[k] self._remove = remove From gvanrossum@users.sourceforge.net Fri Sep 28 21:00:31 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 13:00:31 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules getpath.c,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21822 Modified Files: getpath.c Log Message: Be more rigorous about making pathnames absolute, to address SF bug #424002. Refactor init_path_from_argv0() and rename to copy_absolute(); add absolutize() which does the same in-place. Clean up whitespace (leading tabs -> spaces, delete trailing spaces/tabs). Index: getpath.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/getpath.c,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** getpath.c 2001/08/15 01:14:40 1.38 --- getpath.c 2001/09/28 20:00:29 1.39 *************** *** 114,118 **** #ifndef PYTHONPATH #define PYTHONPATH PREFIX "/lib/python" VERSION ":" \ ! EXEC_PREFIX "/lib/python" VERSION "/lib-dynload" #endif --- 114,118 ---- #ifndef PYTHONPATH #define PYTHONPATH PREFIX "/lib/python" VERSION ":" \ ! EXEC_PREFIX "/lib/python" VERSION "/lib-dynload" #endif *************** *** 120,124 **** #define LANDMARK "os.py" #endif ! static char prefix[MAXPATHLEN+1]; static char exec_prefix[MAXPATHLEN+1]; --- 120,124 ---- #define LANDMARK "os.py" #endif ! static char prefix[MAXPATHLEN+1]; static char exec_prefix[MAXPATHLEN+1]; *************** *** 138,142 **** static int ! isfile(char *filename) /* Is file, not directory */ { struct stat buf; --- 138,142 ---- static int ! isfile(char *filename) /* Is file, not directory */ { struct stat buf; *************** *** 150,154 **** static int ! ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */ { if (isfile(filename)) --- 150,154 ---- static int ! ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */ { if (isfile(filename)) *************** *** 166,170 **** static int ! isxfile(char *filename) /* Is executable file */ { struct stat buf; --- 166,170 ---- static int ! isxfile(char *filename) /* Is executable file */ { struct stat buf; *************** *** 180,184 **** static int ! isdir(char *filename) /* Is directory */ { struct stat buf; --- 180,184 ---- static int ! isdir(char *filename) /* Is directory */ { struct stat buf; *************** *** 214,240 **** } ! /* init_path_from_argv0 requires that path be allocated at least ! MAXPATHLEN + 1 bytes and that argv0_path be no more than MAXPATHLEN ! bytes. ! */ static void ! init_path_from_argv0(char *path, char *argv0_path) { ! if (argv0_path[0] == '/') ! strcpy(path, argv0_path); ! else if (argv0_path[0] == '.') { ! getcwd(path, MAXPATHLEN); ! if (argv0_path[1] == '/') ! joinpath(path, argv0_path + 2); ! else ! joinpath(path, argv0_path); ! } else { ! getcwd(path, MAXPATHLEN); ! joinpath(path, argv0_path); } } ! /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ --- 214,245 ---- } ! /* copy_absolute requires that path be allocated at least ! MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */ static void ! copy_absolute(char *path, char *p) { ! if (p[0] == SEP) ! strcpy(path, p); else { ! getcwd(path, MAXPATHLEN); ! if (p[0] == '.' && p[1] == SEP) ! p += 2; ! joinpath(path, p); } } ! /* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */ ! static void ! absolutize(char *path) ! { ! char buffer[MAXPATHLEN + 1]; ! ! if (path[0] == SEP) ! return; ! copy_absolute(buffer, path); ! strcpy(path, buffer); ! } ! ! /* search_for_prefix requires that argv0_path be no more than MAXPATHLEN bytes long. */ *************** *** 272,276 **** /* Search from argv0_path, until root is found */ ! init_path_from_argv0(prefix, argv0_path); do { n = strlen(prefix); --- 277,281 ---- /* Search from argv0_path, until root is found */ ! copy_absolute(prefix, argv0_path); do { n = strlen(prefix); *************** *** 296,300 **** /* search_for_exec_prefix requires that argv0_path be no more than ! MAXPATHLEN bytes long. */ static int --- 301,305 ---- /* search_for_exec_prefix requires that argv0_path be no more than ! MAXPATHLEN bytes long. */ static int *************** *** 325,329 **** /* Search from argv0_path, until root is found */ ! init_path_from_argv0(exec_prefix, argv0_path); do { n = strlen(exec_prefix); --- 330,334 ---- /* Search from argv0_path, until root is found */ ! copy_absolute(exec_prefix, argv0_path); do { n = strlen(exec_prefix); *************** *** 369,373 **** NSModule pythonModule; #endif ! #ifdef WITH_NEXT_FRAMEWORK pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); --- 374,378 ---- NSModule pythonModule; #endif ! #ifdef WITH_NEXT_FRAMEWORK pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize")); *************** *** 388,398 **** joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { ! /* We are in the build directory so use the name of the ! executable - we know that the absolute path is passed */ ! strncpy(progpath, prog, MAXPATHLEN); } else { ! /* Use the location of the library as the progpath */ ! strncpy(progpath, buf, MAXPATHLEN); } } --- 393,403 ---- joinpath(argv0_path, LANDMARK); if (!ismodule(argv0_path)) { ! /* We are in the build directory so use the name of the ! executable - we know that the absolute path is passed */ ! strncpy(progpath, prog, MAXPATHLEN); } else { ! /* Use the location of the library as the progpath */ ! strncpy(progpath, buf, MAXPATHLEN); } } *************** *** 401,414 **** (even though NSNameOfModule() probably does the same thing.) */ #endif ! ! /* If there is no slash in the argv0 path, then we have to ! * assume python is on the user's $PATH, since there's no ! * other way to find a directory to start the search from. If ! * $PATH isn't exported, you lose. ! */ ! if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); ! else if (path) { ! int bufspace = MAXPATHLEN; while (1) { char *delim = strchr(path, DELIM); --- 406,418 ---- (even though NSNameOfModule() probably does the same thing.) */ #endif ! ! /* If there is no slash in the argv0 path, then we have to ! * assume python is on the user's $PATH, since there's no ! * other way to find a directory to start the search from. If ! * $PATH isn't exported, you lose. ! */ ! if (strchr(prog, SEP)) strncpy(progpath, prog, MAXPATHLEN); ! else if (path) { while (1) { char *delim = strchr(path, DELIM); *************** *** 416,427 **** if (delim) { size_t len = delim - path; ! if (len > bufspace) ! len = bufspace; strncpy(progpath, path, len); *(progpath + len) = '\0'; - bufspace -= len; } else ! strncpy(progpath, path, bufspace); joinpath(progpath, prog); --- 420,430 ---- if (delim) { size_t len = delim - path; ! if (len > MAXPATHLEN) ! len = MAXPATHLEN; strncpy(progpath, path, len); *(progpath + len) = '\0'; } else ! strncpy(progpath, path, MAXPATHLEN); joinpath(progpath, prog); *************** *** 435,441 **** path = delim + 1; } ! } ! else progpath[0] = '\0'; #ifdef WITH_NEXT_FRAMEWORK } --- 438,446 ---- path = delim + 1; } ! } ! else progpath[0] = '\0'; + if (progpath[0] != SEP) + absolutize(progpath); #ifdef WITH_NEXT_FRAMEWORK } *************** *** 443,447 **** strncpy(argv0_path, progpath, MAXPATHLEN); ! #if HAVE_READLINK { --- 448,452 ---- strncpy(argv0_path, progpath, MAXPATHLEN); ! #if HAVE_READLINK { *************** *** 452,457 **** tmpbuffer[linklen] = '\0'; if (tmpbuffer[0] == SEP) ! /* tmpbuffer should never be longer than MAXPATHLEN, ! but extra check does not hurt */ strncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { --- 457,462 ---- tmpbuffer[linklen] = '\0'; if (tmpbuffer[0] == SEP) ! /* tmpbuffer should never be longer than MAXPATHLEN, ! but extra check does not hurt */ strncpy(argv0_path, tmpbuffer, MAXPATHLEN); else { *************** *** 473,477 **** if (!Py_FrozenFlag) fprintf(stderr, ! "Could not find platform independent libraries \n"); strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); --- 478,482 ---- if (!Py_FrozenFlag) fprintf(stderr, ! "Could not find platform independent libraries \n"); strncpy(prefix, PREFIX, MAXPATHLEN); joinpath(prefix, lib_python); *************** *** 479,487 **** else reduce(prefix); ! if (!(efound = search_for_exec_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, ! "Could not find platform dependent libraries \n"); strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, "lib/lib-dynload"); --- 484,492 ---- else reduce(prefix); ! if (!(efound = search_for_exec_prefix(argv0_path, home))) { if (!Py_FrozenFlag) fprintf(stderr, ! "Could not find platform dependent libraries \n"); strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN); joinpath(exec_prefix, "lib/lib-dynload"); From fdrake@users.sourceforge.net Fri Sep 28 21:05:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 13:05:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test README,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22877 Modified Files: README Log Message: Reflect recent refinements of the regression testing framework. Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/README,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** README 2001/09/10 01:39:21 1.11 --- README 2001/09/28 20:05:25 1.12 *************** *** 37,48 **** the interface and general guidelines on writing PyUnit based tests. ! The test_support helper module provides a single function for use by PyUnit based tests in the Python regression testing framework: run_unittest() takes a unittest.TestCase derived class as a parameter ! and runs the tests defined in that class. All test methods in the ! Python regression framework have names that start with "test_" and use ! lower-case names with words separated with underscores. doctest based tests --- 37,68 ---- the interface and general guidelines on writing PyUnit based tests. ! The test_support helper module provides a two functions for use by PyUnit based tests in the Python regression testing framework: run_unittest() takes a unittest.TestCase derived class as a parameter ! and runs the tests defined in that class, and run_suite() takes a ! populated TestSuite instance and runs the tests.. All test methods in ! the Python regression framework have names that start with "test_" and ! use lower-case names with words separated with underscores. ! ! All PyUnit-based tests in the Python test suite use boilerplate that ! looks like this: ! ! import unittest ! import test_support ! ! class MyTestCase(unittest.TestCase): ! # define test methods here... ! ! def test_main(): ! test_support.run_unittest(MyTestCase) + if __name__ == "__main__": + test_main() + + This has the advantage that it allows the unittest module to be used + as a script to run individual tests as well as working well with the + regrtest framework. + doctest based tests *************** *** 342,348 **** getting imported. After importing test_spam, regrtest also executes test_spam.test_main(), if test_spam has a "test_main" attribute. ! This is rarely needed, and you shouldn't create a module global ! with name test_main unless you're specifically exploiting this ! gimmick. In such cases, please put a comment saying so near your ! def test_main, because this feature is so rarely used it's not ! obvious when reading the test code. --- 362,372 ---- getting imported. After importing test_spam, regrtest also executes test_spam.test_main(), if test_spam has a "test_main" attribute. ! This is rarely required with the "traditional" Python tests, and ! you shouldn't create a module global with name test_main unless ! you're specifically exploiting this gimmick. This usage does ! prove useful with PyUnit-based tests as well, however; defining ! a test_main() which is run by regrtest and a script-stub in the ! test module ("if __name__ == '__main__': test_main()") allows ! the test to be used like any other Python test and also work ! with the unittest.py-as-a-script approach, allowing a developer ! to run specific tests from the command line. From tim_one@users.sourceforge.net Fri Sep 28 21:14:48 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 28 Sep 2001 13:14:48 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24377/python/Lib/test Modified Files: regrtest.py Log Message: regrtest's -g option stopped working, during the changes to improve error-reporting for the classic compare-expected-output tests. Curiously, the bug consisted of not simplifying the logic enough! Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -d -r1.57 -r1.58 *** regrtest.py 2001/09/25 20:05:11 1.57 --- regrtest.py 2001/09/28 20:14:46 1.58 *************** *** 284,288 **** outputdir = os.path.join(testdir, "output") outputfile = os.path.join(outputdir, test) ! if verbose or generate: cfp = None else: --- 284,288 ---- outputdir = os.path.join(testdir, "output") outputfile = os.path.join(outputdir, test) ! if verbose: cfp = None else: From fdrake@users.sourceforge.net Fri Sep 28 21:16:32 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 13:16:32 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test regrtest.py,1.58,1.59 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv24995/test Modified Files: regrtest.py Log Message: Remove an infelicitous space. Index: regrtest.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/regrtest.py,v retrieving revision 1.58 retrieving revision 1.59 diff -C2 -d -r1.58 -r1.59 *** regrtest.py 2001/09/28 20:14:46 1.58 --- regrtest.py 2001/09/28 20:16:30 1.59 *************** *** 287,291 **** cfp = None else: ! cfp = StringIO.StringIO() try: save_stdout = sys.stdout --- 287,291 ---- cfp = None else: ! cfp = StringIO.StringIO() try: save_stdout = sys.stdout From fdrake@users.sourceforge.net Fri Sep 28 21:25:47 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 13:25:47 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.37,1.38 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv27033/xml/dom Modified Files: minidom.py Log Message: Tighten up the new NodeList implementation. Clean up a little; do not create an alias that is only used once, or store attributes with constant values in an instance. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.37 retrieving revision 1.38 diff -C2 -d -r1.37 -r1.38 *** minidom.py 2001/09/28 04:33:06 1.37 --- minidom.py 2001/09/28 20:25:45 1.38 *************** *** 31,47 **** import xml.dom - _Node = xml.dom.Node if list is type([]): class NodeList(list): def item(self, index): if 0 <= index < len(self): return self[index] ! def __getattr__(self, name): ! if name == "length": ! return len(self) ! raise AttributeError, name else: --- 31,46 ---- import xml.dom if list is type([]): class NodeList(list): + __dynamic__ = 0 + def item(self, index): if 0 <= index < len(self): return self[index] ! length = property(lambda self: len(self), ! doc="The number of nodes in the NodeList.") else: *************** *** 50,54 **** ! class Node(_Node): allnodes = {} _debug = 0 --- 49,53 ---- ! class Node(xml.dom.Node): allnodes = {} _debug = 0 *************** *** 57,64 **** childNodeTypes = () namespaceURI = None # this is non-null only for elements and attributes def __init__(self): self.childNodes = NodeList() - self.parentNode = self.ownerDocument = None if Node._debug: index = repr(id(self)) + repr(self.__class__) --- 56,64 ---- childNodeTypes = () namespaceURI = None # this is non-null only for elements and attributes + parentNode = None + ownerDocument = None def __init__(self): self.childNodes = NodeList() if Node._debug: index = repr(id(self)) + repr(self.__class__) From akuchling@users.sourceforge.net Fri Sep 28 21:29:17 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Fri, 28 Sep 2001 13:29:17 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.59,1.60 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv28358 Modified Files: Makefile.pre.in Log Message: Install the new compiler and email packages Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -d -r1.59 -r1.60 *** Makefile.pre.in 2001/09/18 02:40:21 1.59 --- Makefile.pre.in 2001/09/28 20:29:15 1.60 *************** *** 577,580 **** --- 577,581 ---- XMLLIBSUBDIRS= xml xml/dom xml/parsers xml/sax LIBSUBDIRS= lib-old lib-tk site-packages test test/output encodings \ + email compiler \ distutils distutils/command $(XMLLIBSUBDIRS) curses $(MACHDEPS) libinstall: $(PYTHON) $(srcdir)/Lib/$(PLATDIR) From fdrake@users.sourceforge.net Fri Sep 28 21:31:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 13:31:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_minidom,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv29274/output Modified Files: test_minidom Log Message: Update the xml.dom.minidom tests to cover the DOM-compliant parts of the NodeList interface. Index: test_minidom =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_minidom,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** test_minidom 2001/06/03 14:27:02 1.13 --- test_minidom 2001/09/28 20:31:50 1.14 *************** *** 125,128 **** --- 125,131 ---- Test Succeeded testLegalChildren Passed assertion: len(Node.allnodes) == 0 + Passed test NodeList.item() + Test Succeeded testNodeListItem + Passed assertion: len(Node.allnodes) == 0 Passed Test Passed Test From fdrake@users.sourceforge.net Fri Sep 28 21:31:52 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 13:31:52 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_minidom.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv29274 Modified Files: test_minidom.py Log Message: Update the xml.dom.minidom tests to cover the DOM-compliant parts of the NodeList interface. Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** test_minidom.py 2001/06/03 14:27:02 1.27 --- test_minidom.py 2001/09/28 20:31:50 1.28 *************** *** 45,50 **** --- 45,53 ---- root.insertBefore(nelem, elem) confirm(len(root.childNodes) == 2 + and root.childNodes.length == 2 and root.childNodes[0] is nelem + and root.childNodes.item(0) is nelem and root.childNodes[1] is elem + and root.childNodes.item(1) is elem and root.firstChild is nelem and root.lastChild is elem *************** *** 54,59 **** --- 57,65 ---- root.insertBefore(nelem, None) confirm(len(root.childNodes) == 3 + and root.childNodes.length == 3 and root.childNodes[1] is elem + and root.childNodes.item(1) is elem and root.childNodes[2] is nelem + and root.childNodes.item(2) is nelem and root.lastChild is nelem and nelem.previousSibling is elem *************** *** 63,68 **** --- 69,77 ---- root.insertBefore(nelem2, nelem) confirm(len(root.childNodes) == 4 + and root.childNodes.length == 4 and root.childNodes[2] is nelem2 + and root.childNodes.item(2) is nelem2 and root.childNodes[3] is nelem + and root.childNodes.item(3) is nelem and nelem2.nextSibling is nelem and nelem.previousSibling is nelem2 *************** *** 370,373 **** --- 379,383 ---- dom, clone = _setupCloneElement(0) confirm(len(clone.childNodes) == 0 + and clone.childNodes.length == 0 and clone.parentNode is None and clone.toxml() == '' *************** *** 378,381 **** --- 388,392 ---- dom, clone = _setupCloneElement(1) confirm(len(clone.childNodes) == 1 + and clone.childNodes.length == 1 and clone.parentNode is None and clone.toxml() == '' *************** *** 433,439 **** root.appendChild(doc.createTextNode("first")) root.appendChild(doc.createTextNode("second")) ! confirm(len(root.childNodes) == 2, "testNormalize -- preparation") doc.normalize() confirm(len(root.childNodes) == 1 and root.firstChild is root.lastChild and root.firstChild.data == "firstsecond" --- 444,452 ---- root.appendChild(doc.createTextNode("first")) root.appendChild(doc.createTextNode("second")) ! confirm(len(root.childNodes) == 2 ! and root.childNodes.length == 2, "testNormalize -- preparation") doc.normalize() confirm(len(root.childNodes) == 1 + and root.childNodes.length == 1 and root.firstChild is root.lastChild and root.firstChild.data == "firstsecond" *************** *** 445,449 **** root.appendChild(doc.createTextNode("")) doc.normalize() ! confirm(len(root.childNodes) == 0, "testNormalize -- single empty node removed") doc.unlink() --- 458,463 ---- root.appendChild(doc.createTextNode("")) doc.normalize() ! confirm(len(root.childNodes) == 0 ! and root.childNodes.length == 0, "testNormalize -- single empty node removed") doc.unlink() *************** *** 476,479 **** --- 490,505 ---- elm3.parentNode is elm2b, "testParents") + doc.unlink() + + def testNodeListItem(): + doc = parseString("") + children = doc.childNodes + docelem = children[0] + confirm(children[0] is children.item(0) + and children.item(1) is None + and docelem.childNodes.item(0) is docelem.childNodes[0] + and docelem.childNodes.item(1) is docelem.childNodes[1] + and docelem.childNodes.item(0).childNodes.item(0) is None, + "test NodeList.item()") doc.unlink() From akuchling@users.sourceforge.net Fri Sep 28 22:26:59 2001 From: akuchling@users.sourceforge.net (A.M. Kuchling) Date: Fri, 28 Sep 2001 14:26:59 -0700 Subject: [Python-checkins] CVS: python/nondist/sandbox/parrot parrot-gen.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/parrot In directory usw-pr-cvs1:/tmp/cvs-serv12741 Modified Files: parrot-gen.py Log Message: Specify verbosity flag as keyword arg Index: parrot-gen.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/parrot/parrot-gen.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** parrot-gen.py 2001/09/26 20:37:43 1.1 --- parrot-gen.py 2001/09/28 21:26:56 1.2 *************** *** 353,357 **** # Determine locals and assign them to registers ! lnf = walk(ast, LocalNameFinder(), 0) for name in lnf.getLocals().elements(): reg = LOCAL_REGS[name] = random.choice(FREE_REGISTERS) --- 353,357 ---- # Determine locals and assign them to registers ! lnf = walk(ast, LocalNameFinder(), verbose=0) for name in lnf.getLocals().elements(): reg = LOCAL_REGS[name] = random.choice(FREE_REGISTERS) From tim_one@users.sourceforge.net Fri Sep 28 22:53:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 28 Sep 2001 14:53:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.258,1.259 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv19173/python/Misc Modified Files: NEWS Log Message: Post-release fiddling (prep for 2.2b1). Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.258 retrieving revision 1.259 diff -C2 -d -r1.258 -r1.259 *** NEWS 2001/09/28 17:01:02 1.258 --- NEWS 2001/09/28 21:53:41 1.259 *************** *** 1,2 **** --- 1,25 ---- + What's New in Python 2.2b1? + Release date: 28-Sep-2100 + =========================== + + Type/class unification and new-style classes + + Core + + Library + + Tools + + Build + + C API + + New platforms + + Tests + + Windows + + What's New in Python 2.2a4? Release date: 28-Sep-2001 From tim_one@users.sourceforge.net Fri Sep 28 22:53:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 28 Sep 2001 14:53:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.wse,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv19173/python/PCbuild Modified Files: python20.wse Log Message: Post-release fiddling (prep for 2.2b1). Index: python20.wse =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.wse,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -d -r1.91 -r1.92 *** python20.wse 2001/09/23 07:02:29 1.91 --- python20.wse 2001/09/28 21:53:42 1.92 *************** *** 2,6 **** item: Global Version=8.14 ! Title=Python 2.2 alpha 4 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 --- 2,6 ---- item: Global Version=8.14 ! Title=Python 2.2 beta 1 Flags=00010100 Languages=65 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 *************** *** 19,25 **** Patch Threshold=85 Patch Memory=4000 ! EXE Filename=Python-2.2a4.exe Dialogs Version=8 ! Version File=2.2a4 Version Description=Python Programming Language Version Copyright=©2001 Python Software Foundation --- 19,25 ---- Patch Threshold=85 Patch Memory=4000 ! EXE Filename=Python-2.2b1.exe Dialogs Version=8 ! Version File=2.2b1 Version Description=Python Programming Language Version Copyright=©2001 Python Software Foundation *************** *** 65,69 **** item: Set Variable Variable=PYVER_STRING ! Value=2.2a4 end item: Remark --- 65,69 ---- item: Set Variable Variable=PYVER_STRING ! Value=2.2b1 end item: Remark From fdrake@users.sourceforge.net Fri Sep 28 23:02:23 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 15:02:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsimplexmlrpc.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21205/lib Added Files: libsimplexmlrpc.tex Log Message: Preliminary documentation for the SimpleXMLRPCServer module. --- NEW FILE: libsimplexmlrpc.tex --- \section{\module{SimpleXMLRPCServer} --- Basic XML-RPC server} \declaremodule{standard}{SimpleXMLRPCServer} \moduleauthor{Brian Quinlan}{brianq@activestate.com} \sectionauthor{Fred L. Drake, Jr.}{fdrake@acm.org} The \module{SimpleXMLRPCServer} module provides a basic server framework for XML-RPC servers written in Python. The server object is based on the \code{\refmodule{SocketServer}.TCPServer} class, and the request handler is based on the \code{\refmodule{BaseHTTPServer}.BaseHTTPRequestHandler} class. \begin{classdesc}{SimpleXMLRPCServer}{addr\optional{, requestHandler\optional{, logRequests}}} Create a new server instance. The \var{requestHandler} parameter should be a factory for request handler instances; it defaults to \class{SimpleXMLRPCRequestHandler}. The \var{addr} and \var{requestHandler} parameters are passed to the \class{\refmodule{SocketServer}.TCPServer} constructor. If \var{logRequests} is true (the default), requests will be logged; setting this parameter to false will turn off logging. This class provides methods for registration of functions that can be called by the XML-RPC protocol. \end{classdesc} \begin{classdesc}{SimpleXMLRPCRequestHandler}{} Create a new request handler instance. This request handler supports \code{POST} requests and modifies logging so that the \var{logRequests} parameter to the \class{SimpleXMLRPCServer} constructor parameter is honored. \end{classdesc} \subsection{SimpleXMLRPCServer Objects \label{simple-xmlrpc-servers}} The \class{SimpleXMLRPCServer} class provides two methods that an application can use to register functions that can be called via the XML-RPC protocol via the request handler. \begin{methoddesc}[SimpleXMLRPCServer]{register_function}{function\optional{, name}} Register a function that can respond to XML-RPC requests. The function must be callable with a single parameter which will be the return value of \function{\refmodule{xmlrpclib}.loads()} when called with the payload of the request. If \var{name} is given, it will be the method name associated with \var{function}, otherwise \code{\var{function}.__name__} will be used. \var{name} can be either a normal or Unicode string, and may contain characters not legal in Python identifiers, including the period character. \end{methoddesc} \begin{methoddesc}[SimpleXMLRPCServer]{register_instance}{instance} Register an object which is used to expose method names which have not been registered using \method{register_function()}. If \var{instance} contains a \method{_dispatch()} method, it is called with the requested method name and the parameters from the request; the return value is returned to the client as the result. If \var{instance} does not have a \method{_dispatch()} method, it is searched for an attribute matching the name of the requested method; if the requested method name contains periods, each component of the method name is searched for individually, with the effect that a simple hierarchical search is performed. The value found from this search is then called with the parameters from the request, and the return value is passed back to the client. \end{methoddesc} From fdrake@users.sourceforge.net Fri Sep 28 23:02:51 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 15:02:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.74,1.75 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv21273 Modified Files: Makefile.deps Log Message: Add entry for the SimpleXMLRPCServer module. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.74 retrieving revision 1.75 diff -C2 -d -r1.74 -r1.75 *** Makefile.deps 2001/09/27 20:08:20 1.74 --- Makefile.deps 2001/09/28 22:02:49 1.75 *************** *** 199,202 **** --- 199,203 ---- lib/libxmllib.tex \ lib/libxmlrpclib.tex \ + lib/libsimplexmlrpc.tex \ lib/libpyexpat.tex \ lib/xmldom.tex \ From fdrake@users.sourceforge.net Fri Sep 28 23:03:43 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 15:03:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.192,1.193 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21458/lib Modified Files: lib.tex Log Message: Move XML-RPC-related docs to the "Internet Protocols" chapter. Add entry for the SimpleXMLRPCServer module. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.192 retrieving revision 1.193 diff -C2 -d -r1.192 -r1.193 *** lib.tex 2001/09/27 20:11:07 1.192 --- lib.tex 2001/09/28 22:03:40 1.193 *************** *** 212,215 **** --- 212,217 ---- \input{libcgihttp} \input{libcookie} + \input{libxmlrpclib} + \input{libsimplexmlrpc} \input{libasyncore} *************** *** 255,259 **** \input{xmlsaxreader} \input{libxmllib} - \input{libxmlrpclib} \input{libmm} % Multimedia Services --- 257,260 ---- From gvanrossum@users.sourceforge.net Fri Sep 28 23:58:54 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 15:58:54 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects typeobject.c,2.76,2.77 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv32432 Modified Files: typeobject.c Log Message: Ouch. The wrapper for __rpow__ was the same as for __pow__, resulting in bizarre outcomes. Test forthcoming. Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.76 retrieving revision 2.77 diff -C2 -d -r2.76 -r2.77 *** typeobject.c 2001/09/27 20:30:07 2.76 --- typeobject.c 2001/09/28 22:58:52 2.77 *************** *** 1889,1892 **** --- 1889,1906 ---- } + static PyObject * + wrap_ternaryfunc_r(PyObject *self, PyObject *args, void *wrapped) + { + ternaryfunc func = (ternaryfunc)wrapped; + PyObject *other; + PyObject *third = Py_None; + + /* Note: This wrapper only works for __pow__() */ + + if (!PyArg_ParseTuple(args, "O|O", &other, &third)) + return NULL; + return (*func)(other, self, third); + } + #undef TERNARY #define TERNARY(NAME, OP) \ *************** *** 1896,1900 **** "x.__" #NAME "__(y, z) <==> " #OP}, \ {"__r" #NAME "__", \ ! (wrapperfunc)wrap_ternaryfunc, \ "y.__r" #NAME "__(x, z) <==> " #OP}, \ {0} \ --- 1910,1914 ---- "x.__" #NAME "__(y, z) <==> " #OP}, \ {"__r" #NAME "__", \ ! (wrapperfunc)wrap_ternaryfunc_r, \ "y.__r" #NAME "__(x, z) <==> " #OP}, \ {0} \ From gvanrossum@users.sourceforge.net Sat Sep 29 00:49:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 16:49:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.79,2.80 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9262/Objects Modified Files: abstract.c Log Message: It's a fact: for binary operators, *under certain circumstances*, __rop__ now takes precendence over __op__. Those circumstances are: - Both arguments are new-style classes - Both arguments are new-style numbers - Their implementation slots for tp_op differ - Their types differ - The right argument's type is a subtype of the left argument's type Also did this for the ternary operator (pow) -- only the binary case is dealt with properly though, since __rpow__ is not supported anyway. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.79 retrieving revision 2.80 diff -C2 -d -r2.79 -r2.80 *** abstract.c 2001/09/14 16:47:50 2.79 --- abstract.c 2001/09/28 23:49:48 2.80 *************** *** 301,309 **** v w Action ------------------------------------------------------------------- ! new new v.op(v,w), w.op(v,w) new old v.op(v,w), coerce(v,w), v.op(v,w) old new w.op(v,w), coerce(v,w), v.op(v,w) old old coerce(v,w), v.op(v,w) Legend: ------- --- 301,312 ---- v w Action ------------------------------------------------------------------- ! new new w.op(v,w)[*], v.op(v,w), w.op(v,w) new old v.op(v,w), coerce(v,w), v.op(v,w) old new w.op(v,w), coerce(v,w), v.op(v,w) old old coerce(v,w), v.op(v,w) + [*] only when v->ob_type != w->ob_type && w->ob_type is a subclass of + v->ob_type + Legend: ------- *************** *** 319,346 **** { PyObject *x; ! binaryfunc *slot; ! if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v)) { ! slot = NB_BINOP(v->ob_type->tp_as_number, op_slot); ! if (*slot) { ! x = (*slot)(v, w); ! if (x != Py_NotImplemented) { ! return x; ! } ! Py_DECREF(x); /* can't do it */ ! } ! if (v->ob_type == w->ob_type) { ! goto binop_error; ! } } ! if (w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) { ! slot = NB_BINOP(w->ob_type->tp_as_number, op_slot); ! if (*slot) { ! x = (*slot)(v, w); ! if (x != Py_NotImplemented) { ! return x; ! } ! Py_DECREF(x); /* can't do it */ ! } } if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) { int err = PyNumber_CoerceEx(&v, &w); --- 322,355 ---- { PyObject *x; ! binaryfunc slotv = NULL; ! binaryfunc slotw = NULL; ! ! if (v->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(v)) ! slotv = *NB_BINOP(v->ob_type->tp_as_number, op_slot); ! if (w->ob_type != v->ob_type && ! w->ob_type->tp_as_number != NULL && NEW_STYLE_NUMBER(w)) { ! slotw = *NB_BINOP(w->ob_type->tp_as_number, op_slot); ! if (slotw == slotv) ! slotw = NULL; } ! if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { ! x = slotw(v, w); ! if (x != Py_NotImplemented) ! return x; ! Py_DECREF(x); /* can't do it */ ! slotw = NULL; } + if (slotv) { + x = slotv(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } + if (slotw) { + x = slotw(v, w); + if (x != Py_NotImplemented) + return x; + Py_DECREF(x); /* can't do it */ + } if (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w)) { int err = PyNumber_CoerceEx(&v, &w); *************** *** 351,357 **** PyNumberMethods *mv = v->ob_type->tp_as_number; if (mv) { ! slot = NB_BINOP(mv, op_slot); ! if (*slot) { ! PyObject *x = (*slot)(v, w); Py_DECREF(v); Py_DECREF(w); --- 360,367 ---- PyNumberMethods *mv = v->ob_type->tp_as_number; if (mv) { ! binaryfunc slot; ! slot = *NB_BINOP(mv, op_slot); ! if (slot) { ! PyObject *x = slot(v, w); Py_DECREF(v); Py_DECREF(w); *************** *** 364,368 **** } } - binop_error: Py_INCREF(Py_NotImplemented); return Py_NotImplemented; --- 374,377 ---- *************** *** 421,424 **** --- 430,445 ---- mv = v->ob_type->tp_as_number; + mw = w->ob_type->tp_as_number; + if (v->ob_type != w->ob_type && mw && NEW_STYLE_NUMBER(w)) { + slot = NB_TERNOP(mw, op_slot); + if (*slot && *slot != *NB_TERNOP(mv, op_slot) && + PyType_IsSubtype(w->ob_type, v->ob_type)) { + x = (*slot)(v, w, z); + if (x != Py_NotImplemented) + return x; + /* Can't do it... fall through */ + Py_DECREF(x); + } + } if (mv != NULL && NEW_STYLE_NUMBER(v)) { /* try v.op(v,w,z) */ *************** *** 436,440 **** } } - mw = w->ob_type->tp_as_number; if (mw != NULL && NEW_STYLE_NUMBER(w)) { /* try w.op(v,w,z) */ --- 457,460 ---- From gvanrossum@users.sourceforge.net Sat Sep 29 00:49:51 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 16:49:51 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.77,1.78 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv9262/Lib/test Modified Files: test_descr.py Log Message: It's a fact: for binary operators, *under certain circumstances*, __rop__ now takes precendence over __op__. Those circumstances are: - Both arguments are new-style classes - Both arguments are new-style numbers - Their implementation slots for tp_op differ - Their types differ - The right argument's type is a subtype of the left argument's type Also did this for the ternary operator (pow) -- only the binary case is dealt with properly though, since __rpow__ is not supported anyway. Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.77 retrieving revision 1.78 diff -C2 -d -r1.77 -r1.78 *** test_descr.py 2001/09/28 18:13:29 1.77 --- test_descr.py 2001/09/28 23:49:45 1.78 *************** *** 1,7 **** ! # Test descriptor-related enhancements from test_support import verify, verbose, TestFailed, TESTFN from copy import deepcopy def testunop(a, res, expr="len(a)", meth="__len__"): if verbose: print "checking", expr --- 1,11 ---- ! # Test enhancements related to descriptors and new-style classes from test_support import verify, verbose, TestFailed, TESTFN from copy import deepcopy + def vereq(a, b): + if a != b: + raise TestFailed, "%r != %r" % (a, b) + def testunop(a, res, expr="len(a)", meth="__len__"): if verbose: print "checking", expr *************** *** 2134,2138 **** --- 2138,2172 ---- verify(d.bar == [1,2,3]) + def binopoverride(): + if verbose: print "Testing overrides of binary operations..." + class I(int): + def __repr__(self): + return "I(%r)" % int(self) + def __add__(self, other): + return I(int(self) + int(other)) + __radd__ = __add__ + def __pow__(self, other, mod=None): + if mod is None: + return I(pow(int(self), int(other))) + else: + return I(pow(int(self), int(other), int(mod))) + def __rpow__(self, other, mod=None): + if mod is None: + return I(pow(int(other), int(self), mod)) + else: + return I(pow(int(other), int(self), int(mod))) + + vereq(`I(1) + I(2)`, "I(3)") + vereq(`I(1) + 2`, "I(3)") + vereq(`1 + I(2)`, "I(3)") + vereq(`I(2) ** I(3)`, "I(8)") + vereq(`2 ** I(3)`, "I(8)") + vereq(`I(2) ** 3`, "I(8)") + vereq(`pow(I(2), I(3), I(5))`, "I(3)") + class S(str): + def __eq__(self, other): + return self.lower() == other.lower() + def test_main(): lists() *************** *** 2179,2182 **** --- 2213,2217 ---- pickles() copies() + binopoverride() if verbose: print "All OK" From gvanrossum@users.sourceforge.net Sat Sep 29 01:40:27 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 17:40:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_descr.py,1.78,1.79 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv20318 Modified Files: test_descr.py Log Message: Add a few ``__dynamic__ = 0'' lines in classes that need to preserve staticness when __dynamic__ = 1 becomes the default: - Some classes which are used to test the difference between static and dynamic. - Subclasses of complex: complex uses old-style numbers and the slot wrappers used by dynamic classes only support new-style numbers. (Ideally, the complex type should be fixed, but that looks like a labor-intensive job.) Index: test_descr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_descr.py,v retrieving revision 1.78 retrieving revision 1.79 diff -C2 -d -r1.78 -r1.79 *** test_descr.py 2001/09/28 23:49:45 1.78 --- test_descr.py 2001/09/29 00:40:25 1.79 *************** *** 833,839 **** class S1: __metaclass__ = type verify(S1.__dynamic__ == 0) class S(object): ! pass verify(S.__dynamic__ == 0) class D(object): --- 833,840 ---- class S1: __metaclass__ = type + __dynamic__ = 0 verify(S1.__dynamic__ == 0) class S(object): ! __dynamic__ = 0 verify(S.__dynamic__ == 0) class D(object): *************** *** 1523,1526 **** --- 1524,1528 ---- class madcomplex(complex): + __dynamic__ = 0 def __repr__(self): return "%.17gj%+.17g" % (self.imag, self.real) *************** *** 1902,1910 **** print "Testing rich comparisons..." class Z(complex): ! pass z = Z(1) verify(z == 1+0j) verify(1+0j == z) class ZZ(complex): def __eq__(self, other): try: --- 1904,1913 ---- print "Testing rich comparisons..." class Z(complex): ! __dynamic__ = 0 z = Z(1) verify(z == 1+0j) verify(1+0j == z) class ZZ(complex): + __dynamic__ = 0 def __eq__(self, other): try: *************** *** 1993,1997 **** coerce(0L, F(0)) coerce(0., F(0)) ! class C(complex): pass coerce(C(0), 0) coerce(C(0), 0L) --- 1996,2001 ---- coerce(0L, F(0)) coerce(0., F(0)) ! class C(complex): ! __dynamic__ = 0 coerce(C(0), 0) coerce(C(0), 0L) From gvanrossum@users.sourceforge.net Sat Sep 29 01:42:22 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 17:42:22 -0700 Subject: [Python-checkins] CVS: python/dist/src Makefile.pre.in,1.60,1.61 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv20600 Modified Files: Makefile.pre.in Log Message: Clarify the warning about the relative dates of Setup.dist and Setup; Jeremy had seen the warning but not realized what he should do about it. Add the hint "Usually, copying Setup.dist to Setup will work." Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.pre.in,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -d -r1.60 -r1.61 *** Makefile.pre.in 2001/09/28 20:29:15 1.60 --- Makefile.pre.in 2001/09/29 00:42:19 1.61 *************** *** 377,380 **** --- 377,381 ---- echo "check to make sure you have all the updates you"; \ echo "need in your Modules/Setup file."; \ + echo "Usually, copying Setup.dist to Setup will work."; \ echo "-----------------------------------------------"; \ fi From gvanrossum@users.sourceforge.net Sat Sep 29 02:05:05 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Fri, 28 Sep 2001 18:05:05 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.80,2.81 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv23611 Modified Files: abstract.c Log Message: The changes to ternary_op could cause a core dump. Fix this, and rewrite the code a bit to avoid calling the same slot more than once. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -d -r2.80 -r2.81 *** abstract.c 2001/09/28 23:49:48 2.80 --- abstract.c 2001/09/29 01:05:03 2.81 *************** *** 395,398 **** --- 395,400 ---- Calling scheme used for ternary operations: + *** In some cases, w.op is called before v.op; see binary_op1. *** + v w z Action ------------------------------------------------------------------- *************** *** 426,485 **** { PyNumberMethods *mv, *mw, *mz; ! register PyObject *x = NULL; ! register ternaryfunc *slot; mv = v->ob_type->tp_as_number; mw = w->ob_type->tp_as_number; ! if (v->ob_type != w->ob_type && mw && NEW_STYLE_NUMBER(w)) { ! slot = NB_TERNOP(mw, op_slot); ! if (*slot && *slot != *NB_TERNOP(mv, op_slot) && ! PyType_IsSubtype(w->ob_type, v->ob_type)) { ! x = (*slot)(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! /* Can't do it... fall through */ ! Py_DECREF(x); ! } } ! if (mv != NULL && NEW_STYLE_NUMBER(v)) { ! /* try v.op(v,w,z) */ ! slot = NB_TERNOP(mv, op_slot); ! if (*slot) { ! x = (*slot)(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! /* Can't do it... fall through */ ! Py_DECREF(x); ! } ! if (v->ob_type == w->ob_type && ! (z == Py_None || z->ob_type == v->ob_type)) { ! goto ternary_error; ! } } ! if (mw != NULL && NEW_STYLE_NUMBER(w)) { ! /* try w.op(v,w,z) */ ! slot = NB_TERNOP(mw,op_slot); ! if (*slot) { ! x = (*slot)(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! /* Can't do it... fall through */ ! Py_DECREF(x); ! } ! if (NEW_STYLE_NUMBER(v) && ! (z == Py_None || z->ob_type == v->ob_type)) { ! goto ternary_error; ! } } mz = z->ob_type->tp_as_number; if (mz != NULL && NEW_STYLE_NUMBER(z)) { ! /* try: z.op(v,w,z) */ ! slot = NB_TERNOP(mz, op_slot); ! if (*slot) { ! x = (*slot)(v, w, z); if (x != Py_NotImplemented) return x; ! /* Can't do it... fall through */ ! Py_DECREF(x); } } --- 428,475 ---- { PyNumberMethods *mv, *mw, *mz; ! PyObject *x = NULL; ! ternaryfunc slotv = NULL; ! ternaryfunc slotw = NULL; ! ternaryfunc slotz = NULL; mv = v->ob_type->tp_as_number; mw = w->ob_type->tp_as_number; ! if (mv != NULL && NEW_STYLE_NUMBER(v)) ! slotv = *NB_TERNOP(mv, op_slot); ! if (w->ob_type != v->ob_type && ! mv != NULL && NEW_STYLE_NUMBER(w)) { ! slotw = *NB_TERNOP(mw, op_slot); ! if (slotw == slotv) ! slotw = NULL; } ! if (slotw && PyType_IsSubtype(w->ob_type, v->ob_type)) { ! x = slotw(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! Py_DECREF(x); /* can't do it */ ! slotw = NULL; } ! if (slotv) { ! x = slotv(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! Py_DECREF(x); /* can't do it */ ! } ! if (slotw) { ! x = slotw(v, w, z); ! if (x != Py_NotImplemented) ! return x; ! Py_DECREF(x); /* can't do it */ } mz = z->ob_type->tp_as_number; if (mz != NULL && NEW_STYLE_NUMBER(z)) { ! slotz = *NB_TERNOP(mz, op_slot); ! if (slotz == slotv || slotz == slotw) ! slotz = NULL; ! if (slotz) { ! x = slotz(v, w, z); if (x != Py_NotImplemented) return x; ! Py_DECREF(x); /* can't do it */ } } *************** *** 499,506 **** if (z == Py_None) { if (v->ob_type->tp_as_number) { ! slot = NB_TERNOP(v->ob_type->tp_as_number, ! op_slot); ! if (*slot) ! x = (*slot)(v, w, z); else c = -1; --- 489,496 ---- if (z == Py_None) { if (v->ob_type->tp_as_number) { ! slotz = *NB_TERNOP(v->ob_type->tp_as_number, ! op_slot); ! if (slotz) ! x = slotz(v, w, z); else c = -1; *************** *** 522,529 **** if (v1->ob_type->tp_as_number != NULL) { ! slot = NB_TERNOP(v1->ob_type->tp_as_number, ! op_slot); ! if (*slot) ! x = (*slot)(v1, w2, z2); else c = -1; --- 512,519 ---- if (v1->ob_type->tp_as_number != NULL) { ! slotv = *NB_TERNOP(v1->ob_type->tp_as_number, ! op_slot); ! if (slotv) ! x = slotv(v1, w2, z2); else c = -1; *************** *** 545,549 **** } - ternary_error: PyErr_Format(PyExc_TypeError, "unsupported operand type(s) for %s", op_name); --- 535,538 ---- From tim_one@users.sourceforge.net Sat Sep 29 02:08:21 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Fri, 28 Sep 2001 18:08:21 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.70,1.71 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23946/python/Doc/lib Modified Files: libstdtypes.tex Log Message: The list.sort() docs require a function that returns -1, 0 or +1. That's never been true, and in particular implies cmp() can't be used(!). Get closer to the truth. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.70 retrieving revision 1.71 diff -C2 -d -r1.70 -r1.71 *** libstdtypes.tex 2001/09/23 04:06:04 1.70 --- libstdtypes.tex 2001/09/29 01:08:19 1.71 *************** *** 886,890 **** \item[(6)] The \method{sort()} method takes an optional argument specifying a comparison function of two arguments (list items) which ! should return \code{-1}, \code{0} or \code{1} depending on whether the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process --- 886,890 ---- \item[(6)] The \method{sort()} method takes an optional argument specifying a comparison function of two arguments (list items) which ! should return a negative, zero or positive number depending on whether the first argument is considered smaller than, equal to, or larger than the second argument. Note that this slows the sorting process From fdrake@users.sourceforge.net Sat Sep 29 05:54:35 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 21:54:35 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib SimpleXMLRPCServer.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv22778 Modified Files: SimpleXMLRPCServer.py Log Message: _dispatch(): Do no re-define the resolve_dotted_atttribute() function every time this gets called; move it out as a global helper function. Simplify the call to the _dispatch() method of the registered instance. Index: SimpleXMLRPCServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SimpleXMLRPCServer.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** SimpleXMLRPCServer.py 2001/09/17 17:35:21 1.1 --- SimpleXMLRPCServer.py 2001/09/29 04:54:33 1.2 *************** *** 148,167 **** """ - def resolve_dotted_attribute(obj, attr): - """resolve_dotted_attribute(math, 'cos.__doc__') => math.cos.__doc__ - - Resolves a dotted attribute name to an object. Raises - an AttributeError if any attribute in the chain starts - with a '_'. - """ - for i in attr.split('.'): - if i.startswith('_'): - raise AttributeError( - 'attempt to access private attribute "%s"' % i - ) - else: - obj = getattr(obj,i) - return obj - func = None try: --- 148,151 ---- *************** *** 172,183 **** # check for a _dispatch method if hasattr(self.server.instance, '_dispatch'): ! return apply( ! getattr(self.server.instance,'_dispatch'), ! (method, params) ! ) else: # call instance method directly try: ! func = resolve_dotted_attribute( self.server.instance, method --- 156,164 ---- # check for a _dispatch method if hasattr(self.server.instance, '_dispatch'): ! return self.server.instance._dispatch(method, params) else: # call instance method directly try: ! func = _resolve_dotted_attribute( self.server.instance, method *************** *** 196,199 **** --- 177,195 ---- if self.server.logRequests: BaseHTTPServer.BaseHTTPRequestHandler.log_request(self, code, size) + + + def _resolve_dotted_attribute(obj, attr): + """Resolves a dotted attribute name to an object. Raises + an AttributeError if any attribute in the chain starts with a '_'. + """ + for i in attr.split('.'): + if i.startswith('_'): + raise AttributeError( + 'attempt to access private attribute "%s"' % i + ) + else: + obj = getattr(obj,i) + return obj + class SimpleXMLRPCServer(SocketServer.TCPServer): From fdrake@users.sourceforge.net Sat Sep 29 05:58:34 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 21:58:34 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.38,1.39 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv23226/xml/dom Modified Files: minidom.py Log Message: For Python 2.2, do not use __getattr__(), only use computed properties. This is probably a little bit faster, but mostly is just cleaner code. The old-style support is still used for Python versions < 2.2 so this source file can be shared with PyXML. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -d -r1.38 -r1.39 *** minidom.py 2001/09/28 20:25:45 1.38 --- minidom.py 2001/09/29 04:58:32 1.39 *************** *** 69,99 **** Node.debug.write("create %s\n" % index) - def __getattr__(self, key): - if key[0:2] == "__": - raise AttributeError, key - # getattr should never call getattr! - if self.__dict__.has_key("inGetAttr"): - del self.inGetAttr - raise AttributeError, key - - prefix, attrname = key[:5], key[5:] - if prefix == "_get_": - self.inGetAttr = 1 - if hasattr(self, attrname): - del self.inGetAttr - return (lambda self=self, attrname=attrname: - getattr(self, attrname)) - else: - del self.inGetAttr - raise AttributeError, key - else: - self.inGetAttr = 1 - try: - func = getattr(self, "_get_" + key) - except AttributeError: - raise AttributeError, key - del self.inGetAttr - return func() - def __nonzero__(self): return 1 --- 69,72 ---- *************** *** 125,128 **** --- 98,136 ---- return self.childNodes[-1] + try: + property + except NameError: + def __getattr__(self, key): + if key[0:2] == "__": + raise AttributeError, key + # getattr should never call getattr! + if self.__dict__.has_key("inGetAttr"): + del self.inGetAttr + raise AttributeError, key + + prefix, attrname = key[:5], key[5:] + if prefix == "_get_": + self.inGetAttr = 1 + if hasattr(self, attrname): + del self.inGetAttr + return (lambda self=self, attrname=attrname: + getattr(self, attrname)) + else: + del self.inGetAttr + raise AttributeError, key + else: + self.inGetAttr = 1 + try: + func = getattr(self, "_get_" + key) + except AttributeError: + raise AttributeError, key + del self.inGetAttr + return func() + else: + firstChild = property(_get_firstChild, + doc="First child node, or None.") + lastChild = property(_get_lastChild, + doc="Last child node, or None.") + def insertBefore(self, newChild, refChild): if newChild.nodeType == self.DOCUMENT_FRAGMENT_NODE: *************** *** 363,370 **** self._attrsNS = attrsNS ! def __getattr__(self, name): ! if name == "length": ! return len(self._attrs) ! raise AttributeError, name def item(self, index): --- 371,384 ---- self._attrsNS = attrsNS ! try: ! property ! except NameError: ! def __getattr__(self, name): ! if name == "length": ! return len(self._attrs) ! raise AttributeError, name ! else: ! length = property(lambda self: len(self._attrs), ! doc="Number of nodes in the NamedNodeMap.") def item(self, index): *************** *** 599,602 **** --- 613,624 ---- return AttributeList(self._attrs, self._attrsNS) + try: + property + except NameError: + pass + else: + attributes = property(_get_attributes, + doc="NamedNodeMap of attributes on the element.") + def hasAttributes(self): if self._attrs or self._attrsNS: *************** *** 841,844 **** --- 863,874 ---- if node.nodeType == Node.ELEMENT_NODE: return node + + try: + property + except NameError: + pass + else: + documentElement = property(_get_documentElement, + doc="Top-level element of this document.") def unlink(self): From fdrake@users.sourceforge.net Sat Sep 29 06:02:02 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 22:02:02 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsimplexmlrpc.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv23701/lib Modified Files: libsimplexmlrpc.tex Log Message: Minor markup improvement. Index: libsimplexmlrpc.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsimplexmlrpc.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** libsimplexmlrpc.tex 2001/09/28 22:02:21 1.1 --- libsimplexmlrpc.tex 2001/09/29 05:01:59 1.2 *************** *** 9,15 **** The \module{SimpleXMLRPCServer} module provides a basic server framework for XML-RPC servers written in Python. The server object is ! based on the \code{\refmodule{SocketServer}.TCPServer} class, and the request handler is based on the ! \code{\refmodule{BaseHTTPServer}.BaseHTTPRequestHandler} class. --- 9,15 ---- The \module{SimpleXMLRPCServer} module provides a basic server framework for XML-RPC servers written in Python. The server object is ! based on the \class{\refmodule{SocketServer}.TCPServer} class, and the request handler is based on the ! \class{\refmodule{BaseHTTPServer}.BaseHTTPRequestHandler} class. From fdrake@users.sourceforge.net Sat Sep 29 06:05:27 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Fri, 28 Sep 2001 22:05:27 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv docfixer.py,1.32,1.33 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv24152 Modified Files: docfixer.py Log Message: Fix up whitespace in elements; reduce sequences of consecutive whitespace characters to a single space. Small changes elsewhere, mostly to clean up the code a little. Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -d -r1.32 -r1.33 *** docfixer.py 2001/09/28 17:14:35 1.32 --- docfixer.py 2001/09/29 05:05:25 1.33 *************** *** 390,407 **** d[gi] = gi rewrite_element = d.has_key ! queue = [] ! for node in doc.childNodes: ! if node.nodeType == ELEMENT: ! queue.append(node) while queue: node = queue[0] del queue[0] if rewrite_element(node.tagName): ! children = node.childNodes ! if len(children) == 1 \ ! and children[0].nodeType == TEXT: ! data = children[0].data ! if data[-2:] == "()": ! children[0].data = data[:-2] else: for child in node.childNodes: --- 390,403 ---- d[gi] = gi rewrite_element = d.has_key ! queue = [node for node in doc.childNodes if node.nodeType == ELEMENT] while queue: node = queue[0] del queue[0] if rewrite_element(node.tagName): ! lastchild = node.lastChild ! if lastchild and lastchild.nodeType == TEXT: ! data = lastchild.data ! if data.endswith("()"): ! lastchild.data = data[:-2] else: for child in node.childNodes: *************** *** 774,784 **** args = child.getElementsByTagName("args") for arg in args: ! fixup_args(doc, arg) ! arg.normalize() args = child.getElementsByTagName("constructor-args") for arg in args: ! fixup_args(doc, arg) ! arg.normalize() def fixup_args(doc, arglist): --- 770,784 ---- args = child.getElementsByTagName("args") for arg in args: ! rewrite_args(doc, arg) args = child.getElementsByTagName("constructor-args") for arg in args: ! rewrite_args(doc, arg) + def rewrite_args(doc, arglist): + fixup_args(doc, arglist) + arglist.normalize() + if arglist.childNodes.length == 1 and arglist.firstChild.nodeType == TEXT: + node = arglist.firstChild + node.data = ' '.join(node.data.split()) def fixup_args(doc, arglist): *************** *** 789,795 **** optkids = child.childNodes while optkids: ! k = optkids[0] ! child.removeChild(k) ! arglist.insertBefore(k, child) arglist.insertBefore(doc.createTextNode("]"), child) arglist.removeChild(child) --- 789,793 ---- optkids = child.childNodes while optkids: ! arglist.insertBefore(child.firstChild, child) arglist.insertBefore(doc.createTextNode("]"), child) arglist.removeChild(child) From montanaro@users.sourceforge.net Sat Sep 29 14:49:43 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Sat, 29 Sep 2001 06:49:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtypes.tex,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv883 Modified Files: libtypes.tex Log Message: added description of StringTypes object Index: libtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtypes.tex,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -d -r1.50 -r1.51 *** libtypes.tex 2001/06/25 19:46:25 1.50 --- libtypes.tex 2001/09/29 13:49:41 1.51 *************** *** 156,157 **** --- 156,162 ---- \function{buffer()}\bifuncindex{buffer} function. \end{datadesc} + + \begin{datadesc}{StringTypes} + A list containing StringType and UnicodeTypes used to facilitate easier + checking for any string object, e.g. \code{s in types.StringTypes}. + \end{datadesc} From montanaro@users.sourceforge.net Sat Sep 29 14:53:23 2001 From: montanaro@users.sourceforge.net (Skip Montanaro) Date: Sat, 29 Sep 2001 06:53:23 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libtypes.tex,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv1531 Modified Files: libtypes.tex Log Message: forgot to mark use of StringType and UnicodeType in the text. Index: libtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libtypes.tex,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -d -r1.51 -r1.52 *** libtypes.tex 2001/09/29 13:49:41 1.51 --- libtypes.tex 2001/09/29 13:53:21 1.52 *************** *** 158,162 **** \begin{datadesc}{StringTypes} ! A list containing StringType and UnicodeTypes used to facilitate easier ! checking for any string object, e.g. \code{s in types.StringTypes}. \end{datadesc} --- 158,163 ---- \begin{datadesc}{StringTypes} ! A list containing \var{StringType} and \var{UnicodeType} used to ! facilitate easier checking for any string object, e.g. \code{s in ! types.StringTypes}. \end{datadesc} From gvanrossum@users.sourceforge.net Sat Sep 29 15:28:57 2001 From: gvanrossum@users.sourceforge.net (Guido van Rossum) Date: Sat, 29 Sep 2001 07:28:57 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.85,1.86 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7181 Modified Files: libfuncs.tex Log Message: Fix two typos in the text about compile(), and add two caveats from recent user feedback: you must end the input with \n and you must use \n, not \r\n to represent line endings. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.85 retrieving revision 1.86 diff -C2 -d -r1.85 -r1.86 *** libfuncs.tex 2001/09/20 19:55:29 1.85 --- libfuncs.tex 2001/09/29 14:28:52 1.86 *************** *** 124,128 **** executed by an \keyword{exec} statement or evaluated by a call to \function{eval()}. The \var{filename} argument should ! give the file from which the code was read; pass same recognizable value if it wasn't read from a file (\code{''} is commonly used). The \var{kind} argument specifies what kind of code must be --- 124,128 ---- executed by an \keyword{exec} statement or evaluated by a call to \function{eval()}. The \var{filename} argument should ! give the file from which the code was read; pass some recognizable value if it wasn't read from a file (\code{''} is commonly used). The \var{kind} argument specifies what kind of code must be *************** *** 133,137 **** that evaluate to something else than \code{None} will printed). ! The optional arguments \var{flags} and \optional{dont_inherit} (which are new in Python 2.2) control which future statements (see \pep{236}) affect the compilation of \var{string}. If neither is --- 133,144 ---- that evaluate to something else than \code{None} will printed). ! When compiling multi-line statements, two caveats apply: line ! endings must be represented by a single newline character ! (\code{'\e n'}), and the input must be terminated by at least one ! newline character. If line endings are represented by ! \code{'\e r\e n'}, use the string \method{replace()} method to ! change them into \code{'\e n'}. ! ! The optional arguments \var{flags} and \var{dont_inherit} (which are new in Python 2.2) control which future statements (see \pep{236}) affect the compilation of \var{string}. If neither is From fdrake@users.sourceforge.net Sat Sep 29 20:07:24 2001 From: fdrake@users.sourceforge.net (Fred L. Drake) Date: Sat, 29 Sep 2001 12:07:24 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools/sgmlconv docfixer.py,1.33,1.34 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools/sgmlconv In directory usw-pr-cvs1:/tmp/cvs-serv25741/tools/sgmlconv Modified Files: docfixer.py Log Message: Handle PEP references the same way RFC references. Index: docfixer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/sgmlconv/docfixer.py,v retrieving revision 1.33 retrieving revision 1.34 diff -C2 -d -r1.33 -r1.34 *** docfixer.py 2001/09/29 05:05:25 1.33 --- docfixer.py 2001/09/29 19:07:22 1.34 *************** *** 760,766 **** def fixup_rfc_references(doc, fragment): ! for rfcnode in find_all_elements(fragment, "rfc"): rfcnode.appendChild(doc.createTextNode( ! "RFC " + rfcnode.getAttribute("num"))) --- 760,766 ---- def fixup_rfc_references(doc, fragment): ! for rfcnode in find_all_elements_from_set(fragment, ("pep", "rfc")): rfcnode.appendChild(doc.createTextNode( ! rfcnode.tagName.upper() + " " + rfcnode.getAttribute("num"))) *************** *** 1027,1034 **** for gi in events.parser.get_empties(): d[gi] = gi ! if d.has_key("author"): ! del d["author"] ! if d.has_key("rfc"): ! del d["rfc"] knownempty = d.has_key # --- 1027,1033 ---- for gi in events.parser.get_empties(): d[gi] = gi ! for key in ("author", "pep", "rfc"): ! if d.has_key(key): ! del d[key] knownempty = d.has_key # From tim_one@users.sourceforge.net Sun Sep 30 06:09:38 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:09:38 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/ext extending.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ext In directory usw-pr-cvs1:/tmp/cvs-serv21648/python/Doc/ext Modified Files: extending.tex Log Message: SF [#466125] PyLong_AsLongLong works for any integer. Generalize PyLong_AsLongLong to accept int arguments too. The real point is so that PyArg_ParseTuple's 'L' code does too. That code was undocumented (AFAICT), so documented it. Index: extending.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ext/extending.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** extending.tex 2001/09/06 16:30:30 1.2 --- extending.tex 2001/09/30 05:09:36 1.3 *************** *** 744,747 **** --- 744,752 ---- Convert a Python integer to a C \ctype{long int}. + \item[\samp{L} (integer) {[LONG_LONG]}] + Convert a Python integer to a C \ctype{long long}. This format is only + available on platforms that support \ctype{long long} (or \ctype{_int64} + on Windows). + \item[\samp{c} (string of length 1) {[char]}] Convert a Python character, represented as a string of length 1, to a From tim_one@users.sourceforge.net Sun Sep 30 06:09:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:09:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.112,1.113 NEWS,1.259,1.260 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21648/python/Misc Modified Files: ACKS NEWS Log Message: SF [#466125] PyLong_AsLongLong works for any integer. Generalize PyLong_AsLongLong to accept int arguments too. The real point is so that PyArg_ParseTuple's 'L' code does too. That code was undocumented (AFAICT), so documented it. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.112 retrieving revision 1.113 diff -C2 -d -r1.112 -r1.113 *** ACKS 2001/09/11 19:12:02 1.112 --- ACKS 2001/09/30 05:09:36 1.113 *************** *** 115,118 **** --- 115,119 ---- David Ely Jeff Epler + Tom Epperly Stoffel Erasmus Michael Ernst Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.259 retrieving revision 1.260 diff -C2 -d -r1.259 -r1.260 *** NEWS 2001/09/28 21:53:41 1.259 --- NEWS 2001/09/30 05:09:36 1.260 *************** *** 15,18 **** --- 15,22 ---- C API + - PyLong_AsLongLong() now accepts int (as well as long) arguments. + Consequently, PyArg_ParseTuple's 'L' code also accepts int (as well + as long) arguments. + New platforms From tim_one@users.sourceforge.net Sun Sep 30 06:09:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:09:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules _testcapimodule.c,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21648/python/Modules Modified Files: _testcapimodule.c Log Message: SF [#466125] PyLong_AsLongLong works for any integer. Generalize PyLong_AsLongLong to accept int arguments too. The real point is so that PyArg_ParseTuple's 'L' code does too. That code was undocumented (AFAICT), so documented it. Index: _testcapimodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_testcapimodule.c,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** _testcapimodule.c 2001/09/26 20:01:13 1.11 --- _testcapimodule.c 2001/09/30 05:09:37 1.12 *************** *** 256,259 **** --- 256,308 ---- #undef F_PY_TO_U + /* Test the L code for PyArg_ParseTuple. This should deliver a LONG_LONG + for both long and int arguments. The test may leak a little memory if + it fails. + */ + static PyObject * + test_L_code(PyObject *self, PyObject *args) + { + PyObject *tuple, *num; + LONG_LONG value; + + if (!PyArg_ParseTuple(args, ":test_L_code")) + return NULL; + + tuple = PyTuple_New(1); + if (tuple == NULL) + return NULL; + + num = PyLong_FromLong(42); + if (num == NULL) + return NULL; + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0) + return NULL; + if (value != 42) + return raiseTestError("test_L_code", + "L code returned wrong value for long 42"); + + Py_DECREF(num); + num = PyInt_FromLong(42); + if (num == NULL) + return NULL; + + PyTuple_SET_ITEM(tuple, 0, num); + + value = -1; + if (PyArg_ParseTuple(tuple, "L:test_L_code", &value) < 0) + return NULL; + if (value != 42) + return raiseTestError("test_L_code", + "L code returned wrong value for int 42"); + + Py_DECREF(tuple); + Py_INCREF(Py_None); + return Py_None; + } + #endif /* ifdef HAVE_LONG_LONG */ *************** *** 292,295 **** --- 341,345 ---- #ifdef HAVE_LONG_LONG {"test_longlong_api", test_longlong_api, METH_VARARGS}, + {"test_L_code", test_L_code, METH_VARARGS}, #endif {NULL, NULL} /* sentinel */ From tim_one@users.sourceforge.net Sun Sep 30 06:09:39 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:09:39 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21648/python/Objects Modified Files: longobject.c Log Message: SF [#466125] PyLong_AsLongLong works for any integer. Generalize PyLong_AsLongLong to accept int arguments too. The real point is so that PyArg_ParseTuple's 'L' code does too. That code was undocumented (AFAICT), so documented it. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -d -r1.109 -r1.110 *** longobject.c 2001/09/19 01:25:15 1.109 --- longobject.c 2001/09/30 05:09:37 1.110 *************** *** 680,684 **** int res; ! if (vv == NULL || !PyLong_Check(vv)) { PyErr_BadInternalCall(); return -1; --- 680,690 ---- int res; ! if (vv == NULL) { ! PyErr_BadInternalCall(); ! return -1; ! } ! if (!PyLong_Check(vv)) { ! if (PyInt_Check(vv)) ! return (LONG_LONG)PyInt_AsLong(vv); PyErr_BadInternalCall(); return -1; From tim_one@users.sourceforge.net Sun Sep 30 06:58:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:58:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.278,2.279 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv27904/python/Python Modified Files: ceval.c Log Message: SF bug [#466173] unpack TypeError unclear Replaced 3 instances of "iter() of non-sequence" with "iteration over non-sequence". Restored "unpack non-sequence" for stuff like "a, b = 1". Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.278 retrieving revision 2.279 diff -C2 -d -r2.278 -r2.279 *** ceval.c 2001/09/26 19:24:45 2.278 --- ceval.c 2001/09/30 05:58:42 2.279 *************** *** 1557,1562 **** stack_pointer + oparg)) stack_pointer += oparg; ! else why = WHY_EXCEPTION; Py_DECREF(v); break; --- 1557,1566 ---- stack_pointer + oparg)) stack_pointer += oparg; ! else { ! if (PyErr_ExceptionMatches(PyExc_TypeError)) ! PyErr_SetString(PyExc_TypeError, ! "unpack non-sequence"); why = WHY_EXCEPTION; + } Py_DECREF(v); break; From tim_one@users.sourceforge.net Sun Sep 30 06:58:44 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 22:58:44 -0700 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.81,2.82 classobject.c,2.150,2.151 typeobject.c,2.77,2.78 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27904/python/Objects Modified Files: abstract.c classobject.c typeobject.c Log Message: SF bug [#466173] unpack TypeError unclear Replaced 3 instances of "iter() of non-sequence" with "iteration over non-sequence". Restored "unpack non-sequence" for stuff like "a, b = 1". Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -d -r2.81 -r2.82 *** abstract.c 2001/09/29 01:05:03 2.81 --- abstract.c 2001/09/30 05:58:41 2.82 *************** *** 1860,1864 **** if (PySequence_Check(o)) return PySeqIter_New(o); ! PyErr_SetString(PyExc_TypeError, "iter() of non-sequence"); return NULL; } --- 1860,1864 ---- if (PySequence_Check(o)) return PySeqIter_New(o); ! PyErr_SetString(PyExc_TypeError, "iteration over non-sequence"); return NULL; } Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.150 retrieving revision 2.151 diff -C2 -d -r2.150 -r2.151 *** classobject.c 2001/09/20 21:45:26 2.150 --- classobject.c 2001/09/30 05:58:41 2.151 *************** *** 1840,1844 **** PyErr_Clear(); if ((func = instance_getattr(self, getitemstr)) == NULL) { ! PyErr_SetString(PyExc_TypeError, "iter() of non-sequence"); return NULL; } --- 1840,1844 ---- PyErr_Clear(); if ((func = instance_getattr(self, getitemstr)) == NULL) { ! PyErr_SetString(PyExc_TypeError, "iteration over non-sequence"); return NULL; } Index: typeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/typeobject.c,v retrieving revision 2.77 retrieving revision 2.78 diff -C2 -d -r2.77 -r2.78 *** typeobject.c 2001/09/28 22:58:52 2.77 --- typeobject.c 2001/09/30 05:58:42 2.78 *************** *** 3262,3266 **** func = lookup_method(self, "__getitem__", &getitem_str); if (func == NULL) { ! PyErr_SetString(PyExc_TypeError, "iter() of non-sequence"); return NULL; } --- 3262,3266 ---- func = lookup_method(self, "__getitem__", &getitem_str); if (func == NULL) { ! PyErr_SetString(PyExc_TypeError, "iteration over non-sequence"); return NULL; } From tim_one@users.sourceforge.net Sun Sep 30 07:18:28 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 23:18:28 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.86,1.87 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv30421/python/Doc/lib Modified Files: libfuncs.tex Log Message: Correct docs for long(float). Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.86 retrieving revision 1.87 diff -C2 -d -r1.86 -r1.87 *** libfuncs.tex 2001/09/29 14:28:52 1.86 --- libfuncs.tex 2001/09/30 06:18:26 1.87 *************** *** 490,495 **** long integer or a floating point number, and a long integer with the same value is returned. Conversion of floating ! point numbers to integers is defined by the C semantics; ! see the description of \function{int()}. \end{funcdesc} --- 490,494 ---- long integer or a floating point number, and a long integer with the same value is returned. Conversion of floating ! point numbers to integers truncates (towards zero). \end{funcdesc} From tim_one@users.sourceforge.net Sun Sep 30 07:33:01 2001 From: tim_one@users.sourceforge.net (Tim Peters) Date: Sat, 29 Sep 2001 23:33:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv32238/python/Doc/lib Modified Files: libfuncs.tex Log Message: The execfile() docs imply it acts on locals same as exec. But in truth it acts more like assigning to keys in locals(), i.e. modifications to function locals aren't reflected in the locals when execfile() returns. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -d -r1.87 -r1.88 *** libfuncs.tex 2001/09/30 06:18:26 1.87 --- libfuncs.tex 2001/09/30 06:32:59 1.88 *************** *** 258,261 **** --- 258,268 ---- environment where \function{execfile()} is called. The return value is \code{None}. + + \strong{Warning:} The default \var{locals} act as described for function + \function{locals()} below: modifications to the default \var{locals} + dictionary should not be attempted. Pass an explicit \var{locals} + dictionary if you need to see effects of the code on \var{locals} after + function \function{execfile()} returns. \function{execfile()} cannot + be used reliably to modify a function's locals. \end{funcdesc} From loewis@users.sourceforge.net Sun Sep 30 21:15:43 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:15:43 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib xmlrpclib.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv8421 Modified Files: xmlrpclib.py Log Message: Properly detect recursive structures. Adopted from patch #465298. Index: xmlrpclib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xmlrpclib.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** xmlrpclib.py 2001/09/10 21:45:42 1.7 --- xmlrpclib.py 2001/09/30 20:15:41 1.8 *************** *** 491,494 **** --- 491,498 ---- self.memo[i] = None + def endcontainer(self, value): + if value: + del self.memo[id(value)] + def dump_array(self, value): self.container(value) *************** *** 498,501 **** --- 502,506 ---- self.__dump(v) write("\n") + self.endcontainer(value) dispatch[TupleType] = dump_array dispatch[ListType] = dump_array *************** *** 514,517 **** --- 519,523 ---- write("\n") write("\n") + self.endcontainer(value) dispatch[DictType] = dump_struct From loewis@users.sourceforge.net Sun Sep 30 21:32:13 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:32:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_quopri.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10858/Lib/test Modified Files: test_quopri.py Log Message: Patch #462190, patch #464070: Support quoted printable in the binascii module. Decode and encode underscores for header style encoding. Fixes bug #463996. Index: test_quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_quopri.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** test_quopri.py 2001/09/20 21:33:42 1.5 --- test_quopri.py 2001/09/30 20:32:10 1.6 *************** *** 105,108 **** --- 105,114 ---- ) + # These are used in the "header=1" tests. + HSTRINGS = ( + ('hello world', 'hello_world'), + ('hello_world', 'hello=5Fworld'), + ) + def test_encodestring(self): for p, e in self.STRINGS: *************** *** 136,139 **** --- 142,152 ---- self.assert_(decodestring(e) == p) + def test_encode_header(self): + for p, e in self.HSTRINGS: + self.assert_(encodestring(p, header = 1) == e) + + def test_decode_header(self): + for p, e in self.HSTRINGS: + self.assert_(decodestring(e, header = 1) == p) def test_main(): From loewis@users.sourceforge.net Sun Sep 30 21:32:12 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:32:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Lib quopri.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv10858/Lib Modified Files: quopri.py Log Message: Patch #462190, patch #464070: Support quoted printable in the binascii module. Decode and encode underscores for header style encoding. Fixes bug #463996. Index: quopri.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/quopri.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** quopri.py 2001/09/04 19:14:14 1.15 --- quopri.py 2001/09/30 20:32:10 1.16 *************** *** 12,18 **** EMPTYSTRING = '' ! def needsquoting(c, quotetabs): """Decide whether a particular character needs to be quoted. --- 12,23 ---- EMPTYSTRING = '' + try: + from binascii import a2b_qp, b2a_qp + except: + a2b_qp = None + b2a_qp = None ! def needsquoting(c, quotetabs, header): """Decide whether a particular character needs to be quoted. *************** *** 23,26 **** --- 28,34 ---- if c in ' \t': return quotetabs + # if header, we have to escape _ because _ is used to escape space + if c == '_': + return header return c == ESCAPE or not (' ' <= c <= '~') *************** *** 32,36 **** ! def encode(input, output, quotetabs): """Read 'input', apply quoted-printable encoding, and write to 'output'. --- 40,44 ---- ! def encode(input, output, quotetabs, header = 0): """Read 'input', apply quoted-printable encoding, and write to 'output'. *************** *** 39,43 **** --- 47,60 ---- quoted. Note that line-ending tabs and spaces are always encoded, as per RFC 1521. + The 'header' flag indicates whether we are encoding spaces as _ as per + RFC 1522. """ + + if b2a_qp is not None: + data = input.read() + odata = b2a_qp(data, quotetabs = quotetabs, header = header) + output.write(odata) + return + def write(s, output=output, lineEnd='\n'): # RFC 1521 requires that the line ending in a space or tab must have *************** *** 61,67 **** # Calculate the un-length-limited encoded line for c in line: ! if needsquoting(c, quotetabs): c = quote(c) ! outline.append(c) # First, write out the previous line if prevline is not None: --- 78,87 ---- # Calculate the un-length-limited encoded line for c in line: ! if needsquoting(c, quotetabs, header): c = quote(c) ! if header and c == ' ': ! outline.append('_') ! else: ! outline.append(c) # First, write out the previous line if prevline is not None: *************** *** 81,97 **** write(prevline, lineEnd=stripped) ! def encodestring(s, quotetabs=0): from cStringIO import StringIO infp = StringIO(s) outfp = StringIO() ! encode(infp, outfp, quotetabs) return outfp.getvalue() ! def decode(input, output): """Read 'input', apply quoted-printable decoding, and write to 'output'. ! 'input' and 'output' are files with readline() and write() methods.""" new = '' while 1: --- 101,126 ---- write(prevline, lineEnd=stripped) ! def encodestring(s, quotetabs = 0, header = 0): ! if b2a_qp is not None: ! return b2a_qp(s, quotetabs = quotetabs, header = header) from cStringIO import StringIO infp = StringIO(s) outfp = StringIO() ! encode(infp, outfp, quotetabs, header) return outfp.getvalue() ! def decode(input, output, header = 0): """Read 'input', apply quoted-printable decoding, and write to 'output'. + 'input' and 'output' are files with readline() and write() methods. + If 'header' is true, decode underscore as space (per RFC 1522).""" ! if a2b_qp is not None: ! data = input.read() ! odata = a2b_qp(data, header = header) ! output.write(odata) ! return ! new = '' while 1: *************** *** 108,112 **** while i < n: c = line[i] ! if c != ESCAPE: new = new + c; i = i+1 elif i+1 == n and not partial: --- 137,143 ---- while i < n: c = line[i] ! if c == '_' and header: ! new = new + ' '; i = i+1 ! elif c != ESCAPE: new = new + c; i = i+1 elif i+1 == n and not partial: *************** *** 124,132 **** output.write(new) ! def decodestring(s): from cStringIO import StringIO infp = StringIO(s) outfp = StringIO() ! decode(infp, outfp) return outfp.getvalue() --- 155,165 ---- output.write(new) ! def decodestring(s, header = 0): ! if a2b_qp is not None: ! return a2b_qp(s, header = header) from cStringIO import StringIO infp = StringIO(s) outfp = StringIO() ! decode(infp, outfp, header = header) return outfp.getvalue() From loewis@users.sourceforge.net Sun Sep 30 21:32:13 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:32:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.260,1.261 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv10858/Misc Modified Files: NEWS Log Message: Patch #462190, patch #464070: Support quoted printable in the binascii module. Decode and encode underscores for header style encoding. Fixes bug #463996. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.260 retrieving revision 1.261 diff -C2 -d -r1.260 -r1.261 *** NEWS 2001/09/30 05:09:36 1.260 --- NEWS 2001/09/30 20:32:11 1.261 *************** *** 7,11 **** --- 7,16 ---- Core + - binascii has now two quopri support functions, a2b_qp and b2a_qp. + Library + + - quopri's encode and decode methods take an optional header parameter, + which indicates whether output is intended for the header 'Q' encoding. Tools From loewis@users.sourceforge.net Sun Sep 30 21:32:12 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:32:12 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbinascii.tex,1.20,1.21 libquopri.tex,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv10858/Doc/lib Modified Files: libbinascii.tex libquopri.tex Log Message: Patch #462190, patch #464070: Support quoted printable in the binascii module. Decode and encode underscores for header style encoding. Fixes bug #463996. Index: libbinascii.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbinascii.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -d -r1.20 -r1.21 *** libbinascii.tex 2001/05/09 15:50:17 1.20 --- libbinascii.tex 2001/09/30 20:32:10 1.21 *************** *** 41,44 **** --- 41,62 ---- \end{funcdesc} + \begin{funcdesc}{a2b_qp}{string\optional{, header}} + Convert a block of quoted-printable data back to binary and return the + binary data. More than one line may be passed at a time. + If the optional argument \var{header} is present and true, underscores + will be decoded as spaces. + \end{funcdesc} + + \begin{funcdesc}{b2a_qp}{data\optional{, quotetabs, istext, header}} + Convert binary data to a line(s) of \ASCII{} characters in + quoted-printable encoding. The return value is the converted line(s). + If the optional argument \var{quotetabs} is present and true, all tabs + and spaces will be encoded. If the optional argument \var{header} is + present and true, spaces will be encoded as underscores per RFC1522. + If the optional argument \var{header} is present and false, newline + characters will be encoded as well, otherwise linefeed conversion might + corrupt the binary data stream. + \end{funcdesc} + \begin{funcdesc}{a2b_hqx}{string} Convert binhex4 formatted \ASCII{} data to binary, without doing *************** *** 119,121 **** --- 137,141 ---- \seemodule{uu}{Support for UU encoding used on \UNIX.} + + \seemodule{quopri}{Support for quoted-printable encoding used in MIME email messages. } \end{seealso} Index: libquopri.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libquopri.tex,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -d -r1.13 -r1.14 *** libquopri.tex 2001/06/19 19:44:42 1.13 --- libquopri.tex 2001/09/30 20:32:10 1.14 *************** *** 8,21 **** This module performs quoted-printable transport encoding and decoding, ! as defined in \rfc{1521}: ``MIME (Multipurpose Internet Mail Extensions) ! Part One''. The quoted-printable encoding is designed for data where ! there are relatively few nonprintable characters; the base64 encoding ! scheme available via the \refmodule{base64} module is more compact if there ! are many such characters, as when sending a graphics file. \indexii{quoted-printable}{encoding} \index{MIME!quoted-printable encoding} ! \begin{funcdesc}{decode}{input, output} Decode the contents of the \var{input} file and write the resulting decoded binary data to the \var{output} file. --- 8,23 ---- This module performs quoted-printable transport encoding and decoding, ! as defined in \rfc{1521}: ``MIME (Multipurpose Internet Mail ! Extensions) Part One: Mechanisms for Specifying and Describing the ! Format of Internet Message Bodies''. The quoted-printable encoding is ! designed for data where there are relatively few nonprintable ! characters; the base64 encoding scheme available via the ! \refmodule{base64} module is more compact if there are many such ! characters, as when sending a graphics file. \indexii{quoted-printable}{encoding} \index{MIME!quoted-printable encoding} ! \begin{funcdesc}{decode}{input, output\optional{,header}} Decode the contents of the \var{input} file and write the resulting decoded binary data to the \var{output} file. *************** *** 23,26 **** --- 25,32 ---- mimic the file object interface. \var{input} will be read until \code{\var{input}.readline()} returns an empty string. + If the optional argument \var{header} is present and true, underscore + will be decoded as space. This is used to decode + ``Q''-encoded headers as described in \rfc{1522}: ``MIME (Multipurpose Internet Mail Extensions) + Part Two: Message Header Extensions for Non-ASCII Text''. \end{funcdesc} *************** *** 37,41 **** \end{funcdesc} ! \begin{funcdesc}{decodestring}{s} Like \function{decode()}, except that it accepts a source string and returns the corresponding decoded string. --- 43,47 ---- \end{funcdesc} ! \begin{funcdesc}{decodestring}{s\optional{,header}} Like \function{decode()}, except that it accepts a source string and returns the corresponding decoded string. From loewis@users.sourceforge.net Sun Sep 30 21:32:13 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 13:32:13 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules binascii.c,2.29,2.30 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv10858/Modules Modified Files: binascii.c Log Message: Patch #462190, patch #464070: Support quoted printable in the binascii module. Decode and encode underscores for header style encoding. Fixes bug #463996. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.29 retrieving revision 2.30 diff -C2 -d -r2.29 -r2.30 *** binascii.c 2001/06/07 05:51:36 2.29 --- binascii.c 2001/09/30 20:32:11 2.30 *************** *** 43,46 **** --- 43,55 ---- ** ** Jack Jansen, CWI, July 1995. + ** + ** Added support for quoted-printable encoding, based on rfc 1521 et al + ** quoted-printable encoding specifies that non printable characters (anything + ** below 32 and above 126) be encoded as =XX where XX is the hexadecimal value + ** of the character. It also specifies some other behavior to enable 8bit data + ** in a mail message with little difficulty (maximum line sizes, protecting + ** some cases of whitespace, etc). + ** + ** Brandon Long, September 2001. */ *************** *** 972,975 **** --- 981,1267 ---- This function is also available as \"unhexlify()\""; + static int table_hex[128] = { + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1, -1,-1,-1,-1, + -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,10,11,12, 13,14,15,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1 + }; + + #define hexval(c) table_hex[(unsigned int)(c)] + + #define MAXLINESIZE 76 + + static char doc_a2b_qp[] = "Decode a string of qp-encoded data"; + + static PyObject* + binascii_a2b_qp(PyObject *self, PyObject *args, PyObject *kwargs) + { + unsigned int in, out; + char ch; + unsigned char *data, *odata; + unsigned int datalen = 0; + PyObject *rv; + static char *kwlist[] = {"data", "header", NULL}; + int header = 0; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|i", kwlist, &data, + &datalen, &header)) + return NULL; + + /* We allocate the output same size as input, this is overkill */ + odata = (char *) calloc(1, datalen); + + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + + in = out = 0; + while (in < datalen) { + if (data[in] == '=') { + in++; + if (in >= datalen) break; + /* Soft line breaks */ + if ((data[in] == '\n') || (data[in] == '\r') || + (data[in] == ' ') || (data[in] == '\t')) { + if (data[in] != '\n') { + while (in < datalen && data[in] != '\n') in++; + } + if (in < datalen) in++; + } + else if (data[in] == '=') { + /* broken case from broken python qp */ + odata[out++] = '='; + in++; + } + else if (((data[in] >= 'A' && data[in] <= 'F') || + (data[in] >= 'a' && data[in] <= 'f') || + (data[in] >= '0' && data[in] <= '9')) && + ((data[in+1] >= 'A' && data[in+1] <= 'F') || + (data[in+1] >= 'a' && data[in+1] <= 'f') || + (data[in+1] >= '0' && data[in+1] <= '9'))) { + /* hexval */ + ch = hexval(data[in]) << 4; + in++; + ch |= hexval(data[in]); + in++; + odata[out++] = ch; + } + else { + odata[out++] = '='; + } + } + else if (header && data[in] == '_') { + odata[out++] = ' '; + in++; + } + else { + odata[out] = data[in]; + in++; + out++; + } + } + if ((rv = PyString_FromStringAndSize(odata, out)) == NULL) { + free (odata); + return NULL; + } + free (odata); + return rv; + } + + static int + to_hex (unsigned char ch, unsigned char *s) + { + unsigned int uvalue = ch; + + s[1] = "0123456789ABCDEF"[uvalue % 16]; + uvalue = (uvalue / 16); + s[0] = "0123456789ABCDEF"[uvalue % 16]; + return 0; + } + + static char doc_b2a_qp[] = + "b2a_qp(data, quotetabs=0, istext=1, header=0) -> s; \n\ + Encode a string using quoted-printable encoding. \n\ + \n\ + On encoding, when istext is set, newlines are not encoded, and white \n\ + space at end of lines is. When istext is not set, \\r and \\n (CR/LF) are \n\ + both encoded. When quotetabs is set, space and tabs are encoded."; + + /* XXX: This is ridiculously complicated to be backward compatible + * (mostly) with the quopri module. It doesn't re-create the quopri + * module bug where text ending in CRLF has the CR encoded */ + static PyObject* + binascii_b2a_qp (PyObject *self, PyObject *args, PyObject *kwargs) + { + unsigned int in, out; + unsigned char *data, *odata; + unsigned int datalen = 0, odatalen = 0; + PyObject *rv; + unsigned int linelen = 0; + static char *kwlist[] = {"data", "quotetabs", "istext", "header", NULL}; + int istext = 1; + int quotetabs = 0; + int header = 0; + unsigned char ch; + int crlf = 0; + unsigned char *p; + + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s#|iii", kwlist, &data, + &datalen, "etabs, &istext, &header)) + return NULL; + + /* See if this string is using CRLF line ends */ + /* XXX: this function has the side effect of converting all of + * the end of lines to be the same depending on this detection + * here */ + p = strchr(data, '\n'); + if ((p != NULL) && (p > data) && (*(p-1) == '\r')) + crlf = 1; + + /* First, scan to see how many characters need to be encoded */ + in = 0; + while (in < datalen) { + if ((data[in] > 126) || + (data[in] == '=') || + (header && data[in] == '_') || + ((data[in] == '.') && (linelen == 1)) || + (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || + ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || + ((data[in] < 33) && + (data[in] != '\r') && (data[in] != '\n') && + (quotetabs && ((data[in] != '\t') || (data[in] != ' '))))) + { + if ((linelen + 3) >= MAXLINESIZE) { + linelen = 0; + if (crlf) + odatalen += 3; + else + odatalen += 2; + } + linelen += 3; + odatalen += 3; + in++; + } + else { + if (istext && + ((data[in] == '\n') || + ((in+1 < datalen) && (data[in] == '\r') && + (data[in+1] == '\n')))) + { + linelen = 0; + /* Protect against whitespace on end of line */ + if (in && ((data[in-1] == ' ') || (data[in-1] == '\t'))) + odatalen += 2; + if (crlf) + odatalen += 2; + else + odatalen += 1; + if (data[in] == '\r') + in += 2; + else + in++; + } + else { + if ((in + 1 != datalen) && + (data[in+1] != '\n') && + (linelen + 1) >= MAXLINESIZE) { + linelen = 0; + if (crlf) + odatalen += 3; + else + odatalen += 2; + } + linelen++; + odatalen++; + in++; + } + } + } + + odata = (char *) calloc(1, odatalen); + + if (odata == NULL) { + PyErr_NoMemory(); + return NULL; + } + + in = out = linelen = 0; + while (in < datalen) { + if ((data[in] > 126) || + (data[in] == '=') || + (header && data[in] == '_') || + ((data[in] == '.') && (linelen == 1)) || + (!istext && ((data[in] == '\r') || (data[in] == '\n'))) || + ((data[in] == '\t' || data[in] == ' ') && (in + 1 == datalen)) || + ((data[in] < 33) && + (data[in] != '\r') && (data[in] != '\n') && + (quotetabs && ((data[in] != '\t') || (data[in] != ' '))))) + { + if ((linelen + 3 )>= MAXLINESIZE) { + odata[out++] = '='; + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + linelen = 0; + } + odata[out++] = '='; + to_hex(data[in], &odata[out]); + out += 2; + in++; + linelen += 3; + } + else { + if (istext && + ((data[in] == '\n') || + ((in+1 < datalen) && (data[in] == '\r') && + (data[in+1] == '\n')))) + { + linelen = 0; + /* Protect against whitespace on end of line */ + if (out && ((odata[out-1] == ' ') || (odata[out-1] == '\t'))) { + ch = odata[out-1]; + odata[out-1] = '='; + to_hex(ch, &odata[out]); + out += 2; + } + + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + if (data[in] == '\r') + in += 2; + else + in++; + } + else { + if ((in + 1 != datalen) && + (data[in+1] != '\n') && + (linelen + 1) >= MAXLINESIZE) { + odata[out++] = '='; + if (crlf) odata[out++] = '\r'; + odata[out++] = '\n'; + linelen = 0; + } + linelen++; + if (header && data[in] == ' ') { + odata[out++] = '_'; + in++; + } + else { + odata[out++] = data[in++]; + } + } + } + } + if ((rv = PyString_FromStringAndSize(odata, out)) == NULL) { + free (odata); + return NULL; + } + free (odata); + return rv; + } /* List of functions defined in the module */ *************** *** 991,994 **** --- 1283,1290 ---- {"crc_hqx", binascii_crc_hqx, METH_VARARGS, doc_crc_hqx}, {"crc32", binascii_crc32, METH_VARARGS, doc_crc32}, + {"a2b_qp", (PyCFunction)binascii_a2b_qp, METH_VARARGS | METH_KEYWORDS, + doc_a2b_qp}, + {"b2a_qp", (PyCFunction)binascii_b2a_qp, METH_VARARGS | METH_KEYWORDS, + doc_b2a_qp}, {NULL, NULL} /* sentinel */ }; From loewis@users.sourceforge.net Sun Sep 30 22:10:01 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 14:10:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libreadline.tex,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv18073/Doc/lib Modified Files: libreadline.tex Log Message: Patch #462122: add readline startup and pre_event hooks. Index: libreadline.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libreadline.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** libreadline.tex 2001/08/01 21:42:45 1.6 --- libreadline.tex 2001/09/30 21:09:58 1.7 *************** *** 55,58 **** --- 55,74 ---- \end{funcdesc} + \begin{funcdesc}{set_startup_hook}{\optional{function}} + Set or remove the startup_hook function. If \var{function} is specified, + it will be used as the new startup_hook function; if omitted or + \code{None}, any hook function already installed is removed. The + startup_hook function is called with no arguments just + before readline prints the first prompt. + \end{funcdesc} + + \begin{funcdesc}{set_pre_input_hook}{\optional{function}} + Set or remove the pre_input_hook function. If \var{function} is specified, + it will be used as the new pre_input_hook function; if omitted or + \code{None}, any hook function already installed is removed. The + pre_input_hook function is called with no arguments after the first prompt + has been printed and just before readline starts reading input characters. + \end{funcdesc} + \begin{funcdesc}{set_completer}{\optional{function}} Set or remove the completer function. If \var{function} is specified, From loewis@users.sourceforge.net Sun Sep 30 22:10:01 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 14:10:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.261,1.262 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv18073/Misc Modified Files: NEWS Log Message: Patch #462122: add readline startup and pre_event hooks. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.261 retrieving revision 1.262 diff -C2 -d -r1.261 -r1.262 *** NEWS 2001/09/30 20:32:11 1.261 --- NEWS 2001/09/30 21:09:59 1.262 *************** *** 9,12 **** --- 9,14 ---- - binascii has now two quopri support functions, a2b_qp and b2a_qp. + - readline now supports setting the startup_hook and the pre_event_hook. + Library From loewis@users.sourceforge.net Sun Sep 30 22:10:01 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 14:10:01 -0700 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.56,1.57 configure,1.253,1.254 configure.in,1.261,1.262 pyconfig.h.in,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv18073 Modified Files: acconfig.h configure configure.in pyconfig.h.in Log Message: Patch #462122: add readline startup and pre_event hooks. Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -d -r1.56 -r1.57 *** acconfig.h 2001/09/10 14:10:53 1.56 --- acconfig.h 2001/09/30 21:09:58 1.57 *************** *** 88,91 **** --- 88,94 ---- #undef HAVE_PTH + /* Define if you have readline 4.0 */ + #undef HAVE_RL_PRE_INPUT_HOOK + /* Define if you have readline 4.2 */ #undef HAVE_RL_COMPLETION_MATCHES Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.253 retrieving revision 1.254 diff -C2 -d -r1.253 -r1.254 *** configure 2001/09/28 15:59:37 1.253 --- configure 2001/09/30 21:09:58 1.254 *************** *** 7028,7034 **** fi # check for readline 4.2 echo $ac_n "checking for rl_completion_matches in -lreadline""... $ac_c" 1>&6 ! echo "configure:7033: checking for rl_completion_matches in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_completion_matches | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then --- 7028,7079 ---- fi + # check for readline 4.0 + echo $ac_n "checking for rl_pre_input_hook in -lreadline""... $ac_c" 1>&6 + echo "configure:7033: checking for rl_pre_input_hook in -lreadline" >&5 + ac_lib_var=`echo readline'_'rl_pre_input_hook | sed 'y%./+-%__p_%'` + if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + ac_save_LIBS="$LIBS" + LIBS="-lreadline -ltermcap $LIBS" + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" + fi + rm -f conftest* + LIBS="$ac_save_LIBS" + + fi + if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + cat >> confdefs.h <<\EOF + #define HAVE_RL_PRE_INPUT_HOOK 1 + EOF + + else + echo "$ac_t""no" 1>&6 + fi + + # check for readline 4.2 echo $ac_n "checking for rl_completion_matches in -lreadline""... $ac_c" 1>&6 ! echo "configure:7078: checking for rl_completion_matches in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_completion_matches | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then *************** *** 7038,7042 **** LIBS="-lreadline -ltermcap $LIBS" cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" --- 7094,7098 ---- ; return 0; } EOF ! if { (eval echo configure:7097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" *************** *** 7074,7078 **** echo $ac_n "checking for broken nice()""... $ac_c" 1>&6 ! echo "configure:7077: checking for broken nice()" >&5 if eval "test \"`echo '$''{'ac_cv_broken_nice'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 --- 7119,7123 ---- echo $ac_n "checking for broken nice()""... $ac_c" 1>&6 ! echo "configure:7122: checking for broken nice()" >&5 if eval "test \"`echo '$''{'ac_cv_broken_nice'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 *************** *** 7083,7087 **** else cat > conftest.$ac_ext < conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_broken_nice=yes --- 7140,7144 ---- EOF ! if { (eval echo configure:7143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_broken_nice=yes *************** *** 7126,7135 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:7129: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < --- 7171,7180 ---- EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:7174: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < *************** *** 7180,7184 **** SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7183: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then --- 7225,7229 ---- SRCDIRS="Parser Grammar Objects Python Modules" echo $ac_n "checking for build directories""... $ac_c" 1>&6 ! echo "configure:7228: checking for build directories" >&5 for dir in $SRCDIRS; do if test ! -d $dir; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.261 retrieving revision 1.262 diff -C2 -d -r1.261 -r1.262 *** configure.in 2001/09/28 15:59:38 1.261 --- configure.in 2001/09/30 21:09:58 1.262 *************** *** 1833,1836 **** --- 1833,1840 ---- fi + # check for readline 4.0 + AC_CHECK_LIB(readline, rl_pre_input_hook, + AC_DEFINE(HAVE_RL_PRE_INPUT_HOOK), , -ltermcap) + # check for readline 4.2 AC_CHECK_LIB(readline, rl_completion_matches, Index: pyconfig.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/pyconfig.h.in,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -d -r1.11 -r1.12 *** pyconfig.h.in 2001/09/10 14:10:54 1.11 --- pyconfig.h.in 2001/09/30 21:09:58 1.12 *************** *** 150,153 **** --- 150,156 ---- #undef HAVE_PTH + /* Define if you have readline 4.0 */ + #undef HAVE_RL_PRE_INPUT_HOOK + /* Define if you have readline 4.2 */ #undef HAVE_RL_COMPLETION_MATCHES From loewis@users.sourceforge.net Sun Sep 30 22:10:01 2001 From: loewis@users.sourceforge.net (Martin v. L?wis) Date: Sun, 30 Sep 2001 14:10:01 -0700 Subject: [Python-checkins] CVS: python/dist/src/Modules readline.c,2.37,2.38 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18073/Modules Modified Files: readline.c Log Message: Patch #462122: add readline startup and pre_event hooks. Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.37 retrieving revision 2.38 diff -C2 -d -r2.37 -r2.38 *** readline.c 2001/08/01 21:44:14 2.37 --- readline.c 2001/09/30 21:09:59 2.38 *************** *** 159,168 **** } /* Exported function to specify a word completer in Python */ static PyObject *completer = NULL; ! static PyThreadState *tstate = NULL; static PyObject *begidx = NULL; --- 159,236 ---- } + /* Generic hook function setter */ + + static PyObject * + set_hook(const char * funcname, PyObject **hook_var, PyThreadState **tstate, PyObject *args) + { + PyObject *function = Py_None; + char buf[80]; + sprintf(buf, "|O:set_%s", funcname); + if (!PyArg_ParseTuple(args, buf, &function)) + return NULL; + if (function == Py_None) { + Py_XDECREF(*hook_var); + *hook_var = NULL; + *tstate = NULL; + } + else if (PyCallable_Check(function)) { + PyObject *tmp = *hook_var; + Py_INCREF(function); + *hook_var = function; + Py_XDECREF(tmp); + *tstate = PyThreadState_Get(); + } + else { + sprintf(buf, "set_%s(func): argument not callable", funcname); + PyErr_SetString(PyExc_TypeError, buf); + return NULL; + } + Py_INCREF(Py_None); + return Py_None; + } + + /* Exported functions to specify hook functions in Python */ + + static PyObject *startup_hook = NULL; + static PyThreadState *startup_hook_tstate = NULL; + + #ifdef HAVE_RL_PRE_INPUT_HOOK + static PyObject *pre_input_hook = NULL; + static PyThreadState *pre_input_hook_tstate = NULL; + #endif + + static PyObject * + set_startup_hook(PyObject *self, PyObject *args) + { + return set_hook("startup_hook", &startup_hook, &startup_hook_tstate, args); + } + + static char doc_set_startup_hook[] = "\ + set_startup_hook([function]) -> None\n\ + Set or remove the startup_hook function.\n\ + The function is called with no arguments just\n\ + before readline prints the first prompt.\n\ + "; + + #ifdef HAVE_RL_PRE_INPUT_HOOK + static PyObject * + set_pre_input_hook(PyObject *self, PyObject *args) + { + return set_hook("pre_input_hook", &pre_input_hook, &pre_input_hook_tstate, args); + } + static char doc_set_pre_input_hook[] = "\ + set_pre_input_hook([function]) -> None\n\ + Set or remove the pre_input_hook function.\n\ + The function is called with no arguments after the first prompt\n\ + has been printed and just before readline starts reading input\n\ + characters.\n\ + "; + #endif /* Exported function to specify a word completer in Python */ static PyObject *completer = NULL; ! static PyThreadState *completer_tstate = NULL; static PyObject *begidx = NULL; *************** *** 239,264 **** set_completer(PyObject *self, PyObject *args) { ! PyObject *function = Py_None; ! if (!PyArg_ParseTuple(args, "|O:set_completer", &function)) ! return NULL; ! if (function == Py_None) { ! Py_XDECREF(completer); ! completer = NULL; ! tstate = NULL; ! } ! else if (PyCallable_Check(function)) { ! PyObject *tmp = completer; ! Py_INCREF(function); ! completer = function; ! Py_XDECREF(tmp); ! tstate = PyThreadState_Get(); ! } ! else { ! PyErr_SetString(PyExc_TypeError, ! "set_completer(func): argument not callable"); ! return NULL; ! } ! Py_INCREF(Py_None); ! return Py_None; } --- 307,311 ---- set_completer(PyObject *self, PyObject *args) { ! return set_hook("completer", &completer, &completer_tstate, args); } *************** *** 331,337 **** --- 378,435 ---- {"get_completer_delims", get_completer_delims, METH_OLDARGS, doc_get_completer_delims}, + + {"set_startup_hook", set_startup_hook, METH_VARARGS, doc_set_startup_hook}, + #ifdef HAVE_RL_PRE_INPUT_HOOK + {"set_pre_input_hook", set_pre_input_hook, METH_VARARGS, doc_set_pre_input_hook}, + #endif {0, 0} }; + /* C function to call the Python hooks. */ + + static int + on_hook(PyObject *func, PyThreadState *tstate) + { + int result = 0; + if (func != NULL) { + PyObject *r; + PyThreadState *save_tstate; + /* Note that readline is called with the interpreter + lock released! */ + save_tstate = PyThreadState_Swap(NULL); + PyEval_RestoreThread(tstate); + r = PyObject_CallFunction(func, NULL); + if (r == NULL) + goto error; + if (r == Py_None) + result = 0; + else + result = PyInt_AsLong(r); + Py_DECREF(r); + goto done; + error: + PyErr_Clear(); + Py_XDECREF(r); + done: + PyEval_SaveThread(); + PyThreadState_Swap(save_tstate); + } + return result; + } + + static int + on_startup_hook(void) + { + return on_hook(startup_hook, startup_hook_tstate); + } + + #ifdef HAVE_RL_PRE_INPUT_HOOK + static int + on_pre_input_hook(void) + { + return on_hook(pre_input_hook, pre_input_hook_tstate); + } + #endif + /* C function to call the Python completer. */ *************** *** 346,350 **** lock released! */ save_tstate = PyThreadState_Swap(NULL); ! PyEval_RestoreThread(tstate); r = PyObject_CallFunction(completer, "si", text, state); if (r == NULL) --- 444,448 ---- lock released! */ save_tstate = PyThreadState_Swap(NULL); ! PyEval_RestoreThread(completer_tstate); r = PyObject_CallFunction(completer, "si", text, state); if (r == NULL) *************** *** 396,399 **** --- 494,502 ---- rl_bind_key_in_map ('\t', rl_complete, emacs_meta_keymap); rl_bind_key_in_map ('\033', rl_complete, emacs_meta_keymap); + /* Set our hook functions */ + rl_startup_hook = (Function *)on_startup_hook; + #ifdef HAVE_RL_PRE_INPUT_HOOK + rl_pre_input_hook = (Function *)on_pre_input_hook; + #endif /* Set our completion function */ rl_attempted_completion_function = (CPPFunction *)flex_complete;