From python-dev@python.org Mon Jan 1 19:11:09 2001 From: python-dev@python.org (Guido van Rossum) Date: Mon, 01 Jan 2001 11:11:09 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/lib-tk turtle.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/lib-tk In directory usw-pr-cvs1:/tmp/cvs-serv26735 Modified Files: turtle.py Log Message: Patch by kragen@pobox.com: When tracing is turned on, lines shorter than a pixel don't get drawn at all. If you're building long curves made of such lines, this is a bad thing. Index: turtle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/lib-tk/turtle.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** turtle.py 2000/10/23 18:31:14 1.3 --- turtle.py 2001/01/01 19:11:07 1.4 *************** *** 222,225 **** --- 222,227 ---- self._canvas.update() self._canvas.after(10) + # in case nhops==0 + self._canvas.coords(item, x0, y0, x1, y1) self._canvas.itemconfigure(item, arrow="none") except Tkinter.TclError: From python-dev@python.org Mon Jan 1 20:33:08 2001 From: python-dev@python.org (Fred L. Drake) Date: Mon, 01 Jan 2001 12:33:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/tut tut.tex,1.123,1.124 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tut In directory usw-pr-cvs1:/tmp/cvs-serv31365/tut Modified Files: tut.tex Log Message: Fix up an awkward sentence, pointed out by Chris Ryland . Index: tut.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tut/tut.tex,v retrieving revision 1.123 retrieving revision 1.124 diff -C2 -r1.123 -r1.124 *** tut.tex 2000/11/29 06:03:45 1.123 --- tut.tex 2001/01/01 20:33:06 1.124 *************** *** 2589,2593 **** shortly. The second way is to use the \code{\%} operator with a string as the left argument. The \code{\%} operator interprets the ! left argument as a C much like a \cfunction{sprintf()}-style format string to be applied to the right argument, and returns the string resulting from this formatting operation. --- 2589,2593 ---- shortly. The second way is to use the \code{\%} operator with a string as the left argument. The \code{\%} operator interprets the ! left argument much like a \cfunction{sprintf()}-style format string to be applied to the right argument, and returns the string resulting from this formatting operation. From python-dev@python.org Tue Jan 2 15:58:30 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 07:58:30 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects moduleobject.c,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv10766/Objects Modified Files: moduleobject.c Log Message: Add garbage collection for module objects. Closes patch #102939 and fixes bug #126345. Index: moduleobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/moduleobject.c,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -r2.30 -r2.31 *** moduleobject.c 2000/10/24 19:57:45 2.30 --- moduleobject.c 2001/01/02 15:58:27 2.31 *************** *** 19,22 **** --- 19,23 ---- nameobj = PyString_FromString(name); m->md_dict = PyDict_New(); + PyObject_GC_Init(m); if (m->md_dict == NULL || nameobj == NULL) goto fail; *************** *** 131,139 **** module_dealloc(PyModuleObject *m) { if (m->md_dict != NULL) { _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } ! PyObject_DEL(m); } --- 132,141 ---- module_dealloc(PyModuleObject *m) { + PyObject_GC_Fini(m); if (m->md_dict != NULL) { _PyModule_Clear((PyObject *)m); Py_DECREF(m->md_dict); } ! PyObject_DEL(PyObject_AS_GC(m)); } *************** *** 212,220 **** } PyTypeObject PyModule_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "module", /*tp_name*/ ! sizeof(PyModuleObject), /*tp_size*/ 0, /*tp_itemsize*/ (destructor)module_dealloc, /*tp_dealloc*/ --- 214,233 ---- } + /* We only need a traverse function, no clear function: If the module + is in a cycle, md_dict will be cleared as well, which will break + the cycle. */ + static int + module_traverse(PyModuleObject *m, visitproc visit, void *arg) + { + if (m->md_dict != NULL) + return visit(m->md_dict, arg); + return 0; + } + PyTypeObject PyModule_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "module", /*tp_name*/ ! sizeof(PyModuleObject) + PyGC_HEAD_SIZE, /*tp_size*/ 0, /*tp_itemsize*/ (destructor)module_dealloc, /*tp_dealloc*/ *************** *** 224,226 **** --- 237,251 ---- 0, /*tp_compare*/ (reprfunc)module_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /* tp_hash */ + 0, /* tp_call */ + 0, /* tp_str */ + 0, /* tp_getattro */ + 0, /* tp_setattro */ + 0, /* tp_as_buffer */ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ + 0, /* tp_doc */ + (traverseproc)module_traverse, /* tp_traverse */ }; From python-dev@python.org Tue Jan 2 16:30:33 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 08:30:33 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_coercion,NONE,1.1 test_compare,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv15688/Lib/test/output Added Files: test_coercion test_compare Log Message: Add more tests for compare and coercion in preparation for the coercion overhaul. Closes SF patch #102878. --- NEW FILE: test_coercion --- test_coercion 2 + 2 = 4 2 += 2 => 4 2 - 2 = 0 2 -= 2 => 0 2 * 2 = 4 2 *= 2 => 4 2 / 2 = 1 2 /= 2 => 1 2 ** 2 = 4 2 **= 2 => 4 2 % 2 = 0 2 %= 2 => 0 2 + 2.2 = 4.2 2 += 2.2 => 4.2 2 - 2.2 = -0.2 2 -= 2.2 => -0.2 2 * 2.2 = 4.4 2 *= 2.2 => 4.4 [...1015 lines suppressed...] divmod(None, ) ... exceptions.TypeError divmod(None, ) ... exceptions.TypeError divmod(, 2) ... exceptions.TypeError divmod(, 2.2) ... exceptions.TypeError divmod(, 2) ... exceptions.TypeError divmod(, (2+4j)) ... exceptions.TypeError divmod(, [1]) ... exceptions.TypeError divmod(, (2,)) ... exceptions.TypeError divmod(, None) ... exceptions.TypeError divmod(, ) ... exceptions.TypeError divmod(, ) ... exceptions.TypeError divmod(, 2) = (4, 0) divmod(, 2.2) = (3.0, 1.3999999999999995) divmod(, 2) = (4L, 0L) divmod(, (2+4j)) = (0j, (8+0j)) divmod(, [1]) ... exceptions.TypeError divmod(, (2,)) ... exceptions.TypeError divmod(, None) ... exceptions.TypeError divmod(, ) ... exceptions.TypeError divmod(, ) = (1, 0) --- NEW FILE: test_compare --- test_compare cmp(2, 2) = 0 cmp(2, 2.2) = -1 cmp(2, 2) = 0 cmp(2, (2+4j)) = -1 cmp(2, [1]) = -108 cmp(2, (2,)) = -116 cmp(2, None) = -78 cmp(2, ) = -1 cmp(2, ) = -1 cmp(2, ) = -1 cmp(2, ) = -1 cmp(2.2, 2) = 1 cmp(2.2, 2.2) = 0 cmp(2.2, 2) = 1 cmp(2.2, (2+4j)) = 1 cmp(2.2, [1]) = -108 cmp(2.2, (2,)) = -116 cmp(2.2, None) = -78 cmp(2.2, ) = -1 cmp(2.2, ) = -1 cmp(2.2, ) = -1 cmp(2.2, ) = -1 cmp(2, 2) = 0 cmp(2, 2.2) = -1 cmp(2, 2) = 0 cmp(2, (2+4j)) = -1 cmp(2, [1]) = -108 cmp(2, (2,)) = -116 cmp(2, None) = -78 cmp(2, ) = -1 cmp(2, ) = -1 cmp(2, ) = -1 cmp(2, ) = -1 cmp((2+4j), 2) = 1 cmp((2+4j), 2.2) = -1 cmp((2+4j), 2) = 1 cmp((2+4j), (2+4j)) = 0 cmp((2+4j), [1]) = -108 cmp((2+4j), (2,)) = -116 cmp((2+4j), None) = -78 cmp((2+4j), ) = -1 cmp((2+4j), ) = -1 cmp((2+4j), ) = -1 cmp((2+4j), ) = -1 cmp([1], 2) = 108 cmp([1], 2.2) = 108 cmp([1], 2) = 108 cmp([1], (2+4j)) = 108 cmp([1], [1]) = 0 cmp([1], (2,)) = -8 cmp([1], None) = 30 cmp([1], ) = -1 cmp([1], ) = 1 cmp([1], ) = 1 cmp([1], ) = -1 cmp((2,), 2) = 116 cmp((2,), 2.2) = 116 cmp((2,), 2) = 116 cmp((2,), (2+4j)) = 116 cmp((2,), [1]) = 8 cmp((2,), (2,)) = 0 cmp((2,), None) = 38 cmp((2,), ) = -1 cmp((2,), ) = 1 cmp((2,), ) = 1 cmp((2,), ) = -1 cmp(None, 2) = 78 cmp(None, 2.2) = 78 cmp(None, 2) = 78 cmp(None, (2+4j)) = 78 cmp(None, [1]) = -30 cmp(None, (2,)) = -38 cmp(None, None) = 0 cmp(None, ) = -1 cmp(None, ) = 1 cmp(None, ) = 1 cmp(None, ) = -1 cmp(, 2) = 1 cmp(, 2.2) = 1 cmp(, 2) = 1 cmp(, (2+4j)) = 1 cmp(, [1]) = 1 cmp(, (2,)) = 1 cmp(, None) = 1 cmp(, ) = 0 cmp(, ) = -1 cmp(, ) = -1 cmp(, ) = 1 cmp(, 2) = 1 cmp(, 2.2) = 1 cmp(, 2) = 1 cmp(, (2+4j)) = 1 cmp(, [1]) = -1 cmp(, (2,)) = -1 cmp(, None) = -1 cmp(, ) = 1 cmp(, ) = 0 cmp(, ) = -1 cmp(, ) = -1 cmp(, 2) = 1 cmp(, 2.2) = 1 cmp(, 2) = 1 cmp(, (2+4j)) = 1 cmp(, [1]) = -1 cmp(, (2,)) = -1 cmp(, None) = -1 cmp(, ) = -1 cmp(, ) = 1 cmp(, ) = 0 cmp(, ) = -1 cmp(, 2) = 1 cmp(, 2.2) = 1 cmp(, 2) = 1 cmp(, (2+4j)) = 1 cmp(, [1]) = 1 cmp(, (2,)) = 1 cmp(, None) = 1 cmp(, ) = 1 cmp(, ) = 1 cmp(, ) = 1 cmp(, ) = 0 From python-dev@python.org Tue Jan 2 16:30:33 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 08:30:33 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_coercion.py,NONE,1.1 test_compare.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv15688/Lib/test Added Files: test_coercion.py test_compare.py Log Message: Add more tests for compare and coercion in preparation for the coercion overhaul. Closes SF patch #102878. --- NEW FILE: test_coercion.py --- import copy import sys # Fake a number that implements numeric methods through __coerce__ class CoerceNumber: def __init__(self, arg): self.arg = arg def __repr__(self): return '' % repr(self.arg) def __coerce__(self, other): if isinstance(other, CoerceNumber): return self.arg, other.arg else: return (self.arg, other) # Fake a number that implements numeric ops through methods. class MethodNumber: def __init__(self,arg): self.arg = arg def __repr__(self): return '' % repr(self.arg) def __add__(self,other): return self.arg + other def __radd__(self,other): return other + self.arg def __sub__(self,other): return self.arg - other def __rsub__(self,other): return other - self.arg def __mul__(self,other): return self.arg * other def __rmul__(self,other): return other * self.arg def __div__(self,other): return self.arg / other def __rdiv__(self,other): return other / self.arg def __pow__(self,other): return self.arg ** other def __rpow__(self,other): return other ** self.arg def __mod__(self,other): return self.arg % other def __rmod__(self,other): return other % self.arg def __cmp__(self, other): return cmp(self.arg, other) candidates = [ 2, 2.2, 2L, 2+4j, [1], (2,), None, MethodNumber(1), CoerceNumber(8)] infix_binops = [ '+', '-', '*', '/', '**', '%' ] prefix_binops = [ 'divmod' ] def do_infix_binops(): for a in candidates: for b in candidates: for op in infix_binops: print '%s %s %s' % (a, op, b), try: x = eval('a %s b' % op) except: error = sys.exc_info()[:2] print '... %s' % error[0] else: print '=', x try: z = copy.copy(a) except copy.Error: z = a # assume it has no inplace ops print '%s %s= %s' % (a, op, b), try: exec('z %s= b' % op) except: error = sys.exc_info()[:2] print '... %s' % error[0] else: print '=>', z def do_prefix_binops(): for a in candidates: for b in candidates: for op in prefix_binops: print '%s(%s, %s)' % (op, a, b), try: x = eval('%s(a, b)' % op) except: error = sys.exc_info()[:2] print '... %s' % error[0] else: print '=', x do_infix_binops() do_prefix_binops() --- NEW FILE: test_compare.py --- import sys from test_support import * class Empty: def __repr__(self): return '' class Coerce: def __init__(self, arg): self.arg = arg def __repr__(self): return '' % self.arg def __coerce__(self, other): if isinstance(other, Coerce): return self.arg, other.arg else: return (self.arg, other) class Cmp: def __init__(self,arg): self.arg = arg def __repr__(self): return '' % self.arg def __cmp__(self, other): return cmp(self.arg, other) class RCmp: def __init__(self,arg): self.arg = arg def __repr__(self): return '' % self.arg def __rcmp__(self, other): return cmp(other, self.arg) candidates = [2, 2.2, 2L, 2+4j, [1], (2,), None, Empty(), Coerce(3), Cmp(4), RCmp(5)] def test(): for a in candidates: for b in candidates: print "cmp(%s, %s)" % (a, b), try: x = cmp(a, b) except: print '... %s' % sys.exc_info(0) else: print '=', x test() From python-dev@python.org Tue Jan 2 17:07:51 2001 From: python-dev@python.org (Skip Montanaro) Date: Tue, 02 Jan 2001 09:07:51 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.config.in,1.4,1.4.2.1 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21599 Modified Files: Tag: release20-maint Setup.config.in Log Message: change default linkage of bsddb to shared - closes bug #126564 Index: Setup.config.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.config.in,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -C2 -r1.4 -r1.4.2.1 *** Setup.config.in 2000/09/08 02:17:15 1.4 --- Setup.config.in 2001/01/02 17:07:49 1.4.2.1 *************** *** 13,17 **** # the following line in that case: ! #*shared* # bsddb module enabled by --with-libdb or presence of db.h --- 13,17 ---- # the following line in that case: ! *shared* # bsddb module enabled by --with-libdb or presence of db.h From python-dev@python.org Tue Jan 2 17:09:50 2001 From: python-dev@python.org (Skip Montanaro) Date: Tue, 02 Jan 2001 09:09:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.config.in,1.4.2.1,1.4.2.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv21781 Modified Files: Tag: release20-maint Setup.config.in Log Message: forgot to update the comment to reflect the change in default linkage Index: Setup.config.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.config.in,v retrieving revision 1.4.2.1 retrieving revision 1.4.2.2 diff -C2 -r1.4.2.1 -r1.4.2.2 *** Setup.config.in 2001/01/02 17:07:49 1.4.2.1 --- Setup.config.in 2001/01/02 17:09:48 1.4.2.2 *************** *** 10,15 **** @USE_GC_MODULE@gc gcmodule.c ! # You may want this to be built as a dynamically loaded module; uncomment ! # the following line in that case: *shared* --- 10,14 ---- @USE_GC_MODULE@gc gcmodule.c ! # To build this static comment out the *shared* line below *shared* From python-dev@python.org Tue Jan 2 18:28:55 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 02 Jan 2001 10:28:55 -0800 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle AutoExpand.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv29108 Modified Files: AutoExpand.py Log Message: Add Alt-slash to Unix keydefs (I somehow need it on RH 6.2). Get rid of assignment to unused self.text.wordlist. Index: AutoExpand.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/AutoExpand.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** AutoExpand.py 1999/01/04 16:32:21 1.3 --- AutoExpand.py 2001/01/02 18:28:52 1.4 *************** *** 13,17 **** unix_keydefs = { ! '<>': [''], } --- 13,17 ---- unix_keydefs = { ! '<>': ['', ''], } *************** *** 26,30 **** def __init__(self, editwin): self.text = editwin.text - self.text.wordlist = None # XXX what is this? self.state = None --- 26,29 ---- From python-dev@python.org Tue Jan 2 20:56:44 2001 From: python-dev@python.org (A.M. Kuchling) Date: Tue, 02 Jan 2001 12:56:44 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_minidom.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12361 Modified Files: test_minidom.py Log Message: Add forgotten import Index: test_minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_minidom.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** test_minidom.py 2000/12/31 04:03:27 1.18 --- test_minidom.py 2001/01/02 20:56:42 1.19 *************** *** 2,5 **** --- 2,6 ---- from xml.dom.minidom import parse, Node, Document, parseString + from xml.dom import HierarchyRequestErr import xml.parsers.expat From python-dev@python.org Tue Jan 2 21:22:05 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 02 Jan 2001 13:22:05 -0800 Subject: [Python-checkins] CVS: python/dist/src/Tools/idle ObjectBrowser.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/idle In directory usw-pr-cvs1:/tmp/cvs-serv15575 Modified Files: ObjectBrowser.py Log Message: Make the test program work outside IDLE. Index: ObjectBrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/idle/ObjectBrowser.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** ObjectBrowser.py 1999/06/07 15:38:39 1.2 --- ObjectBrowser.py 2001/01/02 21:22:03 1.3 *************** *** 135,143 **** # Test script ! def test(): import sys ! from Tkinter import Toplevel ! import PyShell ! root = Toplevel(PyShell.root) root.configure(bd=0, bg="yellow") root.focus_set() --- 135,142 ---- # Test script ! def _test(): import sys ! from Tkinter import Tk ! root = Tk() root.configure(bd=0, bg="yellow") root.focus_set() *************** *** 146,151 **** item = make_objecttreeitem("sys", sys) node = TreeNode(sc.canvas, None, item) ! node.expand() if __name__ == '__main__': ! test() --- 145,151 ---- item = make_objecttreeitem("sys", sys) node = TreeNode(sc.canvas, None, item) ! node.update() ! root.mainloop() if __name__ == '__main__': ! _test() From python-dev@python.org Tue Jan 2 22:08:50 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 02 Jan 2001 14:08:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.50,1.51 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv21539/perl Modified Files: l2hinit.perl Log Message: Do not cache tags for navigation icons as agressively; this fixes bug #127151. Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -r1.50 -r1.51 *** l2hinit.perl 2000/10/25 16:18:10 1.50 --- l2hinit.perl 2001/01/02 22:08:48 1.51 *************** *** 108,139 **** } ! sub make_my_icon { ! my($name, $text) = @_; my $iconserver = ($ICONSERVER eq '.') ? '' : "$ICONSERVER/"; ! return "\"$text\""; } - $BLANK_ICON = make_my_icon('blank', ''); - - @my_icons = (); - $my_icons{'next_page_inactive'} = $BLANK_ICON; - $my_icons{'previous_page_inactive'} = $BLANK_ICON; - $my_icons{'up_page_inactive'} = $BLANK_ICON; - $x = make_my_icon('next', 'Next Page'); - $my_icons{'next_page'} = $x; - $my_icons{'next'} = $x; - $x = make_my_icon('previous', 'Previous Page'); - $my_icons{'previous_page'} = $x; - $my_icons{'previous'} = $x; - $my_icons{'up'} = make_my_icon('up', 'Up One Level'); - $my_icons{'contents'} = make_my_icon('contents', 'Contents'); - $my_icons{'index'} = make_my_icon('index', 'Index'); - $my_icons{'modules'} = make_my_icon('modules', 'Module Index'); - - sub use_my_icon { my $s = @_[0]; ! $s =~ s/\/$my_icons{$1}/; return $s; } --- 108,138 ---- } ! @my_icon_tags = (); ! $my_icon_tags{'next'} = 'Next Page'; ! $my_icon_tags{'next_page'} = 'Next Page'; ! $my_icon_tags{'previous'} = 'Previous Page'; ! $my_icon_tags{'previous_page'} = 'Previous Page'; ! $my_icon_tags{'up'} = 'Up One Level'; ! $my_icon_tags{'contents'} = 'Contents'; ! $my_icon_tags{'index'} = 'Index'; ! $my_icon_tags{'modules'} = 'Module Index'; ! ! sub get_my_icon { ! my $name = @_[0]; ! my $text = $my_icon_tags{$name}; ! if ($text eq '') { ! $name = 'blank'; ! } my $iconserver = ($ICONSERVER eq '.') ? '' : "$ICONSERVER/"; ! return "\"$text\""; } sub use_my_icon { my $s = @_[0]; ! if ($s =~ /\/) { ! my $r = get_my_icon($1); ! $s =~ s/\/$r/; ! } return $s; } *************** *** 141,144 **** --- 140,144 ---- sub make_nav_panel { my $s; + my $BLANK_ICON = get_my_icon('blank'); $NEXT = $NEXT_TITLE ? use_my_icon("$NEXT") : $BLANK_ICON; $UP = $UP_TITLE ? use_my_icon("$UP") : $BLANK_ICON; *************** *** 209,213 **** my($dummy, $file, $title) = split($delim, $section_info{join(' ',@link)}); ! $icon =~ s/\/$my_icons{$1}/; if ($title && ($file ne $current_file)) { $title = purify($title); --- 209,216 ---- my($dummy, $file, $title) = split($delim, $section_info{join(' ',@link)}); ! if ($icon =~ /\/) { ! my $r = get_my_icon($1); ! $icon =~ s/\/$r/; ! } if ($title && ($file ne $current_file)) { $title = purify($title); *************** *** 215,228 **** return (make_href($file, $icon), make_href($file, "$title")) } ! elsif ($icon eq $my_icons{"up"} && $EXTERNAL_UP_LINK) { return (make_href($EXTERNAL_UP_LINK, $icon), make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE")) } ! elsif ($icon eq $my_icons{"previous"} && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) { return (make_href($EXTERNAL_PREV_LINK, $icon), make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE")) } ! elsif ($icon eq $my_icons{"next"} && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) { return (make_href($EXTERNAL_DOWN_LINK, $icon), --- 218,231 ---- return (make_href($file, $icon), make_href($file, "$title")) } ! elsif ($icon eq get_my_icon('up') && $EXTERNAL_UP_LINK) { return (make_href($EXTERNAL_UP_LINK, $icon), make_href($EXTERNAL_UP_LINK, "$EXTERNAL_UP_TITLE")) } ! elsif ($icon eq get_my_icon('previous') && $EXTERNAL_PREV_LINK && $EXTERNAL_PREV_TITLE) { return (make_href($EXTERNAL_PREV_LINK, $icon), make_href($EXTERNAL_PREV_LINK, "$EXTERNAL_PREV_TITLE")) } ! elsif ($icon eq get_my_icon('next') && $EXTERNAL_DOWN_LINK && $EXTERNAL_DOWN_TITLE) { return (make_href($EXTERNAL_DOWN_LINK, $icon), *************** *** 234,238 **** sub add_special_link { my($icon, $file, $current_file) = @_; ! $icon =~ s/\/$my_icons{$1}/; return (($file && ($file ne $current_file)) ? make_href($file, $icon) --- 237,244 ---- sub add_special_link { my($icon, $file, $current_file) = @_; ! if ($icon =~ /\/) { ! my $r = get_my_icon($1); ! $icon =~ s/\/$r/; ! } return (($file && ($file ne $current_file)) ? make_href($file, $icon) *************** *** 321,326 **** close(MODIDXFILE); if (!$allthesame) { ! $prefix = < Some module names are followed by an annotation indicating what --- 327,331 ---- close(MODIDXFILE); if (!$allthesame) { ! $prefix .= < Some module names are followed by an annotation indicating what *************** *** 463,471 **** # Add a button to the navigation areas: $CUSTOM_BUTTONS .= ('' ! . $my_icons{'modules'} . ''); } else { ! $CUSTOM_BUTTONS .= $BLANK_ICON; $global{'max_id'} = $id; # not sure why.... s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o; --- 468,476 ---- # Add a button to the navigation areas: $CUSTOM_BUTTONS .= ('' ! . get_my_icon('modules') . ''); } else { ! $CUSTOM_BUTTONS .= get_my_icon('blank'); $global{'max_id'} = $id; # not sure why.... s/([\\]begin\s*$O\d+$C\s*theindex)/\\textohtmlindex $1/o; From python-dev@python.org Wed Jan 3 01:52:13 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 17:52:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_coercion,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv11715/Lib/test/output Modified Files: test_coercion Log Message: Use numbers that can be accurately represented on binary machines. I hope this works on all platforms. Index: test_coercion =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_coercion,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_coercion 2001/01/02 16:30:31 1.1 --- test_coercion 2001/01/03 01:52:11 1.2 *************** *** 12,27 **** 2 % 2 = 0 2 %= 2 => 0 ! 2 + 2.2 = 4.2 ! 2 += 2.2 => 4.2 ! 2 - 2.2 = -0.2 ! 2 -= 2.2 => -0.2 ! 2 * 2.2 = 4.4 ! 2 *= 2.2 => 4.4 ! 2 / 2.2 = 0.909090909091 ! 2 /= 2.2 => 0.909090909091 [...1404 lines suppressed...] divmod(None, ) ... exceptions.TypeError ! divmod(None, ) ... exceptions.TypeError divmod(, 2) ... exceptions.TypeError ! divmod(, 4.0) ... exceptions.TypeError divmod(, 2) ... exceptions.TypeError ! divmod(, (2+0j)) ... exceptions.TypeError divmod(, [1]) ... exceptions.TypeError divmod(, (2,)) ... exceptions.TypeError divmod(, None) ... exceptions.TypeError divmod(, ) ... exceptions.TypeError ! divmod(, ) ... exceptions.TypeError ! divmod(, 2) = (1, 0) ! divmod(, 4.0) = (0.0, 2.0) ! divmod(, 2) = (1L, 0L) ! divmod(, (2+0j)) = ((1+0j), 0j) ! divmod(, [1]) ... exceptions.TypeError ! divmod(, (2,)) ... exceptions.TypeError ! divmod(, None) ... exceptions.TypeError ! divmod(, ) ... exceptions.TypeError ! divmod(, ) = (1, 0) From python-dev@python.org Wed Jan 3 01:52:13 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 17:52:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_coercion.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv11715/Lib/test Modified Files: test_coercion.py Log Message: Use numbers that can be accurately represented on binary machines. I hope this works on all platforms. Index: test_coercion.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_coercion.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_coercion.py 2001/01/02 16:30:31 1.1 --- test_coercion.py 2001/01/03 01:52:10 1.2 *************** *** 66,71 **** ! candidates = [ 2, 2.2, 2L, 2+4j, [1], (2,), None, ! MethodNumber(1), CoerceNumber(8)] infix_binops = [ '+', '-', '*', '/', '**', '%' ] --- 66,71 ---- ! candidates = [ 2, 4.0, 2L, 2+0j, [1], (2,), None, ! MethodNumber(1), CoerceNumber(2)] infix_binops = [ '+', '-', '*', '/', '**', '%' ] From python-dev@python.org Wed Jan 3 02:13:28 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 18:13:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_compare.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13758/Lib/test Modified Files: test_compare.py Log Message: Use == rather than cmp(). The return value of cmp() is not well defined when comparing different types. Index: test_compare.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compare.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_compare.py 2001/01/02 16:30:31 1.1 --- test_compare.py 2001/01/03 02:13:26 1.2 *************** *** 18,22 **** return self.arg, other.arg else: ! return (self.arg, other) class Cmp: --- 18,22 ---- return self.arg, other.arg else: ! return self.arg, other class Cmp: *************** *** 41,57 **** ! candidates = [2, 2.2, 2L, 2+4j, [1], (2,), None, Empty(), Coerce(3), ! Cmp(4), RCmp(5)] def test(): for a in candidates: for b in candidates: - print "cmp(%s, %s)" % (a, b), try: ! x = cmp(a, b) except: ! print '... %s' % sys.exc_info(0) else: ! print '=', x test() --- 41,59 ---- ! candidates = [2, 2.0, 2L, 2+0j, [1], (3,), None, Empty(), Coerce(2), ! Cmp(2.0), RCmp(2L)] def test(): for a in candidates: for b in candidates: try: ! x = a == b except: ! print 'cmp(%s, %s) => %s' % (a, b, sys.exc_info()[0]) else: ! if x: ! print "%s == %s" % (a, b) ! else: ! print "%s != %s" % (a, b) test() From python-dev@python.org Wed Jan 3 02:13:28 2001 From: python-dev@python.org (Neil Schemenauer) Date: Tue, 02 Jan 2001 18:13:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_compare,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv13758/Lib/test/output Modified Files: test_compare Log Message: Use == rather than cmp(). The return value of cmp() is not well defined when comparing different types. Index: test_compare =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_compare,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_compare 2001/01/02 16:30:31 1.1 --- test_compare 2001/01/03 02:13:26 1.2 *************** *** 1,122 **** test_compare ! cmp(2, 2) = 0 ! cmp(2, 2.2) = -1 ! cmp(2, 2) = 0 ! cmp(2, (2+4j)) = -1 ! cmp(2, [1]) = -108 ! cmp(2, (2,)) = -116 ! cmp(2, None) = -78 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp(2.2, 2) = 1 ! cmp(2.2, 2.2) = 0 ! cmp(2.2, 2) = 1 ! cmp(2.2, (2+4j)) = 1 ! cmp(2.2, [1]) = -108 ! cmp(2.2, (2,)) = -116 ! cmp(2.2, None) = -78 ! cmp(2.2, ) = -1 ! cmp(2.2, ) = -1 ! cmp(2.2, ) = -1 ! cmp(2.2, ) = -1 ! cmp(2, 2) = 0 ! cmp(2, 2.2) = -1 ! cmp(2, 2) = 0 ! cmp(2, (2+4j)) = -1 ! cmp(2, [1]) = -108 ! cmp(2, (2,)) = -116 ! cmp(2, None) = -78 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp(2, ) = -1 ! cmp((2+4j), 2) = 1 ! cmp((2+4j), 2.2) = -1 ! cmp((2+4j), 2) = 1 ! cmp((2+4j), (2+4j)) = 0 ! cmp((2+4j), [1]) = -108 ! cmp((2+4j), (2,)) = -116 ! cmp((2+4j), None) = -78 ! cmp((2+4j), ) = -1 ! cmp((2+4j), ) = -1 ! cmp((2+4j), ) = -1 ! cmp((2+4j), ) = -1 ! cmp([1], 2) = 108 ! cmp([1], 2.2) = 108 ! cmp([1], 2) = 108 ! cmp([1], (2+4j)) = 108 ! cmp([1], [1]) = 0 ! cmp([1], (2,)) = -8 ! cmp([1], None) = 30 ! cmp([1], ) = -1 ! cmp([1], ) = 1 ! cmp([1], ) = 1 ! cmp([1], ) = -1 ! cmp((2,), 2) = 116 ! cmp((2,), 2.2) = 116 ! cmp((2,), 2) = 116 ! cmp((2,), (2+4j)) = 116 ! cmp((2,), [1]) = 8 ! cmp((2,), (2,)) = 0 ! cmp((2,), None) = 38 ! cmp((2,), ) = -1 ! cmp((2,), ) = 1 ! cmp((2,), ) = 1 ! cmp((2,), ) = -1 ! cmp(None, 2) = 78 ! cmp(None, 2.2) = 78 ! cmp(None, 2) = 78 ! cmp(None, (2+4j)) = 78 ! cmp(None, [1]) = -30 ! cmp(None, (2,)) = -38 ! cmp(None, None) = 0 ! cmp(None, ) = -1 ! cmp(None, ) = 1 ! cmp(None, ) = 1 ! cmp(None, ) = -1 ! cmp(, 2) = 1 ! cmp(, 2.2) = 1 ! cmp(, 2) = 1 ! cmp(, (2+4j)) = 1 ! cmp(, [1]) = 1 ! cmp(, (2,)) = 1 ! cmp(, None) = 1 ! cmp(, ) = 0 ! cmp(, ) = -1 ! cmp(, ) = -1 ! cmp(, ) = 1 ! cmp(, 2) = 1 ! cmp(, 2.2) = 1 ! cmp(, 2) = 1 ! cmp(, (2+4j)) = 1 ! cmp(, [1]) = -1 ! cmp(, (2,)) = -1 ! cmp(, None) = -1 ! cmp(, ) = 1 ! cmp(, ) = 0 ! cmp(, ) = -1 ! cmp(, ) = -1 ! cmp(, 2) = 1 ! cmp(, 2.2) = 1 ! cmp(, 2) = 1 ! cmp(, (2+4j)) = 1 ! cmp(, [1]) = -1 ! cmp(, (2,)) = -1 ! cmp(, None) = -1 ! cmp(, ) = -1 ! cmp(, ) = 1 ! cmp(, ) = 0 ! cmp(, ) = -1 ! cmp(, 2) = 1 ! cmp(, 2.2) = 1 ! cmp(, 2) = 1 ! cmp(, (2+4j)) = 1 ! cmp(, [1]) = 1 ! cmp(, (2,)) = 1 ! cmp(, None) = 1 ! cmp(, ) = 1 ! cmp(, ) = 1 ! cmp(, ) = 1 ! cmp(, ) = 0 --- 1,122 ---- test_compare ! 2 == 2 ! 2 == 2.0 ! 2 == 2 ! 2 == (2+0j) ! 2 != [1] ! 2 != (3,) ! 2 != None ! 2 != ! 2 == ! 2 == ! 2 != ! 2.0 == 2 ! 2.0 == 2.0 ! 2.0 == 2 ! 2.0 == (2+0j) ! 2.0 != [1] ! 2.0 != (3,) ! 2.0 != None ! 2.0 != ! 2.0 == ! 2.0 == ! 2.0 != ! 2 == 2 ! 2 == 2.0 ! 2 == 2 ! 2 == (2+0j) ! 2 != [1] ! 2 != (3,) ! 2 != None ! 2 != ! 2 == ! 2 == ! 2 != ! (2+0j) == 2 ! (2+0j) == 2.0 ! (2+0j) == 2 ! (2+0j) == (2+0j) ! (2+0j) != [1] ! (2+0j) != (3,) ! (2+0j) != None ! (2+0j) != ! (2+0j) == ! (2+0j) == ! (2+0j) != ! [1] != 2 ! [1] != 2.0 ! [1] != 2 ! [1] != (2+0j) ! [1] == [1] ! [1] != (3,) ! [1] != None ! [1] != ! [1] != ! [1] != ! [1] != ! (3,) != 2 ! (3,) != 2.0 ! (3,) != 2 ! (3,) != (2+0j) ! (3,) != [1] ! (3,) == (3,) ! (3,) != None ! (3,) != ! (3,) != ! (3,) != ! (3,) != ! None != 2 ! None != 2.0 ! None != 2 ! None != (2+0j) ! None != [1] ! None != (3,) ! None == None ! None != ! None != ! None != ! None != ! != 2 ! != 2.0 ! != 2 ! != (2+0j) ! != [1] ! != (3,) ! != None ! == ! != ! != ! != ! == 2 ! == 2.0 ! == 2 ! == (2+0j) ! != [1] ! != (3,) ! != None ! != ! == ! != ! == ! == 2 ! == 2.0 ! == 2 ! == (2+0j) ! != [1] ! != (3,) ! != None ! != ! == ! == ! != ! != 2 ! != 2.0 ! != 2 ! != (2+0j) ! != [1] ! != (3,) ! != None ! != ! != ! != ! == From python-dev@python.org Wed Jan 3 15:36:29 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 07:36:29 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules pyexpat.c,2.30,2.31 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv9929/Modules Modified Files: pyexpat.c Log Message: Mark the "encoding" parameter to ExternalEntityParserCreate() as optional in the docstring. Index: pyexpat.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/pyexpat.c,v retrieving revision 2.30 retrieving revision 2.31 diff -C2 -r2.30 -r2.31 *** pyexpat.c 2000/12/21 17:25:07 2.30 --- pyexpat.c 2001/01/03 15:36:25 2.31 *************** *** 536,540 **** static char xmlparse_ExternalEntityParserCreate__doc__[] = ! "ExternalEntityParserCreate(context, encoding)\n\ Create a parser for parsing an external entity based on the\n\ information passed to the ExternalEntityRefHandler."; --- 536,540 ---- static char xmlparse_ExternalEntityParserCreate__doc__[] = ! "ExternalEntityParserCreate(context[, encoding])\n\ Create a parser for parsing an external entity based on the\n\ information passed to the ExternalEntityRefHandler."; From python-dev@python.org Wed Jan 3 21:29:15 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 13:29:15 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib codecs.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26608/Lib Modified Files: codecs.py Log Message: This patch changes the default behaviour of the builtin charmap codec to not apply Latin-1 mappings for keys which are not found in the mapping dictionaries, but instead treat them as undefined mappings. The patch was originally written by Martin v. Loewis with some additional (cosmetic) changes and an updated test script by Marc-Andre Lemburg. The standard codecs were recreated from the most current files available at the Unicode.org site using the Tools/scripts/gencodec.py tool. This patch closes the bugs #116285 and #119960. Index: codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/codecs.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** codecs.py 2000/12/10 15:12:14 1.13 --- codecs.py 2001/01/03 21:29:13 1.14 *************** *** 540,543 **** --- 540,558 ---- return sr + ### Helpers for charmap-based codecs + + def make_identity_dict(rng): + + """ make_identity_dict(rng) -> dict + + Return a dictionary where elements of the rng sequence are + mapped to themselves. + + """ + res = {} + for i in rng: + res[i]=i + return res + ### Tests From python-dev@python.org Wed Jan 3 21:29:16 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 13:29:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_unicode.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv26608/Lib/test Modified Files: test_unicode.py Log Message: This patch changes the default behaviour of the builtin charmap codec to not apply Latin-1 mappings for keys which are not found in the mapping dictionaries, but instead treat them as undefined mappings. The patch was originally written by Martin v. Loewis with some additional (cosmetic) changes and an updated test script by Marc-Andre Lemburg. The standard codecs were recreated from the most current files available at the Unicode.org site using the Tools/scripts/gencodec.py tool. This patch closes the bugs #116285 and #119960. Index: test_unicode.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_unicode.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** test_unicode.py 2000/12/19 02:22:31 1.24 --- test_unicode.py 2001/01/03 21:29:14 1.25 *************** *** 495,500 **** 'cp863', 'cp865', 'cp866', 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', ! 'iso8859_2', 'iso8859_3', 'iso8859_4', 'iso8859_5', 'iso8859_6', ! 'iso8859_7', 'iso8859_9', 'koi8_r', 'latin_1', 'mac_cyrillic', 'mac_latin2', --- 495,500 ---- 'cp863', 'cp865', 'cp866', 'iso8859_10', 'iso8859_13', 'iso8859_14', 'iso8859_15', ! 'iso8859_2', 'iso8859_4', 'iso8859_5', ! 'iso8859_9', 'koi8_r', 'latin_1', 'mac_cyrillic', 'mac_latin2', *************** *** 503,506 **** --- 503,507 ---- #'cp1256', 'cp1257', 'cp1258', #'cp424', 'cp856', 'cp857', 'cp864', 'cp869', 'cp874', + #'iso8859_3', 'iso8859_6', 'iso8859_7', #'mac_greek', 'mac_iceland','mac_roman', 'mac_turkish', From python-dev@python.org Wed Jan 3 21:29:16 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 13:29:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.70,2.71 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv26608/Objects Modified Files: unicodeobject.c Log Message: This patch changes the default behaviour of the builtin charmap codec to not apply Latin-1 mappings for keys which are not found in the mapping dictionaries, but instead treat them as undefined mappings. The patch was originally written by Martin v. Loewis with some additional (cosmetic) changes and an updated test script by Marc-Andre Lemburg. The standard codecs were recreated from the most current files available at the Unicode.org site using the Tools/scripts/gencodec.py tool. This patch closes the bugs #116285 and #119960. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.70 retrieving revision 2.71 diff -C2 -r2.70 -r2.71 *** unicodeobject.c 2000/12/19 22:49:06 2.70 --- unicodeobject.c 2001/01/03 21:29:14 2.71 *************** *** 1971,1979 **** if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { ! /* No mapping found: default to Latin-1 mapping */ PyErr_Clear(); ! *p++ = (Py_UNICODE)ch; ! continue; ! } goto onError; } --- 1971,1979 ---- if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { ! /* No mapping found means: mapping is undefined. */ PyErr_Clear(); ! x = Py_None; ! Py_INCREF(x); ! } else goto onError; } *************** *** 2087,2100 **** if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { ! /* No mapping found: default to Latin-1 mapping if possible */ PyErr_Clear(); ! if (ch < 256) { ! *s++ = (char)ch; ! continue; ! } ! else if (!charmap_encoding_error(&p, &s, errors, ! "missing character mapping")) ! continue; ! } goto onError; } --- 2087,2095 ---- if (x == NULL) { if (PyErr_ExceptionMatches(PyExc_LookupError)) { ! /* No mapping found means: mapping is undefined. */ PyErr_Clear(); ! x = Py_None; ! Py_INCREF(x); ! } else goto onError; } From python-dev@python.org Wed Jan 3 21:29:16 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 13:29:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Tools/scripts gencodec.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/scripts In directory usw-pr-cvs1:/tmp/cvs-serv26608/Tools/scripts Modified Files: gencodec.py Log Message: This patch changes the default behaviour of the builtin charmap codec to not apply Latin-1 mappings for keys which are not found in the mapping dictionaries, but instead treat them as undefined mappings. The patch was originally written by Martin v. Loewis with some additional (cosmetic) changes and an updated test script by Marc-Andre Lemburg. The standard codecs were recreated from the most current files available at the Unicode.org site using the Tools/scripts/gencodec.py tool. This patch closes the bugs #116285 and #119960. Index: gencodec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/scripts/gencodec.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** gencodec.py 2000/03/17 16:56:23 1.3 --- gencodec.py 2001/01/03 21:29:14 1.4 *************** *** 2,8 **** This script parses Unicode mapping files as available from the Unicode ! site (ftp.unicode.org) and creates Python codec modules from them. The ! codecs use the standard character mapping codec to actually apply the ! mapping. Synopsis: gencodec.py dir codec_prefix --- 2,8 ---- This script parses Unicode mapping files as available from the Unicode ! site (ftp://ftp.unicode.org/Public/MAPPINGS/) and creates Python codec ! modules from them. The codecs use the standard character mapping codec ! to actually apply the mapping. Synopsis: gencodec.py dir codec_prefix *************** *** 19,22 **** --- 19,23 ---- (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright Guido van Rossum, 2000. """#" *************** *** 71,74 **** --- 72,79 ---- f.close() enc2uni = {} + identity = [] + unmapped = range(256) + for i in range(256): + unmapped[i] = i for line in lines: line = strip(line) *************** *** 86,91 **** else: comment = comment[1:] ! if enc != uni: enc2uni[enc] = (uni,comment) return enc2uni --- 91,110 ---- else: comment = comment[1:] ! if enc < 256: ! unmapped.remove(enc) ! if enc == uni: ! identity.append(enc) ! else: ! enc2uni[enc] = (uni,comment) ! else: enc2uni[enc] = (uni,comment) + # If there are more identity-mapped entries than unmapped entries, + # it pays to generate an identity dictionary first, add add explicit + # mappings to None for the rest + if len(identity)>=len(unmapped): + for enc in unmapped: + enc2uni[enc] = (None, "") + enc2uni['IDENTITY'] = 256 + return enc2uni *************** *** 144,152 **** l = [ '''\ ! """ Python Character Mapping Codec generated from '%s'. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 163,172 ---- l = [ '''\ ! """ Python Character Mapping Codec generated from '%s' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 179,191 **** ### Decoding Map - - decoding_map = { ''' % name, ] mappings = map.items() mappings.sort() append = l.append i = 0 - splits = 0 for e,value in mappings: try: --- 199,219 ---- ### Decoding Map ''' % name, ] + + if map.has_key("IDENTITY"): + l.append("decoding_map = codecs.make_identity_dict(range(%d))" + % map["IDENTITY"]) + l.append("decoding_map.update({") + splits = 1 + del map["IDENTITY"] + else: + l.append("decoding_map = {") + splits = 0 + mappings = map.items() mappings.sort() append = l.append i = 0 for e,value in mappings: try: *************** *** 199,203 **** else: append('\t%s: %s,' % (key,unicoderepr(u))) ! i = i + 1 if i == 4096: # Split the definition into parts to that the Python --- 227,231 ---- else: append('\t%s: %s,' % (key,unicoderepr(u))) ! i += 1 if i == 4096: # Split the definition into parts to that the Python *************** *** 207,211 **** else: append('})') ! append('map.update({') i = 0 splits = splits + 1 --- 235,239 ---- else: append('})') ! append('decoding_map.update({') i = 0 splits = splits + 1 *************** *** 266,270 **** mapnames = os.listdir(dir) for mapname in mapnames: ! if mapname[-len('.mapping'):] != '.mapping': continue codefile = mapname[:-len('.mapping')] + '.py' --- 294,298 ---- mapnames = os.listdir(dir) for mapname in mapnames: ! if not mapname.endswith('.mapping'): continue codefile = mapname[:-len('.mapping')] + '.py' From python-dev@python.org Wed Jan 3 21:29:16 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 13:29:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/encodings cp037.py,1.1,1.2 cp1006.py,1.1,1.2 cp1026.py,1.1,1.2 cp1250.py,1.1,1.2 cp1251.py,1.1,1.2 cp1252.py,1.1,1.2 cp1253.py,1.1,1.2 cp1254.py,1.1,1.2 cp1255.py,1.1,1.2 cp1256.py,1.1,1.2 cp1257.py,1.1,1.2 cp1258.py,1.1,1.2 cp424.py,1.1,1.2 cp437.py,1.1,1.2 cp500.py,1.1,1.2 cp737.py,1.1,1.2 cp775.py,1.1,1.2 cp850.py,1.1,1.2 cp852.py,1.1,1.2 cp855.py,1.1,1.2 cp856.py,1.2,1.3 cp857.py,1.1,1.2 cp860.py,1.1,1.2 cp861.py,1.1,1.2 cp862.py,1.1,1.2 cp863.py,1.1,1.2 cp864.py,1.1,1.2 cp865.py,1.1,1.2 cp866.py,1.1,1.2 cp869.py,1.1,1.2 cp874.py,1.1,1.2 cp875.py,1.1,1.2 iso8859_1.py,1.1,1.2 iso8859_10.py,1.1,1.2 iso8859_13.py,1.1,1.2 iso8859_14.py,1.1,1.2 iso8859_15.py,1.1,1.2 iso8859_2.py,1.1,1.2 iso8859_3.py,1.1,1.2 iso8859_4.py,1.1,1.2 iso8859_5.py,1.1,1.2 iso8859_6.py,1.1,1.2 iso8859_7.py,1.1,1.2 iso8859_8.py,1.1,1.2 iso8859_9.py,1.1,1.2 koi8_r.py,1.1,1.2 mac_cyrillic.py,1.1,1.2 mac_greek.py,1.1,1.2 mac_iceland.py,1.1,1.2 mac_latin2.py,1.1,1.2 mac_roman.py,1.1,1.2 mac_turkish.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/encodings In directory usw-pr-cvs1:/tmp/cvs-serv26608/Lib/encodings Modified Files: cp037.py cp1006.py cp1026.py cp1250.py cp1251.py cp1252.py cp1253.py cp1254.py cp1255.py cp1256.py cp1257.py cp1258.py cp424.py cp437.py cp500.py cp737.py cp775.py cp850.py cp852.py cp855.py cp856.py cp857.py cp860.py cp861.py cp862.py cp863.py cp864.py cp865.py cp866.py cp869.py cp874.py cp875.py iso8859_1.py iso8859_10.py iso8859_13.py iso8859_14.py iso8859_15.py iso8859_2.py iso8859_3.py iso8859_4.py iso8859_5.py iso8859_6.py iso8859_7.py iso8859_8.py iso8859_9.py koi8_r.py mac_cyrillic.py mac_greek.py mac_iceland.py mac_latin2.py mac_roman.py mac_turkish.py Log Message: This patch changes the default behaviour of the builtin charmap codec to not apply Latin-1 mappings for keys which are not found in the mapping dictionaries, but instead treat them as undefined mappings. The patch was originally written by Martin v. Loewis with some additional (cosmetic) changes and an updated test script by Marc-Andre Lemburg. The standard codecs were recreated from the most current files available at the Unicode.org site using the Tools/scripts/gencodec.py tool. This patch closes the bugs #116285 and #119960. Index: cp037.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp037.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp037.py 2000/03/10 23:17:18 1.1 --- cp037.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP037.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP037.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION *************** *** 274,278 **** 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! } ### Encoding Map --- 274,278 ---- 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! }) ### Encoding Map Index: cp1006.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1006.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1006.py 2000/03/10 23:17:18 1.1 --- cp1006.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1006.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1006.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x06f0, # EXTENDED ARABIC-INDIC DIGIT ZERO 0x00a2: 0x06f1, # EXTENDED ARABIC-INDIC DIGIT ONE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x06f0, # EXTENDED ARABIC-INDIC DIGIT ZERO 0x00a2: 0x06f1, # EXTENDED ARABIC-INDIC DIGIT ONE *************** *** 132,136 **** 0x00fe: 0xfe7c, # ARABIC SHADDA ISOLATED FORM 0x00ff: 0xfe7d, # ARABIC SHADDA MEDIAL FORM ! } ### Encoding Map --- 132,136 ---- 0x00fe: 0xfe7c, # ARABIC SHADDA ISOLATED FORM 0x00ff: 0xfe7d, # ARABIC SHADDA MEDIAL FORM ! }) ### Encoding Map Index: cp1026.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1026.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1026.py 2000/03/10 23:17:18 1.1 --- cp1026.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1026.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1026.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION *************** *** 274,278 **** 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! } ### Encoding Map --- 274,278 ---- 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! }) ### Encoding Map Index: cp1250.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1250.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1250.py 2000/03/10 23:17:19 1.1 --- cp1250.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1250.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1250.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 117,121 **** 0x00fe: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA 0x00ff: 0x02d9, # DOT ABOVE ! } ### Encoding Map --- 117,121 ---- 0x00fe: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA 0x00ff: 0x02d9, # DOT ABOVE ! }) ### Encoding Map Index: cp1251.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1251.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1251.py 2000/03/10 23:17:19 1.1 --- cp1251.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1251.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1251.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0402, # CYRILLIC CAPITAL LETTER DJE 0x0081: 0x0403, # CYRILLIC CAPITAL LETTER GJE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0402, # CYRILLIC CAPITAL LETTER DJE 0x0081: 0x0403, # CYRILLIC CAPITAL LETTER GJE *************** *** 151,155 **** 0x00fe: 0x044e, # CYRILLIC SMALL LETTER YU 0x00ff: 0x044f, # CYRILLIC SMALL LETTER YA ! } ### Encoding Map --- 151,155 ---- 0x00fe: 0x044e, # CYRILLIC SMALL LETTER YU 0x00ff: 0x044f, # CYRILLIC SMALL LETTER YA ! }) ### Encoding Map Index: cp1252.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1252.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1252.py 2000/03/10 23:17:19 1.1 --- cp1252.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1252.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1252.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 70,74 **** 0x009e: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x009f: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS ! } ### Encoding Map --- 70,74 ---- 0x009e: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x009f: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS ! }) ### Encoding Map Index: cp1253.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1253.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1253.py 2000/03/10 23:17:19 1.1 --- cp1253.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1253.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1253.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 145,149 **** 0x00fe: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS 0x00ff: None, # UNDEFINED ! } ### Encoding Map --- 145,149 ---- 0x00fe: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS 0x00ff: None, # UNDEFINED ! }) ### Encoding Map Index: cp1254.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1254.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1254.py 2000/03/10 23:17:19 1.1 --- cp1254.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1254.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1254.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 76,80 **** 0x00fd: 0x0131, # LATIN SMALL LETTER DOTLESS I 0x00fe: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA ! } ### Encoding Map --- 76,80 ---- 0x00fd: 0x0131, # LATIN SMALL LETTER DOTLESS I 0x00fe: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA ! }) ### Encoding Map Index: cp1255.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1255.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1255.py 2000/03/10 23:17:19 1.1 --- cp1255.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1255.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1255.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 137,141 **** 0x00fe: 0x200f, # RIGHT-TO-LEFT MARK 0x00ff: None, # UNDEFINED ! } ### Encoding Map --- 137,141 ---- 0x00fe: 0x200f, # RIGHT-TO-LEFT MARK 0x00ff: None, # UNDEFINED ! }) ### Encoding Map Index: cp1256.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1256.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1256.py 2000/03/10 23:17:19 1.1 --- cp1256.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1256.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1256.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: 0x067e, # ARABIC LETTER PEH --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: 0x067e, # ARABIC LETTER PEH *************** *** 123,127 **** 0x00fe: 0x200f, # RIGHT-TO-LEFT MARK 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE ! } ### Encoding Map --- 123,127 ---- 0x00fe: 0x200f, # RIGHT-TO-LEFT MARK 0x00ff: 0x06d2, # ARABIC LETTER YEH BARREE ! }) ### Encoding Map Index: cp1257.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1257.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1257.py 2000/03/10 23:17:19 1.1 --- cp1257.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1257.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1257.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 125,129 **** 0x00fe: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x00ff: 0x02d9, # DOT ABOVE ! } ### Encoding Map --- 125,129 ---- 0x00fe: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x00ff: 0x02d9, # DOT ABOVE ! }) ### Encoding Map Index: cp1258.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp1258.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp1258.py 2000/03/10 23:17:19 1.1 --- cp1258.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP1258.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP1258.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 84,88 **** 0x00fd: 0x01b0, # LATIN SMALL LETTER U WITH HORN 0x00fe: 0x20ab, # DONG SIGN ! } ### Encoding Map --- 84,88 ---- 0x00fd: 0x01b0, # LATIN SMALL LETTER U WITH HORN 0x00fe: 0x20ab, # DONG SIGN ! }) ### Encoding Map Index: cp424.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp424.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp424.py 2000/03/10 23:17:19 1.1 --- cp424.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP424.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP424.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0004: 0x009c, # SELECT 0x0005: 0x0009, # HORIZONTAL TABULATION --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0004: 0x009c, # SELECT 0x0005: 0x0009, # HORIZONTAL TABULATION *************** *** 274,278 **** 0x00fe: None, # UNDEFINED 0x00ff: 0x009f, # EIGHT ONES ! } ### Encoding Map --- 274,278 ---- 0x00fe: None, # UNDEFINED 0x00ff: 0x009f, # EIGHT ONES ! }) ### Encoding Map Index: cp437.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp437.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp437.py 2000/03/10 23:17:20 1.1 --- cp437.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP437.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP437.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp500.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp500.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp500.py 2000/03/10 23:17:20 1.1 --- cp500.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP500.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP500.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION *************** *** 274,278 **** 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! } ### Encoding Map --- 274,278 ---- 0x00fe: 0x00da, # LATIN CAPITAL LETTER U WITH ACUTE 0x00ff: 0x009f, # CONTROL ! }) ### Encoding Map Index: cp737.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp737.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp737.py 2000/03/10 23:17:20 1.1 --- cp737.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP737.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP737.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0391, # GREEK CAPITAL LETTER ALPHA 0x0081: 0x0392, # GREEK CAPITAL LETTER BETA --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0391, # GREEK CAPITAL LETTER ALPHA 0x0081: 0x0392, # GREEK CAPITAL LETTER BETA *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp775.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp775.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp775.py 2000/03/10 23:17:20 1.1 --- cp775.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP775.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP775.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0106, # LATIN CAPITAL LETTER C WITH ACUTE 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp850.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp850.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp850.py 2000/03/10 23:17:20 1.1 --- cp850.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP850.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP850.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp852.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp852.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp852.py 2000/03/10 23:17:20 1.1 --- cp852.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP852.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP852.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp855.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp855.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp855.py 2000/03/10 23:17:20 1.1 --- cp855.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP855.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP855.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0452, # CYRILLIC SMALL LETTER DJE 0x0081: 0x0402, # CYRILLIC CAPITAL LETTER DJE *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp856.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp856.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** cp856.py 2000/07/16 12:04:30 1.2 --- cp856.py 2001/01/03 21:29:13 1.3 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP856.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP856.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x05d0, # HEBREW LETTER ALEF 0x0081: 0x05d1, # HEBREW LETTER BET --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x05d0, # HEBREW LETTER ALEF 0x0081: 0x05d1, # HEBREW LETTER BET *************** *** 121,128 **** 0x00d1: None, # UNDEFINED 0x00d2: None, # UNDEFINED ! 0x00d3: None, # UNDEFINED 0x00d4: None, # UNDEFINED 0x00d5: None, # UNDEFINED ! 0x00d6: None, # UNDEFINED 0x00d7: None, # UNDEFINED 0x00d8: None, # UNDEFINED --- 121,128 ---- 0x00d1: None, # UNDEFINED 0x00d2: None, # UNDEFINED ! 0x00d3: None, # UNDEFINEDS 0x00d4: None, # UNDEFINED 0x00d5: None, # UNDEFINED ! 0x00d6: None, # UNDEFINEDE 0x00d7: None, # UNDEFINED 0x00d8: None, # UNDEFINED *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp857.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp857.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp857.py 2000/03/10 23:17:20 1.1 --- cp857.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP857.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP857.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 165,169 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 165,169 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp860.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp860.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp860.py 2000/03/10 23:17:21 1.1 --- cp860.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP860.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP860.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp861.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp861.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp861.py 2000/03/10 23:17:21 1.1 --- cp861.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP861.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP861.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp862.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp862.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp862.py 2000/03/10 23:17:21 1.1 --- cp862.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP862.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP862.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x05d0, # HEBREW LETTER ALEF 0x0081: 0x05d1, # HEBREW LETTER BET --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x05d0, # HEBREW LETTER ALEF 0x0081: 0x05d1, # HEBREW LETTER BET *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp863.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp863.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp863.py 2000/03/10 23:17:21 1.1 --- cp863.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP863.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP863.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp864.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp864.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp864.py 2000/03/10 23:17:21 1.1 --- cp864.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP864.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP864.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0025: 0x066a, # ARABIC PERCENT SIGN 0x0080: 0x00b0, # DEGREE SIGN --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0025: 0x066a, # ARABIC PERCENT SIGN 0x0080: 0x00b0, # DEGREE SIGN *************** *** 164,168 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: None, # UNDEFINED ! } ### Encoding Map --- 164,168 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: None, # UNDEFINED ! }) ### Encoding Map Index: cp865.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp865.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp865.py 2000/03/10 23:17:21 1.1 --- cp865.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP865.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP865.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c7, # LATIN CAPITAL LETTER C WITH CEDILLA 0x0081: 0x00fc, # LATIN SMALL LETTER U WITH DIAERESIS *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp866.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp866.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp866.py 2000/03/10 23:17:21 1.1 --- cp866.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP866.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP866.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp869.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp869.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp869.py 2000/03/10 23:17:21 1.1 --- cp869.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP869.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP869.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: None, # UNDEFINED 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: None, # UNDEFINED 0x0081: None, # UNDEFINED *************** *** 166,170 **** 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x25a0, # BLACK SQUARE 0x00ff: 0x00a0, # NO-BREAK SPACE ! }) ### Encoding Map Index: cp874.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp874.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp874.py 2000/03/10 23:17:21 1.1 --- cp874.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP874.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP874.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x20ac, # EURO SIGN 0x0081: None, # UNDEFINED *************** *** 165,169 **** 0x00fe: None, # UNDEFINED 0x00ff: None, # UNDEFINED ! } ### Encoding Map --- 165,169 ---- 0x00fe: None, # UNDEFINED 0x00ff: None, # UNDEFINED ! }) ### Encoding Map Index: cp875.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/cp875.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** cp875.py 2000/03/10 23:17:21 1.1 --- cp875.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CP875.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CP875.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0004: 0x009c, # CONTROL 0x0005: 0x0009, # HORIZONTAL TABULATION *************** *** 275,279 **** 0x00fe: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0x00ff: 0x009f, # CONTROL ! } ### Encoding Map --- 275,279 ---- 0x00fe: 0x00bb, # RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK 0x00ff: 0x009f, # CONTROL ! }) ### Encoding Map Index: iso8859_1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_1.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_1.py 2000/03/10 23:17:22 1.1 --- iso8859_1.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-1.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-1.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 23,30 **** class StreamWriter(Codec,codecs.StreamWriter): ! ! def __init__(self,stream,errors='strict'): ! ! codecs.StreamWriter.__init__(self,strict,errors) class StreamReader(Codec,codecs.StreamReader): --- 23,27 ---- class StreamWriter(Codec,codecs.StreamWriter): ! pass class StreamReader(Codec,codecs.StreamReader): *************** *** 38,45 **** ### Decoding Map - - decoding_map = { ! } ### Encoding Map --- 35,42 ---- ### Decoding Map ! decoding_map = codecs.make_identity_dict(range(256)) ! decoding_map.update({ ! }) ### Encoding Map Index: iso8859_10.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_10.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_10.py 2000/03/10 23:17:22 1.1 --- iso8859_10.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-10.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-10.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x0112, # LATIN CAPITAL LETTER E WITH MACRON *************** *** 84,88 **** 0x00f9: 0x0173, # LATIN SMALL LETTER U WITH OGONEK 0x00ff: 0x0138, # LATIN SMALL LETTER KRA ! } ### Encoding Map --- 84,88 ---- 0x00f9: 0x0173, # LATIN SMALL LETTER U WITH OGONEK 0x00ff: 0x0138, # LATIN SMALL LETTER KRA ! }) ### Encoding Map Index: iso8859_13.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_13.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_13.py 2000/03/10 23:17:22 1.1 --- iso8859_13.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-13.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-13.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x201d, # RIGHT DOUBLE QUOTATION MARK 0x00a5: 0x201e, # DOUBLE LOW-9 QUOTATION MARK --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x201d, # RIGHT DOUBLE QUOTATION MARK 0x00a5: 0x201e, # DOUBLE LOW-9 QUOTATION MARK *************** *** 94,98 **** 0x00fe: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x00ff: 0x2019, # RIGHT SINGLE QUOTATION MARK ! } ### Encoding Map --- 94,98 ---- 0x00fe: 0x017e, # LATIN SMALL LETTER Z WITH CARON 0x00ff: 0x2019, # RIGHT SINGLE QUOTATION MARK ! }) ### Encoding Map Index: iso8859_14.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_14.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_14.py 2000/03/10 23:17:22 1.1 --- iso8859_14.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-14.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-14.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x1e02, # LATIN CAPITAL LETTER B WITH DOT ABOVE 0x00a2: 0x1e03, # LATIN SMALL LETTER B WITH DOT ABOVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x1e02, # LATIN CAPITAL LETTER B WITH DOT ABOVE 0x00a2: 0x1e03, # LATIN SMALL LETTER B WITH DOT ABOVE *************** *** 69,73 **** 0x00f7: 0x1e6b, # LATIN SMALL LETTER T WITH DOT ABOVE 0x00fe: 0x0177, # LATIN SMALL LETTER Y WITH CIRCUMFLEX ! } ### Encoding Map --- 69,73 ---- 0x00f7: 0x1e6b, # LATIN SMALL LETTER T WITH DOT ABOVE 0x00fe: 0x0177, # LATIN SMALL LETTER Y WITH CIRCUMFLEX ! }) ### Encoding Map Index: iso8859_15.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_15.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_15.py 2000/03/10 23:17:22 1.1 --- iso8859_15.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-15.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-15.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a4: 0x20ac, # EURO SIGN 0x00a6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a4: 0x20ac, # EURO SIGN 0x00a6: 0x0160, # LATIN CAPITAL LETTER S WITH CARON *************** *** 46,50 **** 0x00bd: 0x0153, # LATIN SMALL LIGATURE OE 0x00be: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS ! } ### Encoding Map --- 46,50 ---- 0x00bd: 0x0153, # LATIN SMALL LIGATURE OE 0x00be: 0x0178, # LATIN CAPITAL LETTER Y WITH DIAERESIS ! }) ### Encoding Map Index: iso8859_2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_2.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_2.py 2000/03/10 23:17:22 1.1 --- iso8859_2.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-2.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-2.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x02d8, # BREVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x02d8, # BREVE *************** *** 95,99 **** 0x00fe: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA 0x00ff: 0x02d9, # DOT ABOVE ! } ### Encoding Map --- 95,99 ---- 0x00fe: 0x0163, # LATIN SMALL LETTER T WITH CEDILLA 0x00ff: 0x02d9, # DOT ABOVE ! }) ### Encoding Map Index: iso8859_3.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_3.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_3.py 2000/03/10 23:17:22 1.1 --- iso8859_3.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-3.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-3.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,43 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x0126, # LATIN CAPITAL LETTER H WITH STROKE 0x00a2: 0x02d8, # BREVE 0x00a6: 0x0124, # LATIN CAPITAL LETTER H WITH CIRCUMFLEX 0x00a9: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE --- 35,44 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x0126, # LATIN CAPITAL LETTER H WITH STROKE 0x00a2: 0x02d8, # BREVE + 0x00a5: None, 0x00a6: 0x0124, # LATIN CAPITAL LETTER H WITH CIRCUMFLEX 0x00a9: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE *************** *** 45,48 **** --- 46,50 ---- 0x00ab: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE 0x00ac: 0x0134, # LATIN CAPITAL LETTER J WITH CIRCUMFLEX + 0x00ae: None, 0x00af: 0x017b, # LATIN CAPITAL LETTER Z WITH DOT ABOVE 0x00b1: 0x0127, # LATIN SMALL LETTER H WITH STROKE *************** *** 52,64 **** --- 54,71 ---- 0x00bb: 0x011f, # LATIN SMALL LETTER G WITH BREVE 0x00bc: 0x0135, # LATIN SMALL LETTER J WITH CIRCUMFLEX + 0x00be: None, 0x00bf: 0x017c, # LATIN SMALL LETTER Z WITH DOT ABOVE + 0x00c3: None, 0x00c5: 0x010a, # LATIN CAPITAL LETTER C WITH DOT ABOVE 0x00c6: 0x0108, # LATIN CAPITAL LETTER C WITH CIRCUMFLEX + 0x00d0: None, 0x00d5: 0x0120, # LATIN CAPITAL LETTER G WITH DOT ABOVE 0x00d8: 0x011c, # LATIN CAPITAL LETTER G WITH CIRCUMFLEX 0x00dd: 0x016c, # LATIN CAPITAL LETTER U WITH BREVE 0x00de: 0x015c, # LATIN CAPITAL LETTER S WITH CIRCUMFLEX + 0x00e3: None, 0x00e5: 0x010b, # LATIN SMALL LETTER C WITH DOT ABOVE 0x00e6: 0x0109, # LATIN SMALL LETTER C WITH CIRCUMFLEX + 0x00f0: None, 0x00f5: 0x0121, # LATIN SMALL LETTER G WITH DOT ABOVE 0x00f8: 0x011d, # LATIN SMALL LETTER G WITH CIRCUMFLEX *************** *** 66,70 **** 0x00fe: 0x015d, # LATIN SMALL LETTER S WITH CIRCUMFLEX 0x00ff: 0x02d9, # DOT ABOVE ! } ### Encoding Map --- 73,77 ---- 0x00fe: 0x015d, # LATIN SMALL LETTER S WITH CIRCUMFLEX 0x00ff: 0x02d9, # DOT ABOVE ! }) ### Encoding Map Index: iso8859_4.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_4.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_4.py 2000/03/10 23:17:22 1.1 --- iso8859_4.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-4.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-4.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x0138, # LATIN SMALL LETTER KRA --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x0104, # LATIN CAPITAL LETTER A WITH OGONEK 0x00a2: 0x0138, # LATIN SMALL LETTER KRA *************** *** 88,92 **** 0x00fe: 0x016b, # LATIN SMALL LETTER U WITH MACRON 0x00ff: 0x02d9, # DOT ABOVE ! } ### Encoding Map --- 88,92 ---- 0x00fe: 0x016b, # LATIN SMALL LETTER U WITH MACRON 0x00ff: 0x02d9, # DOT ABOVE ! }) ### Encoding Map Index: iso8859_5.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_5.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_5.py 2000/03/10 23:17:22 1.1 --- iso8859_5.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-5.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-5.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x0401, # CYRILLIC CAPITAL LETTER IO 0x00a2: 0x0402, # CYRILLIC CAPITAL LETTER DJE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x0401, # CYRILLIC CAPITAL LETTER IO 0x00a2: 0x0402, # CYRILLIC CAPITAL LETTER DJE *************** *** 132,136 **** 0x00fe: 0x045e, # CYRILLIC SMALL LETTER SHORT U 0x00ff: 0x045f, # CYRILLIC SMALL LETTER DZHE ! } ### Encoding Map --- 132,136 ---- 0x00fe: 0x045e, # CYRILLIC SMALL LETTER SHORT U 0x00ff: 0x045f, # CYRILLIC SMALL LETTER DZHE ! }) ### Encoding Map Index: iso8859_6.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_6.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_6.py 2000/03/10 23:17:22 1.1 --- iso8859_6.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-6.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-6.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,44 **** ### Decoding Map - - decoding_map = { 0x00ac: 0x060c, # ARABIC COMMA 0x00bb: 0x061b, # ARABIC SEMICOLON 0x00bf: 0x061f, # ARABIC QUESTION MARK 0x00c1: 0x0621, # ARABIC LETTER HAMZA 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE --- 35,71 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ + 0x00a1: None, + 0x00a2: None, + 0x00a3: None, + 0x00a5: None, + 0x00a6: None, + 0x00a7: None, + 0x00a8: None, + 0x00a9: None, + 0x00aa: None, + 0x00ab: None, 0x00ac: 0x060c, # ARABIC COMMA + 0x00ae: None, + 0x00af: None, + 0x00b0: None, + 0x00b1: None, + 0x00b2: None, + 0x00b3: None, + 0x00b4: None, + 0x00b5: None, + 0x00b6: None, + 0x00b7: None, + 0x00b8: None, + 0x00b9: None, + 0x00ba: None, 0x00bb: 0x061b, # ARABIC SEMICOLON + 0x00bc: None, + 0x00bd: None, + 0x00be: None, 0x00bf: 0x061f, # ARABIC QUESTION MARK + 0x00c0: None, 0x00c1: 0x0621, # ARABIC LETTER HAMZA 0x00c2: 0x0622, # ARABIC LETTER ALEF WITH MADDA ABOVE *************** *** 67,70 **** --- 94,102 ---- 0x00d9: 0x0639, # ARABIC LETTER AIN 0x00da: 0x063a, # ARABIC LETTER GHAIN + 0x00db: None, + 0x00dc: None, + 0x00dd: None, + 0x00de: None, + 0x00df: None, 0x00e0: 0x0640, # ARABIC TATWEEL 0x00e1: 0x0641, # ARABIC LETTER FEH *************** *** 86,90 **** 0x00f1: 0x0651, # ARABIC SHADDA 0x00f2: 0x0652, # ARABIC SUKUN ! } ### Encoding Map --- 118,135 ---- 0x00f1: 0x0651, # ARABIC SHADDA 0x00f2: 0x0652, # ARABIC SUKUN ! 0x00f3: None, ! 0x00f4: None, ! 0x00f5: None, ! 0x00f6: None, ! 0x00f7: None, ! 0x00f8: None, ! 0x00f9: None, ! 0x00fa: None, ! 0x00fb: None, ! 0x00fc: None, ! 0x00fd: None, ! 0x00fe: None, ! 0x00ff: None, ! }) ### Encoding Map Index: iso8859_7.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_7.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_7.py 2000/03/10 23:17:23 1.1 --- iso8859_7.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-7.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-7.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,43 **** ### Decoding Map - - decoding_map = { 0x00a1: 0x2018, # LEFT SINGLE QUOTATION MARK 0x00a2: 0x2019, # RIGHT SINGLE QUOTATION MARK 0x00af: 0x2015, # HORIZONTAL BAR 0x00b4: 0x0384, # GREEK TONOS --- 35,47 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00a1: 0x2018, # LEFT SINGLE QUOTATION MARK 0x00a2: 0x2019, # RIGHT SINGLE QUOTATION MARK + 0x00a4: None, + 0x00a5: None, + 0x00aa: None, + 0x00ae: None, 0x00af: 0x2015, # HORIZONTAL BAR 0x00b4: 0x0384, # GREEK TONOS *************** *** 68,71 **** --- 72,76 ---- 0x00d0: 0x03a0, # GREEK CAPITAL LETTER PI 0x00d1: 0x03a1, # GREEK CAPITAL LETTER RHO + 0x00d2: None, 0x00d3: 0x03a3, # GREEK CAPITAL LETTER SIGMA 0x00d4: 0x03a4, # GREEK CAPITAL LETTER TAU *************** *** 112,116 **** 0x00fd: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS 0x00fe: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS ! } ### Encoding Map --- 117,122 ---- 0x00fd: 0x03cd, # GREEK SMALL LETTER UPSILON WITH TONOS 0x00fe: 0x03ce, # GREEK SMALL LETTER OMEGA WITH TONOS ! 0x00ff: None, ! }) ### Encoding Map Index: iso8859_8.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_8.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_8.py 2000/03/10 23:17:23 1.1 --- iso8859_8.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-8.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-8.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,44 **** ### Decoding Map - - decoding_map = { 0x00aa: 0x00d7, # MULTIPLICATION SIGN - 0x00af: 0x203e, # OVERLINE 0x00ba: 0x00f7, # DIVISION SIGN 0x00df: 0x2017, # DOUBLE LOW LINE 0x00e0: 0x05d0, # HEBREW LETTER ALEF --- 35,76 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ + 0x00a1: None, 0x00aa: 0x00d7, # MULTIPLICATION SIGN 0x00ba: 0x00f7, # DIVISION SIGN + 0x00bf: None, + 0x00c0: None, + 0x00c1: None, + 0x00c2: None, + 0x00c3: None, + 0x00c4: None, + 0x00c5: None, + 0x00c6: None, + 0x00c7: None, + 0x00c8: None, + 0x00c9: None, + 0x00ca: None, + 0x00cb: None, + 0x00cc: None, + 0x00cd: None, + 0x00ce: None, + 0x00cf: None, + 0x00d0: None, + 0x00d1: None, + 0x00d2: None, + 0x00d3: None, + 0x00d4: None, + 0x00d5: None, + 0x00d6: None, + 0x00d7: None, + 0x00d8: None, + 0x00d9: None, + 0x00da: None, + 0x00db: None, + 0x00dc: None, + 0x00dd: None, + 0x00de: None, 0x00df: 0x2017, # DOUBLE LOW LINE 0x00e0: 0x05d0, # HEBREW LETTER ALEF *************** *** 69,73 **** 0x00f9: 0x05e9, # HEBREW LETTER SHIN 0x00fa: 0x05ea, # HEBREW LETTER TAV ! } ### Encoding Map --- 101,110 ---- 0x00f9: 0x05e9, # HEBREW LETTER SHIN 0x00fa: 0x05ea, # HEBREW LETTER TAV ! 0x00fb: None, ! 0x00fc: None, ! 0x00fd: 0x200e, # LEFT-TO-RIGHT MARK ! 0x00fe: 0x200f, # RIGHT-TO-LEFT MARK ! 0x00ff: None, ! }) ### Encoding Map Index: iso8859_9.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/iso8859_9.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** iso8859_9.py 2000/03/10 23:17:23 1.1 --- iso8859_9.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from '8859-9.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from '8859-9.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x00d0: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE 0x00dd: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x00d0: 0x011e, # LATIN CAPITAL LETTER G WITH BREVE 0x00dd: 0x0130, # LATIN CAPITAL LETTER I WITH DOT ABOVE *************** *** 44,48 **** 0x00fd: 0x0131, # LATIN SMALL LETTER DOTLESS I 0x00fe: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA ! } ### Encoding Map --- 44,48 ---- 0x00fd: 0x0131, # LATIN SMALL LETTER DOTLESS I 0x00fe: 0x015f, # LATIN SMALL LETTER S WITH CEDILLA ! }) ### Encoding Map Index: koi8_r.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/koi8_r.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** koi8_r.py 2000/03/10 23:17:23 1.1 --- koi8_r.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'KOI8-R.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'KOI8-R.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL 0x0081: 0x2502, # BOX DRAWINGS LIGHT VERTICAL --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x2500, # BOX DRAWINGS LIGHT HORIZONTAL 0x0081: 0x2502, # BOX DRAWINGS LIGHT VERTICAL *************** *** 166,170 **** 0x00fe: 0x0427, # CYRILLIC CAPITAL LETTER CHE 0x00ff: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN ! } ### Encoding Map --- 166,170 ---- 0x00fe: 0x0427, # CYRILLIC CAPITAL LETTER CHE 0x00ff: 0x042a, # CYRILLIC CAPITAL LETTER HARD SIGN ! }) ### Encoding Map Index: mac_cyrillic.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_cyrillic.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_cyrillic.py 2000/03/10 23:17:23 1.1 --- mac_cyrillic.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'CYRILLIC.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'CYRILLIC.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x0410, # CYRILLIC CAPITAL LETTER A 0x0081: 0x0411, # CYRILLIC CAPITAL LETTER BE *************** *** 161,165 **** 0x00fe: 0x044e, # CYRILLIC SMALL LETTER YU 0x00ff: 0x00a4, # CURRENCY SIGN ! } ### Encoding Map --- 161,165 ---- 0x00fe: 0x044e, # CYRILLIC SMALL LETTER YU 0x00ff: 0x00a4, # CURRENCY SIGN ! }) ### Encoding Map Index: mac_greek.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_greek.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_greek.py 2000/03/10 23:17:23 1.1 --- mac_greek.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'GREEK.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'GREEK.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00b9, # SUPERSCRIPT ONE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00b9, # SUPERSCRIPT ONE *************** *** 164,168 **** 0x00fe: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS 0x00ff: None, # UNDEFINED ! } ### Encoding Map --- 164,168 ---- 0x00fe: 0x03b0, # GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS 0x00ff: None, # UNDEFINED ! }) ### Encoding Map Index: mac_iceland.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_iceland.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_iceland.py 2000/03/10 23:17:23 1.1 --- mac_iceland.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'ICELAND.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'ICELAND.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE *************** *** 160,164 **** 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! } ### Encoding Map --- 160,164 ---- 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! }) ### Encoding Map Index: mac_latin2.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_latin2.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_latin2.py 2000/03/10 23:17:23 1.1 --- mac_latin2.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'LATIN2.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'LATIN2.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x0100, # LATIN CAPITAL LETTER A WITH MACRON *************** *** 164,168 **** 0x00fe: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA 0x00ff: 0x02c7, # CARON ! } ### Encoding Map --- 164,168 ---- 0x00fe: 0x0122, # LATIN CAPITAL LETTER G WITH CEDILLA 0x00ff: 0x02c7, # CARON ! }) ### Encoding Map Index: mac_roman.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_roman.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_roman.py 2000/03/10 23:17:23 1.1 --- mac_roman.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'ROMAN.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'ROMAN.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE *************** *** 161,165 **** 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! } ### Encoding Map --- 161,165 ---- 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! }) ### Encoding Map Index: mac_turkish.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/encodings/mac_turkish.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** mac_turkish.py 2000/03/10 23:17:24 1.1 --- mac_turkish.py 2001/01/03 21:29:13 1.2 *************** *** 1,8 **** ! """ Python Character Mapping Codec generated from 'TURKISH.TXT'. - Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. """#" --- 1,8 ---- ! """ Python Character Mapping Codec generated from 'TURKISH.TXT' with gencodec.py. Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright CNRI, All Rights Reserved. NO WARRANTY. + (c) Copyright 2000 Guido van Rossum. """#" *************** *** 35,41 **** ### Decoding Map - - decoding_map = { 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE --- 35,41 ---- ### Decoding Map + decoding_map = codecs.make_identity_dict(range(256)) + decoding_map.update({ 0x0080: 0x00c4, # LATIN CAPITAL LETTER A WITH DIAERESIS 0x0081: 0x00c5, # LATIN CAPITAL LETTER A WITH RING ABOVE *************** *** 161,165 **** 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! } ### Encoding Map --- 161,165 ---- 0x00fe: 0x02db, # OGONEK 0x00ff: 0x02c7, # CARON ! }) ### Encoding Map From python-dev@python.org Wed Jan 3 21:42:48 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 03 Jan 2001 22:42:48 +0100 Subject: [Python-checkins] CVS: python/dist/src/Lib codecs.py,1.13,1.14 References: Message-ID: <3A539CD8.367361B8@lemburg.com> "M.-A. Lemburg" wrote: > > Update of /cvsroot/python/python/dist/src/Lib > In directory usw-pr-cvs1:/tmp/cvs-serv26608/Lib > > Modified Files: > codecs.py > Log Message: > ... > > This patch closes the bugs #116285 and #119960. I was too fast... the subject line of #119960 was misleading. It is still open. -- Marc-Andre Lemburg ______________________________________________________________________ Company: http://www.egenix.com/ Consulting: http://www.lemburg.com/ Python Pages: http://www.lemburg.com/python/ From python-dev@python.org Wed Jan 3 22:32:18 2001 From: python-dev@python.org (Jeremy Hylton) Date: Wed, 03 Jan 2001 14:32:18 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects listobject.c,2.89,2.90 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2530 Modified Files: listobject.c Log Message: fix leak Index: listobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/listobject.c,v retrieving revision 2.89 retrieving revision 2.90 diff -C2 -r2.89 -r2.90 *** listobject.c 2000/12/13 22:35:46 2.89 --- listobject.c 2001/01/03 22:32:16 2.90 *************** *** 597,603 **** register int i; ! if (PyObject_Size(b) == 0) /* short circuit when b is empty */ return 0; if (self == (PyListObject*)b) { --- 597,605 ---- register int i; ! if (PyObject_Size(b) == 0) { /* short circuit when b is empty */ + Py_DECREF(b); return 0; + } if (self == (PyListObject*)b) { From python-dev@python.org Wed Jan 3 22:35:01 2001 From: python-dev@python.org (Jeremy Hylton) Date: Wed, 03 Jan 2001 14:35:01 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects dictobject.c,2.71,2.72 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv2783 Modified Files: dictobject.c Log Message: dict_update has two boundary conditions: a.update(a) and a.update({}) Added test for second one. Index: dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -r2.71 -r2.72 *** dictobject.c 2000/12/13 23:18:45 2.71 --- dictobject.c 2001/01/03 22:34:59 2.72 *************** *** 810,815 **** if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) return NULL; ! if (other == mp) ! goto done; /* a.update(a); nothing to do */ /* Do one big resize at the start, rather than incrementally resizing as we insert new items. Expect that there will be --- 810,815 ---- if (!PyArg_Parse(args, "O!", &PyDict_Type, &other)) return NULL; ! if (other == mp || other->ma_used == 0) ! goto done; /* a.update(a) or a.update({}); nothing to do */ /* Do one big resize at the start, rather than incrementally resizing as we insert new items. Expect that there will be From python-dev@python.org Wed Jan 3 23:51:01 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 03 Jan 2001 15:51:01 -0800 Subject: [Python-checkins] CVS: python/dist/src/Tools/freeze README,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Tools/freeze In directory usw-pr-cvs1:/tmp/cvs-serv10544 Modified Files: README Log Message: New, improved README from Mike Clarkson. Wow! Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Tools/freeze/README,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** README 2000/07/24 16:02:00 1.8 --- README 2001/01/03 23:50:59 1.9 *************** *** 95,120 **** Unfortunately, it is currently not possible to freeze programs that ! use Tkinter. It *seems* to work, but when you ship the frozen program ! to a site without a Tcl/Tk installation, it will fail with a complaint ! about missing Tcl/Tk initialization files. ! A workaround would be possible, in which the Tcl/Tk library files are incorporated in a frozen Python module as string literals and written to a temporary location when the program runs; this is currently left ! as an exercise for the reader. (If you implement this, please post to ! the Python newsgroup!) - Of course, you can also simply require that Tcl/Tk is required on the - target installation. - - - A warning against shared library modules - ---------------------------------------- - - When your Python installation uses shared library modules, these will - not be incorporated in the frozen program. Again, the frozen program - will work when you test it, but it won't work when you ship it to a - site without a Python installation. - Freeze prints a warning when this is the case at the end of the freezing process: --- 95,173 ---- Unfortunately, it is currently not possible to freeze programs that ! use Tkinter without a Tcl/Tk installation. The best way to ship a ! frozen Tkinter program is to decide in advance where you are going ! to place the Tcl and Tk library files in the distributed setup, and ! then declare these directories in your frozen Python program using ! the TCL_LIBRARY, TK_LIBRARY and TIX_LIBRARY environment variables. ! ! For example, assume you will ship your frozen program in the directory ! /bin/windows-x86 and will place your Tcl library files ! in /lib/tcl8.2 and your Tk library files in /lib/tk8.2. Then ! placing the following lines in your frozen Python script before importing ! Tkinter or Tix would set the environment correctly for Tcl/Tk/Tix: ! ! import os ! import os.path ! RootDir = os.path.dirname(os.path.dirname(os.getcwd())) ! ! import sys ! if sys.platform == "win32": ! sys.path = ['', '..\\..\\lib\\python-2.0'] ! os.environ['TCL_LIBRARY'] = RootDir + '\\lib\\tcl8.2' ! os.environ['TK_LIBRARY'] = RootDir + '\\lib\\tk8.2' ! os.environ['TIX_LIBRARY'] = RootDir + '\\lib\\tix8.1' ! elif sys.platform == "linux2": ! sys.path = ['', '../../lib/python-2.0'] ! os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' ! os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' ! os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1' ! elif sys.platform == "solaris": ! sys.path = ['', '../../lib/python-2.0'] ! os.environ['TCL_LIBRARY'] = RootDir + '/lib/tcl8.2' ! os.environ['TK_LIBRARY'] = RootDir + '/lib/tk8.2' ! os.environ['TIX_LIBRARY'] = RootDir + '/lib/tix8.1' ! ! This also adds /lib/python-2.0 to your Python path ! for any Python files such as _tkinter.pyd you may need. ! ! Note that the dynamic libraries (such as tcl82.dll tk82.dll python20.dll ! under Windows, or libtcl8.2.so and libtcl8.2.so under Unix) are required ! at program load time, and are searched by the operating system loader ! before Python can be started. Under Windows, the environment ! variable PATH is consulted, and under Unix, it may be the ! the environment variable LD_LIBRARY_PATH and/or the system ! shared library cache (ld.so). An additional preferred directory for ! finding the dynamic libraries is built into the .dll or .so files at ! compile time - see the LIB_RUNTIME_DIR variable in the Tcl makefile. ! The OS must find the dynamic libraries or your frozen program won't start. ! Usually I make sure that the .so or .dll files are in the same directory ! as the executable, but this may not be foolproof. ! A workaround to installing your Tcl library files with your frozen ! executable would be possible, in which the Tcl/Tk library files are incorporated in a frozen Python module as string literals and written to a temporary location when the program runs; this is currently left ! as an exercise for the reader. An easier approach is to freeze the ! Tcl/Tk/Tix code into the dynamic libraries using the Tcl ET code, ! or the Tix Stand-Alone-Module code. Of course, you can also simply ! require that Tcl/Tk is required on the target installation, but be ! careful that the version corresponds. ! ! There are some caveats using frozen Tkinter applications: ! Under Windows if you use the -s windows option, writing ! to stdout or stderr is an error. ! The Tcl [info nameofexecutable] will be set to where the ! program was frozen, not where it is run from. ! The global variables argc and argv do not exist. ! ! ! A warning about shared library modules ! -------------------------------------- ! ! When your Python installation uses shared library modules such as ! _tkinter.pyd, these will not be incorporated in the frozen program. ! Again, the frozen program will work when you test it, but it won't ! work when you ship it to a site without a Python installation. Freeze prints a warning when this is the case at the end of the freezing process: *************** *** 123,127 **** When this occurs, the best thing to do is usually to rebuild Python ! using static linking only. --- 176,182 ---- When this occurs, the best thing to do is usually to rebuild Python ! using static linking only. Or use the approach described in the previous ! section to declare a library path using sys.path, and place the modules ! such as _tkinter.pyd there. *************** *** 165,173 **** source tree). - You can freeze programs that use Tkinter, but Tcl/Tk must be installed - on the target system. - It is possible to create frozen programs that don't have a console ! window, by specifying the option '-s windows'. --Guido van Rossum (home page: http://www.python.org/~guido/) --- 220,296 ---- source tree). It is possible to create frozen programs that don't have a console ! window, by specifying the option '-s windows'. See the Usage below. ! ! Usage ! ----- ! ! Here is a list of all of the options (taken from freeze.__doc__): ! ! usage: freeze [options...] script [module]... ! ! Options: ! -p prefix: This is the prefix used when you ran ``make install'' ! in the Python build directory. ! (If you never ran this, freeze won't work.) ! The default is whatever sys.prefix evaluates to. ! It can also be the top directory of the Python source ! tree; then -P must point to the build tree. ! ! -P exec_prefix: Like -p but this is the 'exec_prefix', used to ! install objects etc. The default is whatever sys.exec_prefix ! evaluates to, or the -p argument if given. ! If -p points to the Python source tree, -P must point ! to the build tree, if different. ! ! -e extension: A directory containing additional .o files that ! may be used to resolve modules. This directory ! should also have a Setup file describing the .o files. ! On Windows, the name of a .INI file describing one ! or more extensions is passed. ! More than one -e option may be given. ! ! -o dir: Directory where the output files are created; default '.'. ! ! -m: Additional arguments are module names instead of filenames. ! ! -a package=dir: Additional directories to be added to the package's ! __path__. Used to simulate directories added by the ! package at runtime (eg, by OpenGL and win32com). ! More than one -a option may be given for each package. ! ! -l file: Pass the file to the linker (windows only) ! ! -d: Debugging mode for the module finder. ! ! -q: Make the module finder totally quiet. ! ! -h: Print this help message. ! ! -x module Exclude the specified module. ! ! -i filename: Include a file with additional command line options. Used ! to prevent command lines growing beyond the capabilities of ! the shell/OS. All arguments specified in filename ! are read and the -i option replaced with the parsed ! params (note - quoting args in this file is NOT supported) ! ! -s subsystem: Specify the subsystem (For Windows only.); ! 'console' (default), 'windows', 'service' or 'com_dll' ! ! -w: Toggle Windows (NT or 95) behavior. ! (For debugging only -- on a win32 platform, win32 behavior ! is automatic.) ! ! Arguments: ! ! script: The Python script to be executed by the resulting binary. ! ! module ...: Additional Python modules (referenced by pathname) ! that will be included in the resulting binary. These ! may be .py or .pyc files. If -m is specified, these are ! module names that are search in the path instead. ! ! --Guido van Rossum (home page: http://www.python.org/~guido/) From python-dev@python.org Wed Jan 3 23:51:28 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 03 Jan 2001 15:51:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv10607 Modified Files: ACKS Log Message: Two new names. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -r1.68 -r1.69 *** ACKS 2000/10/09 20:07:00 1.68 --- ACKS 2001/01/03 23:51:26 1.69 *************** *** 56,59 **** --- 56,60 ---- Lee Busby Ralph Butler + Daniel Calvelo Mike Carlton Donn Cave *************** *** 67,70 **** --- 68,72 ---- Tom Christiansen Vadim Chugunov + Mike Clarkson Steve Clift Matt Conway From python-dev@python.org Wed Jan 3 23:52:39 2001 From: python-dev@python.org (Jeremy Hylton) Date: Wed, 03 Jan 2001 15:52:39 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.213,2.214 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv9469/Python Modified Files: ceval.c Log Message: Revised implementation of CALL_FUNCTION and friends. More revision still needed. Much of the code that was in the mainloop was moved to a series of helper functions. PyEval_CallObjectWithKeywords was split into two parts. The first part now only does argument handling. The second part is now named call_object and delegates the call to a call_(function,method,etc.) helper. XXX The call_XXX helper functions should be replaced with tp_call functions for the respective types. The CALL_FUNCTION implementation contains three kinds of optimization: 1. fast_cfunction and fast_function are called when the arguments on the stack can be passed directly to eval_code2() without copying them into a tuple. 2. PyCFunction objects are dispatched immediately, because they are presumed to occur more often than anything else. 3. Bound methods are dispatched inline. The method object contains a pointer to the function object that will be called. The function is called from within the mainloop, which may allow optimization #1 to be used, too. The extened call implementation -- f(*args) and f(**kw) -- are implemented as a separate case in the mainloop. This allows the common case of normal function calls to execute without wasting time on checks for extended calls, although it does introduce a small amount of code duplication. Also, the unused final argument of eval_code2() was removed. This is probably the last trace of the access statement :-). Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.213 retrieving revision 2.214 diff -C2 -r2.213 -r2.214 *** ceval.c 2000/10/30 17:15:19 2.213 --- ceval.c 2001/01/03 23:52:36 2.214 *************** *** 30,33 **** --- 30,34 ---- #endif + typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *); /* Forward declarations */ *************** *** 37,42 **** PyObject **, int, PyObject **, int, ! PyObject **, int, ! PyObject *); #ifdef LLTRACE static int prtrace(PyObject *, char *); --- 38,58 ---- PyObject **, int, PyObject **, int, ! PyObject **, int); ! ! static PyObject *call_object(PyObject *, PyObject *, PyObject *); ! static PyObject *call_cfunction(PyObject *, PyObject *, PyObject *); ! static PyObject *call_instance(PyObject *, PyObject *, PyObject *); ! static PyObject *call_method(PyObject *, PyObject *, PyObject *); ! static PyObject *call_eval_code2(PyObject *, PyObject *, PyObject *); ! static PyObject *fast_function(PyObject *, PyObject ***, int, int, int); ! static PyObject *fast_cfunction(PyObject *, PyObject ***, int); ! static PyObject *do_call(PyObject *, PyObject ***, int, int); ! static PyObject *ext_do_call(PyObject *, PyObject ***, int, int, int); ! static PyObject *update_keyword_args(PyObject *, int, PyObject ***); ! static PyObject *update_star_args(int, int, PyObject *, PyObject ***); ! static PyObject *load_args(PyObject ***, int); ! #define CALL_FLAG_VAR 1 ! #define CALL_FLAG_KW 2 ! #ifdef LLTRACE static int prtrace(PyObject *, char *); *************** *** 45,50 **** static int call_trace(PyObject **, PyObject **, PyFrameObject *, char *, PyObject *); - static PyObject *call_builtin(PyObject *, PyObject *, PyObject *); - static PyObject *call_function(PyObject *, PyObject *, PyObject *); static PyObject *loop_subscript(PyObject *, PyObject *); static PyObject *apply_slice(PyObject *, PyObject *, PyObject *); --- 61,64 ---- *************** *** 76,80 **** #endif - #ifdef WITH_THREAD --- 90,93 ---- *************** *** 321,326 **** (PyObject **)NULL, 0, (PyObject **)NULL, 0, ! (PyObject **)NULL, 0, ! (PyObject *)NULL); } --- 334,338 ---- (PyObject **)NULL, 0, (PyObject **)NULL, 0, ! (PyObject **)NULL, 0); } *************** *** 331,343 **** eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount, PyObject *owner) { #ifdef DXPAIRS int lastopcode = 0; #endif register unsigned char *next_instr; register int opcode=0; /* Current opcode */ register int oparg=0; /* Current opcode argument, if any */ - register PyObject **stack_pointer; register enum why_code why; /* Reason for block stack unwind */ register int err; /* Error status -- nonzero if error */ --- 343,355 ---- eval_code2(PyCodeObject *co, PyObject *globals, PyObject *locals, PyObject **args, int argcount, PyObject **kws, int kwcount, ! PyObject **defs, int defcount) { #ifdef DXPAIRS int lastopcode = 0; #endif + PyObject **stack_pointer; register unsigned char *next_instr; register int opcode=0; /* Current opcode */ register int oparg=0; /* Current opcode argument, if any */ register enum why_code why; /* Reason for block stack unwind */ register int err; /* Error status -- nonzero if error */ *************** *** 669,673 **** #endif /* Main switch on opcode */ ! switch (opcode) { --- 681,685 ---- #endif /* Main switch on opcode */ ! switch (opcode) { *************** *** 1798,1801 **** --- 1810,1867 ---- case CALL_FUNCTION: + { + int na = oparg & 0xff; + int nk = (oparg>>8) & 0xff; + int n = na + 2 * nk; + PyObject **pfunc = stack_pointer - n - 1; + PyObject *func = *pfunc; + f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */ + + /* Always dispatch PyCFunction first, because + these are presumed to be the most frequent + callable object. + */ + if (PyCFunction_Check(func)) { + if (PyCFunction_GET_FLAGS(func) == 0) { + x = fast_cfunction(func, + &stack_pointer, na); + } else { + x = do_call(func, &stack_pointer, + na, nk); + } + } else { + if (PyMethod_Check(func) + && PyMethod_GET_SELF(func) != NULL) { + /* optimize access to bound methods */ + PyObject *self = PyMethod_GET_SELF(func); + Py_INCREF(self); + func = PyMethod_GET_FUNCTION(func); + Py_INCREF(func); + Py_DECREF(*pfunc); + *pfunc = self; + na++; + n++; + } else + Py_INCREF(func); + if (PyFunction_Check(func)) { + x = fast_function(func, &stack_pointer, + n, na, nk); + } else { + x = do_call(func, &stack_pointer, + na, nk); + } + Py_DECREF(func); + } + + while (stack_pointer > pfunc) { + w = POP(); + Py_DECREF(w); + } + PUSH(x); + if (x != NULL) + continue; + break; + } + case CALL_FUNCTION_VAR: case CALL_FUNCTION_KW: *************** *** 1805,1989 **** int nk = (oparg>>8) & 0xff; int flags = (opcode - CALL_FUNCTION) & 3; ! int n = na + 2*nk + (flags & 1) + ((flags >> 1) & 1); ! PyObject **pfunc = stack_pointer - n - 1; ! PyObject *func = *pfunc; ! PyObject *self = NULL; ! PyObject *class = NULL; f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */ ! if (PyMethod_Check(func)) { ! self = PyMethod_Self(func); ! class = PyMethod_Class(func); ! func = PyMethod_Function(func); ! Py_INCREF(func); ! if (self != NULL) { Py_INCREF(self); Py_DECREF(*pfunc); *pfunc = self; na++; n++; ! } ! else if (!((flags & 1) && na == 0)) { ! /* Unbound methods must be called with an ! instance of the class (or a derived ! class) as first argument */ ! if (na > 0 && (self = stack_pointer[-n]) != NULL ! && PyInstance_Check(self) ! && PyClass_IsSubclass((PyObject *) ! (((PyInstanceObject *)self)->in_class), ! class)) ! /* Handy-dandy */ ; ! else { ! PyErr_SetString(PyExc_TypeError, ! "unbound method must be called with instance as first argument"); ! x = NULL; ! break; ! } ! } ! } ! else ! Py_INCREF(func); ! if (PyFunction_Check(func) && flags == 0) { ! PyObject *co = PyFunction_GetCode(func); ! PyObject *globals = PyFunction_GetGlobals(func); ! PyObject *argdefs = PyFunction_GetDefaults(func); ! PyObject **d; ! int nd; ! if (argdefs != NULL) { ! d = &PyTuple_GET_ITEM(argdefs, 0); ! nd = ((PyTupleObject *)argdefs)->ob_size; ! } ! else { ! d = NULL; ! nd = 0; ! } ! x = eval_code2((PyCodeObject *)co, globals, ! (PyObject *)NULL, stack_pointer-n, na, ! stack_pointer-2*nk, nk, d, nd, ! class); ! } ! else { ! int nstar = 0; ! PyObject *callargs; ! PyObject *stararg = 0; ! PyObject *kwdict = NULL; ! if (flags & 2) { ! kwdict = POP(); ! if (!PyDict_Check(kwdict)) { ! PyErr_SetString(PyExc_TypeError, ! "** argument must be a dictionary"); ! goto extcall_fail; ! } ! } ! if (flags & 1) { ! stararg = POP(); ! if (!PySequence_Check(stararg)) { ! PyErr_SetString(PyExc_TypeError, ! "* argument must be a sequence"); ! goto extcall_fail; ! } ! /* Convert abstract sequence to concrete tuple */ ! if (!PyTuple_Check(stararg)) { ! PyObject *t = NULL; ! t = PySequence_Tuple(stararg); ! if (t == NULL) { ! goto extcall_fail; ! } ! Py_DECREF(stararg); ! stararg = t; ! } ! nstar = PyTuple_GET_SIZE(stararg); ! if (nstar < 0) { ! goto extcall_fail; ! } ! if (class && self == NULL && na == 0) { ! /* * arg is first argument of method, ! so check it is isinstance of class */ ! self = PyTuple_GET_ITEM(stararg, 0); ! if (!(PyInstance_Check(self) && ! PyClass_IsSubclass((PyObject *) ! (((PyInstanceObject *)self)->in_class), ! class))) { ! PyErr_SetString(PyExc_TypeError, ! "unbound method must be called with instance as first argument"); ! x = NULL; ! break; ! } ! } ! } ! if (nk > 0) { ! if (kwdict == NULL) { ! kwdict = PyDict_New(); ! if (kwdict == NULL) { ! goto extcall_fail; ! } ! } ! else { ! PyObject *d = PyDict_Copy(kwdict); ! if (d == NULL) { ! goto extcall_fail; ! } ! Py_DECREF(kwdict); ! kwdict = d; ! } ! err = 0; ! while (--nk >= 0) { ! PyObject *value = POP(); ! PyObject *key = POP(); ! if (PyDict_GetItem(kwdict, key) != NULL) { ! err = 1; ! PyErr_Format(PyExc_TypeError, ! "keyword parameter '%.400s' " ! "redefined in function call", ! PyString_AsString(key)); ! Py_DECREF(key); ! Py_DECREF(value); ! goto extcall_fail; ! } ! err = PyDict_SetItem(kwdict, key, value); ! Py_DECREF(key); ! Py_DECREF(value); ! if (err) ! break; ! } ! if (err) { ! extcall_fail: ! Py_XDECREF(kwdict); ! Py_XDECREF(stararg); ! Py_DECREF(func); ! x=NULL; ! break; ! } ! } ! callargs = PyTuple_New(na + nstar); ! if (callargs == NULL) { ! x = NULL; ! break; ! } ! if (stararg) { ! int i; ! for (i = 0; i < nstar; i++) { ! PyObject *a = PyTuple_GET_ITEM(stararg, i); ! Py_INCREF(a); ! PyTuple_SET_ITEM(callargs, na + i, a); ! } ! Py_DECREF(stararg); ! } ! while (--na >= 0) { ! w = POP(); ! PyTuple_SET_ITEM(callargs, na, w); ! } ! x = PyEval_CallObjectWithKeywords(func, ! callargs, ! kwdict); ! Py_DECREF(callargs); ! Py_XDECREF(kwdict); ! } Py_DECREF(func); while (stack_pointer > pfunc) { ! w = POP(); ! Py_DECREF(w); } PUSH(x); ! if (x != NULL) continue; break; } --- 1871,1906 ---- int nk = (oparg>>8) & 0xff; int flags = (opcode - CALL_FUNCTION) & 3; ! int n = na + 2 * nk; ! PyObject **pfunc, *func; ! if (flags & CALL_FLAG_VAR) ! n++; ! if (flags & CALL_FLAG_KW) ! n++; ! pfunc = stack_pointer - n - 1; ! func = *pfunc; f->f_lasti = INSTR_OFFSET() - 3; /* For tracing */ ! ! if (PyMethod_Check(func) ! && PyMethod_GET_SELF(func) != NULL) { ! PyObject *self = PyMethod_GET_SELF(func); Py_INCREF(self); + func = PyMethod_GET_FUNCTION(func); + Py_INCREF(func); Py_DECREF(*pfunc); *pfunc = self; na++; n++; ! } else ! Py_INCREF(func); ! x = ext_do_call(func, &stack_pointer, flags, na, nk); Py_DECREF(func); + while (stack_pointer > pfunc) { ! w = POP(); ! Py_DECREF(w); } PUSH(x); ! if (x != NULL) ! continue; break; } *************** *** 2615,2620 **** PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) { ! ternaryfunc call; ! PyObject *result; if (arg == NULL) --- 2532,2536 ---- PyEval_CallObjectWithKeywords(PyObject *func, PyObject *arg, PyObject *kw) { ! PyObject *result; if (arg == NULL) *************** *** 2634,2647 **** return NULL; } - - if ((call = func->ob_type->tp_call) != NULL) - result = (*call)(func, arg, kw); - else if (PyMethod_Check(func) || PyFunction_Check(func)) - result = call_function(func, arg, kw); - else - result = call_builtin(func, arg, kw); Py_DECREF(arg); ! if (result == NULL && !PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, --- 2550,2596 ---- return NULL; } + result = call_object(func, arg, kw); Py_DECREF(arg); ! return result; ! } ! ! /* How often is each kind of object called? The answer depends on the ! program. An instrumented call_object() was used to run the Python ! regression test suite. The results were: ! 4200000 PyCFunctions ! 390000 fast_function() calls ! 94000 other functions ! 480000 all functions (sum of prev two) ! 150000 methods ! 100000 classes ! ! Tests on other bodies of code show that PyCFunctions are still ! most common, but not by such a large margin. ! */ ! ! static PyObject * ! call_object(PyObject *func, PyObject *arg, PyObject *kw) ! { ! ternaryfunc call; ! PyObject *result; ! ! if (PyMethod_Check(func)) ! result = call_method(func, arg, kw); ! else if (PyFunction_Check(func)) ! result = call_eval_code2(func, arg, kw); ! else if (PyCFunction_Check(func)) ! result = call_cfunction(func, arg, kw); ! else if (PyClass_Check(func)) ! result = PyInstance_New(func, arg, kw); ! else if (PyInstance_Check(func)) ! result = call_instance(func, arg, kw); ! else if ((call = func->ob_type->tp_call) != NULL) ! result = (*call)(func, arg, kw); ! else { ! PyErr_Format(PyExc_TypeError, "object is not callable: %s", ! PyString_AS_STRING(PyObject_Repr(func))); ! return NULL; ! } if (result == NULL && !PyErr_Occurred()) PyErr_SetString(PyExc_SystemError, *************** *** 2652,2772 **** static PyObject * ! call_builtin(PyObject *func, PyObject *arg, PyObject *kw) { ! if (PyCFunction_Check(func)) { ! PyCFunctionObject* f = (PyCFunctionObject*) func; ! PyCFunction meth = PyCFunction_GetFunction(func); ! PyObject *self = PyCFunction_GetSelf(func); ! int flags = PyCFunction_GetFlags(func); ! if (!(flags & METH_VARARGS)) { ! int size = PyTuple_Size(arg); ! if (size == 1) ! arg = PyTuple_GET_ITEM(arg, 0); ! else if (size == 0) ! arg = NULL; ! } ! if (flags & METH_KEYWORDS) ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); ! if (kw != NULL && PyDict_Size(kw) != 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no keyword arguments", ! f->m_ml->ml_name); ! return NULL; } return (*meth)(self, arg); } ! if (PyClass_Check(func)) { ! return PyInstance_New(func, arg, kw); } ! if (PyInstance_Check(func)) { ! PyObject *res, *call = PyObject_GetAttrString(func, "__call__"); ! if (call == NULL) { ! PyInstanceObject *inst = (PyInstanceObject*) func; ! PyErr_Clear(); ! PyErr_Format(PyExc_AttributeError, ! "%.200s instance has no __call__ method", ! PyString_AsString(inst->in_class->cl_name)); ! return NULL; ! } ! res = PyEval_CallObjectWithKeywords(call, arg, kw); ! Py_DECREF(call); ! return res; } ! PyErr_Format(PyExc_TypeError, "call of non-function (type %.400s)", ! func->ob_type->tp_name); return NULL; } static PyObject * ! call_function(PyObject *func, PyObject *arg, PyObject *kw) { ! PyObject *class = NULL; /* == owner */ ! PyObject *argdefs; ! PyObject **d, **k; ! int nk, nd; ! PyObject *result; ! ! if (kw != NULL && !PyDict_Check(kw)) { ! PyErr_BadInternalCall(); return NULL; - } - - if (PyMethod_Check(func)) { - PyObject *self = PyMethod_Self(func); - class = PyMethod_Class(func); - func = PyMethod_Function(func); - if (self == NULL) { - /* Unbound methods must be called with an instance of - the class (or a derived class) as first argument */ - if (PyTuple_Size(arg) >= 1) { - self = PyTuple_GET_ITEM(arg, 0); - if (self != NULL && - PyInstance_Check(self) && - PyClass_IsSubclass((PyObject *) - (((PyInstanceObject *)self)->in_class), - class)) - /* Handy-dandy */ ; - else - self = NULL; - } - if (self == NULL) { - PyErr_SetString(PyExc_TypeError, - "unbound method must be called with instance as first argument"); - return NULL; - } - Py_INCREF(arg); - } - else { - int argcount = PyTuple_Size(arg); - PyObject *newarg = PyTuple_New(argcount + 1); - int i; - if (newarg == NULL) - return NULL; - Py_INCREF(self); - PyTuple_SET_ITEM(newarg, 0, self); - for (i = 0; i < argcount; i++) { - PyObject *v = PyTuple_GET_ITEM(arg, i); - Py_XINCREF(v); - PyTuple_SET_ITEM(newarg, i+1, v); - } - arg = newarg; - } - if (!PyFunction_Check(func)) { - result = PyEval_CallObjectWithKeywords(func, arg, kw); - Py_DECREF(arg); - return result; - } } ! else { ! if (!PyFunction_Check(func)) { ! PyErr_Format(PyExc_TypeError, ! "call of non-function (type %.200s)", ! func->ob_type->tp_name); return NULL; } Py_INCREF(arg); } ! ! argdefs = PyFunction_GetDefaults(func); if (argdefs != NULL && PyTuple_Check(argdefs)) { d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0); --- 2601,2714 ---- static PyObject * ! call_cfunction(PyObject *func, PyObject *arg, PyObject *kw) { ! PyCFunctionObject* f = (PyCFunctionObject*)func; ! PyCFunction meth = PyCFunction_GET_FUNCTION(func); ! PyObject *self = PyCFunction_GET_SELF(func); ! int flags = PyCFunction_GET_FLAGS(func); ! ! if (flags & METH_KEYWORDS && kw == NULL) { ! static PyObject *dict = NULL; ! if (dict == NULL) { ! dict = PyDict_New(); ! if (dict == NULL) ! return NULL; } + kw = dict; + Py_INCREF(dict); + } + if (flags & METH_VARARGS && kw == NULL) { return (*meth)(self, arg); } ! if (flags & METH_KEYWORDS) { ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); } ! if (!(flags & METH_VARARGS)) { ! int size = PyTuple_GET_SIZE(arg); ! if (size == 1) ! arg = PyTuple_GET_ITEM(arg, 0); ! else if (size == 0) ! arg = NULL; ! return (*meth)(self, arg); } ! if (kw != NULL && PyDict_Size(kw) != 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no keyword arguments", ! f->m_ml->ml_name); ! return NULL; ! } ! /* should never get here ??? */ ! PyErr_BadInternalCall(); return NULL; } static PyObject * ! call_instance(PyObject *func, PyObject *arg, PyObject *kw) { ! PyObject *res, *call = PyObject_GetAttrString(func, "__call__"); ! if (call == NULL) { ! PyInstanceObject *inst = (PyInstanceObject*) func; ! PyErr_Clear(); ! PyErr_Format(PyExc_AttributeError, ! "%.200s instance has no __call__ method", ! PyString_AsString(inst->in_class->cl_name)); return NULL; } ! res = call_object(call, arg, kw); ! Py_DECREF(call); ! return res; ! } ! ! static PyObject * ! call_method(PyObject *func, PyObject *arg, PyObject *kw) ! { ! PyObject *self = PyMethod_GET_SELF(func); ! PyObject *class = PyMethod_GET_CLASS(func); ! PyObject *result; ! ! func = PyMethod_GET_FUNCTION(func); ! if (self == NULL) { ! /* Unbound methods must be called with an instance of ! the class (or a derived class) as first argument */ ! if (PyTuple_Size(arg) >= 1) ! self = PyTuple_GET_ITEM(arg, 0); ! if (!(self != NULL && PyInstance_Check(self) ! && PyClass_IsSubclass((PyObject *) ! (((PyInstanceObject *)self)->in_class), ! class))) { ! PyErr_SetString(PyExc_TypeError, ! "unbound method must be called with instance as first argument"); return NULL; } Py_INCREF(arg); + } else { + int argcount = PyTuple_Size(arg); + PyObject *newarg = PyTuple_New(argcount + 1); + int i; + if (newarg == NULL) + return NULL; + Py_INCREF(self); + PyTuple_SET_ITEM(newarg, 0, self); + for (i = 0; i < argcount; i++) { + PyObject *v = PyTuple_GET_ITEM(arg, i); + Py_XINCREF(v); + PyTuple_SET_ITEM(newarg, i+1, v); + } + arg = newarg; } ! result = call_object(func, arg, kw); ! Py_DECREF(arg); ! return result; ! } ! ! static PyObject * ! call_eval_code2(PyObject *func, PyObject *arg, PyObject *kw) ! { ! PyObject *result; ! PyObject *argdefs; ! PyObject **d, **k; ! int nk, nd; ! ! argdefs = PyFunction_GET_DEFAULTS(func); if (argdefs != NULL && PyTuple_Check(argdefs)) { d = &PyTuple_GET_ITEM((PyTupleObject *)argdefs, 0); *************** *** 2799,2813 **** result = eval_code2( ! (PyCodeObject *)PyFunction_GetCode(func), ! PyFunction_GetGlobals(func), (PyObject *)NULL, &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), k, nk, ! d, nd, ! class); - Py_DECREF(arg); if (k != NULL) PyMem_DEL(k); return result; } --- 2741,2946 ---- result = eval_code2( ! (PyCodeObject *)PyFunction_GET_CODE(func), ! PyFunction_GET_GLOBALS(func), (PyObject *)NULL, &PyTuple_GET_ITEM(arg, 0), PyTuple_Size(arg), k, nk, ! d, nd); if (k != NULL) PyMem_DEL(k); + return result; + } + + #define EXT_POP(STACK_POINTER) (*--(STACK_POINTER)) + + /* The two fast_xxx() functions optimize calls for which no argument + tuple is necessary; the objects are passed directly from the stack. + fast_cfunction() is called for METH_OLDARGS functions. + fast_function() is for functions with no special argument handling. + */ + + static PyObject * + fast_cfunction(PyObject *func, PyObject ***pp_stack, int na) + { + PyCFunction meth = PyCFunction_GET_FUNCTION(func); + PyObject *self = PyCFunction_GET_SELF(func); + + if (na == 0) + return (*meth)(self, NULL); + else if (na == 1) + return (*meth)(self, EXT_POP(*pp_stack)); + else { + PyObject *args = load_args(pp_stack, na); + PyObject *result = (*meth)(self, args); + Py_DECREF(args); + return result; + } + } + + static PyObject * + fast_function(PyObject *func, PyObject ***pp_stack, int n, int na, int nk) + { + PyObject *co = PyFunction_GET_CODE(func); + PyObject *globals = PyFunction_GET_GLOBALS(func); + PyObject *argdefs = PyFunction_GET_DEFAULTS(func); + PyObject **d = NULL; + int nd = 0; + + if (argdefs != NULL) { + d = &PyTuple_GET_ITEM(argdefs, 0); + nd = ((PyTupleObject *)argdefs)->ob_size; + } + return eval_code2((PyCodeObject *)co, globals, + (PyObject *)NULL, (*pp_stack)-n, na, + (*pp_stack)-2*nk, nk, d, nd); + } + + static PyObject * + update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack) + { + PyObject *kwdict = NULL; + if (orig_kwdict == NULL) + kwdict = PyDict_New(); + else { + kwdict = PyDict_Copy(orig_kwdict); + Py_DECREF(orig_kwdict); + } + if (kwdict == NULL) + return NULL; + while (--nk >= 0) { + int err; + PyObject *value = EXT_POP(*pp_stack); + PyObject *key = EXT_POP(*pp_stack); + if (PyDict_GetItem(kwdict, key) != NULL) { + PyErr_Format(PyExc_TypeError, + "keyword parameter '%.400s' " + "redefined in function call", + PyString_AsString(key)); + Py_DECREF(key); + Py_DECREF(value); + Py_DECREF(kwdict); + return NULL; + } + err = PyDict_SetItem(kwdict, key, value); + Py_DECREF(key); + Py_DECREF(value); + if (err) { + Py_DECREF(kwdict); + return NULL; + } + } + return kwdict; + } + + static PyObject * + update_star_args(int nstack, int nstar, PyObject *stararg, + PyObject ***pp_stack) + { + PyObject *callargs, *w; + + callargs = PyTuple_New(nstack + nstar); + if (callargs == NULL) { + return NULL; + } + if (nstar) { + int i; + for (i = 0; i < nstar; i++) { + PyObject *a = PyTuple_GET_ITEM(stararg, i); + Py_INCREF(a); + PyTuple_SET_ITEM(callargs, nstack + i, a); + } + } + while (--nstack >= 0) { + w = EXT_POP(*pp_stack); + PyTuple_SET_ITEM(callargs, nstack, w); + } + return callargs; + } + + static PyObject * + load_args(PyObject ***pp_stack, int na) + { + PyObject *args = PyTuple_New(na); + PyObject *w; + + if (args == NULL) + return NULL; + while (--na >= 0) { + w = EXT_POP(*pp_stack); + PyTuple_SET_ITEM(args, na, w); + } + return args; + } + + static PyObject * + do_call(PyObject *func, PyObject ***pp_stack, int na, int nk) + { + PyObject *callargs = NULL; + PyObject *kwdict = NULL; + PyObject *result = NULL; + + if (nk > 0) { + kwdict = update_keyword_args(NULL, nk, pp_stack); + if (kwdict == NULL) + goto call_fail; + } + callargs = load_args(pp_stack, na); + if (callargs == NULL) + goto call_fail; + result = call_object(func, callargs, kwdict); + call_fail: + Py_XDECREF(callargs); + Py_XDECREF(kwdict); + return result; + } + + static PyObject * + ext_do_call(PyObject *func, PyObject ***pp_stack, int flags, int na, int nk) + { + int nstar = 0; + PyObject *callargs = NULL; + PyObject *stararg = NULL; + PyObject *kwdict = NULL; + PyObject *result = NULL; + + if (flags & CALL_FLAG_KW) { + kwdict = EXT_POP(*pp_stack); + if (!(kwdict && PyDict_Check(kwdict))) { + PyErr_SetString(PyExc_TypeError, + "** argument must be a dictionary"); + goto ext_call_fail; + } + } + if (flags & CALL_FLAG_VAR) { + stararg = EXT_POP(*pp_stack); + if (!PyTuple_Check(stararg)) { + PyObject *t = NULL; + t = PySequence_Tuple(stararg); + if (t == NULL) { + if (PyErr_ExceptionMatches(PyExc_TypeError)) { + PyErr_SetString(PyExc_TypeError, + "* argument must be a sequence"); + } + goto ext_call_fail; + } + Py_DECREF(stararg); + stararg = t; + } + nstar = PyTuple_GET_SIZE(stararg); + } + if (nk > 0) { + kwdict = update_keyword_args(kwdict, nk, pp_stack); + if (kwdict == NULL) + goto ext_call_fail; + } + callargs = update_star_args(na, nstar, stararg, pp_stack); + if (callargs == NULL) + goto ext_call_fail; + result = call_object(func, callargs, kwdict); + ext_call_fail: + Py_XDECREF(callargs); + Py_XDECREF(kwdict); + Py_XDECREF(stararg); return result; } From python-dev@python.org Wed Jan 3 23:53:33 2001 From: python-dev@python.org (Jeremy Hylton) Date: Wed, 03 Jan 2001 15:53:33 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b1.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv10768/Lib/test Modified Files: test_b1.py Log Message: Actually call the object with an __call__ method, instead of just checking if it is callable. This is the only place in the test suite where an __call__ method is called. Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** test_b1.py 2000/12/12 23:11:42 1.28 --- test_b1.py 2001/01/03 23:53:31 1.29 *************** *** 54,57 **** --- 54,58 ---- y = D() if not callable(y): raise TestFailed, 'callable(y)' + y() print 'chr' From python-dev@python.org Thu Jan 4 01:01:15 2001 From: python-dev@python.org (A.M. Kuchling) Date: Wed, 03 Jan 2001 17:01:15 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules fpectlmodule.c,2.12,2.13 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv16342 Modified Files: fpectlmodule.c Log Message: Patch #103012: Update fpectlmodule for current glibc; The _setfpucw() function/macro doesn't seem to exist any more; instead there's an _FPU_SETCW macro. Index: fpectlmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/fpectlmodule.c,v retrieving revision 2.12 retrieving revision 2.13 diff -C2 -r2.12 -r2.13 *** fpectlmodule.c 2000/09/21 14:32:04 2.12 --- fpectlmodule.c 2001/01/04 01:01:12 2.13 *************** *** 196,200 **** --- 196,207 ---- #include #endif + #ifdef _FPU_SETCW + { + fpu_control_t cw = 0x1372; + _FPU_SETCW(cw); + } + #else __setfpucw(0x1372); + #endif PyOS_setsig(SIGFPE, handler); From python-dev@python.org Thu Jan 4 01:25:52 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:25:52 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref3.tex,1.56,1.57 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv20476/Doc/ref Modified Files: ref3.tex Log Message: Document the NotImplemented object. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.56 retrieving revision 1.57 diff -C2 -r1.56 -r1.57 *** ref3.tex 2000/12/19 14:09:21 1.56 --- ref3.tex 2001/01/04 01:25:50 1.57 *************** *** 131,134 **** --- 131,143 ---- \obindex{None@{\texttt{None}}} + \item[NotImplemented] + This type has a single value. There is a single object with this value. + This object is accessed through the built-in name \code{NotImplemented}. + Binary number methods may return this value if they do not implement the + operation for the types of operands provided. The interpreter will then + try the reverse operation. Its truth value is true. + \ttindex{NotImplemented} + \obindex{NotImplemented@{\texttt{NotImplemented}}} + \item[Ellipsis] This type has a single value. There is a single object with this value. From python-dev@python.org Thu Jan 4 01:30:36 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:30:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Include classobject.h,2.33,2.34 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv21006/Include Modified Files: classobject.h Log Message: Remove PyInstance_*BinOp functions. Index: classobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/classobject.h,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -r2.33 -r2.34 *** classobject.h 2000/09/01 23:29:26 2.33 --- classobject.h 2001/01/04 01:30:34 2.34 *************** *** 60,71 **** extern DL_IMPORT(int) PyClass_IsSubclass(PyObject *, PyObject *); - extern DL_IMPORT(PyObject *) PyInstance_DoBinOp(PyObject *, PyObject *, - char *, char *, - PyObject * (*)(PyObject *, - PyObject *)); - - extern DL_IMPORT(int) - PyInstance_HalfBinOp(PyObject *, PyObject *, char *, PyObject **, - PyObject * (*)(PyObject *, PyObject *), int); #ifdef __cplusplus --- 60,63 ---- From python-dev@python.org Thu Jan 4 01:31:52 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:31:52 -0800 Subject: [Python-checkins] CVS: python/dist/src/Include object.h,2.66,2.67 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv21148/Include Modified Files: object.h Log Message: - Add nb_cmp slot for new style nubmers. - Define type flag for new style numbers. - Add Py_NotImplemented. Index: object.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/object.h,v retrieving revision 2.66 retrieving revision 2.67 diff -C2 -r2.66 -r2.67 *** object.h 2000/09/10 01:02:41 2.66 --- object.h 2001/01/04 01:31:50 2.67 *************** *** 120,123 **** --- 120,128 ---- typedef struct { + /* For old style numbers all arguments are guaranteed to be of the + object's type (modulo coercion hacks that is); new style numbers + should check both arguments for proper type and implement the + necessary conversions in the slots themselves. */ + binaryfunc nb_add; binaryfunc nb_subtract; *************** *** 154,157 **** --- 159,168 ---- binaryfunc nb_inplace_xor; binaryfunc nb_inplace_or; + + /* New style number slots; these are only used the + Py_TPFLAGS_NEWSTYLENUMBER flag is set */ + + binaryfunc nb_cmp; /* XXX this should be richcmpfunc */ + } PyNumberMethods; *************** *** 323,326 **** --- 334,340 ---- #define Py_TPFLAGS_HAVE_INPLACEOPS (1L<<3) + /* PyNumberMethods do their own coercion */ + #define Py_TPFLAGS_NEWSTYLENUMBER (1L<<4) + #define Py_TPFLAGS_DEFAULT (Py_TPFLAGS_HAVE_GETCHARBUFFER | \ Py_TPFLAGS_HAVE_SEQUENCE_IN | \ *************** *** 435,438 **** --- 449,460 ---- #define Py_None (&_Py_NoneStruct) + /* + Py_NotImplemented is a singleton used to signal that an operation is + not implemented for a given type combination. + */ + + extern DL_IMPORT(PyObject) _Py_NotImplementedStruct; /* Don't use this directly */ + + #define Py_NotImplemented (&_Py_NotImplementedStruct) /* From python-dev@python.org Thu Jan 4 01:33:43 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:33:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b1.py,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21390/Lib/test Modified Files: test_b1.py Log Message: Numbers no longer compare smaller than all other types. Fix the only part of the testsuite that breaks. The old behavior may be restored. Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** test_b1.py 2001/01/03 23:53:31 1.29 --- test_b1.py 2001/01/04 01:33:41 1.30 *************** *** 61,64 **** --- 61,65 ---- if chr(97) != 'a': raise TestFailed, 'chr(97)' + # cmp print 'cmp' if cmp(-1, 1) != -1: raise TestFailed, 'cmp(-1, 1)' *************** *** 466,470 **** if map(None, Squares(3), Squares(2)) != [(0,0), (1,1), (4,None)]: raise TestFailed, 'map(None, Squares(3), Squares(2))' ! if map(max, Squares(3), Squares(2)) != [0, 1, None]: raise TestFailed, 'map(max, Squares(3), Squares(2))' --- 467,471 ---- if map(None, Squares(3), Squares(2)) != [(0,0), (1,1), (4,None)]: raise TestFailed, 'map(None, Squares(3), Squares(2))' ! if map(max, Squares(3), Squares(2)) != [0, 1, 4]: raise TestFailed, 'map(max, Squares(3), Squares(2))' From python-dev@python.org Thu Jan 4 01:34:54 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:34:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_compare.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv21553/Lib/test Modified Files: test_compare.py Log Message: __rcmp__ no longer gets called on instances. Remove the test for it. Index: test_compare.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_compare.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_compare.py 2001/01/03 02:13:26 1.2 --- test_compare.py 2001/01/04 01:34:52 1.3 *************** *** 30,46 **** return cmp(self.arg, other) - class RCmp: - def __init__(self,arg): - self.arg = arg ! def __repr__(self): ! return '' % self.arg ! ! def __rcmp__(self, other): ! return cmp(other, self.arg) ! ! ! candidates = [2, 2.0, 2L, 2+0j, [1], (3,), None, Empty(), Coerce(2), ! Cmp(2.0), RCmp(2L)] def test(): --- 30,35 ---- return cmp(self.arg, other) ! candidates = [2, 2.0, 2L, 2+0j, [1], (3,), None, Empty(), Coerce(2), Cmp(2.0)] def test(): From python-dev@python.org Thu Jan 4 01:36:27 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:36:27 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_coercion,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv21710/Lib/test/output Modified Files: test_coercion Log Message: Sequence repeat works now for in-place multiply with an integer type as the left operand. I don't know if this is a feature or a bug. Index: test_coercion =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_coercion,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_coercion 2001/01/03 01:52:11 1.2 --- test_coercion 2001/01/04 01:36:25 1.3 *************** *** 53,57 **** 2 -= [1] ... exceptions.TypeError 2 * [1] = [1, 1] ! 2 *= [1] ... exceptions.TypeError 2 / [1] ... exceptions.TypeError 2 /= [1] ... exceptions.TypeError --- 53,57 ---- 2 -= [1] ... exceptions.TypeError 2 * [1] = [1, 1] ! 2 *= [1] => [1, 1] 2 / [1] ... exceptions.TypeError 2 /= [1] ... exceptions.TypeError *************** *** 65,69 **** 2 -= (2,) ... exceptions.TypeError 2 * (2,) = (2, 2) ! 2 *= (2,) ... exceptions.TypeError 2 / (2,) ... exceptions.TypeError 2 /= (2,) ... exceptions.TypeError --- 65,69 ---- 2 -= (2,) ... exceptions.TypeError 2 * (2,) = (2, 2) ! 2 *= (2,) => (2, 2) 2 / (2,) ... exceptions.TypeError 2 /= (2,) ... exceptions.TypeError *************** *** 269,273 **** 2 -= [1] ... exceptions.TypeError 2 * [1] = [1, 1] ! 2 *= [1] ... exceptions.TypeError 2 / [1] ... exceptions.TypeError 2 /= [1] ... exceptions.TypeError --- 269,273 ---- 2 -= [1] ... exceptions.TypeError 2 * [1] = [1, 1] ! 2 *= [1] => [1, 1] 2 / [1] ... exceptions.TypeError 2 /= [1] ... exceptions.TypeError *************** *** 281,285 **** 2 -= (2,) ... exceptions.TypeError 2 * (2,) = (2, 2) ! 2 *= (2,) ... exceptions.TypeError 2 / (2,) ... exceptions.TypeError 2 /= (2,) ... exceptions.TypeError --- 281,285 ---- 2 -= (2,) ... exceptions.TypeError 2 * (2,) = (2, 2) ! 2 *= (2,) => (2, 2) 2 / (2,) ... exceptions.TypeError 2 /= (2,) ... exceptions.TypeError From python-dev@python.org Thu Jan 4 01:36:52 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:36:52 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_compare,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv21763/Lib/test/output Modified Files: test_compare Log Message: No more RCmp. Index: test_compare =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_compare,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** test_compare 2001/01/03 02:13:26 1.2 --- test_compare 2001/01/04 01:36:50 1.3 *************** *** 10,14 **** 2 == 2 == - 2 != 2.0 == 2 2.0 == 2.0 --- 10,13 ---- *************** *** 21,25 **** 2.0 == 2.0 == - 2.0 != 2 == 2 2 == 2.0 --- 20,23 ---- *************** *** 32,36 **** 2 == 2 == - 2 != (2+0j) == 2 (2+0j) == 2.0 --- 30,33 ---- *************** *** 43,47 **** (2+0j) == (2+0j) == - (2+0j) != [1] != 2 [1] != 2.0 --- 40,43 ---- *************** *** 54,58 **** [1] != [1] != - [1] != (3,) != 2 (3,) != 2.0 --- 50,53 ---- *************** *** 65,69 **** (3,) != (3,) != - (3,) != None != 2 None != 2.0 --- 60,63 ---- *************** *** 76,80 **** None != None != - None != != 2 != 2.0 --- 70,73 ---- *************** *** 87,91 **** != != - != == 2 == 2.0 --- 80,83 ---- *************** *** 97,102 **** != == ! != ! == == 2 == 2.0 --- 89,93 ---- != == ! == == 2 == 2.0 *************** *** 109,122 **** == == - != - != 2 - != 2.0 - != 2 - != (2+0j) - != [1] - != (3,) - != None - != - != - != - == --- 100,101 ---- From python-dev@python.org Thu Jan 4 01:39:08 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:39:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects abstract.c,2.55,2.56 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv21963/Objects Modified Files: abstract.c Log Message: Massive changes as per PEP 208. Read it for details. Index: abstract.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/abstract.c,v retrieving revision 2.55 retrieving revision 2.56 diff -C2 -r2.55 -r2.56 *** abstract.c 2000/10/05 12:43:25 2.55 --- abstract.c 2001/01/04 01:39:06 2.56 *************** *** 1,6 **** --- 1,11 ---- /* Abstract Object Interface (many thanks to Jim Fulton) */ + #include "Python.h" #include + #include "structmember.h" /* we need the offsetof() macro from there */ + + #define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \ + Py_TPFLAGS_NEWSTYLENUMBER) [...1222 lines suppressed...] else if (PyUnicode_Check(v)) return PyUnicode_Format(v, w); else ! return binary_iop(v, w, NB_SLOT(nb_inplace_remainder), ! NB_SLOT(nb_remainder), "%="); } + PyObject * PyNumber_InPlacePower(PyObject *v, PyObject *w, PyObject *z) { ! if (HASINPLACE(v) && v->ob_type->tp_as_number && ! v->ob_type->tp_as_number->nb_inplace_power != NULL) { ! return ternary_op(v, w, z, NB_SLOT(nb_inplace_power), "**="); ! } ! else { ! return ternary_op(v, w, z, NB_SLOT(nb_power), "**="); ! } } From python-dev@python.org Thu Jan 4 01:43:48 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:43:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects classobject.c,2.112,2.113 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22355/Objects Modified Files: classobject.c Log Message: Make instances a new style number type. See PEP 208 for details. Instance types no longer get special treatment from abstract.c so more number number methods have to be implemented. Index: classobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/classobject.c,v retrieving revision 2.112 retrieving revision 2.113 diff -C2 -r2.112 -r2.113 *** classobject.c 2000/10/24 19:57:45 2.112 --- classobject.c 2001/01/04 01:43:46 2.113 *************** *** 5,8 **** --- 5,9 ---- #include "structmember.h" + /* Forward */ static PyObject *class_lookup(PyClassObject *, PyObject *, *************** *** 756,789 **** } - static PyObject * - instance_compare1(PyObject *inst, PyObject *other) - { - return PyInstance_DoBinOp(inst, other, "__cmp__", "__rcmp__", - instance_compare1); - } - - static int - instance_compare(PyObject *inst, PyObject *other) - { - PyObject *result; - long outcome; - result = instance_compare1(inst, other); - if (result == NULL) - return -1; - if (!PyInt_Check(result)) { - Py_DECREF(result); - PyErr_SetString(PyExc_TypeError, - "comparison did not return an int"); - return -1; - } - outcome = PyInt_AsLong(result); - Py_DECREF(result); - if (outcome < 0) - return -1; - else if (outcome > 0) - return 1; - return 0; - } - static long instance_hash(PyInstanceObject *inst) --- 757,760 ---- *************** *** 1185,1302 **** return res; } - ! /* Implement a binary operator involving at least one class instance. */ ! ! PyObject * ! PyInstance_DoBinOp(PyObject *v, PyObject *w, char *opname, char *ropname, ! PyObject * (*thisfunc)(PyObject *, PyObject *)) { ! char buf[256]; ! PyObject *result = NULL; ! ! if (PyInstance_HalfBinOp(v, w, opname, &result, thisfunc, 0) <= 0) ! return result; ! if (PyInstance_HalfBinOp(w, v, ropname, &result, thisfunc, 1) <= 0) ! return result; ! /* Sigh -- special case for comparisons */ ! if (strcmp(opname, "__cmp__") == 0) { ! Py_uintptr_t iv = (Py_uintptr_t)v; ! Py_uintptr_t iw = (Py_uintptr_t)w; ! long c = (iv < iw) ? -1 : (iv > iw) ? 1 : 0; ! return PyInt_FromLong(c); } ! sprintf(buf, "%s nor %s defined for these operands", opname, ropname); ! PyErr_SetString(PyExc_TypeError, buf); ! return NULL; } - /* Try one half of a binary operator involving a class instance. - Return value: - -1 if an exception is to be reported right away - 0 if we have a valid result - 1 if we could try another operation - */ - static PyObject *coerce_obj; ! int ! PyInstance_HalfBinOp(PyObject *v, PyObject *w, char *opname, PyObject **r_result, ! PyObject * (*thisfunc)(PyObject *, PyObject *), int swapped) { - PyObject *func; PyObject *args; PyObject *coercefunc; PyObject *coerced = NULL; PyObject *v1; ! if (!PyInstance_Check(v)) ! return 1; if (coerce_obj == NULL) { coerce_obj = PyString_InternFromString("__coerce__"); if (coerce_obj == NULL) ! return -1; } coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { PyErr_Clear(); } ! else { ! args = Py_BuildValue("(O)", w); ! if (args == NULL) { ! return -1; ! } ! coerced = PyEval_CallObject(coercefunc, args); ! Py_DECREF(args); ! Py_DECREF(coercefunc); ! if (coerced == NULL) { ! return -1; ! } ! if (coerced == Py_None) { ! Py_DECREF(coerced); ! return 1; ! } ! if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { ! Py_DECREF(coerced); ! PyErr_SetString(PyExc_TypeError, ! "coercion should return None or 2-tuple"); ! return -1; ! } ! v1 = PyTuple_GetItem(coerced, 0); ! w = PyTuple_GetItem(coerced, 1); ! if (v1 != v) { ! v = v1; ! if (!PyInstance_Check(v) && !PyInstance_Check(w)) { ! if (swapped) ! *r_result = (*thisfunc)(w, v); ! else ! *r_result = (*thisfunc)(v, w); ! Py_DECREF(coerced); ! return *r_result == NULL ? -1 : 0; ! } ! } ! } ! func = PyObject_GetAttrString(v, opname); ! if (func == NULL) { ! Py_XDECREF(coerced); ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return -1; ! PyErr_Clear(); ! return 1; ! } args = Py_BuildValue("(O)", w); if (args == NULL) { ! Py_DECREF(func); ! Py_XDECREF(coerced); ! return -1; } ! *r_result = PyEval_CallObject(func, args); Py_DECREF(args); ! Py_DECREF(func); ! Py_XDECREF(coerced); ! return *r_result == NULL ? -1 : 0; } static int instance_coerce(PyObject **pv, PyObject **pw) --- 1156,1275 ---- return res; } ! static PyObject * ! generic_binary_op(PyObject *v, PyObject *w, char *opname) { ! PyObject *result; ! PyObject *args; ! PyObject *func = PyObject_GetAttrString(v, opname); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! Py_INCREF(Py_NotImplemented); ! return Py_NotImplemented; } ! args = Py_BuildValue("(O)", w); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); ! Py_DECREF(args); ! Py_DECREF(func); ! return result; } static PyObject *coerce_obj; ! /* Try one half of a binary operator involving a class instance. */ ! static PyObject * ! half_binop(PyObject *v, PyObject *w, char *opname, binaryfunc thisfunc, ! int swapped) { PyObject *args; PyObject *coercefunc; PyObject *coerced = NULL; PyObject *v1; + PyObject *result; ! if (!PyInstance_Check(v)) { ! Py_INCREF(Py_NotImplemented); ! return Py_NotImplemented; ! } ! if (coerce_obj == NULL) { coerce_obj = PyString_InternFromString("__coerce__"); if (coerce_obj == NULL) ! return NULL; } coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { PyErr_Clear(); + return generic_binary_op(v, w, opname); } ! args = Py_BuildValue("(O)", w); if (args == NULL) { ! return NULL; } ! coerced = PyEval_CallObject(coercefunc, args); Py_DECREF(args); ! Py_DECREF(coercefunc); ! if (coerced == NULL) { ! return NULL; ! } ! if (coerced == Py_None || coerced == Py_NotImplemented) { ! Py_DECREF(coerced); ! return generic_binary_op(v, w, opname); ! } ! if (!PyTuple_Check(coerced) || PyTuple_Size(coerced) != 2) { ! Py_DECREF(coerced); ! PyErr_SetString(PyExc_TypeError, ! "coercion should return None or 2-tuple"); ! return NULL; ! } ! v1 = PyTuple_GetItem(coerced, 0); ! w = PyTuple_GetItem(coerced, 1); ! if (v1 == v) { ! /* prevent recursion if __coerce__ returns self as the first ! * argument */ ! result = generic_binary_op(v, w, opname); ! } else { ! if (swapped) ! result = (thisfunc)(w, v1); ! else ! result = (thisfunc)(v1, w); ! } ! Py_DECREF(coerced); ! return result; ! } ! ! /* Implement a binary operator involving at least one class instance. */ ! static PyObject * ! do_binop(PyObject *v, PyObject *w, char *opname, char *ropname, ! binaryfunc thisfunc) ! { ! PyObject *result = half_binop(v, w, opname, thisfunc, 0); ! if (result == Py_NotImplemented) { ! Py_DECREF(Py_NotImplemented); ! result = half_binop(w, v, ropname, thisfunc, 1); ! } ! return result; } + static PyObject * + do_binop_inplace(PyObject *v, PyObject *w, char *iopname, char *opname, + char *ropname, binaryfunc thisfunc) + { + PyObject *result = half_binop(v, w, iopname, thisfunc, 0); + if (result == Py_NotImplemented) { + Py_DECREF(Py_NotImplemented); + result = do_binop(v, w, opname, ropname, thisfunc); + } + return result; + } + static int instance_coerce(PyObject **pv, PyObject **pw) *************** *** 1315,1323 **** coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { ! /* No __coerce__ method: always OK */ PyErr_Clear(); Py_INCREF(v); Py_INCREF(w); ! return 0; } /* Has __coerce__ method: call it */ --- 1288,1296 ---- coercefunc = PyObject_GetAttr(v, coerce_obj); if (coercefunc == NULL) { ! /* No __coerce__ method */ PyErr_Clear(); Py_INCREF(v); Py_INCREF(w); ! return 1; } /* Has __coerce__ method: call it */ *************** *** 1333,1337 **** return -1; } ! if (coerced == Py_None) { /* __coerce__ says "I can't do it" */ Py_DECREF(coerced); --- 1306,1310 ---- return -1; } ! if (coerced == Py_None || coerced == Py_NotImplemented) { /* __coerce__ says "I can't do it" */ Py_DECREF(coerced); *************** *** 1354,1358 **** } - #define UNARY(funcname, methodname) \ static PyObject *funcname(PyInstanceObject *self) { \ --- 1327,1330 ---- *************** *** 1362,1370 **** --- 1334,1434 ---- } + #define BINARY(f, m, n) \ + static PyObject *f(PyObject *v, PyObject *w) { \ + return do_binop(v, w, "__" m "__", "__r" m "__", n); \ + } + + #define BINARY_INPLACE(f, m, n) \ + static PyObject *f(PyObject *v, PyObject *w) { \ + return do_binop_inplace(v, w, "__i" m "__", "__" m "__", \ + "__r" m "__", n); \ + } + UNARY(instance_neg, "__neg__") UNARY(instance_pos, "__pos__") UNARY(instance_abs, "__abs__") + BINARY(instance_or, "or", PyNumber_Or) + BINARY(instance_and, "and", PyNumber_And) + BINARY(instance_xor, "xor", PyNumber_Xor) + BINARY(instance_lshift, "lshift", PyNumber_Lshift) + BINARY(instance_rshift, "rshift", PyNumber_Rshift) + BINARY(instance_add, "add", PyNumber_Add) + BINARY(instance_sub, "sub", PyNumber_Subtract) + BINARY(instance_mul, "mul", PyNumber_Multiply) + BINARY(instance_div, "div", PyNumber_Divide) + BINARY(instance_mod, "mod", PyNumber_Remainder) + BINARY(instance_divmod, "divmod", PyNumber_Divmod) + + BINARY_INPLACE(instance_ior, "or", PyNumber_InPlaceOr) + BINARY_INPLACE(instance_ixor, "xor", PyNumber_InPlaceXor) + BINARY_INPLACE(instance_iand, "and", PyNumber_InPlaceAnd) + BINARY_INPLACE(instance_ilshift, "lshift", PyNumber_InPlaceLshift) + BINARY_INPLACE(instance_irshift, "rshift", PyNumber_InPlaceRshift) + BINARY_INPLACE(instance_iadd, "add", PyNumber_InPlaceAdd) + BINARY_INPLACE(instance_isub, "sub", PyNumber_InPlaceSubtract) + BINARY_INPLACE(instance_imul, "mul", PyNumber_InPlaceMultiply) + BINARY_INPLACE(instance_idiv, "div", PyNumber_InPlaceDivide) + BINARY_INPLACE(instance_imod, "mod", PyNumber_InPlaceRemainder) + + static PyObject * + do_cmp(PyObject *v, PyObject *w) + { + int cmp = PyObject_Compare(v, w); + if (PyErr_Occurred()) { + return NULL; + } + return PyInt_FromLong(cmp); + } + + static PyObject * + instance_cmp(PyObject *v, PyObject *w) + { + PyObject *result = half_binop(v, w, "__cmp__", do_cmp, 0); + if (result == Py_NotImplemented) { + Py_DECREF(Py_NotImplemented); + /* __rcmp__ is not called on instances, instead they + * automaticly reverse the arguments and return the negative of + * __cmp__ if it exists */ + result = half_binop(w, v, "__cmp__", do_cmp, 0); + + if (result != Py_NotImplemented && result != NULL) { + PyObject *r = PyNumber_Negative(result); + Py_DECREF(result); + result = r; + } + } + return result; + } + static int + instance_compare(PyObject *inst, PyObject *other) + { + PyObject *result; + long outcome; + result = instance_cmp(inst, other); + if (result == NULL) { + return -1; + } + if (result == Py_NotImplemented) { + Py_DECREF(result); + return -1; + } + if (!PyInt_Check(result)) { + Py_DECREF(result); + PyErr_SetString(PyExc_TypeError, + "comparison did not return an int"); + return -1; + } + outcome = PyInt_AsLong(result); + Py_DECREF(result); + if (outcome < 0) + return -1; + else if (outcome > 0) + return 1; + return 0; + } + + static int instance_nonzero(PyInstanceObject *self) { *************** *** 1413,1479 **** UNARY(instance_hex, "__hex__") /* This version is for ternary calls only (z != None) */ static PyObject * instance_pow(PyObject *v, PyObject *w, PyObject *z) ! { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! static PyObject *powstr; ! if (powstr == NULL) ! powstr = PyString_InternFromString("__pow__"); ! func = PyObject_GetAttr(v, powstr); ! if (func == NULL) ! return NULL; ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { Py_DECREF(func); ! return NULL; } - result = PyEval_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; } static PyObject * ! instance_inplace_pow(PyObject *v, PyObject *w, PyObject *z) { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! static PyObject *ipowstr; ! if (ipowstr == NULL) ! ipowstr = PyString_InternFromString("__ipow__"); ! func = PyObject_GetAttr(v, ipowstr); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! return instance_pow(v, w, z); } ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { Py_DECREF(func); ! return NULL; } - result = PyEval_CallObject(func, args); - Py_DECREF(func); - Py_DECREF(args); - return result; } static PyNumberMethods instance_as_number = { ! 0, /*nb_add*/ ! 0, /*nb_subtract*/ ! 0, /*nb_multiply*/ ! 0, /*nb_divide*/ ! 0, /*nb_remainder*/ ! 0, /*nb_divmod*/ (ternaryfunc)instance_pow, /*nb_power*/ (unaryfunc)instance_neg, /*nb_negative*/ --- 1477,1562 ---- UNARY(instance_hex, "__hex__") + static PyObject * + bin_power(PyObject *v, PyObject *w) + { + return PyNumber_Power(v, w, Py_None); + } + /* This version is for ternary calls only (z != None) */ static PyObject * instance_pow(PyObject *v, PyObject *w, PyObject *z) ! { ! if (z == Py_None) { ! return do_binop(v, w, "__pow__", "__rpow__", bin_power); ! } ! else { ! PyObject *func; ! PyObject *args; ! PyObject *result; ! /* XXX Doesn't do coercions... */ ! func = PyObject_GetAttrString(v, "__pow__"); ! if (func == NULL) ! return NULL; ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); Py_DECREF(func); ! Py_DECREF(args); ! return result; } } static PyObject * ! bin_inplace_power(PyObject *v, PyObject *w) { ! return PyNumber_InPlacePower(v, w, Py_None); ! } ! ! static PyObject * ! instance_ipow(PyObject *v, PyObject *w, PyObject *z) ! { ! if (z == Py_None) { ! return do_binop_inplace(v, w, "__ipow__", "__pow__", ! "__rpow__", bin_inplace_power); } ! else { ! /* XXX Doesn't do coercions... */ ! PyObject *func; ! PyObject *args; ! PyObject *result; ! ! func = PyObject_GetAttrString(v, "__ipow__"); ! if (func == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return NULL; ! PyErr_Clear(); ! return instance_pow(v, w, z); ! } ! args = Py_BuildValue("(OO)", w, z); ! if (args == NULL) { ! Py_DECREF(func); ! return NULL; ! } ! result = PyEval_CallObject(func, args); Py_DECREF(func); ! Py_DECREF(args); ! return result; } } + static PyNumberMethods instance_as_number = { ! (binaryfunc)instance_add, /*nb_add*/ ! (binaryfunc)instance_sub, /*nb_subtract*/ ! (binaryfunc)instance_mul, /*nb_multiply*/ ! (binaryfunc)instance_div, /*nb_divide*/ ! (binaryfunc)instance_mod, /*nb_remainder*/ ! (binaryfunc)instance_divmod, /*nb_divmod*/ (ternaryfunc)instance_pow, /*nb_power*/ (unaryfunc)instance_neg, /*nb_negative*/ *************** *** 1482,1490 **** (inquiry)instance_nonzero, /*nb_nonzero*/ (unaryfunc)instance_invert, /*nb_invert*/ ! 0, /*nb_lshift*/ ! 0, /*nb_rshift*/ ! 0, /*nb_and*/ ! 0, /*nb_xor*/ ! 0, /*nb_or*/ (coercion)instance_coerce, /*nb_coerce*/ (unaryfunc)instance_int, /*nb_int*/ --- 1565,1573 ---- (inquiry)instance_nonzero, /*nb_nonzero*/ (unaryfunc)instance_invert, /*nb_invert*/ ! (binaryfunc)instance_lshift, /*nb_lshift*/ ! (binaryfunc)instance_rshift, /*nb_rshift*/ ! (binaryfunc)instance_and, /*nb_and*/ ! (binaryfunc)instance_xor, /*nb_xor*/ ! (binaryfunc)instance_or, /*nb_or*/ (coercion)instance_coerce, /*nb_coerce*/ (unaryfunc)instance_int, /*nb_int*/ *************** *** 1493,1507 **** (unaryfunc)instance_oct, /*nb_oct*/ (unaryfunc)instance_hex, /*nb_hex*/ ! 0, /*nb_inplace_add*/ ! 0, /*nb_inplace_subtract*/ ! 0, /*nb_inplace_multiply*/ ! 0, /*nb_inplace_divide*/ ! 0, /*nb_inplace_remainder*/ ! (ternaryfunc)instance_inplace_pow, /*nb_inplace_power*/ ! 0, /*nb_inplace_lshift*/ ! 0, /*nb_inplace_rshift*/ ! 0, /*nb_inplace_and*/ ! 0, /*nb_inplace_xor*/ ! 0, /*nb_inplace_or*/ }; --- 1576,1591 ---- (unaryfunc)instance_oct, /*nb_oct*/ (unaryfunc)instance_hex, /*nb_hex*/ ! (binaryfunc)instance_iadd, /*nb_inplace_add*/ ! (binaryfunc)instance_isub, /*nb_inplace_subtract*/ ! (binaryfunc)instance_imul, /*nb_inplace_multiply*/ ! (binaryfunc)instance_idiv, /*nb_inplace_divide*/ ! (binaryfunc)instance_imod, /*nb_inplace_remainder*/ ! (ternaryfunc)instance_ipow, /*nb_inplace_power*/ ! (binaryfunc)instance_ilshift, /*nb_inplace_lshift*/ ! (binaryfunc)instance_irshift, /*nb_inplace_rshift*/ ! (binaryfunc)instance_iand, /*nb_inplace_and*/ ! (binaryfunc)instance_ixor, /*nb_inplace_xor*/ ! (binaryfunc)instance_ior, /*nb_inplace_or*/ ! (binaryfunc)instance_cmp, /*nb_cmp*/ }; *************** *** 1526,1531 **** (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)instance_traverse, /* tp_traverse */ --- 1610,1615 ---- (getattrofunc)instance_getattr, /*tp_getattro*/ (setattrofunc)instance_setattr, /*tp_setattro*/ ! 0, /* tp_as_buffer */ ! Py_TPFLAGS_DEFAULT | Py_TPFLAGS_GC | Py_TPFLAGS_NEWSTYLENUMBER, /*tp_flags*/ 0, /* tp_doc */ (traverseproc)instance_traverse, /* tp_traverse */ From python-dev@python.org Thu Jan 4 01:44:37 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:44:37 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.75,2.76 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22446/Objects Modified Files: floatobject.c Log Message: Make float a new style number type. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.75 retrieving revision 2.76 diff -C2 -r2.75 -r2.76 *** floatobject.c 2000/10/24 19:57:45 2.75 --- floatobject.c 2001/01/04 01:44:34 2.76 *************** *** 257,260 **** --- 257,292 ---- } + /* Macro and helper that convert PyObject obj to a C double and store + the value in dbl; this replaces the functionality of the coercion + slot function */ + + #define CONVERT_TO_DOUBLE(obj, dbl) \ + if (PyFloat_Check(obj)) \ + dbl = PyFloat_AS_DOUBLE(obj); \ + else if (convert_to_double(&(obj), &(dbl)) < 0) \ + return obj; + + 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(result) + } + else { + Py_INCREF(Py_NotImplemented); + *v = Py_NotImplemented; + return -1; + } + return 0; + } + /* Precisions used by repr() and str(), respectively. *************** *** 315,318 **** --- 347,359 ---- } + /* Needed for the new style number compare slots */ + static PyObject * + float_cmp(PyObject *v, PyObject *w) + { + double a,b; + CONVERT_TO_DOUBLE(v, a); + CONVERT_TO_DOUBLE(w, b); + return PyInt_FromLong((a < b) ? -1 : (a > b) ? 1 : 0); + } static long *************** *** 323,376 **** static PyObject * ! float_add(PyFloatObject *v, PyFloatObject *w) { ! double result; PyFPE_START_PROTECT("add", return 0) ! result = v->ob_fval + w->ob_fval; ! PyFPE_END_PROTECT(result) ! return PyFloat_FromDouble(result); } static PyObject * ! float_sub(PyFloatObject *v, PyFloatObject *w) { ! double result; PyFPE_START_PROTECT("subtract", return 0) ! result = v->ob_fval - w->ob_fval; ! PyFPE_END_PROTECT(result) ! return PyFloat_FromDouble(result); } static PyObject * ! float_mul(PyFloatObject *v, PyFloatObject *w) { ! double result; ! PyFPE_START_PROTECT("multiply", return 0) ! result = v->ob_fval * w->ob_fval; ! PyFPE_END_PROTECT(result) ! return PyFloat_FromDouble(result); } static PyObject * ! float_div(PyFloatObject *v, PyFloatObject *w) { ! double result; ! if (w->ob_fval == 0) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); return NULL; } PyFPE_START_PROTECT("divide", return 0) ! result = v->ob_fval / w->ob_fval; ! PyFPE_END_PROTECT(result) ! return PyFloat_FromDouble(result); } static PyObject * ! float_rem(PyFloatObject *v, PyFloatObject *w) { double vx, wx; double mod; ! wx = w->ob_fval; if (wx == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float modulo"); --- 364,425 ---- static PyObject * ! float_add(PyObject *v, PyObject *w) { ! double a,b; ! CONVERT_TO_DOUBLE(v, a); ! CONVERT_TO_DOUBLE(w, b); PyFPE_START_PROTECT("add", return 0) ! a = a + b; ! PyFPE_END_PROTECT(a) ! return PyFloat_FromDouble(a); } static PyObject * ! float_sub(PyObject *v, PyObject *w) { ! double a,b; ! CONVERT_TO_DOUBLE(v, a); ! CONVERT_TO_DOUBLE(w, b); PyFPE_START_PROTECT("subtract", return 0) ! a = a - b; ! PyFPE_END_PROTECT(a) ! return PyFloat_FromDouble(a); } static PyObject * ! float_mul(PyObject *v, PyObject *w) { ! double a,b; ! CONVERT_TO_DOUBLE(v, a); ! CONVERT_TO_DOUBLE(w, b); PyFPE_START_PROTECT("multiply", return 0) ! a = a * b; ! PyFPE_END_PROTECT(a) ! return PyFloat_FromDouble(a); } static PyObject * ! float_div(PyObject *v, PyObject *w) { ! double a,b; ! CONVERT_TO_DOUBLE(v, a); ! CONVERT_TO_DOUBLE(w, b); ! if (b == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float division"); return NULL; } PyFPE_START_PROTECT("divide", return 0) ! a = a / b; ! PyFPE_END_PROTECT(a) ! return PyFloat_FromDouble(a); } static PyObject * ! float_rem(PyObject *v, PyObject *w) { double vx, wx; double mod; ! CONVERT_TO_DOUBLE(v, vx); ! CONVERT_TO_DOUBLE(w, wx); if (wx == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float modulo"); *************** *** 378,382 **** } PyFPE_START_PROTECT("modulo", return 0) - vx = v->ob_fval; mod = fmod(vx, wx); /* note: checking mod*wx < 0 is incorrect -- underflows to --- 427,430 ---- *************** *** 390,398 **** static PyObject * ! float_divmod(PyFloatObject *v, PyFloatObject *w) { double vx, wx; double div, mod, floordiv; ! wx = w->ob_fval; if (wx == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); --- 438,447 ---- static PyObject * ! float_divmod(PyObject *v, PyObject *w) { double vx, wx; double div, mod, floordiv; ! CONVERT_TO_DOUBLE(v, vx); ! CONVERT_TO_DOUBLE(w, wx); if (wx == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, "float divmod()"); *************** *** 400,404 **** } PyFPE_START_PROTECT("divmod", return 0) - vx = v->ob_fval; mod = fmod(vx, wx); /* fmod is typically exact, so vx-mod is *mathematically* an --- 449,452 ---- *************** *** 438,442 **** static PyObject * ! float_pow(PyFloatObject *v, PyObject *w, PyFloatObject *z) { double iv, iw, ix; --- 486,490 ---- static PyObject * ! float_pow(PyObject *v, PyObject *w, PyObject *z) { double iv, iw, ix; *************** *** 447,452 **** * [AMK] */ ! iv = v->ob_fval; ! iw = ((PyFloatObject *)w)->ob_fval; intw = (long)iw; --- 495,500 ---- * [AMK] */ ! CONVERT_TO_DOUBLE(v, iv); ! CONVERT_TO_DOUBLE(w, iw); intw = (long)iw; *************** *** 455,461 **** PyFPE_START_PROTECT("pow", return NULL) if ((PyObject *)z != Py_None) { ! ix = fmod(1.0, z->ob_fval); ! if (ix != 0 && z->ob_fval < 0) ! ix += z->ob_fval; } else --- 503,510 ---- PyFPE_START_PROTECT("pow", return NULL) if ((PyObject *)z != Py_None) { ! double iz; ! CONVERT_TO_DOUBLE(w, iz); ! ix=fmod(1.0, iz); ! if (ix!=0 && iz<0) ix+=iz; } else *************** *** 502,514 **** } if ((PyObject *)z != Py_None) { ! PyFPE_START_PROTECT("pow", return NULL) ! ix = fmod(ix, z->ob_fval); /* XXX To Be Rewritten */ ! if (ix != 0 && ! ((iv < 0 && z->ob_fval > 0) || ! (iv > 0 && z->ob_fval < 0) ! )) { ! ix += z->ob_fval; } ! PyFPE_END_PROTECT(ix) } return PyFloat_FromDouble(ix); --- 551,562 ---- } 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); *************** *** 612,615 **** --- 660,677 ---- 0, /*nb_oct*/ 0, /*nb_hex*/ + 0, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_divide*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + + /* New style slots: */ + (binaryfunc)float_cmp, /*nb_cmp*/ }; *************** *** 632,635 **** --- 694,701 ---- 0, /*tp_call*/ (reprfunc)float_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_NEWSTYLENUMBER /*tp_flags*/ }; From python-dev@python.org Thu Jan 4 01:45:35 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:45:35 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects intobject.c,2.53,2.54 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22541/Objects Modified Files: intobject.c Log Message: Make int a new style number type. Sequence repeat is now done here now as well. Index: intobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/intobject.c,v retrieving revision 2.53 retrieving revision 2.54 diff -C2 -r2.53 -r2.54 *** intobject.c 2000/10/24 19:57:45 2.53 --- intobject.c 2001/01/04 01:45:33 2.54 *************** *** 220,223 **** --- 220,236 ---- /* Methods */ + /* Integers are seen as the "smallest" of all numeric types and thus + don't have any knowledge about conversion of other types to + integers. */ + + #define CONVERT_TO_LONG(obj, lng) \ + if (PyInt_Check(obj)) { \ + lng = PyInt_AS_LONG(obj); \ + } \ + else { \ + Py_INCREF(Py_NotImplemented); \ + return Py_NotImplemented; \ + } + /* ARGSUSED */ static int *************** *** 245,248 **** --- 258,271 ---- } + /* Needed for the new style number compare slots */ + static PyObject * + int_cmp(PyObject *v, PyObject *w) + { + register long a, b; + CONVERT_TO_LONG(v, a); + CONVERT_TO_LONG(w, b); + return PyInt_FromLong((a < b) ? -1 : (a > b) ? 1 : 0); + } + static long int_hash(PyIntObject *v) *************** *** 260,265 **** { register long a, b, x; ! a = v->ob_ival; ! b = w->ob_ival; x = a + b; if ((x^a) < 0 && (x^b) < 0) --- 283,288 ---- { register long a, b, x; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); x = a + b; if ((x^a) < 0 && (x^b) < 0) *************** *** 272,277 **** { register long a, b, x; ! a = v->ob_ival; ! b = w->ob_ival; x = a - b; if ((x^a) < 0 && (x^~b) < 0) --- 295,300 ---- { register long a, b, x; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); x = a - b; if ((x^a) < 0 && (x^~b) < 0) *************** *** 310,320 **** static PyObject * ! int_mul(PyIntObject *v, PyIntObject *w) { long a, b, ah, bh, x, y; int s = 1; ! a = v->ob_ival; ! b = w->ob_ival; ah = a >> (LONG_BIT/2); bh = b >> (LONG_BIT/2); --- 333,356 ---- static PyObject * ! int_mul(PyObject *v, PyObject *w) { long a, b, ah, bh, x, y; int s = 1; ! if (v->ob_type->tp_as_sequence && ! v->ob_type->tp_as_sequence->sq_repeat) { ! /* sequence * int */ ! a = PyInt_AsLong(w); ! return (*v->ob_type->tp_as_sequence->sq_repeat)(v, a); ! } ! else if (w->ob_type->tp_as_sequence && ! w->ob_type->tp_as_sequence->sq_repeat) { ! /* int * sequence */ ! a = PyInt_AsLong(v); ! return (*w->ob_type->tp_as_sequence->sq_repeat)(w, a); ! } ! ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); ah = a >> (LONG_BIT/2); bh = b >> (LONG_BIT/2); *************** *** 409,417 **** static int ! i_divmod(register PyIntObject *x, register PyIntObject *y, long *p_xdivy, long *p_xmody) { - long xi = x->ob_ival; - long yi = y->ob_ival; long xdivy, xmody; --- 445,451 ---- static int ! i_divmod(register long xi, register long yi, long *p_xdivy, long *p_xmody) { long xdivy, xmody; *************** *** 452,457 **** int_div(PyIntObject *x, PyIntObject *y) { long d, m; ! if (i_divmod(x, y, &d, &m) < 0) return NULL; return PyInt_FromLong(d); --- 486,494 ---- int_div(PyIntObject *x, PyIntObject *y) { + long xi, yi; long d, m; ! CONVERT_TO_LONG(x, xi); ! CONVERT_TO_LONG(y, yi); ! if (i_divmod(xi, yi, &d, &m) < 0) return NULL; return PyInt_FromLong(d); *************** *** 461,466 **** int_mod(PyIntObject *x, PyIntObject *y) { long d, m; ! if (i_divmod(x, y, &d, &m) < 0) return NULL; return PyInt_FromLong(m); --- 498,506 ---- int_mod(PyIntObject *x, PyIntObject *y) { + long xi, yi; long d, m; ! CONVERT_TO_LONG(x, xi); ! CONVERT_TO_LONG(y, yi); ! if (i_divmod(xi, yi, &d, &m) < 0) return NULL; return PyInt_FromLong(m); *************** *** 470,475 **** int_divmod(PyIntObject *x, PyIntObject *y) { long d, m; ! if (i_divmod(x, y, &d, &m) < 0) return NULL; return Py_BuildValue("(ll)", d, m); --- 510,518 ---- int_divmod(PyIntObject *x, PyIntObject *y) { + long xi, yi; long d, m; ! CONVERT_TO_LONG(x, xi); ! CONVERT_TO_LONG(y, yi); ! if (i_divmod(xi, yi, &d, &m) < 0) return NULL; return Py_BuildValue("(ll)", d, m); *************** *** 481,486 **** #if 1 register long iv, iw, iz=0, ix, temp, prev; ! iv = v->ob_ival; ! iw = w->ob_ival; if (iw < 0) { if (iv) --- 524,529 ---- #if 1 register long iv, iw, iz=0, ix, temp, prev; ! CONVERT_TO_LONG(v, iv); ! CONVERT_TO_LONG(w, iw); if (iw < 0) { if (iv) *************** *** 493,497 **** } if ((PyObject *)z != Py_None) { ! iz = z->ob_ival; if (iz == 0) { PyErr_SetString(PyExc_ValueError, --- 536,540 ---- } if ((PyObject *)z != Py_None) { ! CONVERT_TO_LONG(z, iz); if (iz == 0) { PyErr_SetString(PyExc_ValueError, *************** *** 532,549 **** } if (iz) { ! PyObject *t1, *t2; ! long int div, mod; ! t1=PyInt_FromLong(ix); ! t2=PyInt_FromLong(iz); ! if (t1==NULL || t2==NULL || ! i_divmod((PyIntObject *)t1, ! (PyIntObject *)t2, &div, &mod)<0) ! { ! Py_XDECREF(t1); ! Py_XDECREF(t2); return(NULL); - } - Py_DECREF(t1); - Py_DECREF(t2); ix=mod; } --- 575,581 ---- } if (iz) { ! long div, mod; ! if (i_divmod(ix, iz, &div, &mod) < 0) return(NULL); ix=mod; } *************** *** 551,556 **** #else register long iv, iw, ix; ! iv = v->ob_ival; ! iw = w->ob_ival; if (iw < 0) { PyErr_SetString(PyExc_ValueError, --- 583,588 ---- #else register long iv, iw, ix; ! CONVERT_TO_LONG(v, iv); ! CONVERT_TO_LONG(w, iw); if (iw < 0) { PyErr_SetString(PyExc_ValueError, *************** *** 619,624 **** { register long a, b; ! a = v->ob_ival; ! b = w->ob_ival; if (b < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); --- 651,656 ---- { register long a, b; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); if (b < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); *************** *** 640,645 **** { register long a, b; ! a = v->ob_ival; ! b = w->ob_ival; if (b < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); --- 672,677 ---- { register long a, b; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); if (b < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); *************** *** 666,671 **** { register long a, b; ! a = v->ob_ival; ! b = w->ob_ival; return PyInt_FromLong(a & b); } --- 698,703 ---- { register long a, b; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); return PyInt_FromLong(a & b); } *************** *** 675,680 **** { register long a, b; ! a = v->ob_ival; ! b = w->ob_ival; return PyInt_FromLong(a ^ b); } --- 707,712 ---- { register long a, b; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); return PyInt_FromLong(a ^ b); } *************** *** 684,689 **** { register long a, b; ! a = v->ob_ival; ! b = w->ob_ival; return PyInt_FromLong(a | b); } --- 716,721 ---- { register long a, b; ! CONVERT_TO_LONG(v, a); ! CONVERT_TO_LONG(w, b); return PyInt_FromLong(a | b); } *************** *** 730,756 **** static PyNumberMethods int_as_number = { ! (binaryfunc)int_add, /*nb_add*/ ! (binaryfunc)int_sub, /*nb_subtract*/ ! (binaryfunc)int_mul, /*nb_multiply*/ ! (binaryfunc)int_div, /*nb_divide*/ ! (binaryfunc)int_mod, /*nb_remainder*/ ! (binaryfunc)int_divmod, /*nb_divmod*/ ! (ternaryfunc)int_pow, /*nb_power*/ ! (unaryfunc)int_neg, /*nb_negative*/ ! (unaryfunc)int_pos, /*nb_positive*/ ! (unaryfunc)int_abs, /*nb_absolute*/ ! (inquiry)int_nonzero, /*nb_nonzero*/ ! (unaryfunc)int_invert, /*nb_invert*/ ! (binaryfunc)int_lshift, /*nb_lshift*/ ! (binaryfunc)int_rshift, /*nb_rshift*/ ! (binaryfunc)int_and, /*nb_and*/ ! (binaryfunc)int_xor, /*nb_xor*/ ! (binaryfunc)int_or, /*nb_or*/ ! 0, /*nb_coerce*/ ! (unaryfunc)int_int, /*nb_int*/ ! (unaryfunc)int_long, /*nb_long*/ ! (unaryfunc)int_float, /*nb_float*/ ! (unaryfunc)int_oct, /*nb_oct*/ ! (unaryfunc)int_hex, /*nb_hex*/ }; --- 762,802 ---- static PyNumberMethods int_as_number = { ! (binaryfunc)int_add, /*nb_add*/ ! (binaryfunc)int_sub, /*nb_subtract*/ ! (binaryfunc)int_mul, /*nb_multiply*/ ! (binaryfunc)int_div, /*nb_divide*/ ! (binaryfunc)int_mod, /*nb_remainder*/ ! (binaryfunc)int_divmod, /*nb_divmod*/ ! (ternaryfunc)int_pow, /*nb_power*/ ! (unaryfunc)int_neg, /*nb_negative*/ ! (unaryfunc)int_pos, /*nb_positive*/ ! (unaryfunc)int_abs, /*nb_absolute*/ ! (inquiry)int_nonzero, /*nb_nonzero*/ ! (unaryfunc)int_invert, /*nb_invert*/ ! (binaryfunc)int_lshift, /*nb_lshift*/ ! (binaryfunc)int_rshift, /*nb_rshift*/ ! (binaryfunc)int_and, /*nb_and*/ ! (binaryfunc)int_xor, /*nb_xor*/ ! (binaryfunc)int_or, /*nb_or*/ ! 0, /*nb_coerce*/ ! (unaryfunc)int_int, /*nb_int*/ ! (unaryfunc)int_long, /*nb_long*/ ! (unaryfunc)int_float, /*nb_float*/ ! (unaryfunc)int_oct, /*nb_oct*/ ! (unaryfunc)int_hex, /*nb_hex*/ ! 0, /*nb_inplace_add*/ ! 0, /*nb_inplace_subtract*/ ! 0, /*nb_inplace_multiply*/ ! 0, /*nb_inplace_divide*/ ! 0, /*nb_inplace_remainder*/ ! 0, /*nb_inplace_power*/ ! 0, /*nb_inplace_lshift*/ ! 0, /*nb_inplace_rshift*/ ! 0, /*nb_inplace_and*/ ! 0, /*nb_inplace_xor*/ ! 0, /*nb_inplace_or*/ ! ! /* New style slots: */ ! (binaryfunc)int_cmp, /*nb_cmp*/ }; *************** *** 771,774 **** --- 817,826 ---- 0, /*tp_as_mapping*/ (hashfunc)int_hash, /*tp_hash*/ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_NEWSTYLENUMBER /*tp_flags*/ }; From python-dev@python.org Thu Jan 4 01:46:05 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:46:05 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects longobject.c,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22592/Objects Modified Files: longobject.c Log Message: Make long a new style number type. Sequence repeat is now done here now as well. Index: longobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/longobject.c,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -r1.69 -r1.70 *** longobject.c 2000/10/24 19:57:45 1.69 --- longobject.c 2001/01/04 01:46:03 1.70 *************** *** 458,461 **** --- 458,495 ---- #endif /* HAVE_LONG_LONG */ + + static int + convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) { + if (PyLong_Check(v)) { + *a = (PyLongObject *) v; + Py_INCREF(v); + } + else if (PyInt_Check(v)) { + *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v)); + } + else { + return 0; + } + if (PyLong_Check(w)) { + *b = (PyLongObject *) w; + Py_INCREF(w); + } + else if (PyInt_Check(w)) { + *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w)); + } + else { + Py_DECREF(*a); + return 0; + } + return 1; + } + + #define CONVERT_BINOP(v, w, a, b) \ + if (!convert_binop(v, w, a, b)) { \ + Py_INCREF(Py_NotImplemented); \ + return Py_NotImplemented; \ + } + + /* Multiply by a single digit, ignoring the sign. */ *************** *** 933,936 **** --- 967,983 ---- } + /* Needed for the new style number compare slots */ + static PyObject * + long_cmp(PyObject *v, PyObject *w) + { + PyLongObject *a, *b; + int c; + CONVERT_BINOP(v, w, &a, &b); + c = long_compare(a, b); + Py_DECREF(a); + Py_DECREF(b); + return PyInt_FromLong(c); + } + static long long_hash(PyLongObject *v) *************** *** 1051,1058 **** static PyObject * ! long_add(PyLongObject *a, PyLongObject *b) { ! PyLongObject *z; if (a->ob_size < 0) { if (b->ob_size < 0) { --- 1098,1107 ---- static PyObject * ! long_add(PyLongObject *v, PyLongObject *w) { ! PyLongObject *a, *b, *z; + CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + if (a->ob_size < 0) { if (b->ob_size < 0) { *************** *** 1070,1081 **** z = x_add(a, b); } return (PyObject *)z; } static PyObject * ! long_sub(PyLongObject *a, PyLongObject *b) { ! PyLongObject *z; if (a->ob_size < 0) { if (b->ob_size < 0) --- 1119,1134 ---- z = x_add(a, b); } + Py_DECREF(a); + Py_DECREF(b); return (PyObject *)z; } static PyObject * ! long_sub(PyLongObject *v, PyLongObject *w) { ! PyLongObject *a, *b, *z; + CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + if (a->ob_size < 0) { if (b->ob_size < 0) *************** *** 1092,1106 **** z = x_sub(a, b); } return (PyObject *)z; } static PyObject * ! long_mul(PyLongObject *a, PyLongObject *b) { int size_a; int size_b; - PyLongObject *z; int i; size_a = ABS(a->ob_size); size_b = ABS(b->ob_size); --- 1145,1183 ---- z = x_sub(a, b); } + Py_DECREF(a); + Py_DECREF(b); return (PyObject *)z; } static PyObject * ! long_repeat(PyObject *v, PyLongObject *w) { + /* sequence * long */ + long n = PyLong_AsLong((PyObject *) w); + if (n == -1 && PyErr_Occurred()) + return NULL; + else + return (*v->ob_type->tp_as_sequence->sq_repeat)(v, n); + } + + static PyObject * + long_mul(PyLongObject *v, PyLongObject *w) + { + PyLongObject *a, *b, *z; int size_a; int size_b; int i; + if (v->ob_type->tp_as_sequence && + v->ob_type->tp_as_sequence->sq_repeat) { + return long_repeat((PyObject *)v, w); + } + else if (w->ob_type->tp_as_sequence && + w->ob_type->tp_as_sequence->sq_repeat) { + return long_repeat((PyObject *)w, v); + } + + CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + size_a = ABS(a->ob_size); size_b = ABS(b->ob_size); *************** *** 1115,1120 **** } z = _PyLong_New(size_a + size_b); ! if (z == NULL) return NULL; for (i = 0; i < z->ob_size; ++i) z->ob_digit[i] = 0; --- 1192,1200 ---- } z = _PyLong_New(size_a + size_b); ! if (z == NULL) { ! Py_DECREF(a); ! Py_DECREF(b); return NULL; + } for (i = 0; i < z->ob_size; ++i) z->ob_digit[i] = 0; *************** *** 1125,1128 **** --- 1205,1210 ---- SIGCHECK({ + Py_DECREF(a); + Py_DECREF(b); Py_DECREF(z); return NULL; *************** *** 1144,1147 **** --- 1226,1231 ---- if (b->ob_size < 0) z->ob_size = -(z->ob_size); + Py_DECREF(a); + Py_DECREF(b); return (PyObject *) long_normalize(z); } *************** *** 1199,1207 **** static PyObject * ! long_div(PyLongObject *v, PyLongObject *w) { ! PyLongObject *div, *mod; ! if (l_divmod(v, w, &div, &mod) < 0) return NULL; Py_DECREF(mod); return (PyObject *)div; --- 1283,1299 ---- static PyObject * ! long_div(PyObject *v, PyObject *w) { ! PyLongObject *a, *b, *div, *mod; ! ! CONVERT_BINOP(v, w, &a, &b); ! ! if (l_divmod(a, b, &div, &mod) < 0) { ! Py_DECREF(a); ! Py_DECREF(b); return NULL; + } + Py_DECREF(a); + Py_DECREF(b); Py_DECREF(mod); return (PyObject *)div; *************** *** 1209,1217 **** static PyObject * ! long_mod(PyLongObject *v, PyLongObject *w) { ! PyLongObject *div, *mod; ! if (l_divmod(v, w, &div, &mod) < 0) return NULL; Py_DECREF(div); return (PyObject *)mod; --- 1301,1317 ---- static PyObject * ! long_mod(PyObject *v, PyObject *w) { ! PyLongObject *a, *b, *div, *mod; ! ! CONVERT_BINOP(v, w, &a, &b); ! ! if (l_divmod(a, b, &div, &mod) < 0) { ! Py_DECREF(a); ! Py_DECREF(b); return NULL; + } + Py_DECREF(a); + Py_DECREF(b); Py_DECREF(div); return (PyObject *)mod; *************** *** 1219,1228 **** static PyObject * ! long_divmod(PyLongObject *v, PyLongObject *w) { PyObject *z; ! PyLongObject *div, *mod; ! if (l_divmod(v, w, &div, &mod) < 0) return NULL; z = PyTuple_New(2); if (z != NULL) { --- 1319,1334 ---- static PyObject * ! long_divmod(PyObject *v, PyObject *w) { + PyLongObject *a, *b, *div, *mod; PyObject *z; ! ! CONVERT_BINOP(v, w, &a, &b); ! ! if (l_divmod(a, b, &div, &mod) < 0) { ! Py_DECREF(a); ! Py_DECREF(b); return NULL; + } z = PyTuple_New(2); if (z != NULL) { *************** *** 1234,1245 **** Py_DECREF(mod); } return z; } static PyObject * ! long_pow(PyLongObject *a, PyLongObject *b, PyLongObject *c) { PyLongObject *z, *div, *mod; int size_b, i; size_b = b->ob_size; --- 1340,1370 ---- Py_DECREF(mod); } + Py_DECREF(a); + Py_DECREF(b); return z; } static PyObject * ! long_pow(PyObject *v, PyObject *w, PyObject *x) { + PyLongObject *a, *b; + PyObject *c; PyLongObject *z, *div, *mod; int size_b, i; + + CONVERT_BINOP(v, w, &a, &b); + if (PyLong_Check(x) || Py_None == x) { + c = x; + Py_INCREF(x); + } + else if (PyInt_Check(x)) { + c = PyLong_FromLong(PyInt_AS_LONG(x)); + } + else { + Py_DECREF(a); + Py_DECREF(b); + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } size_b = b->ob_size; *************** *** 1251,1258 **** PyErr_SetString(PyExc_ZeroDivisionError, "zero to a negative power"); ! return NULL; } z = (PyLongObject *)PyLong_FromLong(1L); - Py_INCREF(a); for (i = 0; i < size_b; ++i) { digit bi = b->ob_digit[i]; --- 1376,1383 ---- PyErr_SetString(PyExc_ZeroDivisionError, "zero to a negative power"); ! z = NULL; ! goto error; } z = (PyLongObject *)PyLong_FromLong(1L); for (i = 0; i < size_b; ++i) { digit bi = b->ob_digit[i]; *************** *** 1265,1270 **** temp = (PyLongObject *)long_mul(z, a); Py_DECREF(z); ! if ((PyObject*)c!=Py_None && temp!=NULL) { ! if (l_divmod(temp,c,&div,&mod) < 0) { Py_DECREF(temp); z = NULL; --- 1390,1396 ---- temp = (PyLongObject *)long_mul(z, a); Py_DECREF(z); ! if (c!=Py_None && temp!=NULL) { ! if (l_divmod(temp,(PyLongObject *)c, ! &div,&mod) < 0) { Py_DECREF(temp); z = NULL; *************** *** 1284,1289 **** temp = (PyLongObject *)long_mul(a, a); Py_DECREF(a); ! if ((PyObject*)c!=Py_None && temp!=NULL) { ! if (l_divmod(temp, c, &div, &mod) < 0) { Py_DECREF(temp); z = NULL; --- 1410,1416 ---- temp = (PyLongObject *)long_mul(a, a); Py_DECREF(a); ! if (c!=Py_None && temp!=NULL) { ! if (l_divmod(temp, (PyLongObject *)c, &div, ! &mod) < 0) { Py_DECREF(temp); z = NULL; *************** *** 1304,1310 **** break; } ! Py_XDECREF(a); ! if ((PyObject*)c!=Py_None && z!=NULL) { ! if (l_divmod(z, c, &div, &mod) < 0) { Py_DECREF(z); z = NULL; --- 1431,1436 ---- break; } ! if (c!=Py_None && z!=NULL) { ! if (l_divmod(z, (PyLongObject *)c, &div, &mod) < 0) { Py_DECREF(z); z = NULL; *************** *** 1317,1320 **** --- 1443,1449 ---- } error: + Py_XDECREF(a); + Py_DECREF(b); + Py_DECREF(c); return (PyObject *)z; } *************** *** 1383,1457 **** static PyObject * ! long_rshift(PyLongObject *a, PyLongObject *b) { ! PyLongObject *z; long shiftby; int newsize, wordshift, loshift, hishift, i, j; digit lomask, himask; if (a->ob_size < 0) { /* Right shifting negative numbers is harder */ ! PyLongObject *a1, *a2, *a3; a1 = (PyLongObject *) long_invert(a); ! if (a1 == NULL) return NULL; a2 = (PyLongObject *) long_rshift(a1, b); Py_DECREF(a1); ! if (a2 == NULL) return NULL; ! a3 = (PyLongObject *) long_invert(a2); Py_DECREF(a2); - return (PyObject *) a3; - } - - shiftby = PyLong_AsLong((PyObject *)b); - if (shiftby == -1L && PyErr_Occurred()) - return NULL; - if (shiftby < 0) { - PyErr_SetString(PyExc_ValueError, "negative shift count"); - return NULL; } ! wordshift = shiftby / SHIFT; ! newsize = ABS(a->ob_size) - wordshift; ! if (newsize <= 0) { ! z = _PyLong_New(0); ! return (PyObject *)z; ! } ! loshift = shiftby % SHIFT; ! hishift = SHIFT - loshift; ! lomask = ((digit)1 << hishift) - 1; ! himask = MASK ^ lomask; ! z = _PyLong_New(newsize); ! if (z == NULL) ! return NULL; ! if (a->ob_size < 0) ! z->ob_size = -(z->ob_size); ! for (i = 0, j = wordshift; i < newsize; i++, j++) { ! z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; ! if (i+1 < newsize) ! z->ob_digit[i] |= ! (a->ob_digit[j+1] << hishift) & himask; } ! return (PyObject *) long_normalize(z); } static PyObject * ! long_lshift(PyLongObject *a, PyLongObject *b) { /* This version due to Tim Peters */ ! PyLongObject *z; long shiftby; int oldsize, newsize, wordshift, remshift, i, j; twodigits accum; shiftby = PyLong_AsLong((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) ! return NULL; if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); ! return NULL; } if ((long)(int)shiftby != shiftby) { PyErr_SetString(PyExc_ValueError, "outrageous left shift count"); ! return NULL; } /* wordshift, remshift = divmod(shiftby, SHIFT) */ --- 1512,1603 ---- static PyObject * ! long_rshift(PyLongObject *v, PyLongObject *w) { ! PyLongObject *a, *b; ! PyLongObject *z = NULL; long shiftby; int newsize, wordshift, loshift, hishift, i, j; digit lomask, himask; + CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + if (a->ob_size < 0) { /* Right shifting negative numbers is harder */ ! PyLongObject *a1, *a2; a1 = (PyLongObject *) long_invert(a); ! if (a1 == NULL) ! goto rshift_error; a2 = (PyLongObject *) long_rshift(a1, b); Py_DECREF(a1); ! if (a2 == NULL) ! goto rshift_error; ! z = (PyLongObject *) long_invert(a2); Py_DECREF(a2); } ! else { ! ! shiftby = PyLong_AsLong((PyObject *)b); ! if (shiftby == -1L && PyErr_Occurred()) ! goto rshift_error; ! if (shiftby < 0) { ! PyErr_SetString(PyExc_ValueError, ! "negative shift count"); ! goto rshift_error; ! } ! wordshift = shiftby / SHIFT; ! newsize = ABS(a->ob_size) - wordshift; ! if (newsize <= 0) { ! z = _PyLong_New(0); ! Py_DECREF(a); ! Py_DECREF(b); ! return (PyObject *)z; ! } ! loshift = shiftby % SHIFT; ! hishift = SHIFT - loshift; ! lomask = ((digit)1 << hishift) - 1; ! himask = MASK ^ lomask; ! z = _PyLong_New(newsize); ! if (z == NULL) ! goto rshift_error; ! if (a->ob_size < 0) ! z->ob_size = -(z->ob_size); ! for (i = 0, j = wordshift; i < newsize; i++, j++) { ! z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; ! if (i+1 < newsize) ! z->ob_digit[i] |= ! (a->ob_digit[j+1] << hishift) & himask; ! } ! z = long_normalize(z); } ! rshift_error: ! Py_DECREF(a); ! Py_DECREF(b); ! return (PyObject *) z; ! } static PyObject * ! long_lshift(PyObject *v, PyObject *w) { /* This version due to Tim Peters */ ! PyLongObject *a, *b; ! PyLongObject *z = NULL; long shiftby; int oldsize, newsize, wordshift, remshift, i, j; twodigits accum; + CONVERT_BINOP(v, w, &a, &b); + shiftby = PyLong_AsLong((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) ! goto lshift_error; if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); ! goto lshift_error; } if ((long)(int)shiftby != shiftby) { PyErr_SetString(PyExc_ValueError, "outrageous left shift count"); ! goto lshift_error; } /* wordshift, remshift = divmod(shiftby, SHIFT) */ *************** *** 1465,1469 **** z = _PyLong_New(newsize); if (z == NULL) ! return NULL; if (a->ob_size < 0) z->ob_size = -(z->ob_size); --- 1611,1615 ---- z = _PyLong_New(newsize); if (z == NULL) ! goto lshift_error; if (a->ob_size < 0) z->ob_size = -(z->ob_size); *************** *** 1480,1484 **** else assert(!accum); ! return (PyObject *) long_normalize(z); } --- 1626,1634 ---- else assert(!accum); ! z = long_normalize(z); ! lshift_error: ! Py_DECREF(a); ! Py_DECREF(b); ! return (PyObject *) z; } *************** *** 1591,1609 **** static PyObject * ! long_and(PyLongObject *a, PyLongObject *b) { ! return long_bitwise(a, '&', b); } static PyObject * ! long_xor(PyLongObject *a, PyLongObject *b) { ! return long_bitwise(a, '^', b); } static PyObject * ! long_or(PyLongObject *a, PyLongObject *b) { ! return long_bitwise(a, '|', b); } --- 1741,1777 ---- static PyObject * ! long_and(PyObject *v, PyObject *w) { ! PyLongObject *a, *b; ! PyObject *c; ! CONVERT_BINOP(v, w, &a, &b); ! c = long_bitwise(a, '&', b); ! Py_DECREF(a); ! Py_DECREF(b); ! return c; } static PyObject * ! long_xor(PyObject *v, PyObject *w) { ! PyLongObject *a, *b; ! PyObject *c; ! CONVERT_BINOP(v, w, &a, &b); ! c = long_bitwise(a, '^', b); ! Py_DECREF(a); ! Py_DECREF(b); ! return c; } static PyObject * ! long_or(PyObject *v, PyObject *w) { ! PyLongObject *a, *b; ! PyObject *c; ! CONVERT_BINOP(v, w, &a, &b); ! c = long_bitwise(a, '|', b); ! Py_DECREF(a); ! Py_DECREF(b); ! return c; } *************** *** 1612,1616 **** { if (PyInt_Check(*pw)) { ! *pw = PyLong_FromLong(PyInt_AsLong(*pw)); Py_INCREF(*pv); return 0; --- 1780,1784 ---- { if (PyInt_Check(*pw)) { ! *pw = PyLong_FromLong(PyInt_AS_LONG(*pw)); Py_INCREF(*pv); return 0; *************** *** 1682,1685 **** --- 1850,1867 ---- (unaryfunc) long_oct, /*nb_oct*/ (unaryfunc) long_hex, /*nb_hex*/ + 0, /*nb_inplace_add*/ + 0, /*nb_inplace_subtract*/ + 0, /*nb_inplace_multiply*/ + 0, /*nb_inplace_divide*/ + 0, /*nb_inplace_remainder*/ + 0, /*nb_inplace_power*/ + 0, /*nb_inplace_lshift*/ + 0, /*nb_inplace_rshift*/ + 0, /*nb_inplace_and*/ + 0, /*nb_inplace_xor*/ + 0, /*nb_inplace_or*/ + + /* New style slots */ + (binaryfunc) long_cmp, /*nb_cmp*/ }; *************** *** 1702,1704 **** --- 1884,1890 ---- 0, /*tp_call*/ (reprfunc)long_str, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_NEWSTYLENUMBER /*tp_flags*/ }; From python-dev@python.org Thu Jan 4 01:48:12 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:48:12 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects object.c,2.103,2.104 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv22836/Objects Modified Files: object.c Log Message: Changes for PEP 208. PyObject_Compare has been rewritten. Instances no longer get special treatment. The Py_NotImplemented type is here as well. Index: object.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/object.c,v retrieving revision 2.103 retrieving revision 2.104 diff -C2 -r2.103 -r2.104 *** object.c 2000/10/24 19:57:45 2.103 --- object.c 2001/01/04 01:48:10 2.104 *************** *** 309,326 **** } ! static PyObject * do_cmp(PyObject *v, PyObject *w) { ! long c; ! /* __rcmp__ actually won't be called unless __cmp__ isn't defined, ! because the check in cmpobject() reverses the objects first. ! This is intentional -- it makes no sense to define cmp(x,y) ! different than -cmp(y,x). */ ! if (PyInstance_Check(v) || PyInstance_Check(w)) ! return PyInstance_DoBinOp(v, w, "__cmp__", "__rcmp__", do_cmp); ! c = PyObject_Compare(v, w); ! if (c && PyErr_Occurred()) ! return NULL; ! return PyInt_FromLong(c); } --- 309,402 ---- } ! #define NEW_STYLE_NUMBER(o) PyType_HasFeature((o)->ob_type, \ ! Py_TPFLAGS_NEWSTYLENUMBER) ! ! static int ! cmp_to_int(PyObject *result) ! { ! int c; ! if (result == NULL) ! return -1; ! if (!PyInt_Check(result)) { ! PyErr_SetString(PyExc_TypeError, ! "comparison did not return an int"); ! return -1; ! } ! c = PyInt_AS_LONG(result); ! Py_DECREF(result); ! return (c < 0) ? -1 : (c > 0) ? 1 : 0; ! } ! ! static int do_cmp(PyObject *v, PyObject *w) { ! PyNumberMethods *mv, *mw; ! PyObject *x; ! int c; ! ! /* new style nb_cmp gets priority */ ! mv = v->ob_type->tp_as_number; ! if (mv != NULL && NEW_STYLE_NUMBER(v) && mv->nb_cmp) { ! x = (*mv->nb_cmp)(v, w); ! if (x != Py_NotImplemented) ! return cmp_to_int(x); ! Py_DECREF(x); ! } ! mw = w->ob_type->tp_as_number; ! if (mw != NULL && NEW_STYLE_NUMBER(w) && mw->nb_cmp) { ! x = (*mw->nb_cmp)(v, w); ! if (x != Py_NotImplemented) ! return cmp_to_int(x); ! Py_DECREF(x); ! } ! /* fall back to tp_compare */ ! if (v->ob_type == w->ob_type) { ! if (v->ob_type->tp_compare != NULL) { ! return (*v->ob_type->tp_compare)(v, w); ! } ! else { ! Py_uintptr_t iv = (Py_uintptr_t)v; ! Py_uintptr_t iw = (Py_uintptr_t)w; ! return (iv < iw) ? -1 : (iv > iw) ? 1 : 0; ! } ! } ! if (PyUnicode_Check(v) || PyUnicode_Check(w)) { ! c = PyUnicode_Compare(v, w); ! if (c == -1 && ! PyErr_Occurred() && ! PyErr_ExceptionMatches(PyExc_TypeError)) ! /* TypeErrors are ignored: if Unicode coercion ! fails due to one of the arguments not having ! the right type, we continue as defined by the ! coercion protocol (see above). Luckily, ! decoding errors are reported as ValueErrors and ! are not masked by this technique. */ ! PyErr_Clear(); ! else ! return c; ! } ! /* fall back to coercion */ ! if (mv && mw && (!NEW_STYLE_NUMBER(v) || !NEW_STYLE_NUMBER(w))) { ! /* old style operand, both operations numeric, coerce */ ! int err = PyNumber_CoerceEx(&v, &w); ! if (err < 0) ! return -1; ! if (err == 0) { ! if (v->ob_type->tp_compare) { ! c = (*v->ob_type->tp_compare)(v, w); ! } ! else { ! Py_uintptr_t iv = (Py_uintptr_t)v; ! Py_uintptr_t iw = (Py_uintptr_t)w; ! c = (iv < iw) ? -1 : (iv > iw) ? 1 : 0; ! } ! Py_DECREF(v); ! Py_DECREF(w); ! return c; ! } ! } ! /* last resort, use type names */ ! c = strcmp(v->ob_type->tp_name, w->ob_type->tp_name); ! return (c < 0) ? -1: (c > 0) ? 1 : 0; } *************** *** 402,508 **** if (v == w) return 0; ! if (PyInstance_Check(v) || PyInstance_Check(w)) { ! PyObject *res; ! int c; ! if (!PyInstance_Check(v)) ! return -PyObject_Compare(w, v); ! _PyCompareState_nesting++; ! if (_PyCompareState_nesting > NESTING_LIMIT) { ! PyObject *inprogress, *pair; ! ! inprogress = get_inprogress_dict(); ! if (inprogress == NULL) { ! _PyCompareState_nesting--; ! return -1; ! } ! pair = make_pair(v, w); ! if (PyDict_GetItem(inprogress, pair)) { ! /* already comparing these objects. assume ! they're equal until shown otherwise */ ! Py_DECREF(pair); ! _PyCompareState_nesting--; ! return 0; ! } ! if (PyDict_SetItem(inprogress, pair, pair) == -1) { ! _PyCompareState_nesting--; ! return -1; ! } ! res = do_cmp(v, w); ! /* XXX DelItem shouldn't fail */ ! PyDict_DelItem(inprogress, pair); ! Py_DECREF(pair); ! } else { ! res = do_cmp(v, w); ! } ! _PyCompareState_nesting--; ! if (res == NULL) ! return -1; ! if (!PyInt_Check(res)) { ! Py_DECREF(res); ! PyErr_SetString(PyExc_TypeError, ! "comparison did not return an int"); ! return -1; ! } ! c = PyInt_AsLong(res); ! Py_DECREF(res); ! return (c < 0) ? -1 : (c > 0) ? 1 : 0; ! } ! if ((vtp = v->ob_type) != (wtp = w->ob_type)) { ! char *vname = vtp->tp_name; ! char *wname = wtp->tp_name; ! if (vtp->tp_as_number != NULL && wtp->tp_as_number != NULL) { ! int err; ! err = PyNumber_CoerceEx(&v, &w); ! if (err < 0) ! return -1; ! else if (err == 0) { ! int cmp; ! vtp = v->ob_type; ! if (vtp->tp_compare == NULL) ! cmp = (v < w) ? -1 : 1; ! else ! cmp = (*vtp->tp_compare)(v, w); ! Py_DECREF(v); ! Py_DECREF(w); ! return cmp; ! } ! } ! else if (PyUnicode_Check(v) || PyUnicode_Check(w)) { ! int result = PyUnicode_Compare(v, w); ! if (result == -1 && PyErr_Occurred() && ! PyErr_ExceptionMatches(PyExc_TypeError)) ! /* TypeErrors are ignored: if Unicode coercion ! fails due to one of the arguments not ! having the right type, we continue as ! defined by the coercion protocol (see ! above). Luckily, decoding errors are ! reported as ValueErrors and are not masked ! by this technique. */ ! PyErr_Clear(); ! else ! return result; ! } ! else if (vtp->tp_as_number != NULL) ! vname = ""; ! else if (wtp->tp_as_number != NULL) ! wname = ""; ! /* Numerical types compare smaller than all other types */ ! return strcmp(vname, wname); ! } ! if (vtp->tp_compare == NULL) { ! Py_uintptr_t iv = (Py_uintptr_t)v; ! Py_uintptr_t iw = (Py_uintptr_t)w; ! return (iv < iw) ? -1 : 1; ! } _PyCompareState_nesting++; ! if (_PyCompareState_nesting > NESTING_LIMIT ! && (vtp->tp_as_mapping ! || (vtp->tp_as_sequence && !PyString_Check(v)))) { PyObject *inprogress, *pair; inprogress = get_inprogress_dict(); if (inprogress == NULL) { ! _PyCompareState_nesting--; ! return -1; } pair = make_pair(v, w); --- 478,495 ---- if (v == w) return 0; ! vtp = v->ob_type; ! wtp = w->ob_type; _PyCompareState_nesting++; ! if (_PyCompareState_nesting > NESTING_LIMIT && ! (vtp->tp_as_mapping ! || PyInstance_Check(v) ! || (vtp->tp_as_sequence && !PyString_Check(v)))) { ! /* try to detect circular data structures */ PyObject *inprogress, *pair; inprogress = get_inprogress_dict(); if (inprogress == NULL) { ! result = -1; ! goto exit_cmp; } pair = make_pair(v, w); *************** *** 511,527 **** they're equal until shown otherwise */ Py_DECREF(pair); ! _PyCompareState_nesting--; ! return 0; } if (PyDict_SetItem(inprogress, pair, pair) == -1) { ! _PyCompareState_nesting--; ! return -1; } ! result = (*vtp->tp_compare)(v, w); ! PyDict_DelItem(inprogress, pair); /* XXX shouldn't fail */ Py_DECREF(pair); - } else { - result = (*vtp->tp_compare)(v, w); } _PyCompareState_nesting--; return result; --- 498,517 ---- they're equal until shown otherwise */ Py_DECREF(pair); ! result = 0; ! goto exit_cmp; } if (PyDict_SetItem(inprogress, pair, pair) == -1) { ! result = -1; ! goto exit_cmp; } ! result = do_cmp(v, w); ! /* XXX DelItem shouldn't fail */ ! PyDict_DelItem(inprogress, pair); Py_DECREF(pair); } + else { + result = do_cmp(v, w); + } + exit_cmp: _PyCompareState_nesting--; return result; *************** *** 916,919 **** --- 906,940 ---- PyObject _Py_NoneStruct = { PyObject_HEAD_INIT(&PyNothing_Type) + }; + + /* NotImplemented is an object that can be used to signal that an + operation is not implemented for the given type combination. */ + + static PyObject * + NotImplemented_repr(PyObject *op) + { + return PyString_FromString("NotImplemented"); + } + + static PyTypeObject PyNotImplemented_Type = { + PyObject_HEAD_INIT(&PyType_Type) + 0, + "NotImplemented", + 0, + 0, + 0, /*tp_dealloc*/ /*never called*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)NotImplemented_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + }; + + PyObject _Py_NotImplementedStruct = { + PyObject_HEAD_INIT(&PyNotImplemented_Type) }; From python-dev@python.org Thu Jan 4 01:48:45 2001 From: python-dev@python.org (Neil Schemenauer) Date: Wed, 03 Jan 2001 17:48:45 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.186,2.187 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv22928/Python Modified Files: bltinmodule.c Log Message: Add NotImplemented to the builtin module. Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.186 retrieving revision 2.187 diff -C2 -r2.186 -r2.187 *** bltinmodule.c 2000/12/23 14:11:28 2.186 --- bltinmodule.c 2001/01/04 01:48:42 2.187 *************** *** 2262,2265 **** --- 2262,2268 ---- if (PyDict_SetItemString(dict, "Ellipsis", Py_Ellipsis) < 0) return NULL; + if (PyDict_SetItemString(dict, "NotImplemented", + Py_NotImplemented) < 0) + return NULL; debug = PyInt_FromLong(Py_OptimizeFlag == 0); if (PyDict_SetItemString(dict, "__debug__", debug) < 0) { From python-dev@python.org Thu Jan 4 05:09:18 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:09:18 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfuncs.tex,1.72,1.73 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv3897/lib Modified Files: libfuncs.tex Log Message: Description of long(): A string parameter is no longer required to be *decimal*. This closes SF bug #127273. Index: libfuncs.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libfuncs.tex,v retrieving revision 1.72 retrieving revision 1.73 diff -C2 -r1.72 -r1.73 *** libfuncs.tex 2000/11/17 19:44:14 1.72 --- libfuncs.tex 2001/01/04 05:09:16 1.73 *************** *** 397,401 **** \begin{funcdesc}{long}{x\optional{, radix}} Convert a string or number to a long integer. If the argument is a ! string, it must contain a possibly signed decimal number of arbitrary size, possibly embedded in whitespace; this behaves identical to \code{string.atol(\var{x})}. The --- 397,401 ---- \begin{funcdesc}{long}{x\optional{, radix}} Convert a string or number to a long integer. If the argument is a ! string, it must contain a possibly signed number of arbitrary size, possibly embedded in whitespace; this behaves identical to \code{string.atol(\var{x})}. The From python-dev@python.org Thu Jan 4 05:12:54 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:12:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbisect.tex,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv4109/lib Modified Files: libbisect.tex Log Message: Update documentation to include the new functions, and use the more explicitly-named bisect_right() in the example code. This closes SF bug #127055. Index: libbisect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbisect.tex,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** libbisect.tex 2000/04/03 20:13:52 1.7 --- libbisect.tex 2001/01/04 05:12:52 1.8 *************** *** 20,37 **** The following functions are provided: ! \begin{funcdesc}{bisect}{list, item\optional{, lo\optional{, hi}}} ! Locate the proper insertion point for \var{item} in \var{list} to ! maintain sorted order. The parameters \var{lo} and \var{hi} may be ! used to specify a subset of the list which should be considered. The ! return value is suitable for use as the first parameter to ! \code{\var{list}.insert()}. \end{funcdesc} ! \begin{funcdesc}{insort}{list, item\optional{, lo\optional{, hi}}} ! Insert \var{item} in \var{list} in sorted order. This is equivalent ! to \code{\var{list}.insert(bisect.bisect(\var{list}, \var{item}, ! \var{lo}, \var{hi}), \var{item})}. \end{funcdesc} \subsection{Example} --- 20,64 ---- The following functions are provided: ! \begin{funcdesc}{bisect_left}{list, item\optional{, lo\optional{, hi}}} ! Locate the proper insertion point for \var{item} in \var{list} to ! maintain sorted order. The parameters \var{lo} and \var{hi} may be ! used to specify a subset of the list which should be considered; by ! default the entire list is used. If \var{item} is already present ! in \var{list}, the insertion point will be before (to the left of) ! any existing entries. The return value is suitable for use as the ! first parameter to \code{\var{list}.insert()}. This assumes that ! \var{list} is already sorted. ! \versionadded{2.1} \end{funcdesc} ! \begin{funcdesc}{bisect_right}{list, item\optional{, lo\optional{, hi}}} ! Similar to \function{bisect_left()}, but returns an insertion point ! which comes after (to the right of) any existing entries of ! \var{item} in \var{list}. ! \versionadded{2.1} \end{funcdesc} + \begin{funcdesc}{bisect}{\unspecified} + Alias for \function{bisect_right()} for backward compatibility. + \end{funcdesc} + + \begin{funcdesc}{insort_left}{list, item\optional{, lo\optional{, hi}}} + Insert \var{item} in \var{list} in sorted order. This is equivalent + to \code{\var{list}.insert(bisect.bisect_left(\var{list}, \var{item}, + \var{lo}, \var{hi}), \var{item})}. This assumes that \var{list} is + already sorted. + \versionadded{2.1} + \end{funcdesc} + + \begin{funcdesc}{insort_right}{list, item\optional{, lo\optional{, hi}}} + Similar to \function{insort_left()}, but inserting \var{item} in + \var{list} after any existing entries of \var{item}. + \versionadded{2.1} + \end{funcdesc} + + \begin{funcdesc}{insort}{\unspecified} + Alias for \function{insort_right()} for backward compatibility. + \end{funcdesc} + \subsection{Example} *************** *** 39,43 **** The \function{bisect()} function is generally useful for categorizing ! numeric data. This example uses \function{bisect()} to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', 75..84 is a `B', etc. --- 66,70 ---- The \function{bisect()} function is generally useful for categorizing ! numeric data. This example uses \function{bisect_right()} to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', 75..84 is a `B', etc. *************** *** 46,52 **** >>> grades = "FEDCBA" >>> breakpoints = [30, 44, 66, 75, 85] ! >>> from bisect import bisect >>> def grade(total): ! ... return grades[bisect(breakpoints, total)] ... >>> grade(66) --- 73,79 ---- >>> grades = "FEDCBA" >>> breakpoints = [30, 44, 66, 75, 85] ! >>> from bisect import bisect_right >>> def grade(total): ! ... return grades[bisect_right(breakpoints, total)] ... >>> grade(66) From python-dev@python.org Thu Jan 4 05:14:47 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:14:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libcurses.tex,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv4227/lib Modified Files: libcurses.tex Log Message: Markup nit: OK and ERR should be marked \constant in running text. Index: libcurses.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcurses.tex,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** libcurses.tex 2000/12/26 15:58:27 1.28 --- libcurses.tex 2001/01/04 05:14:45 1.29 *************** *** 1029,1039 **** \begin{datadesc}{ERR} Some curses routines that return an integer, such as ! \function{getch()}, return ERR upon failure. \end{datadesc} \begin{datadesc}{OK} Some curses routines that return an integer, such as ! \function{napms()}, return OK upon success. ! \end{datadesc} --- 1029,1038 ---- \begin{datadesc}{ERR} Some curses routines that return an integer, such as ! \function{getch()}, return \constant{ERR} upon failure. \end{datadesc} \begin{datadesc}{OK} Some curses routines that return an integer, such as ! \function{napms()}, return \constant{OK} upon success. \end{datadesc} From python-dev@python.org Thu Jan 4 05:16:41 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:16:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstdtypes.tex,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv4364/lib Modified Files: libstdtypes.tex Log Message: Added information about the interaction of opening a file in append mode and seek() in the description of seek(). This closes SF bug #126850. Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -r1.45 -r1.46 *** libstdtypes.tex 2000/12/12 22:03:47 1.45 --- libstdtypes.tex 2001/01/04 05:16:39 1.46 *************** *** 1080,1084 **** (absolute file positioning); other values are \code{1} (seek relative to the current position) and \code{2} (seek relative to the ! file's end). There is no return value. \end{methoddesc} --- 1080,1089 ---- (absolute file positioning); other values are \code{1} (seek relative to the current position) and \code{2} (seek relative to the ! file's end). There is no return value. Note that if the file is ! opened for appending (mode \code{'a'} or \code{'a+'}), any ! \method{seek()} operations will be undone at the next write. If the ! file is only opened for writing in append mode (mode \code{'a'}), ! this method is essentially a no-op, but it remains useful for files ! opened in append mode with reading enabled (mode \code{'a+'}). \end{methoddesc} From python-dev@python.org Thu Jan 4 05:48:10 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:48:10 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpyexpat.tex,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6449/lib Modified Files: libpyexpat.tex Log Message: Fix typo spotted by Detlef Lannert . Index: libpyexpat.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpyexpat.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** libpyexpat.tex 2000/12/23 22:19:05 1.10 --- libpyexpat.tex 2001/01/04 05:48:08 1.11 *************** *** 119,123 **** Create a ``child'' parser which can be used to parse an external parsed entity referred to by content parsed by the parent parser. The ! \var{content} parameter should be the string passed to the \method{ExternalEntityRefHandler()} handler function, described below. \end{methoddesc} --- 119,123 ---- Create a ``child'' parser which can be used to parse an external parsed entity referred to by content parsed by the parent parser. The ! \var{context} parameter should be the string passed to the \method{ExternalEntityRefHandler()} handler function, described below. \end{methoddesc} From python-dev@python.org Thu Jan 4 05:56:36 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:56:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/api api.tex,1.100,1.101 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv7015/api Modified Files: api.tex Log Message: Markup nit: Command line options should be marked with \programopt. Index: api.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/api.tex,v retrieving revision 1.100 retrieving revision 1.101 diff -C2 -r1.100 -r1.101 *** api.tex 2000/12/19 03:53:01 1.100 --- api.tex 2001/01/04 05:56:34 1.101 *************** *** 976,981 **** For information about warning control, see the documentation for the ! \module{warnings} module and the \samp{-W} option in the command line ! documentation. There is no C API for warning control. \end{cfuncdesc} --- 976,981 ---- For information about warning control, see the documentation for the ! \module{warnings} module and the \programopt{-W} option in the command ! line documentation. There is no C API for warning control. \end{cfuncdesc} From python-dev@python.org Thu Jan 4 05:59:39 2001 From: python-dev@python.org (Fred L. Drake) Date: Wed, 03 Jan 2001 21:59:39 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libwarnings.tex,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv7150/lib Modified Files: libwarnings.tex Log Message: Markup nit: Command line options should be marked with \programopt. Other minor markup nits fixed. Make reference to PyErr_Warn() a hyperlink. Index: libwarnings.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwarnings.tex,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** libwarnings.tex 2000/12/25 06:19:08 1.2 --- libwarnings.tex 2001/01/04 05:59:37 1.3 *************** *** 4,10 **** \declaremodule{standard}{warnings} \modulesynopsis{Issue warning messages and control their disposition.} - \index{warnings} Warning messages are typically issued in situations where it is useful --- 4,10 ---- \declaremodule{standard}{warnings} \modulesynopsis{Issue warning messages and control their disposition.} \index{warnings} + \versionadded{2.1} Warning messages are typically issued in situations where it is useful *************** *** 16,20 **** Python programmers issue warnings by calling the \function{warn()} function defined in this module. (C programmers use ! \code{PyErr_Warn()}). Warning messages are normally written to \code{sys.stderr}, but their --- 16,22 ---- Python programmers issue warnings by calling the \function{warn()} function defined in this module. (C programmers use ! \cfunction{PyErr_Warn()}; see the ! \citetitle[../api/exceptionHandling.html]{Python/C API Reference ! Manual} for details). Warning messages are normally written to \code{sys.stderr}, but their *************** *** 51,55 **** currently defined: ! \begin{tableii}{l|l}{code}{Class}{Description} \lineii{Warning}{This is the base class of all warning category --- 53,57 ---- currently defined: ! \begin{tableii}{l|l}{exception}{Class}{Description} \lineii{Warning}{This is the base class of all warning category *************** *** 93,111 **** \item \var{action} is one of the following strings: ! \begin{tableii}{l|l}{code}{value}{disposition} ! \lineii{\code{"error"}}{turn matching warnings into exceptions} ! \lineii{\code{"ignore"}}{never print matching warnings} ! \lineii{\code{"always"}}{always print matching warnings} ! \lineii{\code{"default"}}{print the first occurrence of matching warnings for each location where the warning is issued} ! \lineii{\code{"module"}}{print the first occurrence of matching warnings for each module where the warning is issued} ! \lineii{\code{"once"}}{print only the first occurrence of matching warnings, regardless of location} --- 95,113 ---- \item \var{action} is one of the following strings: ! \begin{tableii}{l|l}{code}{Value}{Disposition} ! \lineii{"error"}{turn matching warnings into exceptions} ! \lineii{"ignore"}{never print matching warnings} ! \lineii{"always"}{always print matching warnings} ! \lineii{"default"}{print the first occurrence of matching warnings for each location where the warning is issued} ! \lineii{"module"}{print the first occurrence of matching warnings for each module where the warning is issued} ! \lineii{"once"}{print only the first occurrence of matching warnings, regardless of location} *************** *** 131,137 **** raise \code{category(message)}. ! The warnings filter is initialized by \samp{-W} options passed to the ! Python interpreter command line. The interpreter saves the arguments ! for all \samp{-W} options without interpretation in \code{sys.warnoptions}; the \module{warnings} module parses these when it is first imported (invalid options are ignored, after printing a --- 133,139 ---- raise \code{category(message)}. ! The warnings filter is initialized by \programopt{-W} options passed ! to the Python interpreter command line. The interpreter saves the ! arguments for all \programopt{-W} options without interpretation in \code{sys.warnoptions}; the \module{warnings} module parses these when it is first imported (invalid options are ignored, after printing a *************** *** 188,192 **** \begin{funcdesc}{resetwarnings}{} Reset the warnings filter. This discards the effect of all previous ! calls to \function{filterwarnings()}, including that of the \samp{-W} ! command line options. \end{funcdesc} --- 190,194 ---- \begin{funcdesc}{resetwarnings}{} Reset the warnings filter. This discards the effect of all previous ! calls to \function{filterwarnings()}, including that of the ! \programopt{-W} command line options. \end{funcdesc} From python-dev@python.org Thu Jan 4 14:18:58 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 06:18:58 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbisect.tex,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv9470/lib Modified Files: libbisect.tex Log Message: Based on comments from Guido, do not describe bisect() and insert() as being "for backward compatibility." Also revert to using bisect() in the example, since Guido thinks that is the best recommendation for typical usage. Index: libbisect.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbisect.tex,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** libbisect.tex 2001/01/04 05:12:52 1.8 --- libbisect.tex 2001/01/04 14:18:55 1.9 *************** *** 40,44 **** \begin{funcdesc}{bisect}{\unspecified} ! Alias for \function{bisect_right()} for backward compatibility. \end{funcdesc} --- 40,44 ---- \begin{funcdesc}{bisect}{\unspecified} ! Alias for \function{bisect_right()}. \end{funcdesc} *************** *** 58,62 **** \begin{funcdesc}{insort}{\unspecified} ! Alias for \function{insort_right()} for backward compatibility. \end{funcdesc} --- 58,62 ---- \begin{funcdesc}{insort}{\unspecified} ! Alias for \function{insort_right()}. \end{funcdesc} *************** *** 66,70 **** The \function{bisect()} function is generally useful for categorizing ! numeric data. This example uses \function{bisect_right()} to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', 75..84 is a `B', etc. --- 66,70 ---- The \function{bisect()} function is generally useful for categorizing ! numeric data. This example uses \function{bisect()} to look up a letter grade for an exam total (say) based on a set of ordered numeric breakpoints: 85 and up is an `A', 75..84 is a `B', etc. *************** *** 73,79 **** >>> grades = "FEDCBA" >>> breakpoints = [30, 44, 66, 75, 85] ! >>> from bisect import bisect_right >>> def grade(total): ! ... return grades[bisect_right(breakpoints, total)] ... >>> grade(66) --- 73,79 ---- >>> grades = "FEDCBA" >>> breakpoints = [30, 44, 66, 75, 85] ! >>> from bisect import bisect >>> def grade(total): ! ... return grades[bisect(breakpoints, total)] ... >>> grade(66) From python-dev@python.org Thu Jan 4 15:11:50 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 07:11:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref3.tex,1.57,1.58 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv17971/ref Modified Files: ref3.tex Log Message: __rcmp__() description: Changed to indicate that this is no longer supported as of Python 2.1. We still need to have an entry for this since it is reasonable for users to want to understand existing code. This closes SF bug #122715. Index: ref3.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref3.tex,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** ref3.tex 2001/01/04 01:25:50 1.57 --- ref3.tex 2001/01/04 15:11:48 1.58 *************** *** 956,967 **** \begin{methoddesc}[object]{__rcmp__}{self, other} ! Called by all comparison operations. Should return a negative integer if ! \code{self < other}, zero if \code{self == other}, a positive integer if ! \code{self > other}. If no \method{__cmp__()} operation is defined, class ! instances are compared by object identity (``address''). ! (Note: the restriction that exceptions are not propagated by ! \method{__cmp__()} has been removed in Python 1.5.) ! \bifuncindex{cmp} ! \index{comparisons} \end{methoddesc} --- 956,960 ---- \begin{methoddesc}[object]{__rcmp__}{self, other} ! \versionchanged[No longer supported]{2.1} \end{methoddesc} From python-dev@python.org Thu Jan 4 15:16:03 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 07:16:03 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv18910/perl Modified Files: l2hinit.perl Log Message: Fix the bugfix for SF bug #127151 -- make sure we map "previous_page" to "previous" and "next_page" to "next". This way the proper icons are found. Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -r1.51 -r1.52 *** l2hinit.perl 2001/01/02 22:08:48 1.51 --- l2hinit.perl 2001/01/04 15:16:01 1.52 *************** *** 118,124 **** --- 118,131 ---- $my_icon_tags{'modules'} = 'Module Index'; + @my_icon_names = (); + $my_icon_names{'previous_page'} = 'previous'; + $my_icon_names{'next_page'} = 'next'; + sub get_my_icon { my $name = @_[0]; my $text = $my_icon_tags{$name}; + if ($my_icon_names{$name}) { + $name = $my_icon_names{$name}; + } if ($text eq '') { $name = 'blank'; From python-dev@python.org Thu Jan 4 20:30:58 2001 From: python-dev@python.org (Martin v. Löwis) Date: Thu, 04 Jan 2001 12:30:58 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.87,1.88 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv22388/Misc Modified Files: NEWS Log Message: Recognize pyc files even if they don't end in pyc. Patch #103067 with modifications as discussed in email. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.87 retrieving revision 1.88 diff -C2 -r1.87 -r1.88 *** NEWS 2000/12/29 02:06:45 1.87 --- NEWS 2001/01/04 20:30:56 1.88 *************** *** 4,7 **** --- 4,15 ---- Core language, builtins, and interpreter + - The interpreter accepts now bytecode files on the command line even + if they do not have a .pyc or .pyo extension. On Linux, after executing + + echo ':pyc:M::\x87\xc6\x0d\x0a::/usr/local/bin/python:' > /proc/sys/fs/binfmt_misc/register + + any byte code file can be used as an executable (i.e. as an argument + to execve(2)). + - %[xXo] formats of negative Python longs now produce a sign character. In 1.6 and earlier, they never produced a sign, From python-dev@python.org Thu Jan 4 20:30:59 2001 From: python-dev@python.org (Martin v. Löwis) Date: Thu, 04 Jan 2001 12:30:59 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.115,2.116 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv22388/Python Modified Files: pythonrun.c Log Message: Recognize pyc files even if they don't end in pyc. Patch #103067 with modifications as discussed in email. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.115 retrieving revision 2.116 diff -C2 -r2.115 -r2.116 *** pythonrun.c 2000/09/16 16:32:19 2.115 --- pythonrun.c 2001/01/04 20:30:56 2.116 *************** *** 547,550 **** --- 547,582 ---- } + /* Check whether a file maybe a pyc file: Look at the extension, + the file type, and, if we may close it, at the first few bytes. */ + + static int + maybe_pyc_file(FILE *fp, char* filename, char* ext, int closeit) + { + if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0) + return 1; + + #ifdef macintosh + /* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */ + if (PyMac_getfiletype(filename) == 'PYC ' + || PyMac_getfiletype(filename) == 'APPL') + return 1; + #endif /* macintosh */ + + /* Only look into the file if we are allowed to close it, since + it then should also be seekable. */ + if (closeit) { + /* Read only two bytes of the magic. If the file was opened in + text mode, the bytes 3 and 4 of the magic (\r\n) might not + be read as they are on disk. */ + unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; + unsigned char buf[2]; + if (fread(buf, 1, 2, fp) == 2 + && (buf[1]<<8 | buf[0]) == halfmagic) + return 1; + fseek(fp, 0, SEEK_SET); + } + return 0; + } + int PyRun_SimpleFileEx(FILE *fp, char *filename, int closeit) *************** *** 558,568 **** d = PyModule_GetDict(m); ext = filename + strlen(filename) - 4; ! if (strcmp(ext, ".pyc") == 0 || strcmp(ext, ".pyo") == 0 ! #ifdef macintosh ! /* On a mac, we also assume a pyc file for types 'PYC ' and 'APPL' */ ! || PyMac_getfiletype(filename) == 'PYC ' ! || PyMac_getfiletype(filename) == 'APPL' ! #endif /* macintosh */ ! ) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) --- 590,594 ---- d = PyModule_GetDict(m); ext = filename + strlen(filename) - 4; ! if (maybe_pyc_file(fp, filename, ext, closeit)) { /* Try to run a pyc file. First, re-open in binary */ if (closeit) From python-dev@python.org Thu Jan 4 22:33:04 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 14:33:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.214,2.215 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv5906/Python Modified Files: ceval.c Log Message: When a PyCFunction that takes only positional parameters is called with an empty keywords dictionary (via apply() or the extended call syntax), the keywords dict should be ignored. If the keywords dict is not empty, TypeError should be raised. (Between the restructuring of the call machinery and this patch, an empty dict in this situation would trigger a SystemError via PyErr_BadInternalCall().) Added regression tests to detect errors for this. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.214 retrieving revision 2.215 diff -C2 -r2.214 -r2.215 *** ceval.c 2001/01/03 23:52:36 2.214 --- ceval.c 2001/01/04 22:33:01 2.215 *************** *** 2608,2628 **** int flags = PyCFunction_GET_FLAGS(func); ! if (flags & METH_KEYWORDS && kw == NULL) { ! static PyObject *dict = NULL; ! if (dict == NULL) { ! dict = PyDict_New(); ! if (dict == NULL) ! return NULL; } ! kw = dict; ! Py_INCREF(dict); } ! if (flags & METH_VARARGS && kw == NULL) { ! return (*meth)(self, arg); } ! if (flags & METH_KEYWORDS) { ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); } if (!(flags & METH_VARARGS)) { int size = PyTuple_GET_SIZE(arg); if (size == 1) --- 2608,2635 ---- int flags = PyCFunction_GET_FLAGS(func); ! if (flags & METH_KEYWORDS) { ! if (kw == NULL) { ! static PyObject *dict = NULL; ! if (dict == NULL) { ! dict = PyDict_New(); ! if (dict == NULL) ! return NULL; ! } ! kw = dict; ! Py_INCREF(dict); } ! return (*(PyCFunctionWithKeywords)meth)(self, arg, kw); } ! if (kw != NULL && PyDict_Size(kw) != 0) { ! PyErr_Format(PyExc_TypeError, ! "%.200s() takes no keyword arguments", ! f->m_ml->ml_name); ! return NULL; } ! if (flags & METH_VARARGS) { ! return (*meth)(self, arg); } if (!(flags & METH_VARARGS)) { + /* the really old style */ int size = PyTuple_GET_SIZE(arg); if (size == 1) *************** *** 2631,2640 **** arg = NULL; return (*meth)(self, arg); - } - if (kw != NULL && PyDict_Size(kw) != 0) { - PyErr_Format(PyExc_TypeError, - "%.200s() takes no keyword arguments", - f->m_ml->ml_name); - return NULL; } /* should never get here ??? */ --- 2638,2641 ---- From python-dev@python.org Thu Jan 4 22:33:04 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 14:33:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_b1.py,1.30,1.31 test_extcall.py,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5906/Lib/test Modified Files: test_b1.py test_extcall.py Log Message: When a PyCFunction that takes only positional parameters is called with an empty keywords dictionary (via apply() or the extended call syntax), the keywords dict should be ignored. If the keywords dict is not empty, TypeError should be raised. (Between the restructuring of the call machinery and this patch, an empty dict in this situation would trigger a SystemError via PyErr_BadInternalCall().) Added regression tests to detect errors for this. Index: test_b1.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_b1.py,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -r1.30 -r1.31 *** test_b1.py 2001/01/04 01:33:41 1.30 --- test_b1.py 2001/01/04 22:33:02 1.31 *************** *** 40,43 **** --- 40,54 ---- apply(f3, (1, 2, 3)) + # A PyCFunction that takes only positional parameters should allow an + # empty keyword dictionary to pass without a complaint, but raise a + # TypeError if the dictionary is non-empty. + apply(id, (1,), {}) + try: + apply(id, (1,), {"foo": 1}) + except TypeError: + pass + else: + raise TestFailed, 'expected TypeError; no exception raised' + print 'callable' if not callable(len):raise TestFailed, 'callable(len)' Index: test_extcall.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_extcall.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** test_extcall.py 2000/10/30 17:15:20 1.7 --- test_extcall.py 2001/01/04 22:33:02 1.8 *************** *** 1,3 **** --- 1,4 ---- from UserList import UserList + from test_support import TestFailed def f(*a, **k): *************** *** 162,164 **** print err ! --- 163,174 ---- print err ! # A PyCFunction that takes only positional parameters should allow an ! # empty keyword dictionary to pass without a complaint, but raise a ! # TypeError if the dictionary is non-empty. ! id(1, **{}) ! try: ! id(1, **{"foo": 1}) ! except TypeError: ! pass ! else: ! raise TestFailed, 'expected TypeError; no exception raised' From python-dev@python.org Thu Jan 4 22:34:40 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 14:34:40 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0226.txt,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv6209 Modified Files: pep-0226.txt Log Message: Updates based on today's PythonLabs meeting. Index: pep-0226.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0226.txt,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pep-0226.txt 2000/10/30 20:48:44 1.2 --- pep-0226.txt 2001/01/04 22:34:38 1.3 *************** *** 21,30 **** 16-Oct-2000: Python 2.0 final release ! These dates represent goals, not commitments. 16-Dec-2000: 2.1 PEPs ready for review ! 01-Feb-2001: First 2.1 beta release ! 16-Mar-2001: 2.1 final release --- 21,31 ---- 16-Oct-2000: Python 2.0 final release ! These dates represent goals, not commitments. 16-Dec-2000: 2.1 PEPs ready for review ! 19-Jan-2001: First 2.1 alpha release ! 23-Feb-2001: First 2.1 beta release ! 01-Apr-2001: 2.1 final release From python-dev@python.org Fri Jan 5 00:54:32 2001 From: python-dev@python.org (Tim Peters) Date: Thu, 04 Jan 2001 16:54:32 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python pythonrun.c,2.116,2.117 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv25746/python/dist/src/python Modified Files: pythonrun.c Log Message: Fix signed/unsigned wng. Unfortunately, (unsigned char) << int has type int in C. Index: pythonrun.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/pythonrun.c,v retrieving revision 2.116 retrieving revision 2.117 diff -C2 -r2.116 -r2.117 *** pythonrun.c 2001/01/04 20:30:56 2.116 --- pythonrun.c 2001/01/05 00:54:29 2.117 *************** *** 571,576 **** unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; unsigned char buf[2]; ! if (fread(buf, 1, 2, fp) == 2 ! && (buf[1]<<8 | buf[0]) == halfmagic) return 1; fseek(fp, 0, SEEK_SET); --- 571,576 ---- unsigned int halfmagic = PyImport_GetMagicNumber() & 0xFFFF; unsigned char buf[2]; ! if (fread(buf, 1, 2, fp) == 2 ! && ((unsigned int)buf[1]<<8 | buf[0]) == halfmagic) return 1; fseek(fp, 0, SEEK_SET); From python-dev@python.org Fri Jan 5 05:54:43 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 21:54:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib urlparse.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv4905/Lib Modified Files: urlparse.py Log Message: urlunparse(): Do not add a leading slash to the path if it is empty. urljoin(): Make this conform to RFC 1808 for all examples given in that RFC (both "Normal" and "Abnormal"), so long as that RFC does not conflict the older RFC 1630, which also specified relative URL resolution. This closes SF bug #110832 (Jitterbug PR#194). Index: urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urlparse.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** urlparse.py 2000/12/19 16:48:13 1.26 --- urlparse.py 2001/01/05 05:54:41 1.27 *************** *** 115,119 **** (the draft states that these are equivalent).""" if netloc or (scheme in uses_netloc and url[:2] == '//'): ! if url[:1] != '/': url = '/' + url url = '//' + (netloc or '') + url if scheme: --- 115,119 ---- (the draft states that these are equivalent).""" if netloc or (scheme in uses_netloc and url[:2] == '//'): ! if url and url[:1] != '/': url = '/' + url url = '//' + (netloc or '') + url if scheme: *************** *** 132,135 **** --- 132,137 ---- if not base: return url + if not url: + return base bscheme, bnetloc, bpath, bparams, bquery, bfragment = \ urlparse(base, '', allow_fragments) *************** *** 137,142 **** urlparse(url, bscheme, allow_fragments) if scheme != bscheme or scheme not in uses_relative: ! return urlunparse((scheme, netloc, path, ! params, query, fragment)) if scheme in uses_netloc: if netloc: --- 139,143 ---- urlparse(url, bscheme, allow_fragments) if scheme != bscheme or scheme not in uses_relative: ! return url if scheme in uses_netloc: if netloc: *************** *** 148,153 **** params, query, fragment)) if not path: return urlunparse((scheme, netloc, bpath, ! params, query or bquery, fragment)) segments = bpath.split('/')[:-1] + path.split('/') # XXX The stuff below is bogus in various ways... --- 149,158 ---- params, query, fragment)) if not path: + if not params: + params = bparams + if not query: + query = bquery return urlunparse((scheme, netloc, bpath, ! params, query, fragment)) segments = bpath.split('/')[:-1] + path.split('/') # XXX The stuff below is bogus in various ways... *************** *** 160,164 **** n = len(segments) - 1 while i < n: ! if segments[i] == '..' and segments[i-1]: del segments[i-1:i+1] break --- 165,170 ---- n = len(segments) - 1 while i < n: ! if (segments[i] == '..' ! and segments[i-1] not in ('', '..')): del segments[i-1:i+1] break *************** *** 166,170 **** else: break ! if len(segments) == 2 and segments[1] == '..' and segments[0] == '': segments[-1] = '' elif len(segments) >= 2 and segments[-1] == '..': --- 172,176 ---- else: break ! if segments == ['', '..']: segments[-1] = '' elif len(segments) >= 2 and segments[-1] == '..': From python-dev@python.org Fri Jan 5 05:57:06 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 21:57:06 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_urlparse.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv5092/Lib/test Modified Files: test_urlparse.py Log Message: Add test cases based on RFC 1808. So now we actually have a test suite the urljoin() function, which exercises the urlparse() and urlunparse() functions as side effects. (Moshe, why did we have perfectly empty tests checked in for this?) Index: test_urlparse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_urlparse.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_urlparse.py 2000/08/03 17:28:50 1.1 --- test_urlparse.py 2001/01/05 05:57:04 1.2 *************** *** 0 **** --- 1,66 ---- + import urlparse + + errors = 0 + + RFC1808_BASE = "http://a/b/c/d;p?q#f" + + def checkJoin(relurl, expected): + global errors + result = urlparse.urljoin(RFC1808_BASE, relurl) + print "%-13s = %r" % (relurl, result) + if result != expected: + errors += 1 + print "urljoin(%r, %r)" % (RFC1808_BASE, relurl) + print ("expected %r,\n" + " got %r") % (expected, result) + + print "urlparse.urljoin() tests" + print + + # "normal" cases from RFC 1808: + checkJoin('g:h', 'g:h') + checkJoin('g', 'http://a/b/c/g') + checkJoin('./g', 'http://a/b/c/g') + checkJoin('g/', 'http://a/b/c/g/') + checkJoin('/g', 'http://a/g') + checkJoin('//g', 'http://g') + checkJoin('?y', 'http://a/b/c/d;p?y') + checkJoin('g?y', 'http://a/b/c/g?y') + checkJoin('g?y/./x', 'http://a/b/c/g?y/./x') + checkJoin('#s', 'http://a/b/c/d;p?q#s') + checkJoin('g#s', 'http://a/b/c/g#s') + checkJoin('g#s/./x', 'http://a/b/c/g#s/./x') + checkJoin('g?y#s', 'http://a/b/c/g?y#s') + checkJoin(';x', 'http://a/b/c/d;x') + checkJoin('g;x', 'http://a/b/c/g;x') + checkJoin('g;x?y#s', 'http://a/b/c/g;x?y#s') + checkJoin('.', 'http://a/b/c/') + checkJoin('./', 'http://a/b/c/') + checkJoin('..', 'http://a/b/') + checkJoin('../', 'http://a/b/') + checkJoin('../g', 'http://a/b/g') + checkJoin('../..', 'http://a/') + checkJoin('../../', 'http://a/') + checkJoin('../../g', 'http://a/g') + + # "abnormal" cases from RFC 1808: + checkJoin('', 'http://a/b/c/d;p?q#f') + checkJoin('../../../g', 'http://a/../g') + checkJoin('../../../../g', 'http://a/../../g') + checkJoin('/./g', 'http://a/./g') + checkJoin('/../g', 'http://a/../g') + checkJoin('g.', 'http://a/b/c/g.') + checkJoin('.g', 'http://a/b/c/.g') + checkJoin('g..', 'http://a/b/c/g..') + checkJoin('..g', 'http://a/b/c/..g') + checkJoin('./../g', 'http://a/b/g') + checkJoin('./g/.', 'http://a/b/c/g/') + checkJoin('g/./h', 'http://a/b/c/g/h') + checkJoin('g/../h', 'http://a/b/c/h') + + # RFC 1808 and RFC 1630 disagree on these (according to RFC 1808), + # so we'll not actually run these tests (which expect 1808 behavior). + #checkJoin('http:g', 'http:g') + #checkJoin('http:', 'http:') + + print errors, "errors" From python-dev@python.org Fri Jan 5 05:57:06 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 21:57:06 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_urlparse,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv5092/Lib/test/output Modified Files: test_urlparse Log Message: Add test cases based on RFC 1808. So now we actually have a test suite the urljoin() function, which exercises the urlparse() and urlunparse() functions as side effects. (Moshe, why did we have perfectly empty tests checked in for this?) Index: test_urlparse =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_urlparse,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_urlparse 2000/08/03 17:28:50 1.1 --- test_urlparse 2001/01/05 05:57:04 1.2 *************** *** 1 **** --- 1,41 ---- test_urlparse + urlparse.urljoin() tests + + g:h = 'g:h' + g = 'http://a/b/c/g' + ./g = 'http://a/b/c/g' + g/ = 'http://a/b/c/g/' + /g = 'http://a/g' + //g = 'http://g' + ?y = 'http://a/b/c/d;p?y' + g?y = 'http://a/b/c/g?y' + g?y/./x = 'http://a/b/c/g?y/./x' + #s = 'http://a/b/c/d;p?q#s' + g#s = 'http://a/b/c/g#s' + g#s/./x = 'http://a/b/c/g#s/./x' + g?y#s = 'http://a/b/c/g?y#s' + ;x = 'http://a/b/c/d;x' + g;x = 'http://a/b/c/g;x' + g;x?y#s = 'http://a/b/c/g;x?y#s' + . = 'http://a/b/c/' + ./ = 'http://a/b/c/' + .. = 'http://a/b/' + ../ = 'http://a/b/' + ../g = 'http://a/b/g' + ../.. = 'http://a/' + ../../ = 'http://a/' + ../../g = 'http://a/g' + = 'http://a/b/c/d;p?q#f' + ../../../g = 'http://a/../g' + ../../../../g = 'http://a/../../g' + /./g = 'http://a/./g' + /../g = 'http://a/../g' + g. = 'http://a/b/c/g.' + .g = 'http://a/b/c/.g' + g.. = 'http://a/b/c/g..' + ..g = 'http://a/b/c/..g' + ./../g = 'http://a/b/g' + ./g/. = 'http://a/b/c/g/' + g/./h = 'http://a/b/c/g/h' + g/../h = 'http://a/b/c/h' + 0 errors From python-dev@python.org Fri Jan 5 06:44:21 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 04 Jan 2001 22:44:21 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libbsddb.tex,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8632/lib Modified Files: libbsddb.tex Log Message: Update explanation of the set_location() method to indicate that in BTree databases, the key need not be in the database. Also, tell about the exception if the key is not in the DB for other DB types. This closes SF bug #127377. Index: libbsddb.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libbsddb.tex,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** libbsddb.tex 2000/09/15 15:19:35 1.5 --- libbsddb.tex 2001/01/05 06:44:19 1.6 *************** *** 104,108 **** \begin{methoddesc}{set_location}{key} ! Set the cursor to the item indicated by the key and return it. \end{methoddesc} --- 104,114 ---- \begin{methoddesc}{set_location}{key} ! Set the cursor to the item indicated by \var{key} and return a tuple ! containing the key and its value. For binary tree databases (opened ! using \function{btopen()}), if \var{key} does not actually exist in ! the database, the cursor will point to the next item in sorted order ! and return that key and value. For other databases, ! \exception{KeyError} will be raised if \var{key} is not found in the ! database. \end{methoddesc} From python-dev@python.org Fri Jan 5 08:05:34 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 05 Jan 2001 00:05:34 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.88,1.89 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv14118/python/dist/src/misc Modified Files: NEWS Log Message: Clarification of new bisect module functions. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.88 retrieving revision 1.89 diff -C2 -r1.88 -r1.89 *** NEWS 2001/01/04 20:30:56 1.88 --- NEWS 2001/01/05 08:05:32 1.89 *************** *** 52,56 **** compares equal to one or more elements already in the list: the XXX_left methods insert to the left, the XXX_right methods to the ! right. --- 52,57 ---- compares equal to one or more elements already in the list: the XXX_left methods insert to the left, the XXX_right methods to the ! right. Code that doesn't care where equal elements end up should ! continue to use the old, short names ("bisect" and "insort"). From python-dev@python.org Fri Jan 5 14:43:07 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 06:43:07 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.96,2.97 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv3183 Modified Files: fileobject.c Log Message: Restructured get_line() for clarity and speed. - The raw_input() functionality is moved to a separate function. - Drop GNU getline() in favor of getc_unlocked(), which exists on more platforms (and is even a tad faster on my system). Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.96 retrieving revision 2.97 diff -C2 -r2.96 -r2.97 *** fileobject.c 2000/12/20 00:55:07 2.96 --- fileobject.c 2001/01/05 14:43:05 2.97 *************** *** 640,686 **** > 0: max length; = 0: read arbitrary line; ! < 0: strip trailing '\n', raise EOFError if EOF reached immediately */ static PyObject * get_line(PyFileObject *f, int n) { ! register FILE *fp = f->f_fp; ! register int c; char *buf, *end; size_t n1, n2; PyObject *v; - #if defined(HAVE_GETLINE) && defined(_GNU_SOURCE) - /* Use GNU libc extension getline() for arbitrary-sized lines */ - if (n == 0) { - size_t size = 0; - buf = NULL; - Py_BEGIN_ALLOW_THREADS - n1 = getline(&buf, &size, fp); - Py_END_ALLOW_THREADS - if (n1 == -1) { - if (buf){ - free(buf); - } - clearerr(fp); - if (PyErr_CheckSignals()) { - return NULL; - } - if (n < 0 && feof(fp)) { - PyErr_SetString(PyExc_EOFError, - "EOF when reading a line"); - return NULL; - } - return PyString_FromStringAndSize(NULL, 0); - } - /* No error */ - - v = PyString_FromStringAndSize(buf, n1); - free(buf); - return v; - } - #endif - n2 = n > 0 ? n : 100; v = PyString_FromStringAndSize((char *)NULL, n2); --- 640,665 ---- > 0: max length; = 0: read arbitrary line; ! < 0: illegal (use get_line_raw() instead) */ + #ifdef HAVE_GETC_UNLOCKED + #define GETC(f) getc_unlocked(f) + #define FLOCKFILE(f) flockfile(f) + #define FUNLOCKFILE(f) funlockfile(f) + #else + #define GETC(f) getc(f) + #define FLOCKFILE(f) + #define FUNLOCKFILE(f) + #endif + static PyObject * get_line(PyFileObject *f, int n) { ! FILE *fp = f->f_fp; ! int c; char *buf, *end; size_t n1, n2; PyObject *v; n2 = n > 0 ? n : 100; v = PyString_FromStringAndSize((char *)NULL, n2); *************** *** 690,735 **** end = buf + n2; - Py_BEGIN_ALLOW_THREADS for (;;) { ! if ((c = getc(fp)) == EOF) { clearerr(fp); - Py_BLOCK_THREADS if (PyErr_CheckSignals()) { Py_DECREF(v); return NULL; } - if (n < 0 && buf == BUF(v)) { - Py_DECREF(v); - PyErr_SetString(PyExc_EOFError, - "EOF when reading a line"); - return NULL; - } - Py_UNBLOCK_THREADS break; } ! if ((*buf++ = c) == '\n') { ! if (n < 0) ! buf--; break; ! } ! if (buf == end) { ! if (n > 0) ! break; ! n1 = n2; ! n2 += 1000; ! if (n2 > INT_MAX) { ! PyErr_SetString(PyExc_OverflowError, ! "line is longer than a Python string can hold"); ! return NULL; ! } ! Py_BLOCK_THREADS ! if (_PyString_Resize(&v, n2) < 0) ! return NULL; ! Py_UNBLOCK_THREADS ! buf = BUF(v) + n1; ! end = BUF(v) + n2; } } - Py_END_ALLOW_THREADS n1 = buf - BUF(v); --- 669,706 ---- end = buf + n2; for (;;) { ! Py_BEGIN_ALLOW_THREADS ! FLOCKFILE(fp); ! while ((c = GETC(fp)) != EOF && ! (*buf++ = c) != '\n' && ! buf != end) ! ; ! FUNLOCKFILE(fp); ! Py_END_ALLOW_THREADS ! if (c == '\n') ! break; ! if (c == EOF) { clearerr(fp); if (PyErr_CheckSignals()) { Py_DECREF(v); return NULL; } break; } ! /* Must be because buf == end */ ! if (n > 0) break; ! n1 = n2; ! n2 += 1000; ! if (n2 > INT_MAX) { ! PyErr_SetString(PyExc_OverflowError, ! "line is longer than a Python string can hold"); ! return NULL; } + if (_PyString_Resize(&v, n2) < 0) + return NULL; + buf = BUF(v) + n1; + end = BUF(v) + n2; } n1 = buf - BUF(v); *************** *** 739,742 **** --- 710,732 ---- } + /* Internal routine to get a line for raw_input(): + strip trailing '\n', raise EOFError if EOF reached immediately + */ + + static PyObject * + get_line_raw(PyFileObject *f) + { + PyObject *line; + + line = get_line(f, 0); + if (line == NULL || PyString_GET_SIZE(line) > 0) + return line; + else { + Py_DECREF(line); + PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); + return NULL; + } + } + /* External C interface */ *************** *** 797,801 **** if (((PyFileObject*)f)->f_fp == NULL) return err_closed(); ! return get_line((PyFileObject *)f, n); } --- 787,794 ---- if (((PyFileObject*)f)->f_fp == NULL) return err_closed(); ! if (n < 0) ! return get_line_raw((PyFileObject *)f); ! else ! return get_line((PyFileObject *)f, n); } From python-dev@python.org Fri Jan 5 14:44:41 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 06:44:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib fileinput.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3615 Modified Files: fileinput.py Log Message: Speed it up by using readlines(sizehint). It's still slower than other ways of reading input. :-( In the process, I added an optional bufsize argument to the input() function and the FileInput class. Index: fileinput.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fileinput.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** fileinput.py 2000/04/10 17:16:12 1.5 --- fileinput.py 2001/01/05 14:44:39 1.6 *************** *** 63,71 **** does not work for MS-DOS 8+3 filesystems. XXX Possible additions: - optional getopt argument processing - specify open mode ('r' or 'rb') - - specify buffer size - fileno() - isatty() --- 63,77 ---- does not work for MS-DOS 8+3 filesystems. + Performance: this module is unfortunately one of the slower ways of + processing large numbers of input lines. Nevertheless, a significant + speed-up has been obtained by using readlines(bufsize) instead of + readline(). A new keyword argument, bufsize=N, is present on the + input() function and the FileInput() class to override the default + buffer size. + XXX Possible additions: - optional getopt argument processing - specify open mode ('r' or 'rb') - fileno() - isatty() *************** *** 77,86 **** _state = None ! def input(files=None, inplace=0, backup=""): global _state if _state and _state._file: raise RuntimeError, "input() already active" ! _state = FileInput(files, inplace, backup) return _state --- 83,94 ---- _state = None + + DEFAULT_BUFSIZE = 8*1024 ! def input(files=None, inplace=0, backup="", bufsize=0): global _state if _state and _state._file: raise RuntimeError, "input() already active" ! _state = FileInput(files, inplace, backup, bufsize) return _state *************** *** 124,128 **** class FileInput: ! def __init__(self, files=None, inplace=0, backup=""): if type(files) == type(''): files = (files,) --- 132,136 ---- class FileInput: ! def __init__(self, files=None, inplace=0, backup="", bufsize=0): if type(files) == type(''): files = (files,) *************** *** 137,140 **** --- 145,149 ---- self._inplace = inplace self._backup = backup + self._bufsize = bufsize or DEFAULT_BUFSIZE self._savestdout = None self._output = None *************** *** 145,148 **** --- 154,159 ---- self._isstdin = 0 self._backupfilename = None + self._buffer = [] + self._bufindex = 0 def __del__(self): *************** *** 154,157 **** --- 165,177 ---- def __getitem__(self, i): + try: + line = self._buffer[self._bufindex] + except IndexError: + pass + else: + self._bufindex += 1 + self._lineno += 1 + self._filelineno += 1 + return line if i != self._lineno: raise RuntimeError, "accessing lines out of order" *************** *** 184,189 **** --- 204,220 ---- self._isstdin = 0 + self._buffer = [] + self._bufindex = 0 def readline(self): + try: + line = self._buffer[self._bufindex] + except IndexError: + pass + else: + self._bufindex += 1 + self._lineno += 1 + self._filelineno += 1 + return line if not self._file: if not self._files: *************** *** 226,235 **** # This may raise IOError self._file = open(self._filename, "r") ! line = self._file.readline() ! if line: ! self._lineno = self._lineno + 1 ! self._filelineno = self._filelineno + 1 ! return line ! self.nextfile() # Recursive call return self.readline() --- 257,264 ---- # This may raise IOError self._file = open(self._filename, "r") ! self._buffer = self._file.readlines(self._bufsize) ! self._bufindex = 0 ! if not self._buffer: ! self.nextfile() # Recursive call return self.readline() From python-dev@python.org Fri Jan 5 14:45:51 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 06:45:51 -0800 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.39,1.40 config.h.in,2.80,2.81 configure,1.173,1.174 configure.in,1.181,1.182 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv3749 Modified Files: acconfig.h config.h.in configure configure.in Log Message: Configuration test for working getc_unlocked() (and flockfile() and funlockfile()). Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** acconfig.h 2000/10/09 17:01:03 1.39 --- acconfig.h 2001/01/05 14:45:48 1.40 *************** *** 33,36 **** --- 33,39 ---- #undef HAVE_ALTZONE + /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ + #undef HAVE_GETC_UNLOCKED + /* Define this if you have gethostbyname() */ #undef HAVE_GETHOSTBYNAME Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -r2.80 -r2.81 *** config.h.in 2000/11/29 02:44:05 2.80 --- config.h.in 2001/01/05 14:45:48 2.81 *************** *** 98,101 **** --- 98,104 ---- #undef HAVE_ALTZONE + /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ + #undef HAVE_GETC_UNLOCKED + /* Define this if you have some version of gethostbyname_r() */ #undef HAVE_GETHOSTBYNAME_R Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.173 retrieving revision 1.174 diff -C2 -r1.173 -r1.174 *** configure 2000/12/13 17:37:02 1.173 --- configure 2001/01/05 14:45:48 1.174 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.180 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.182 # Guess values for system-dependent variables and create Makefiles. *************** *** 5949,5952 **** --- 5949,5992 ---- fi + # check for getc_unlocked and related locking functions + echo $ac_n "checking for getc_unlocked() and friends""... $ac_c" 1>&6 + echo "configure:5954: checking for getc_unlocked() and friends" >&5 + if eval "test \"`echo '$''{'ac_cv_have_getc_unlocked'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 + else + + cat > conftest.$ac_ext < + int main() { + + FILE *f = fopen("/dev/null", "r"); + flockfile(f); + getc_unlocked(f); + funlockfile(f); + + ; return 0; } + EOF + if { (eval echo configure:5972: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + ac_cv_have_getc_unlocked=yes + else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + ac_cv_have_getc_unlocked=no + fi + rm -f conftest* + fi + + echo "$ac_t""$ac_cv_have_getc_unlocked" 1>&6 + if test "$ac_cv_have_getc_unlocked" = yes + then + cat >> confdefs.h <<\EOF + #define HAVE_GETC_UNLOCKED 1 + EOF + + fi # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! *************** *** 5958,5967 **** EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:5961: 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 < --- 5998,6007 ---- EOF echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 ! echo "configure:6001: 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 < *************** *** 5992,5996 **** echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:5995: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then --- 6032,6036 ---- echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6035: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.181 retrieving revision 1.182 diff -C2 -r1.181 -r1.182 *** configure.in 2000/12/13 17:37:02 1.181 --- configure.in 2001/01/05 14:45:49 1.182 *************** *** 1292,1295 **** --- 1292,1309 ---- fi + # check for getc_unlocked and related locking functions + AC_MSG_CHECKING(for getc_unlocked() and friends) + AC_CACHE_VAL(ac_cv_have_getc_unlocked, [ + AC_TRY_LINK([#include ],[ + FILE *f = fopen("/dev/null", "r"); + flockfile(f); + getc_unlocked(f); + funlockfile(f); + ], ac_cv_have_getc_unlocked=yes, ac_cv_have_getc_unlocked=no)]) + AC_MSG_RESULT($ac_cv_have_getc_unlocked) + if test "$ac_cv_have_getc_unlocked" = yes + then + AC_DEFINE(HAVE_GETC_UNLOCKED) + fi # THIS MUST BE LAST, IT CAN BREAK OTHER TESTS! From python-dev@python.org Fri Jan 5 14:59:20 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 06:59:20 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.59,1.60 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv5882 Modified Files: pep-0000.txt Log Message: Move 229 to active PEPs -- after all, Andrew seems close to a solution already! Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.59 retrieving revision 1.60 diff -C2 -r1.59 -r1.60 *** pep-0000.txt 2000/12/14 15:37:25 1.59 --- pep-0000.txt 2001/01/05 14:59:17 1.60 *************** *** 39,42 **** --- 39,43 ---- I 226 pep-0226.txt Python 2.1 Release Schedule Hylton S 227 pep-0227.txt Statically Nested Scopes Hylton + S 229 pep-0229.txt Using Distutils to Build Python Kuchling S 230 pep-0230.txt Warning Framework van Rossum S 232 pep-0232.txt Function Attributes Warsaw *************** *** 54,58 **** SD 225 pep-0225.txt Elementwise/Objectwise Operators Zhu, Lielens S 228 pep-0228.txt Reworking Python's Numeric Model Zadka - S 229 pep-0229.txt Using Distutils to Build Python Kuchling Incomplete PEPs (only an abstract) --- 55,58 ---- From python-dev@python.org Fri Jan 5 15:10:45 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 07:10:45 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0226.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv7639 Modified Files: pep-0226.txt Log Message: Update release date mentioned in intro para. Index: pep-0226.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0226.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** pep-0226.txt 2001/01/04 22:34:38 1.3 --- pep-0226.txt 2001/01/05 15:10:42 1.4 *************** *** 13,17 **** This document describes the post Python 2.0 development and release schedule. According to this schedule, Python 2.1 will be ! released in mid-March of 2001. The schedule primarily concerns itself with PEP-size items. Small bug fixes and changes will occur up until the first beta release. --- 13,17 ---- This document describes the post Python 2.0 development and release schedule. According to this schedule, Python 2.1 will be ! released in April of 2001. The schedule primarily concerns itself with PEP-size items. Small bug fixes and changes will occur up until the first beta release. From python-dev@python.org Fri Jan 5 16:54:37 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 08:54:37 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.60,1.61 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv24521 Modified Files: pep-0000.txt Log Message: Correct authorship on 207 and 208. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.60 retrieving revision 1.61 diff -C2 -r1.60 -r1.61 *** pep-0000.txt 2001/01/05 14:59:17 1.60 --- pep-0000.txt 2001/01/05 16:54:35 1.61 *************** *** 33,38 **** I 42 pep-0042.txt Small Feature Requests Hylton SD 205 pep-0205.txt Weak References Drake ! S 207 pep-0207.txt Rich Comparisons Lemburg, van Rossum ! S 208 pep-0208.txt Reworking the Coercion Model Schemenauer S 217 pep-0217.txt Display Hook for Interactive Use Zadka S 222 pep-0222.txt Web Library Enhancements Kuchling --- 33,38 ---- I 42 pep-0042.txt Small Feature Requests Hylton SD 205 pep-0205.txt Weak References Drake ! S 207 pep-0207.txt Rich Comparisons van Rossum, Ascher ! S 208 pep-0208.txt Reworking the Coercion Model Schemenauer, Lemburg S 217 pep-0217.txt Display Hook for Interactive Use Zadka S 222 pep-0222.txt Web Library Enhancements Kuchling *************** *** 105,110 **** SD 205 pep-0205.txt Weak References Drake I 206 pep-0206.txt 2.0 Batteries Included Zadka ! S 207 pep-0207.txt Rich Comparisons Lemburg, van Rossum ! S 208 pep-0208.txt Reworking the Coercion Model Schemenauer SD 209 pep-0209.txt Adding Multidimensional Arrays Ascher SD 210 pep-0210.txt Decoupling the Interpreter Loop Ascher --- 105,110 ---- SD 205 pep-0205.txt Weak References Drake I 206 pep-0206.txt 2.0 Batteries Included Zadka ! S 207 pep-0207.txt Rich Comparisons van Rossum, Ascher ! S 208 pep-0208.txt Reworking the Coercion Model Schemenauer, Lemburg SD 209 pep-0209.txt Adding Multidimensional Arrays Ascher SD 210 pep-0210.txt Decoupling the Interpreter Loop Ascher From python-dev@python.org Fri Jan 5 20:54:09 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 05 Jan 2001 12:54:09 -0800 Subject: [Python-checkins] CVS: python/dist/src/Demo/curses repeat.py,NONE,1.1 README,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/curses In directory usw-pr-cvs1:/tmp/cvs-serv19728 Modified Files: README Added Files: repeat.py Log Message: Added "repeat.py" -- repeatedly execute a shell command (like watch(1)). Updated and untabified the README file. --- NEW FILE: repeat.py --- #! /usr/bin/env python """repeat This simple program repeatedly (with 1-second intervals) executes the shell command given on the command line and displays the output (or as much of it as fits on the screen). It uses curses to paint each new output on top of the old output, so that if nothing changes, the screen doesn't change. This is handy to watch for changes in e.g. a directory or process listing. To end, hit Control-C. """ # Author: Guido van Rossum # Disclaimer: there's a Linux program named 'watch' that does the same # thing. Honestly, I didn't know of its existence when I wrote this! # To do: add features until it has the same functionality as watch(1); # then compare code size and development time. import os import sys import time import curses def main(): if not sys.argv[1:]: print __doc__ sys.exit(0) cmd = " ".join(sys.argv[1:]) p = os.popen(cmd, "r") text = p.read() sts = p.close() if sts: print >>sys.stderr, "Exit code:", sts sys.exit(sts) w = curses.initscr() try: while 1: w.erase() try: w.addstr(text) except curses.error: pass w.refresh() time.sleep(1) p = os.popen(cmd, "r") text = p.read() sts = p.close() if sts: print >>sys.stderr, "Exit code:", sts sys.exit(sts) finally: curses.endwin() main() Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/curses/README,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** README 2000/12/21 16:26:37 1.3 --- README 2001/01/05 20:54:07 1.4 *************** *** 11,19 **** course. ! ncurses.py -- currently only a panels demo XXX this won't work until panel support is checked in ! rain.py -- raindrops keep falling on my desktop ! tclock.py -- ASCII clock, by Howard Jones ! xmas.py -- I'm dreaming of an ASCII christmas Please send bugfixes and new contributions to me or, even better, --- 11,19 ---- course. ! ncurses.py -- currently only a panels demo XXX this won't work until panel support is checked in ! rain.py -- raindrops keep falling on my desktop ! tclock.py -- ASCII clock, by Howard Jones ! xmas.py -- I'm dreaming of an ASCII christmas Please send bugfixes and new contributions to me or, even better, *************** *** 25,29 **** =========== ! life.py Simple game of Life ! ! --- 25,28 ---- =========== ! life.py -- Simple game of Life ! repeat.py -- Repeatedly execute a shell command (like watch(1)) From python-dev@python.org Sat Jan 6 07:03:14 2001 From: python-dev@python.org (Barry Warsaw) Date: Fri, 05 Jan 2001 23:03:14 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0232.txt,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv5506 Modified Files: pep-0232.txt Log Message: Rewritten a bit for clarity, add a note about what you can set func.__dict__ to, added a note in the open issues about support for built-in function attributes, and included a link to the SF patch #103123. Index: pep-0232.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0232.txt,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** pep-0232.txt 2000/12/20 16:42:59 1.3 --- pep-0232.txt 2001/01/06 07:03:11 1.4 *************** *** 31,40 **** again, overloading docstrings with additional semantics. ! For example, John Aycock[1] has written a system where docstrings ! are used to define parsing rules. Zope's ZPublisher ORB[2] uses docstrings to signal "publishable" methods, i.e. methods that can ! be called through the web. And Tim Peters[3] has developed a ! system called doctest, where docstrings actually contain unit ! tests. The problem with this approach is that the overloaded semantics --- 31,39 ---- again, overloading docstrings with additional semantics. ! For example, John Aycock has written a system where docstrings are ! used to define parsing rules[1]. Zope's ZPublisher ORB[2] uses docstrings to signal "publishable" methods, i.e. methods that can ! be called through the web. And Tim Peters has developed a system ! called doctest[3], where docstrings actually contain unit tests. The problem with this approach is that the overloaded semantics *************** *** 46,52 **** Proposal ! This proposal simply adds a new dictionary to function objects, ! called func_dict (a.k.a. __dict__). This dictionary can be set ! and get using ordinary attribute set and get syntax. Unbound methods also gain set and get attribute syntax, but they --- 45,51 ---- Proposal ! This proposal adds a new dictionary to function objects, called ! func_dict (a.k.a. __dict__). This dictionary can be set and get ! using ordinary attribute set and get syntax. Unbound methods also gain set and get attribute syntax, but they *************** *** 58,62 **** --- 57,65 ---- the underlying function object. + A function object's __dict__ can also be set, but only to a + dictionary object (i.e. setting __dict__ to UserDict raises a + TypeError). + Examples *************** *** 78,83 **** def a(self): 'just a docstring' - C.a.publish = 1 c = C() if c.a.publish: --- 81,86 ---- def a(self): 'just a docstring' + a.publish = 1 c = C() if c.a.publish: *************** *** 87,91 **** Other Uses ! Paul Prescod enumerated a bunch of uses http://mail.python.org/pipermail/python-dev/2000-April/003364.html --- 90,94 ---- Other Uses ! Paul Prescod enumerated a bunch of other uses: http://mail.python.org/pipermail/python-dev/2000-April/003364.html *************** *** 96,104 **** 1) Should function attributes be settable or gettable when in restricted execution mode? What about __dict__/func_dict? ! 2) __doc__ is the only function attribute that currently has syntactic support for conveniently setting. It may be ! worthwhile to enhance the language for supporting easy function ! attribute setting. Here are some suggested syntaxes: def a { --- 99,116 ---- 1) Should function attributes be settable or gettable when in restricted execution mode? What about __dict__/func_dict? + + 2) Should built-in functions have writable attributes? The + current patch only supports attributes on user defined + (i.e. Python) functions and methods. Adding support to + built-in functions isn't difficult -- it would essentially + mirror the implementation for user defined functions (i.e. we + add a PyObject* to the PyCFunctionObject struct and write + getattro and setattro functions to read and write them). ! 3) __doc__ is the only function attribute that currently has syntactic support for conveniently setting. It may be ! worthwhile to eventually enhance the language for supporting ! easy function attribute setting. Here are some syntaxes ! suggested by PEP reviewers: def a { *************** *** 117,121 **** It isn't currently clear if special syntax is necessary or ! desirable. --- 129,134 ---- It isn't currently clear if special syntax is necessary or ! desirable. It would be sufficient to postpone syntactic ! support for some future PEP. *************** *** 135,141 **** - useless until syntactic support is included ! Countering some of these arguments is the observation that, with ! the current implementation, __doc__ can in fact be set to any type ! of object, so some semblance of writable function attributes are already feasible. But that approach is yet another corruption of __doc__. --- 148,154 ---- - useless until syntactic support is included ! Countering some of these arguments is the observation that with ! vanilla Python 2.0, __doc__ can in fact be set to any type of ! object, so some semblance of writable function attributes are already feasible. But that approach is yet another corruption of __doc__. *************** *** 153,158 **** Reference Implementation ! A reference implementation will be uploaded to SourceForge soon. --- 166,176 ---- Reference Implementation + + The reference implementation is available on SourceForge as a + patch against the Python CVS tree (patch #103123). This patch + doesn't include the regrtest module and output file. Those are + available upon request. ! http://sourceforge.net/patch/?func=detailpatch&patch_id=103123&group_id=5470 From python-dev@python.org Sat Jan 6 15:00:00 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Sat, 06 Jan 2001 07:00:00 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects unicodeobject.c,2.71,2.72 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv1461/Objects Modified Files: unicodeobject.c Log Message: This patch adds a new feature to the builtin charmap codec: The mapping dictionaries can now contain 1-n mappings, meaning that character ordinals may be mapped to strings or Unicode object, e.g. 0x0078 ('x') -> u"abc", causing the ordinal to be replaced by the complete string or Unicode object instead of just one character. Another feature introduced by the patch is that of mapping oridnals to the emtpy string. This allows removing characters. The patch is different from patch #103100 in that it does not cause a performance hit for the normal use case of 1-1 mappings. Written by Marc-Andre Lemburg, copyright assigned to Guido van Rossum. Index: unicodeobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/unicodeobject.c,v retrieving revision 2.71 retrieving revision 2.72 diff -C2 -r2.71 -r2.72 *** unicodeobject.c 2001/01/03 21:29:14 2.71 --- unicodeobject.c 2001/01/06 14:59:58 2.72 *************** *** 1948,1951 **** --- 1948,1952 ---- PyUnicodeObject *v; Py_UNICODE *p; + int extrachars = 0; /* Default to Latin-1 */ *************** *** 1999,2010 **** } else if (PyUnicode_Check(x)) { ! if (PyUnicode_GET_SIZE(x) != 1) { /* 1-n mapping */ ! PyErr_SetString(PyExc_NotImplementedError, ! "1-n mappings are currently not implemented"); Py_DECREF(x); goto onError; } ! *p++ = *PyUnicode_AS_UNICODE(x); } else { --- 2000,2030 ---- } else if (PyUnicode_Check(x)) { ! int targetsize = PyUnicode_GET_SIZE(x); ! ! if (targetsize == 1) ! /* 1-1 mapping */ ! *p++ = *PyUnicode_AS_UNICODE(x); ! ! else if (targetsize > 1) { /* 1-n mapping */ ! if (targetsize > extrachars) { ! /* resize first */ ! int oldpos = (int)(p - PyUnicode_AS_UNICODE(v)); ! int needed = (targetsize - extrachars) + \ ! (targetsize << 2); ! extrachars += needed; ! if (_PyUnicode_Resize(v, PyUnicode_GET_SIZE(v) + needed)) { Py_DECREF(x); goto onError; + } + p = PyUnicode_AS_UNICODE(v) + oldpos; + } + Py_UNICODE_COPY(p, + PyUnicode_AS_UNICODE(x), + targetsize); + p += targetsize; + extrachars -= targetsize; } ! /* 1-0 mapping: skip the character */ } else { *************** *** 2064,2067 **** --- 2084,2088 ---- PyObject *v; char *s; + int extrachars = 0; /* Default to Latin-1 */ *************** *** 2115,2126 **** } else if (PyString_Check(x)) { ! if (PyString_GET_SIZE(x) != 1) { /* 1-n mapping */ ! PyErr_SetString(PyExc_NotImplementedError, ! "1-n mappings are currently not implemented"); Py_DECREF(x); goto onError; } ! *s++ = *PyString_AS_STRING(x); } else { --- 2136,2166 ---- } else if (PyString_Check(x)) { ! int targetsize = PyString_GET_SIZE(x); ! ! if (targetsize == 1) ! /* 1-1 mapping */ ! *s++ = *PyString_AS_STRING(x); ! ! else if (targetsize > 1) { /* 1-n mapping */ ! if (targetsize > extrachars) { ! /* resize first */ ! int oldpos = (int)(s - PyString_AS_STRING(v)); ! int needed = (targetsize - extrachars) + \ ! (targetsize << 2); ! extrachars += needed; ! if (_PyString_Resize(&v, PyString_GET_SIZE(v) + needed)) { Py_DECREF(x); goto onError; + } + s = PyString_AS_STRING(v) + oldpos; + } + memcpy(s, + PyString_AS_STRING(x), + targetsize); + s += targetsize; + extrachars -= targetsize; } ! /* 1-0 mapping: skip the character */ } else { From python-dev@python.org Sat Jan 6 15:09:59 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Sat, 06 Jan 2001 07:09:59 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_charmapcodec.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv1958/Lib/test Added Files: test_charmapcodec.py Log Message: This patch adds a new feature to the builtin charmap codec: the mapping dictionaries can now contain 1-n mappings, meaning that character ordinals may be mapped to strings or Unicode object, e.g. 0x0078 ('x') -> u"abc", causing the ordinal to be replaced by the complete string or Unicode object instead of just one character. Another feature introduced by the patch is that of mapping oridnals to the emtpy string. This allows removing characters. The patch is different from patch #103100 in that it does not cause a performance hit for the normal use case of 1-1 mappings. Written by Marc-Andre Lemburg, copyright assigned to Guido van Rossum. --- NEW FILE: test_charmapcodec.py --- """ Python Character Mapping Codec test Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright 2000 Guido van Rossum. """#" import codecs ### Codec APIs class Codec(codecs.Codec): def encode(self,input,errors='strict'): return codecs.charmap_encode(input,errors,encoding_map) def decode(self,input,errors='strict'): return codecs.charmap_decode(input,errors,decoding_map) class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### encodings module API def getregentry(): return (Codec().encode,Codec().decode,StreamReader,StreamWriter) ### Decoding Map decoding_map = codecs.make_identity_dict(range(256)) decoding_map.update({ 0x0078: u"abc", "abc": 0x0078, }) ### Encoding Map encoding_map = {} for k,v in decoding_map.items(): encoding_map[v] = k ### Tests def check(a, b): if a != b: print '*** check failed: %s != %s' % (repr(a), repr(b)) check(unicode('abc', 'mycp'), u'abc') check(unicode('xdef', 'mycp'), u'abcdef') check(unicode('defx', 'mycp'), u'defabc') check(unicode('dxf', 'mycp'), u'dabcf') check(unicode('dxfx', 'mycp'), u'dabcfabc') check(u'abc'.encode('mycp'), 'abc') check(u'xdef'.encode('mycp'), 'abcdef') check(u'defx'.encode('mycp'), 'defabc') check(u'dxf'.encode('mycp'), 'dabcf') check(u'dxfx'.encode('mycp'), 'dabcfabc') From python-dev@python.org Sat Jan 6 15:09:59 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Sat, 06 Jan 2001 07:09:59 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_charmapcodec,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv1958/Lib/test/output Added Files: test_charmapcodec Log Message: This patch adds a new feature to the builtin charmap codec: the mapping dictionaries can now contain 1-n mappings, meaning that character ordinals may be mapped to strings or Unicode object, e.g. 0x0078 ('x') -> u"abc", causing the ordinal to be replaced by the complete string or Unicode object instead of just one character. Another feature introduced by the patch is that of mapping oridnals to the emtpy string. This allows removing characters. The patch is different from patch #103100 in that it does not cause a performance hit for the normal use case of 1-1 mappings. Written by Marc-Andre Lemburg, copyright assigned to Guido van Rossum. --- NEW FILE: test_charmapcodec --- test_charmapcodec From python-dev@python.org Sun Jan 7 06:00:01 2001 From: python-dev@python.org (Fred L. Drake) Date: Sat, 06 Jan 2001 22:00:01 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules parsermodule.c,2.59,2.60 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv13436/Modules Modified Files: parsermodule.c Log Message: Fix problems with validation of import statement parse trees. This closes SF bug #127271. Index: parsermodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/parsermodule.c,v retrieving revision 2.59 retrieving revision 2.60 diff -C2 -r2.59 -r2.60 *** parsermodule.c 2000/12/11 22:08:27 2.59 --- parsermodule.c 2001/01/07 05:59:59 2.60 *************** *** 1559,1562 **** --- 1559,1581 ---- + /* dotted_name: NAME ("." NAME)* + */ + static int + validate_dotted_name(node *tree) + { + int nch = NCH(tree); + int res = (validate_ntype(tree, dotted_name) + && is_odd(nch) + && validate_name(CHILD(tree, 0), NULL)); + int i; + + for (i = 1; res && (i < nch); i += 2) { + res = (validate_dot(CHILD(tree, i)) + && validate_name(CHILD(tree, i+1), NULL)); + } + return res; + } + + /* dotted_as_name: dotted_name [NAME NAME] */ *************** *** 1569,1575 **** if (res) { if (nch == 1) ! res = validate_ntype(CHILD(tree, 0), dotted_name); else if (nch == 3) ! res = (validate_ntype(CHILD(tree, 0), dotted_name) && validate_name(CHILD(tree, 1), "as") && validate_name(CHILD(tree, 2), NULL)); --- 1588,1594 ---- if (res) { if (nch == 1) ! res = validate_dotted_name(CHILD(tree, 0)); else if (nch == 3) ! res = (validate_dotted_name(CHILD(tree, 0)) && validate_name(CHILD(tree, 1), "as") && validate_name(CHILD(tree, 2), NULL)); *************** *** 1602,1611 **** for (j = 2; res && (j < nch); j += 2) res = (validate_comma(CHILD(tree, j)) ! && validate_ntype(CHILD(tree, j + 1), dotted_name)); } else if (res && (res = validate_name(CHILD(tree, 0), "from"))) { res = ((nch >= 4) && is_even(nch) ! && validate_name(CHILD(tree, 2), "import") ! && validate_dotted_as_name(CHILD(tree, 1))); if (nch == 4) { if (TYPE(CHILD(tree, 3)) == import_as_name) --- 1621,1630 ---- for (j = 2; res && (j < nch); j += 2) res = (validate_comma(CHILD(tree, j)) ! && validate_dotted_as_name(CHILD(tree, j + 1))); } else if (res && (res = validate_name(CHILD(tree, 0), "from"))) { res = ((nch >= 4) && is_even(nch) ! && validate_dotted_name(CHILD(tree, 1)) ! && validate_name(CHILD(tree, 2), "import")); if (nch == 4) { if (TYPE(CHILD(tree, 3)) == import_as_name) From python-dev@python.org Sun Jan 7 06:02:21 2001 From: python-dev@python.org (Fred L. Drake) Date: Sat, 06 Jan 2001 22:02:21 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_parser.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13664/Lib/test Modified Files: test_parser.py Log Message: Add more regression tests, including for the import statement variations. These will detect regression on SF bug #127271 and other import statement bugs. Index: test_parser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_parser.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** test_parser.py 2000/12/11 22:12:09 1.3 --- test_parser.py 2001/01/07 06:02:19 1.4 *************** *** 4,9 **** import sys ! from parser import expr, suite, sequence2ast ! from test_support import verbose # --- 4,8 ---- import sys ! from test_support import TestFailed # *************** *** 19,36 **** st2 = parser.sequence2ast(t) except parser.ParserError: ! print "Failing syntax tree:" ! pprint.pprint(t) ! raise def roundtrip_fromfile(filename): ! roundtrip(suite, open(filename).read()) def test_expr(s): print "expr:", s ! roundtrip(expr, s) def test_suite(s): print "suite:", s ! roundtrip(suite, s) --- 18,33 ---- st2 = parser.sequence2ast(t) except parser.ParserError: ! raise TestFailed, s def roundtrip_fromfile(filename): ! roundtrip(parser.suite, open(filename).read()) def test_expr(s): print "expr:", s ! roundtrip(parser.expr, s) def test_suite(s): print "suite:", s ! roundtrip(parser.suite, s) *************** *** 89,94 **** --- 86,120 ---- test_suite("a >>= b") test_suite("a **= b") + test_suite("def f(): pass") + test_suite("def f(*args): pass") + test_suite("def f(*args, **kw): pass") + test_suite("def f(**kw): pass") test_suite("def f(foo=bar): pass") + test_suite("def f(foo=bar, *args): pass") + test_suite("def f(foo=bar, *args, **kw): pass") + test_suite("def f(foo=bar, **kw): pass") + + test_suite("def f(a, b): pass") + test_suite("def f(a, b, *args): pass") + test_suite("def f(a, b, *args, **kw): pass") + test_suite("def f(a, b, **kw): pass") + test_suite("def f(a, b, foo=bar): pass") + test_suite("def f(a, b, foo=bar, *args): pass") + test_suite("def f(a, b, foo=bar, *args, **kw): pass") + test_suite("def f(a, b, foo=bar, **kw): pass") + + test_suite("from sys.path import *") + test_suite("from sys.path import dirname") + test_suite("from sys.path import dirname as my_dirname") + test_suite("from sys.path import dirname, basename") + test_suite("from sys.path import dirname as my_dirname, basename") + test_suite("from sys.path import dirname, basename as my_basename") + + test_suite("import sys") + test_suite("import sys as system") + test_suite("import sys, math") + test_suite("import sys as system, math") + test_suite("import sys, math as my_math") #d = os.path.dirname(os.__file__) *************** *** 108,115 **** print label try: ! sequence2ast(tree) except parser.ParserError: print "caught expected exception for invalid tree" - pass else: print "test failed: did not properly detect invalid tree:" --- 134,140 ---- print label try: ! parser.sequence2ast(tree) except parser.ParserError: print "caught expected exception for invalid tree" else: print "test failed: did not properly detect invalid tree:" From python-dev@python.org Sun Jan 7 06:02:21 2001 From: python-dev@python.org (Fred L. Drake) Date: Sat, 06 Jan 2001 22:02:21 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_parser,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv13664/Lib/test/output Modified Files: test_parser Log Message: Add more regression tests, including for the import statement variations. These will detect regression on SF bug #127271 and other import statement bugs. Index: test_parser =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_parser,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** test_parser 2000/12/11 22:12:09 1.3 --- test_parser 2001/01/07 06:02:19 1.4 *************** *** 51,55 **** --- 51,80 ---- suite: a **= b suite: def f(): pass + suite: def f(*args): pass + suite: def f(*args, **kw): pass + suite: def f(**kw): pass suite: def f(foo=bar): pass + suite: def f(foo=bar, *args): pass + suite: def f(foo=bar, *args, **kw): pass + suite: def f(foo=bar, **kw): pass + suite: def f(a, b): pass + suite: def f(a, b, *args): pass + suite: def f(a, b, *args, **kw): pass + suite: def f(a, b, **kw): pass + suite: def f(a, b, foo=bar): pass + suite: def f(a, b, foo=bar, *args): pass + suite: def f(a, b, foo=bar, *args, **kw): pass + suite: def f(a, b, foo=bar, **kw): pass + suite: from sys.path import * + suite: from sys.path import dirname + suite: from sys.path import dirname as my_dirname + suite: from sys.path import dirname, basename + suite: from sys.path import dirname as my_dirname, basename + suite: from sys.path import dirname, basename as my_basename + suite: import sys + suite: import sys as system + suite: import sys, math + suite: import sys as system, math + suite: import sys, math as my_math Invalid parse trees: From python-dev@python.org Sun Jan 7 20:51:41 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 07 Jan 2001 12:51:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.97,2.98 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv17414 Modified Files: fileobject.c Log Message: Tim noticed that I had botched get_line_raw(). Looking again, I realized that this behavior is already present in PyFile_GetLine(), which is the only place that needs it. A little refactoring of that function made get_line_raw() redundant. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.97 retrieving revision 2.98 diff -C2 -r2.97 -r2.98 *** fileobject.c 2001/01/05 14:43:05 2.97 --- fileobject.c 2001/01/07 20:51:39 2.98 *************** *** 640,644 **** > 0: max length; = 0: read arbitrary line; ! < 0: illegal (use get_line_raw() instead) */ --- 640,644 ---- > 0: max length; = 0: read arbitrary line; ! < 0: invalid */ *************** *** 710,732 **** } - /* Internal routine to get a line for raw_input(): - strip trailing '\n', raise EOFError if EOF reached immediately - */ - - static PyObject * - get_line_raw(PyFileObject *f) - { - PyObject *line; - - line = get_line(f, 0); - if (line == NULL || PyString_GET_SIZE(line) > 0) - return line; - else { - Py_DECREF(line); - PyErr_SetString(PyExc_EOFError, "EOF when reading a line"); - return NULL; - } - } - /* External C interface */ --- 710,713 ---- *************** *** 734,745 **** PyFile_GetLine(PyObject *f, int n) { if (f == NULL) { PyErr_BadInternalCall(); return NULL; } ! if (!PyFile_Check(f)) { PyObject *reader; PyObject *args; ! PyObject *result; reader = PyObject_GetAttrString(f, "readline"); if (reader == NULL) --- 715,734 ---- PyFile_GetLine(PyObject *f, int n) { + PyObject *result; + if (f == NULL) { PyErr_BadInternalCall(); return NULL; } ! ! if (PyFile_Check(f)) { ! if (((PyFileObject*)f)->f_fp == NULL) ! return err_closed(); ! result = get_line((PyFileObject *)f, n); ! } ! else { PyObject *reader; PyObject *args; ! reader = PyObject_GetAttrString(f, "readline"); if (reader == NULL) *************** *** 761,794 **** PyErr_SetString(PyExc_TypeError, "object.readline() returned non-string"); } ! if (n < 0 && result != NULL) { ! char *s = PyString_AsString(result); ! int len = PyString_Size(result); ! if (len == 0) { Py_DECREF(result); ! result = NULL; ! PyErr_SetString(PyExc_EOFError, ! "EOF when reading a line"); ! } ! else if (s[len-1] == '\n') { ! if (result->ob_refcnt == 1) ! _PyString_Resize(&result, len-1); ! else { ! PyObject *v; ! v = PyString_FromStringAndSize(s, ! len-1); ! Py_DECREF(result); ! result = v; ! } } } - return result; } ! if (((PyFileObject*)f)->f_fp == NULL) ! return err_closed(); ! if (n < 0) ! return get_line_raw((PyFileObject *)f); ! else ! return get_line((PyFileObject *)f, n); } --- 750,777 ---- PyErr_SetString(PyExc_TypeError, "object.readline() returned non-string"); + } + } + + if (n < 0 && result != NULL && PyString_Check(result)) { + char *s = PyString_AS_STRING(result); + int len = PyString_GET_SIZE(result); + if (len == 0) { + Py_DECREF(result); + result = NULL; + PyErr_SetString(PyExc_EOFError, + "EOF when reading a line"); } ! else if (s[len-1] == '\n') { ! if (result->ob_refcnt == 1) ! _PyString_Resize(&result, len-1); ! else { ! PyObject *v; ! v = PyString_FromStringAndSize(s, len-1); Py_DECREF(result); ! result = v; } } } ! return result; } From python-dev@python.org Sun Jan 7 21:19:36 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 13:19:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_bufio.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19540/python/dist/src/Lib/test Added Files: test_bufio.py Log Message: MS Win32 .readline() speedup, as discussed on Python-Dev. This is a tricky variant that never needs to "search from the right". Also fixed unlikely memory leak in get_line, if string size overflows INTMAX. Also new std test test_bufio to make sure .readline() works. --- NEW FILE: test_bufio.py --- from test_support import TestFailed, TESTFN # Simple test to ensure that optimizations in fileobject.c deliver # the expected results. For best testing, run this under a debug-build # Python too (to exercise asserts in the C code). # Repeat string 'pattern' as often as needed to reach total length # 'length'. Then call try_one with that string, a string one larger # than that, and a string one smaller than that. The main driver # feeds this all small sizes and various powers of 2, so we exercise # all likely stdio buffer sizes, and "off by one" errors on both # sides. def drive_one(pattern, length): q, r = divmod(length, len(pattern)) teststring = pattern * q + pattern[:r] assert len(teststring) == length try_one(teststring) try_one(teststring + "x") try_one(teststring[:-1]) # Write s + "\n" + s to file, then open it and ensure that successive # .readline()s deliver what we wrote. def try_one(s): # Since C doesn't guarantee we can write/read arbitrary bytes in text # files, use binary mode. f = open(TESTFN, "wb") # write once with \n and once without f.write(s) f.write("\n") f.write(s) f.close() f = open(TESTFN, "rb") line = f.readline() if line != s + "\n": raise TestFailed("Expected %r got %r" % (s + "\n", line)) line = f.readline() if line != s: raise TestFailed("Expected %r got %r" % (s, line)) line = f.readline() if line: raise TestFailed("Expected EOF but got %r" % line) f.close() # A pattern with prime length, to avoid simple relationships with # stdio buffer sizes. primepat = "1234567890\00\01\02\03\04\05\06\07" nullpat = "\0" * 1000 try: for size in range(1, 257) + [512, 1000, 1024, 2048, 4096, 8192, 10000, 16384, 32768, 65536, 1000000]: drive_one(primepat, size) drive_one(nullpat, size) finally: try: import os os.unlink(TESTFN) except: pass From python-dev@python.org Sun Jan 7 21:19:36 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 13:19:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_bufio,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv19540/python/dist/src/Lib/test/output Added Files: test_bufio Log Message: MS Win32 .readline() speedup, as discussed on Python-Dev. This is a tricky variant that never needs to "search from the right". Also fixed unlikely memory leak in get_line, if string size overflows INTMAX. Also new std test test_bufio to make sure .readline() works. --- NEW FILE: test_bufio --- test_bufio From python-dev@python.org Sun Jan 7 21:19:36 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 13:19:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.98,2.99 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv19540/python/dist/src/Objects Modified Files: fileobject.c Log Message: MS Win32 .readline() speedup, as discussed on Python-Dev. This is a tricky variant that never needs to "search from the right". Also fixed unlikely memory leak in get_line, if string size overflows INTMAX. Also new std test test_bufio to make sure .readline() works. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.98 retrieving revision 2.99 diff -C2 -r2.98 -r2.99 *** fileobject.c 2001/01/07 20:51:39 2.98 --- fileobject.c 2001/01/07 21:19:34 2.99 *************** *** 245,249 **** return 0 on success, non-zero on failure (with errno set) */ int ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 _portable_fseek(FILE *fp, fpos_t offset, int whence) #else --- 245,249 ---- return 0 on success, non-zero on failure (with errno set) */ int ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 _portable_fseek(FILE *fp, fpos_t offset, int whence) #else *************** *** 257,261 **** #elif defined(__BEOS__) return _fseek(fp, offset, whence); ! #elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable fsetpos() and tell() to implement fseek()*/ --- 257,261 ---- #elif defined(__BEOS__) return _fseek(fp, offset, whence); ! #elif defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_FPOS_T >= 8 /* lacking a 64-bit capable fseek() (as Win64 does) use a 64-bit capable fsetpos() and tell() to implement fseek()*/ *************** *** 288,292 **** Return -1 on failure with errno set appropriately, current file position on success */ ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t #else --- 288,292 ---- Return -1 on failure with errno set appropriately, current file position on success */ ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t #else *************** *** 315,319 **** int whence; int ret; ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t offset, pos; #else --- 315,319 ---- int whence; int ret; ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t offset, pos; #else *************** *** 321,325 **** #endif /* !MS_WIN64 */ PyObject *offobj; ! if (f->f_fp == NULL) return err_closed(); --- 321,325 ---- #endif /* !MS_WIN64 */ PyObject *offobj; ! if (f->f_fp == NULL) return err_closed(); *************** *** 335,339 **** if (PyErr_Occurred()) return NULL; ! Py_BEGIN_ALLOW_THREADS errno = 0; --- 335,339 ---- if (PyErr_Occurred()) return NULL; ! Py_BEGIN_ALLOW_THREADS errno = 0; *************** *** 356,360 **** { int ret; ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t newsize; #else --- 356,360 ---- { int ret; ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t newsize; #else *************** *** 362,366 **** #endif PyObject *newsizeobj; ! if (f->f_fp == NULL) return err_closed(); --- 362,366 ---- #endif PyObject *newsizeobj; ! if (f->f_fp == NULL) return err_closed(); *************** *** 417,421 **** if (ret != 0) goto onioerror; #endif /* !MS_WIN32 */ ! Py_INCREF(Py_None); return Py_None; --- 417,421 ---- if (ret != 0) goto onioerror; #endif /* !MS_WIN32 */ ! Py_INCREF(Py_None); return Py_None; *************** *** 431,435 **** file_tell(PyFileObject *f, PyObject *args) { ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t pos; #else --- 431,435 ---- file_tell(PyFileObject *f, PyObject *args) { ! #if defined(HAVE_LARGEFILE_SUPPORT) && SIZEOF_OFF_T < 8 && SIZEOF_FPOS_T >= 8 fpos_t pos; #else *************** *** 471,475 **** { int res; ! if (f->f_fp == NULL) return err_closed(); --- 471,475 ---- { int res; ! if (f->f_fp == NULL) return err_closed(); *************** *** 560,564 **** size_t bytesread, buffersize, chunksize; PyObject *v; ! if (f->f_fp == NULL) return err_closed(); --- 560,564 ---- size_t bytesread, buffersize, chunksize; PyObject *v; ! if (f->f_fp == NULL) return err_closed(); *************** *** 611,615 **** char *ptr; size_t ntodo, ndone, nnow; ! if (f->f_fp == NULL) return err_closed(); --- 611,615 ---- char *ptr; size_t ntodo, ndone, nnow; ! if (f->f_fp == NULL) return err_closed(); *************** *** 635,638 **** --- 635,802 ---- } + /************************************************************************** + Win32 MS routine to get next line. + + Under MSVC 6: + + + MS threadsafe getc is very slow (multiple layers of function calls + before+after each character, to lock+unlock the stream). + + The stream-locking functions are MS-internal -- can't access them + from user code. + + There's nothing Tim could find in the MS C or platform SDK libraries + that can worm around this. + + MS fgets locks/unlocks only once per line; it's the only hook we have. + + So we use fgets for speed(!), despite that it's painful. + + MS realloc is also slow. + + In the usual case, we have one pleasantly small line already sitting in a + stdio buffer, and we optimize heavily for that case. + + CAUTION: This routine cheats, relying on how MSVC 6 works internally. + They seem to be relatively safe cheats, but we should expect this code + to break someday. + **************************************************************************/ + + /* if Win32 and MS's compiler */ + #if defined(MS_WIN32) && defined(_MSC_VER) + #define USE_MS_GETLINE_HACK + #endif + + #ifdef USE_MS_GETLINE_HACK + static PyObject* + ms_getline_hack(FILE *fp) + { + #define INITBUFSIZE 100 + #define INCBUFSIZE 1000 + PyObject* v; /* the string object result */ + size_t total_v_size; /* total # chars in v's buffer */ + char* pvfree; /* address of next free slot */ + char* pvend; /* address one beyond last free slot */ + char* p; /* temp */ + + if (fp->_cnt > 0) { /* HACK: "_cnt" isn't advertised */ + /* optimize for normal case: something sitting in the + * buffer ready to go; avoid thread fiddling & realloc + * if possible + */ + char msbuf[INITBUFSIZE]; + memset(msbuf, '\n', INITBUFSIZE); + p = fgets(msbuf, INITBUFSIZE, fp); + /* since we didn't lock the file, there's no guarantee + * anything was still in the buffer + */ + if (p == NULL) { + clearerr(fp); + if (PyErr_CheckSignals()) + return NULL; + v = PyString_FromStringAndSize("", 0); + return v; + } + /* fgets read *something* */ + p = memchr(msbuf, '\n', INITBUFSIZE); + if (p != NULL) { + /* Did the \n come from fgets or from us? + * Since fgets stops at the first \n, and then + * writes \0, if it's from fgets a \0 must be next. + * But if that's so, it could not have come from us, + * since the \n's we filled the buffer with have only + * more \n's to the right. + */ + pvend = msbuf + INITBUFSIZE; + if (p+1 < pvend && *(p+1) == '\0') { + /* it's from fgets: we win! */ + v = PyString_FromStringAndSize(msbuf, + p - msbuf + 1); + return v; + } + /* Must be from us: fgets didn't fill the buffer + * and didn't find a newline, so it must be the + * last and newline-free line of the file. + */ + assert(p > msbuf && *(p-1) == '\0'); + v = PyString_FromStringAndSize(msbuf, p - msbuf - 1); + return v; + } + /* yuck: fgets overwrote all the newlines, i.e. the entire + * buffer. So this line isn't over yet, or maybe it is but + * we're exactly at EOF; in either case, we're tired . + */ + assert(msbuf[INITBUFSIZE-1] == '\0'); + total_v_size = INITBUFSIZE + INCBUFSIZE; + v = PyString_FromStringAndSize((char*)NULL, + (int)total_v_size); + if (v == NULL) + return v; + /* copy over everything except the last null byte */ + memcpy(BUF(v), msbuf, INITBUFSIZE-1); + pvfree = BUF(v) + INITBUFSIZE - 1; + } + else { + /* The stream isn't ready or isn't buffered. */ + v = PyString_FromStringAndSize((char*)NULL, INITBUFSIZE); + if (v == NULL) + return v; + total_v_size = INITBUFSIZE; + pvfree = BUF(v); + } + + /* Keep reading stuff into v; if it ever ends successfully, break + * after setting p one beyond the end of the line. + */ + for (;;) { + size_t nfree; + + Py_BEGIN_ALLOW_THREADS + pvend = BUF(v) + total_v_size; + nfree = pvend - pvfree; + memset(pvfree, '\n', nfree); + p = fgets(pvfree, nfree, fp); + Py_END_ALLOW_THREADS + + if (p == NULL) { + clearerr(fp); + if (PyErr_CheckSignals()) { + Py_DECREF(v); + return NULL; + } + p = pvfree; + break; + } + /* See the "normal case" comments above for details. */ + p = memchr(pvfree, '\n', nfree); + if (p != NULL) { + if (p+1 < pvend && *(p+1) == '\0') { + /* \n came from fgets */ + ++p; + break; + } + /* \n came from us; last line of file, no newline */ + assert(p > pvfree && *(p-1) == '\0'); + --p; + break; + } + /* expand buffer and try again */ + assert(*(pvend-1) == '\0'); + total_v_size += INCBUFSIZE; + if (total_v_size > INT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "line is longer than a Python string can hold"); + Py_DECREF(v); + return NULL; + } + if (_PyString_Resize(&v, (int)total_v_size) < 0) + return NULL; + /* overwrite the trailing null byte */ + pvfree = BUF(v) + (total_v_size - INCBUFSIZE - 1); + } + if (BUF(v) + total_v_size != p) + _PyString_Resize(&v, p - BUF(v)); + return v; + #undef INITBUFSIZE + #undef INCBUFSIZE + } + #endif /* ifdef USE_MS_GETLINE_HACK */ /* Internal routine to get a line. *************** *** 662,665 **** --- 826,833 ---- PyObject *v; + #ifdef USE_MS_GETLINE_HACK + if (n == 0) + return ms_getline_hack(fp); + #endif n2 = n > 0 ? n : 100; v = PyString_FromStringAndSize((char *)NULL, n2); *************** *** 696,699 **** --- 864,868 ---- PyErr_SetString(PyExc_OverflowError, "line is longer than a Python string can hold"); + Py_DECREF(v); return NULL; } *************** *** 1000,1004 **** const char *buffer; int len; ! if (((f->f_binary && PyObject_AsReadBuffer(v, (const void**)&buffer, --- 1169,1173 ---- const char *buffer; int len; ! if (((f->f_binary && PyObject_AsReadBuffer(v, (const void**)&buffer, *************** *** 1256,1260 **** if (fno == NULL) return -1; ! if (PyInt_Check(fno)) { fd = PyInt_AsLong(fno); --- 1425,1429 ---- if (fno == NULL) return -1; ! if (PyInt_Check(fno)) { fd = PyInt_AsLong(fno); From python-dev@python.org Mon Jan 8 00:53:15 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 16:53:15 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.99,2.100 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv9879/python/dist/src/objects Modified Files: fileobject.c Log Message: Fiddled ms_getline_hack after talking w/ Guido: made clearer that the code duplication is to let us get away without a realloc whenever possible; boosted the init buf size (the cutoff at which we *can* get away without a realloc) from 100 to 200 so that more files can enjoy this boost; and allowed other threads to run in all cases. The last two cost something, but not significantly: in my fat test case, less than a 1% slowdown total. Since my test case has a great many short lines, that's probably the worst slowdown, too. While the logic barely changed, there were lots of edits. This also gets rid of the reference to fp->_cnt, so the last platform assumption being made here is that fgets doesn't overwrite bytes capriciously (== beyond the terminating null byte it must write). Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.99 retrieving revision 2.100 diff -C2 -r2.99 -r2.100 *** fileobject.c 2001/01/07 21:19:34 2.99 --- fileobject.c 2001/01/08 00:53:12 2.100 *************** *** 655,661 **** stdio buffer, and we optimize heavily for that case. ! CAUTION: This routine cheats, relying on how MSVC 6 works internally. ! They seem to be relatively safe cheats, but we should expect this code ! to break someday. **************************************************************************/ --- 655,662 ---- stdio buffer, and we optimize heavily for that case. ! CAUTION: This routine cheats, relying on that MSVC 6 fgets doesn't overwrite ! any buffer positions to the right of the terminating null byte. Seems ! unlikely that will change in the future, but ... std test test_bufio should ! catch it if that changes. **************************************************************************/ *************** *** 669,673 **** ms_getline_hack(FILE *fp) { ! #define INITBUFSIZE 100 #define INCBUFSIZE 1000 PyObject* v; /* the string object result */ --- 670,684 ---- ms_getline_hack(FILE *fp) { ! /* INITBUFSIZE is the maximum line length that lets us get away with the fast ! * no-realloc path. get_line uses 100 for its initial size, but isn't trying ! * to avoid reallocs. Under MSVC 6, and using files with lines all under 100 ! * chars long, dropping this from 200 to 100 bought less than 1% speedup. ! * Since many kinds of log files have lines exceeding 100 chars, the tiny ! * slowdown from using 200 is more than offset by the large speedup for such ! * log files. ! * INCBUFSIZE is the amount by which we grow the buffer, if INITBUFSIZE isn't ! * enough. It doesn't much matter what this set to. ! */ ! #define INITBUFSIZE 200 #define INCBUFSIZE 1000 PyObject* v; /* the string object result */ *************** *** 676,748 **** char* pvend; /* address one beyond last free slot */ char* p; /* temp */ ! if (fp->_cnt > 0) { /* HACK: "_cnt" isn't advertised */ ! /* optimize for normal case: something sitting in the ! * buffer ready to go; avoid thread fiddling & realloc ! * if possible ! */ ! char msbuf[INITBUFSIZE]; ! memset(msbuf, '\n', INITBUFSIZE); ! p = fgets(msbuf, INITBUFSIZE, fp); ! /* since we didn't lock the file, there's no guarantee ! * anything was still in the buffer */ ! if (p == NULL) { ! clearerr(fp); ! if (PyErr_CheckSignals()) ! return NULL; ! v = PyString_FromStringAndSize("", 0); ! return v; ! } ! /* fgets read *something* */ ! p = memchr(msbuf, '\n', INITBUFSIZE); ! if (p != NULL) { ! /* Did the \n come from fgets or from us? ! * Since fgets stops at the first \n, and then ! * writes \0, if it's from fgets a \0 must be next. ! * But if that's so, it could not have come from us, ! * since the \n's we filled the buffer with have only ! * more \n's to the right. ! */ ! pvend = msbuf + INITBUFSIZE; ! if (p+1 < pvend && *(p+1) == '\0') { ! /* it's from fgets: we win! */ ! v = PyString_FromStringAndSize(msbuf, ! p - msbuf + 1); ! return v; ! } ! /* Must be from us: fgets didn't fill the buffer ! * and didn't find a newline, so it must be the ! * last and newline-free line of the file. */ ! assert(p > msbuf && *(p-1) == '\0'); ! v = PyString_FromStringAndSize(msbuf, p - msbuf - 1); return v; } ! /* yuck: fgets overwrote all the newlines, i.e. the entire ! * buffer. So this line isn't over yet, or maybe it is but ! * we're exactly at EOF; in either case, we're tired . */ ! assert(msbuf[INITBUFSIZE-1] == '\0'); ! total_v_size = INITBUFSIZE + INCBUFSIZE; ! v = PyString_FromStringAndSize((char*)NULL, ! (int)total_v_size); ! if (v == NULL) ! return v; ! /* copy over everything except the last null byte */ ! memcpy(BUF(v), msbuf, INITBUFSIZE-1); ! pvfree = BUF(v) + INITBUFSIZE - 1; } ! else { ! /* The stream isn't ready or isn't buffered. */ ! v = PyString_FromStringAndSize((char*)NULL, INITBUFSIZE); ! if (v == NULL) ! return v; ! total_v_size = INITBUFSIZE; ! pvfree = BUF(v); ! } /* Keep reading stuff into v; if it ever ends successfully, break ! * after setting p one beyond the end of the line. */ for (;;) { --- 687,751 ---- char* pvend; /* address one beyond last free slot */ char* p; /* temp */ + char msbuf[INITBUFSIZE]; ! /* Optimize for normal case: avoid _PyString_Resize if at all ! * possible via first reading into auto msbuf. ! */ ! Py_BEGIN_ALLOW_THREADS ! memset(msbuf, '\n', INITBUFSIZE); ! p = fgets(msbuf, INITBUFSIZE, fp); ! Py_END_ALLOW_THREADS ! ! if (p == NULL) { ! clearerr(fp); ! if (PyErr_CheckSignals()) ! return NULL; ! v = PyString_FromStringAndSize("", 0); ! return v; ! } ! /* fgets read *something* */ ! p = memchr(msbuf, '\n', INITBUFSIZE); ! if (p != NULL) { ! /* Did the \n come from fgets or from us? ! * Since fgets stops at the first \n, and then writes \0, if ! * it's from fgets a \0 must be next. But if that's so, it ! * could not have come from us, since the \n's we filled the ! * buffer with have only more \n's to the right. */ ! pvend = msbuf + INITBUFSIZE; ! if (p+1 < pvend && *(p+1) == '\0') { ! /* It's from fgets: we win! In particular, we ! * haven't done any mallocs yet, and can build the ! * final result on the first try. */ ! v = PyString_FromStringAndSize(msbuf, p - msbuf + 1); return v; } ! /* Must be from us: fgets didn't fill the buffer and didn't ! * find a newline, so it must be the last and newline-free ! * line of the file. */ ! assert(p > msbuf && *(p-1) == '\0'); ! v = PyString_FromStringAndSize(msbuf, p - msbuf - 1); ! return v; } ! /* yuck: fgets overwrote all the newlines, i.e. the entire buffer. ! * So this line isn't over yet, or maybe it is but we're exactly at ! *EOF; in either case, we're tired . ! */ ! assert(msbuf[INITBUFSIZE-1] == '\0'); ! total_v_size = INITBUFSIZE + INCBUFSIZE; ! v = PyString_FromStringAndSize((char*)NULL, ! (int)total_v_size); ! if (v == NULL) ! return v; ! /* copy over everything except the last null byte */ ! memcpy(BUF(v), msbuf, INITBUFSIZE-1); ! pvfree = BUF(v) + INITBUFSIZE - 1; /* Keep reading stuff into v; if it ever ends successfully, break ! * after setting p one beyond the end of the line. The code here is ! * very much like the code above, except reads into v's buffer; see ! * the code above for detailed comments about the logic. */ for (;;) { *************** *** 765,769 **** break; } - /* See the "normal case" comments above for details. */ p = memchr(pvfree, '\n', nfree); if (p != NULL) { --- 768,771 ---- From python-dev@python.org Mon Jan 8 01:17:28 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 17:17:28 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_bufio.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv13083/python/dist/src/lib/test Modified Files: test_bufio.py Log Message: 18 isn't a prime (duh). Index: test_bufio.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_bufio.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_bufio.py 2001/01/07 21:19:34 1.1 --- test_bufio.py 2001/01/08 01:17:26 1.2 *************** *** 44,48 **** # A pattern with prime length, to avoid simple relationships with # stdio buffer sizes. ! primepat = "1234567890\00\01\02\03\04\05\06\07" nullpat = "\0" * 1000 --- 44,48 ---- # A pattern with prime length, to avoid simple relationships with # stdio buffer sizes. ! primepat = "1234567890\00\01\02\03\04\05\06" nullpat = "\0" * 1000 From python-dev@python.org Mon Jan 8 01:26:49 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 07 Jan 2001 17:26:49 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.100,2.101 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv13967 Modified Files: fileobject.c Log Message: Let's hope that three time's a charm... Tim discovered another "bug" in my get_line() code: while the comments said that n<0 was invalid, it was in fact still called with n<0 (when PyFile_GetLine() was called with n<0). In that case fortunately executed the same code as for n==0. Changed the comment to admit this fact, and changed Tim's MS speed hack code to use 'n <= 0' as the criteria for the speed hack. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.100 retrieving revision 2.101 diff -C2 -r2.100 -r2.101 *** fileobject.c 2001/01/08 00:53:12 2.100 --- fileobject.c 2001/01/08 01:26:47 2.101 *************** *** 805,810 **** Size argument interpretation: > 0: max length; ! = 0: read arbitrary line; ! < 0: invalid */ --- 805,809 ---- Size argument interpretation: > 0: max length; ! <= 0: read arbitrary line */ *************** *** 829,833 **** #ifdef USE_MS_GETLINE_HACK ! if (n == 0) return ms_getline_hack(fp); #endif --- 828,833 ---- #ifdef USE_MS_GETLINE_HACK ! ! if (n <= 0) return ms_getline_hack(fp); #endif From python-dev@python.org Mon Jan 8 04:02:09 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 07 Jan 2001 20:02:09 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.101,2.102 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv27389/python/dist/src/objects Modified Files: fileobject.c Log Message: A few reformats; no logic changes. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.101 retrieving revision 2.102 diff -C2 -r2.101 -r2.102 *** fileobject.c 2001/01/08 01:26:47 2.101 --- fileobject.c 2001/01/08 04:02:07 2.102 *************** *** 640,649 **** Under MSVC 6: ! + MS threadsafe getc is very slow (multiple layers of function calls ! before+after each character, to lock+unlock the stream). ! + The stream-locking functions are MS-internal -- can't access them ! from user code. ! + There's nothing Tim could find in the MS C or platform SDK libraries ! that can worm around this. + MS fgets locks/unlocks only once per line; it's the only hook we have. --- 640,649 ---- Under MSVC 6: ! + MS threadsafe getc is very slow (multiple layers of function calls before+ ! after each character, to lock+unlock the stream). ! + The stream-locking functions are MS-internal -- can't access them from user ! code. ! + There's nothing Tim could find in the MS C or platform SDK libraries that ! can worm around this. + MS fgets locks/unlocks only once per line; it's the only hook we have. *************** *** 732,741 **** /* yuck: fgets overwrote all the newlines, i.e. the entire buffer. * So this line isn't over yet, or maybe it is but we're exactly at ! *EOF; in either case, we're tired . */ assert(msbuf[INITBUFSIZE-1] == '\0'); total_v_size = INITBUFSIZE + INCBUFSIZE; ! v = PyString_FromStringAndSize((char*)NULL, ! (int)total_v_size); if (v == NULL) return v; --- 732,740 ---- /* yuck: fgets overwrote all the newlines, i.e. the entire buffer. * So this line isn't over yet, or maybe it is but we're exactly at ! * EOF; in either case, we're tired . */ assert(msbuf[INITBUFSIZE-1] == '\0'); total_v_size = INITBUFSIZE + INCBUFSIZE; ! v = PyString_FromStringAndSize((char*)NULL, (int)total_v_size); if (v == NULL) return v; From python-dev@python.org Mon Jan 8 04:04:36 2001 From: python-dev@python.org (Fred L. Drake) Date: Sun, 07 Jan 2001 20:04:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/xml/dom minidom.py,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/xml/dom In directory usw-pr-cvs1:/tmp/cvs-serv27552 Modified Files: minidom.py Log Message: Text.__init__(): Make sure the data parameter is a string (8-bit or Unicode); raise TypeError if not. This closes SF bug #126866. Index: minidom.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/xml/dom/minidom.py,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** minidom.py 2000/12/31 03:50:23 1.18 --- minidom.py 2001/01/08 04:04:34 1.19 *************** *** 554,557 **** --- 554,559 ---- def __init__(self, data): + if type(data) not in _StringTypes: + raise TypeError, "node contents must be a string" Node.__init__(self) self.data = self.nodeValue = data From python-dev@python.org Mon Jan 8 05:53:55 2001 From: python-dev@python.org (Fred L. Drake) Date: Sun, 07 Jan 2001 21:53:55 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/api refcounts.dat,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/api In directory usw-pr-cvs1:/tmp/cvs-serv2655/Doc/api Modified Files: refcounts.dat Log Message: The Python/C API deals in PyObject*, not PyDictObject*. Index: refcounts.dat =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/api/refcounts.dat,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** refcounts.dat 2000/12/19 03:58:11 1.21 --- refcounts.dat 2001/01/08 05:53:53 1.22 *************** *** 94,120 **** PyDict_Clear:void::: ! PyDict_Clear:PyDictObject*:p:0: PyDict_DelItem:int::: ! PyDict_DelItem:PyDictObject*:p:0: PyDict_DelItem:PyObject*:key:0: PyDict_DelItemString:int::: ! PyDict_DelItemString:PyDictObject*:p:0: PyDict_DelItemString:char*:key:: PyDict_GetItem:PyObject*::0:0 ! PyDict_GetItem:PyDictObject*:p:0: PyDict_GetItem:PyObject*:key:0: PyDict_GetItemString:PyObject*::0: ! PyDict_GetItemString:PyDictObject*:p:0: PyDict_GetItemString:char*:key:: PyDict_Items:PyObject*::+1: ! PyDict_Items:PyDictObject*:p:0: PyDict_Keys:PyObject*::+1: ! PyDict_Keys:PyDictObject*:p:0: PyDict_New:PyObject*::+1: --- 94,120 ---- PyDict_Clear:void::: ! PyDict_Clear:PyObject*:p:0: PyDict_DelItem:int::: ! PyDict_DelItem:PyObject*:p:0: PyDict_DelItem:PyObject*:key:0: PyDict_DelItemString:int::: ! PyDict_DelItemString:PyObject*:p:0: PyDict_DelItemString:char*:key:: PyDict_GetItem:PyObject*::0:0 ! PyDict_GetItem:PyObject*:p:0: PyDict_GetItem:PyObject*:key:0: PyDict_GetItemString:PyObject*::0: ! PyDict_GetItemString:PyObject*:p:0: PyDict_GetItemString:char*:key:: PyDict_Items:PyObject*::+1: ! PyDict_Items:PyObject*:p:0: PyDict_Keys:PyObject*::+1: ! PyDict_Keys:PyObject*:p:0: PyDict_New:PyObject*::+1: *************** *** 124,128 **** PyDict_Next:int::: ! PyDict_Next:PyDictObject*:p:0: PyDict_Next:int:ppos:: PyDict_Next:PyObject**:pkey:0: --- 124,128 ---- PyDict_Next:int::: ! PyDict_Next:PyObject*:p:0: PyDict_Next:int:ppos:: PyDict_Next:PyObject**:pkey:0: *************** *** 130,147 **** PyDict_SetItem:int::: ! PyDict_SetItem:PyDictObject*:p:0: PyDict_SetItem:PyObject*:key:+1: PyDict_SetItem:PyObject*:val:+1: PyDict_SetItemString:int::: ! PyDict_SetItemString:PyDictObject*:p:0: PyDict_SetItemString:char*:key:: PyDict_SetItemString:PyObject*:val:+1: PyDict_Size:int::: ! PyDict_Size:PyDictObject*:p:: PyDict_Values:PyObject*::+1: ! PyDict_Values:PyDictObject*:p:0: PyErr_BadArgument:int::: --- 130,147 ---- PyDict_SetItem:int::: ! PyDict_SetItem:PyObject*:p:0: PyDict_SetItem:PyObject*:key:+1: PyDict_SetItem:PyObject*:val:+1: PyDict_SetItemString:int::: ! PyDict_SetItemString:PyObject*:p:0: PyDict_SetItemString:char*:key:: PyDict_SetItemString:PyObject*:val:+1: PyDict_Size:int::: ! PyDict_Size:PyObject*:p:: PyDict_Values:PyObject*::+1: ! PyDict_Values:PyObject*:p:0: PyErr_BadArgument:int::: From python-dev@python.org Mon Jan 8 06:29:52 2001 From: python-dev@python.org (Neil Schemenauer) Date: Sun, 07 Jan 2001 22:29:52 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects floatobject.c,2.76,2.77 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv4845/Objects Modified Files: floatobject.c Log Message: Fix a silly bug in float_pow. Sorry Tim. Index: floatobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/floatobject.c,v retrieving revision 2.76 retrieving revision 2.77 diff -C2 -r2.76 -r2.77 *** floatobject.c 2001/01/04 01:44:34 2.76 --- floatobject.c 2001/01/08 06:29:50 2.77 *************** *** 504,508 **** if ((PyObject *)z != Py_None) { double iz; ! CONVERT_TO_DOUBLE(w, iz); ix=fmod(1.0, iz); if (ix!=0 && iz<0) ix+=iz; --- 504,508 ---- if ((PyObject *)z != Py_None) { double iz; ! CONVERT_TO_DOUBLE(z, iz); ix=fmod(1.0, iz); if (ix!=0 && iz<0) ix+=iz; From python-dev@python.org Mon Jan 8 07:09:27 2001 From: python-dev@python.org (Moshe Zadka) Date: Sun, 07 Jan 2001 23:09:27 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib urllib.py,1.109,1.110 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv7257/Lib Modified Files: urllib.py Log Message: Fixed bug which caused HTTPS not to work at all with string URLs Index: urllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/urllib.py,v retrieving revision 1.109 retrieving revision 1.110 diff -C2 -r1.109 -r1.110 *** urllib.py 2000/12/15 15:01:37 1.109 --- urllib.py 2001/01/08 07:09:25 1.110 *************** *** 314,318 **** import httplib user_passwd = None ! if type(url) in types.StringTypes: host, selector = splithost(url) if host: --- 314,318 ---- import httplib user_passwd = None ! if type(url) is types.StringType: host, selector = splithost(url) if host: From python-dev@python.org Mon Jan 8 15:39:35 2001 From: python-dev@python.org (Fred L. Drake) Date: Mon, 08 Jan 2001 07:39:35 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib getopt.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv18643 Modified Files: getopt.py Log Message: GetoptError is always initialized with exactly two parameters, so simplify the constructor. Index: getopt.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/getopt.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** getopt.py 2000/12/29 02:17:56 1.13 --- getopt.py 2001/01/08 15:39:32 1.14 *************** *** 21,31 **** opt = '' msg = '' ! def __init__(self, *args): ! self.args = args ! if len(args) == 1: ! self.msg = args[0] ! elif len(args) == 2: ! self.msg = args[0] ! self.opt = args[1] def __str__(self): --- 21,28 ---- opt = '' msg = '' ! def __init__(self, msg, opt): ! self.msg = msg ! self.opt = opt ! Exception.__init__(self, msg, opt) def __str__(self): From python-dev@python.org Mon Jan 8 16:05:54 2001 From: python-dev@python.org (Fred L. Drake) Date: Mon, 08 Jan 2001 08:05:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libgetopt.tex,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv22746/lib Modified Files: libgetopt.tex Log Message: Explain that long options are matched based on a unique prefix rather than requiring the whole option to be typed out. This closes SF bug #126863. Index: libgetopt.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libgetopt.tex,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** libgetopt.tex 2000/10/10 17:03:45 1.15 --- libgetopt.tex 2001/01/08 16:05:51 1.16 *************** *** 30,34 **** \code{'-}\code{-'} characters should not be included in the option name. Long options which require an argument should be followed by an ! equal sign (\character{=}). The return value consists of two elements: the first is a list of --- 30,41 ---- \code{'-}\code{-'} characters should not be included in the option name. Long options which require an argument should be followed by an ! equal sign (\character{=}). To accept only long options, ! \var{options} should be an empty string. Long options on the command ! line can be recognized so long as they provide a prefix of the option ! name that matches exactly one of the accepted options. For example, ! it \var{long_options} is \code{['foo', 'frob']}, the option ! \longprogramopt{fo} will match as \longprogramopt{foo}, but ! \longprogramopt{f} will not match uniquely, so \exception{GetoptError} ! will be raised. The return value consists of two elements: the first is a list of From python-dev@python.org Mon Jan 8 17:51:57 2001 From: python-dev@python.org (Guido van Rossum) Date: Mon, 08 Jan 2001 09:51:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules posixmodule.c,2.179,2.180 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7193 Modified Files: posixmodule.c Log Message: Anonymous SF bug report #128053 point out that the #ifdef for including "tmpfile" in the posix_methods[] array is wrong -- should be HAVE_TMPFILE, not HAVE_TMPNAM. Index: posixmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/posixmodule.c,v retrieving revision 2.179 retrieving revision 2.180 diff -C2 -r2.179 -r2.180 *** posixmodule.c 2000/12/12 00:37:58 2.179 --- posixmodule.c 2001/01/08 17:51:55 2.180 *************** *** 5358,5362 **** {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, #endif ! #ifdef HAVE_TMPNAM {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, #endif --- 5358,5362 ---- {"statvfs", posix_statvfs, METH_VARARGS, posix_statvfs__doc__}, #endif ! #ifdef HAVE_TMPFILE {"tmpfile", posix_tmpfile, METH_VARARGS, posix_tmpfile__doc__}, #endif From python-dev@python.org Mon Jan 8 17:58:58 2001 From: python-dev@python.org (A.M. Kuchling) Date: Mon, 08 Jan 2001 09:58:58 -0800 Subject: [Python-checkins] CVS: python/dist/src config.h.in,2.81,2.82 configure.in,1.182,1.183 configure,1.174,1.175 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv7811 Modified Files: config.h.in configure.in configure Log Message: Remove configure test for getline(), since it's no longer used at all Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -r2.81 -r2.82 *** config.h.in 2001/01/05 14:45:48 2.81 --- config.h.in 2001/01/08 17:58:56 2.82 *************** *** 345,351 **** #undef HAVE_GETHOSTBYNAME - /* Define if you have the getline function. */ - #undef HAVE_GETLINE - /* Define if you have the getlogin function. */ #undef HAVE_GETLOGIN --- 345,348 ---- Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.182 retrieving revision 1.183 diff -C2 -r1.182 -r1.183 *** configure.in 2001/01/05 14:45:49 1.182 --- configure.in 2001/01/08 17:58:56 1.183 *************** *** 977,981 **** AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ ! getgroups getline getlogin getpeername getpid getpwent getwd \ kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ --- 977,981 ---- AC_CHECK_FUNCS(alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ ! getgroups getlogin getpeername getpid getpwent getwd \ kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.174 retrieving revision 1.175 diff -C2 -r1.174 -r1.175 *** configure 2001/01/05 14:45:48 1.174 --- configure 2001/01/08 17:58:56 1.175 *************** *** 4059,4063 **** for ac_func in alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ ! getgroups getline getlogin getpeername getpid getpwent getwd \ kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ --- 4059,4063 ---- for ac_func in alarm chown clock confstr ctermid ctermid_r execv \ flock fork fsync fdatasync fpathconf ftime ftruncate \ ! getgroups getlogin getpeername getpid getpwent getwd \ kill link lstat mkfifo mktime mremap \ nice pathconf pause plock poll pthread_init \ From python-dev@python.org Tue Jan 9 02:00:13 2001 From: python-dev@python.org (Guido van Rossum) Date: Mon, 08 Jan 2001 18:00:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.102,2.103 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv30509 Modified Files: fileobject.c Log Message: Tsk, tsk, tsk. Treat FreeBSD the same as the other BSDs when defining a fallback for TELL64. Fixes SF Bug #128119. Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.102 retrieving revision 2.103 diff -C2 -r2.102 -r2.103 *** fileobject.c 2001/01/08 04:02:07 2.102 --- fileobject.c 2001/01/09 02:00:11 2.103 *************** *** 59,63 **** #if defined(MS_WIN64) #define TELL64 _telli64 ! #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(_HAVE_BSDI) || defined(__APPLE__) /* NOTE: this is only used on older NetBSD prior to f*o() funcions */ --- 59,63 ---- #if defined(MS_WIN64) #define TELL64 _telli64 ! #elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(_HAVE_BSDI) || defined(__APPLE__) /* NOTE: this is only used on older NetBSD prior to f*o() funcions */ From python-dev@python.org Tue Jan 9 02:11:59 2001 From: python-dev@python.org (Guido van Rossum) Date: Mon, 08 Jan 2001 18:11:59 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules binascii.c,2.27,2.28 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv31519 Modified Files: binascii.c Log Message: Address a bug in the uuencode decoder, reported bu "donut" in SF bug #127718: '@' and '`' seem to be confused. Index: binascii.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/binascii.c,v retrieving revision 2.27 retrieving revision 2.28 diff -C2 -r2.27 -r2.28 *** binascii.c 2000/09/01 23:29:26 2.27 --- binascii.c 2001/01/09 02:11:57 2.28 *************** *** 205,209 **** ** The 64 in stead of the expected 63 is because ** there are a few uuencodes out there that use ! ** '@' as zero instead of space. */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { --- 205,209 ---- ** The 64 in stead of the expected 63 is because ** there are a few uuencodes out there that use ! ** '`' as zero instead of space. */ if ( this_ch < ' ' || this_ch > (' ' + 64)) { *************** *** 233,238 **** while( ascii_len-- > 0 ) { this_ch = *ascii_data++; ! /* Extra '@' may be written as padding in some cases */ ! if ( this_ch != ' ' && this_ch != '@' && this_ch != '\n' && this_ch != '\r' ) { PyErr_SetString(Error, "Trailing garbage"); --- 233,238 ---- while( ascii_len-- > 0 ) { this_ch = *ascii_data++; ! /* Extra '`' may be written as padding in some cases */ ! if ( this_ch != ' ' && this_ch != ' '+64 && this_ch != '\n' && this_ch != '\r' ) { PyErr_SetString(Error, "Trailing garbage"); From python-dev@python.org Tue Jan 9 03:01:18 2001 From: python-dev@python.org (A.M. Kuchling) Date: Mon, 08 Jan 2001 19:01:18 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib shlex.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3254 Modified Files: shlex.py Log Message: Patch #102953: Fix bug #125452, where shlex.shlex hangs when it encounters a string with an unmatched quote, by adding a check for EOF in the 'quotes' state. Index: shlex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/shlex.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** shlex.py 2000/12/23 14:20:23 1.10 --- shlex.py 2001/01/09 03:01:15 1.11 *************** *** 124,127 **** --- 124,132 ---- self.state = ' ' break + elif not nextchar: # end of file + if self.debug >= 2: + print "shlex: I see EOF in quotes state" + # XXX what error should be raised here? + raise ValueError, "No closing quotation" elif self.state == 'a': if not nextchar: From python-dev@python.org Tue Jan 9 03:15:49 2001 From: python-dev@python.org (A.M. Kuchling) Date: Mon, 08 Jan 2001 19:15:49 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils/command build_ext.py,1.68,1.69 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils/command In directory usw-pr-cvs1:/tmp/cvs-serv4467 Modified Files: build_ext.py Log Message: Check in patch #102971: if library_dirs is a string, split it using os.pathsep Index: build_ext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/command/build_ext.py,v retrieving revision 1.68 retrieving revision 1.69 diff -C2 -r1.68 -r1.69 *** build_ext.py 2000/09/30 18:27:54 1.68 --- build_ext.py 2001/01/09 03:15:47 1.69 *************** *** 150,153 **** --- 150,155 ---- if self.library_dirs is None: self.library_dirs = [] + elif type(self.library_dirs) is StringType: + self.library_dirs = string.split(self.library_dirs, os.pathsep) if self.rpath is None: self.rpath = [] From python-dev@python.org Tue Jan 9 15:53:18 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 09 Jan 2001 07:53:18 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.61,1.62 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv1815 Modified Files: pep-0000.txt Log Message: Andrew withdraws 222 from 2.1. Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.61 retrieving revision 1.62 diff -C2 -r1.61 -r1.62 *** pep-0000.txt 2001/01/05 16:54:35 1.61 --- pep-0000.txt 2001/01/09 15:53:16 1.62 *************** *** 36,40 **** S 208 pep-0208.txt Reworking the Coercion Model Schemenauer, Lemburg S 217 pep-0217.txt Display Hook for Interactive Use Zadka - S 222 pep-0222.txt Web Library Enhancements Kuchling I 226 pep-0226.txt Python 2.1 Release Schedule Hylton S 227 pep-0227.txt Statically Nested Scopes Hylton --- 36,39 ---- *************** *** 52,55 **** --- 51,55 ---- I 216 pep-0216.txt Docstring Format Zadka SD 218 pep-0218.txt Adding a Built-In Set Object Type Wilson + S 222 pep-0222.txt Web Library Enhancements Kuchling SD 224 pep-0224.txt Attribute Docstrings Lemburg SD 225 pep-0225.txt Elementwise/Objectwise Operators Zhu, Lielens From python-dev@python.org Tue Jan 9 20:38:56 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 12:38:56 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libfpectl.tex,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv8213/lib Added Files: libfpectl.tex Log Message: Documentation for the fpectl module, from Lee Busby. (Thanks!) --- NEW FILE: libfpectl.tex --- \section{\module{fpectl} --- Floating point exception control} \declaremodule{extension}{fpectl} \platform{Unix, Windows} \moduleauthor{Lee Busby}{busby1@llnl.gov} \sectionauthor{Lee Busby}{busby1@llnl.gov} \modulesynopsis{Provide control for floating point exception handling.} Most computers carry out floating point operations\index{IEEE-754} in conformance with the so-called IEEE-754 standard. On any real computer, some floating point operations produce results that cannot be expressed as a normal floating point value. For example, try \begin{verbatim} >>> import math >>> math.exp(1000) inf >>> math.exp(1000)/math.exp(1000) nan \end{verbatim} (The example above will work on many platforms. DEC Alpha may be one exception.) "Inf" is a special, non-numeric value in IEEE-754 that stands for "infinity", and "nan" means "not a number." Note that, other than the non-numeric results, nothing special happened when you asked Python to carry out those calculations. That is in fact the default behaviour prescribed in the IEEE-754 standard, and if it works for you, stop reading now. In some circumstances, it would be better to raise an exception and stop processing at the point where the faulty operation was attempted. The \module{fpectl} module is for use in that situation. It provides control over floating point units from several hardware manufacturers, allowing the user to turn on the generation of \constant{SIGFPE} whenever any of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid Operation occurs. In tandem with a pair of wrapper macros that are inserted into the C code comprising your python system, \constant{SIGFPE} is trapped and converted into the Python \exception{FloatingPointError} exception. The \module{fpectl} module defines the following functions and may raise the given exception: \begin{funcdesc}{turnon_sigfpe}{} Turn on the generation of \constant{SIGFPE}, and set up an appropriate signal handler. \end{funcdesc} \begin{funcdesc}{turnoff_sigfpe}{} Reset default handling of floating point exceptions. \end{funcdesc} \begin{excdesc}{FloatingPointError} After \function{turnon_sigfpe()} has been executed, a floating point operation that raises one of the IEEE-754 exceptions Division by Zero, Overflow, or Invalid operation will in turn raise this standard Python exception. \end{excdesc} \subsection{Example \label{fpectl-example}} The following example demonstrates how to start up and test operation of the \module{fpectl} module. \begin{verbatim} >>> import fpectl >>> import fpetest >>> fpectl.turnon_sigfpe() >>> fpetest.test() overflow PASS FloatingPointError: Overflow div by 0 PASS FloatingPointError: Division by zero [ more output from test elided ] >>> import math >>> math.exp(1000) Traceback (most recent call last): File "", line 1, in ? FloatingPointError: in math_1 \end{verbatim} \subsection{Limitations and other considerations} Setting up a given processor to trap IEEE-754 floating point errors currently requires custom code on a per-architecture basis. You may have to modify \module{fpectl} to control your particular hardware. Conversion of an IEEE-754 exception to a Python exception requires that the wrapper macros \code{PyFPE_START_PROTECT} and \code{PyFPE_END_PROTECT} be inserted into your code in an appropriate fashion. Python itself has been modified to support the \module{fpectl} module, but many other codes of interest to numerical analysts have not. The \module{fpectl} module is not thread-safe. \begin{seealso} \seetext{Some files in the source distribution may be interesting in learning more about how this module operates. The include file \file{Include/pyfpe.h} discusses the implementation of this module at some length. \file{Modules/fpetestmodule.c} gives several examples of use. Many additional examples can be found in \file{Objects/floatobject.c}.} \end{seealso} From python-dev@python.org Tue Jan 9 20:50:05 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 12:50:05 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc Makefile.deps,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv9648 Modified Files: Makefile.deps Log Message: Added entry for fpectl module documentation. Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -r1.52 -r1.53 *** Makefile.deps 2000/12/19 06:01:22 1.52 --- Makefile.deps 2001/01/09 20:50:02 1.53 *************** *** 52,55 **** --- 52,56 ---- ../lib/libpython.tex \ ../lib/libsys.tex \ + ../lib/libfpectl.tex \ ../lib/libgc.tex \ ../lib/libtypes.tex \ From python-dev@python.org Tue Jan 9 20:52:51 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 12:52:51 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib lib.tex,1.173,1.174 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv10004/lib Modified Files: lib.tex Log Message: Added entry for fpectl module documentation. Moved the mutex docs to be adjacent to the sched docs, since these are meant to be used together (if they are used at all!). Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.173 retrieving revision 1.174 diff -C2 -r1.173 -r1.174 *** lib.tex 2000/12/19 06:01:22 1.173 --- lib.tex 2001/01/09 20:52:49 1.174 *************** *** 75,78 **** --- 75,79 ---- \input{libsys} \input{libgc} + \input{libfpectl} \input{libatexit} \input{libtypes} *************** *** 138,141 **** --- 139,143 ---- \input{libtime} \input{libsched} + \input{libmutex} \input{libgetpass} \input{libcurses} *************** *** 156,160 **** \input{libthread} \input{libthreading} - \input{libmutex} \input{libqueue} \input{libmmap} --- 158,161 ---- From python-dev@python.org Tue Jan 9 20:54:17 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 12:54:17 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmutex.tex,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv10159/lib Modified Files: libmutex.tex Log Message: Added missing word; fixed minor nits. Index: libmutex.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmutex.tex,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** libmutex.tex 2000/12/01 15:25:23 1.4 --- libmutex.tex 2001/01/09 20:54:15 1.5 *************** *** 1,3 **** - % LaTeXed from comments in file \section{\module{mutex} --- Mutual exclusion support} --- 1,2 ---- *************** *** 7,11 **** \modulesynopsis{Lock and queue for mutual exclusion.} ! The \module{mutex} defines a class that allows mutual-exclusion via acquiring and releasing locks. It does not require (or imply) threading or multi-tasking, though it could be useful for --- 6,10 ---- \modulesynopsis{Lock and queue for mutual exclusion.} ! The \module{mutex} module defines a class that allows mutual-exclusion via acquiring and releasing locks. It does not require (or imply) threading or multi-tasking, though it could be useful for *************** *** 19,23 **** A mutex has two pieces of state --- a ``locked'' bit and a queue. When the mutex is not locked, the queue is empty. ! Otherwise, the queue contains 0 or more \code{(\var{function}, \var{argument})} pairs representing functions (or methods) waiting to acquire the lock. --- 18,22 ---- A mutex has two pieces of state --- a ``locked'' bit and a queue. When the mutex is not locked, the queue is empty. ! Otherwise, the queue contains zero or more \code{(\var{function}, \var{argument})} pairs representing functions (or methods) waiting to acquire the lock. *************** *** 28,32 **** Of course, no multi-threading is implied -- hence the funny interface ! for lock, where a function is called once the lock is acquired. \end{classdesc} --- 27,32 ---- Of course, no multi-threading is implied -- hence the funny interface ! for \method{lock()}, where a function is called once the lock is ! acquired. \end{classdesc} From python-dev@python.org Tue Jan 9 20:55:11 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 12:55:11 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv10257 Modified Files: ACKS Log Message: Added names. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** ACKS 2000/12/07 00:06:46 1.11 --- ACKS 2001/01/09 20:55:09 1.12 *************** *** 30,33 **** --- 30,34 ---- Aaron Brancotti Keith Briggs + Lee Busby Lorenzo M. Catucci Mauro Cicognini *************** *** 126,129 **** --- 127,131 ---- Donald Wallace Rouse II Nick Russo + Chris Ryland Constantina S. Hugh Sasse From python-dev@python.org Tue Jan 9 21:38:18 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 13:38:18 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv17100 Modified Files: ACKS Log Message: Steve Holden : Clarify the handling of characters following backslashes in raw strings. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** ACKS 2001/01/09 20:55:09 1.12 --- ACKS 2001/01/09 21:38:16 1.13 *************** *** 64,67 **** --- 64,68 ---- Albert Hofkamp Gregor Hoffleit + Steve Holden Gerrit Holl Rob Hooft From python-dev@python.org Tue Jan 9 21:38:18 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 13:38:18 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref2.tex,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv17100/ref Modified Files: ref2.tex Log Message: Steve Holden : Clarify the handling of characters following backslashes in raw strings. Index: ref2.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref2.tex,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** ref2.tex 2000/12/19 04:52:03 1.21 --- ref2.tex 2001/01/09 21:38:16 1.22 *************** *** 373,389 **** escapes for non-Unicode string literals. ! When an `r' or `R' prefix is present, backslashes are still used to ! quote the following character, but \emph{all backslashes are left in ! the string}. For example, the string literal \code{r"\e n"} consists ! of two characters: a backslash and a lowercase `n'. String quotes can ! be escaped with a backslash, but the backslash remains in the string; ! for example, \code{r"\e""} is a valid string literal consisting of two ! characters: a backslash and a double quote; \code{r"\e"} is not a value ! string literal (even a raw string cannot end in an odd number of ! backslashes). Specifically, \emph{a raw string cannot end in a single ! backslash} (since the backslash would escape the following quote ! character). Note also that a single backslash followed by a newline ! is interpreted as those two characters as part of the string, ! \emph{not} as a line continuation. \subsection{String literal concatenation\label{string-catenation}} --- 373,389 ---- escapes for non-Unicode string literals. ! When an `r' or `R' prefix is present, a character following a ! backslash is included in the string without change, and \emph{all ! backslashes are left in the string}. For example, the string literal ! \code{r"\e n"} consists of two characters: a backslash and a lowercase ! `n'. String quotes can be escaped with a backslash, but the backslash ! remains in the string; for example, \code{r"\e""} is a valid string ! literal consisting of two characters: a backslash and a double quote; ! \code{r"\e"} is not a value string literal (even a raw string cannot ! end in an odd number of backslashes). Specifically, \emph{a raw ! string cannot end in a single backslash} (since the backslash would ! escape the following quote character). Note also that a single ! backslash followed by a newline is interpreted as those two characters ! as part of the string, \emph{not} as a line continuation. \subsection{String literal concatenation\label{string-catenation}} From python-dev@python.org Tue Jan 9 21:40:54 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 13:40:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/texinputs boilerplate.tex,1.51,1.52 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/texinputs In directory usw-pr-cvs1:/tmp/cvs-serv17563/texinputs Modified Files: boilerplate.tex Log Message: Miscellaneous updates. Index: boilerplate.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/texinputs/boilerplate.tex,v retrieving revision 1.51 retrieving revision 1.52 diff -C2 -r1.51 -r1.52 *** boilerplate.tex 2000/11/17 19:05:12 1.51 --- boilerplate.tex 2001/01/09 21:40:52 1.52 *************** *** 2,10 **** Fred L. Drake, Jr., editor} \authoraddress{ ! BeOpen PythonLabs\\ E-mail: \email{python-docs@python.org} } \date{\today} % XXX update before release! ! \release{2.0} % software release, not documentation ! \setshortversion{2.0} % major.minor only for software --- 2,10 ---- Fred L. Drake, Jr., editor} \authoraddress{ ! PythonLabs\\ E-mail: \email{python-docs@python.org} } \date{\today} % XXX update before release! ! \release{2.1 alpha} % software release, not documentation ! \setshortversion{2.1} % major.minor only for software From python-dev@python.org Tue Jan 9 21:46:53 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 09 Jan 2001 13:46:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules xreadlinesmodule.c,NONE,1.1 Setup.dist,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv18385 Modified Files: Setup.dist Added Files: xreadlinesmodule.c Log Message: Jeff Epler's xreadlines module, with slight reformatting and some changes for safety and tuning. --- NEW FILE: xreadlinesmodule.c --- #include "Python.h" static char xreadlines_doc [] = "xreadlines(f)\n\ \n\ Return an xreadlines object for the file f."; typedef struct { PyObject_HEAD PyObject *file; PyObject *lines; int lineslen; int lineno; int abslineno; } PyXReadlinesObject; staticforward PyTypeObject XReadlinesObject_Type; static void xreadlines_dealloc(PyXReadlinesObject *op) { Py_XDECREF(op->file); Py_XDECREF(op->lines); PyObject_DEL(op); } /* A larger chunk size doesn't seem to make a difference */ #define CHUNKSIZE 8192 static PyXReadlinesObject * newreadlinesobject(PyObject *file) { PyXReadlinesObject *op; op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type); if (op == NULL) return NULL; Py_XINCREF(file); op->file = file; op->lines = NULL; op->abslineno = op->lineno = op->lineslen = 0; return op; } static PyObject * xreadlines(PyObject *self, PyObject *args) { PyObject *file; PyXReadlinesObject *ret; if (!PyArg_ParseTuple(args, "O:xreadlines", &file)) return NULL; ret = newreadlinesobject(file); Py_XINCREF(ret); return (PyObject*)ret; } static PyObject* xreadlines_item(PyXReadlinesObject *a, int i) { if (i != a->abslineno) { PyErr_SetString(PyExc_RuntimeError, "xreadlines object accessed out of order"); return NULL; } if (a->lineno >= a->lineslen) { Py_XDECREF(a->lines); a->lines = PyObject_CallMethod(a->file, "readlines", "(i)", CHUNKSIZE); if (a->lines == NULL) return NULL; a->lineno = 0; if ((a->lineslen = PySequence_Size(a->lines)) < 0) return NULL; } a->abslineno++; return PySequence_GetItem(a->lines, a->lineno++); } static PySequenceMethods xreadlines_as_sequence = { 0, /*sq_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ (intargfunc)xreadlines_item, /*sq_item*/ }; static PyTypeObject XReadlinesObject_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, "xreadlines", sizeof(PyXReadlinesObject) + PyGC_HEAD_SIZE, 0, (destructor)xreadlines_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &xreadlines_as_sequence, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /* tp_doc */ }; static PyMethodDef xreadlines_methods[] = { {"xreadlines", xreadlines, METH_VARARGS, xreadlines_doc}, {NULL, NULL} }; void initxreadlines(void) { PyObject *m; m = Py_InitModule("xreadlines", xreadlines_methods); } Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** Setup.dist 2000/12/22 21:57:33 1.3 --- Setup.dist 2001/01/09 21:46:50 1.4 *************** *** 157,160 **** --- 157,163 ---- mmap mmapmodule.c + # Dynamic readlines + xreadlines xreadlinesmodule.c + # Socket module compiled with SSL support; you must edit the SSL variable: #SSL=/usr/local/ssl From python-dev@python.org Tue Jan 9 21:47:46 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 09 Jan 2001 13:47:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_xreadline,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv18530/output Added Files: test_xreadline Log Message: Test for xreadline. --- NEW FILE: test_xreadline --- test_xrl AttributeError TypeError RuntimeError xreadlines object accessed out of order From python-dev@python.org Tue Jan 9 21:47:46 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 09 Jan 2001 13:47:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_xreadline.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv18530 Added Files: test_xreadline.py Log Message: Test for xreadline. --- NEW FILE: test_xreadline.py --- from test_support import verbose class XReader: def __init__(self): self.count = 5 def readlines(self, sizehint = None): self.count = self.count - 1 return map(lambda x: "%d\n" % x, range(self.count)) class Null: pass import xreadlines lineno = 0 try: xreadlines.xreadlines(Null())[0] except AttributeError, detail: print "AttributeError" else: print "Did not throw attribute error" try: xreadlines.xreadlines(XReader)[0] except TypeError, detail: print "TypeError" else: print "Did not throw type error" try: xreadlines.xreadlines(XReader())[1] except RuntimeError, detail: print "RuntimeError", detail else: print "Did not throw runtime error" xresult = ['0\n', '1\n', '2\n', '3\n', '0\n', '1\n', '2\n', '0\n', '1\n', '0\n'] for line in xreadlines.xreadlines(XReader()): if line != xresult[lineno]: print "line %d differs" % lineno lineno = lineno + 1 From python-dev@python.org Tue Jan 9 21:50:27 2001 From: python-dev@python.org (Guido van Rossum) Date: Tue, 09 Jan 2001 13:50:27 -0800 Subject: [Python-checkins] CVS: python/dist/src/Objects fileobject.c,2.103,2.104 Message-ID: Update of /cvsroot/python/python/dist/src/Objects In directory usw-pr-cvs1:/tmp/cvs-serv18990 Modified Files: fileobject.c Log Message: Jeff Epler's patch adding an xreadlines() method. (It just imports the xreadlines module and lets it do its thing.) Index: fileobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/fileobject.c,v retrieving revision 2.103 retrieving revision 2.104 diff -C2 -r2.103 -r2.104 *** fileobject.c 2001/01/09 02:00:11 2.103 --- fileobject.c 2001/01/09 21:50:24 2.104 *************** *** 965,968 **** --- 965,991 ---- static PyObject * + file_xreadlines(PyFileObject *f, PyObject *args) + { + static PyObject* xreadlines_function = NULL; + + if (!PyArg_ParseTuple(args, ":xreadlines")) + return NULL; + + if (!xreadlines_function) { + PyObject *xreadlines_module = + PyImport_ImportModule("xreadlines"); + if(!xreadlines_module) + return NULL; + + xreadlines_function = PyObject_GetAttrString(xreadlines_module, + "xreadlines"); + Py_DECREF(xreadlines_module); + if(!xreadlines_function) + return NULL; + } + return PyObject_CallFunction(xreadlines_function, "(O)", f); + } + + static PyObject * file_readlines(PyFileObject *f, PyObject *args) { *************** *** 1010,1014 **** if (buffersize > INT_MAX) { PyErr_SetString(PyExc_OverflowError, ! "line is longer than a Python string can hold"); goto error; } --- 1033,1037 ---- if (buffersize > INT_MAX) { PyErr_SetString(PyExc_OverflowError, ! "line is longer than a Python string can hold"); goto error; } *************** *** 1233,1236 **** --- 1256,1260 ---- {"readinto", (PyCFunction)file_readinto, 0}, {"readlines", (PyCFunction)file_readlines, 1}, + {"xreadlines", (PyCFunction)file_xreadlines, 1}, {"writelines", (PyCFunction)file_writelines, 0}, {"flush", (PyCFunction)file_flush, 0}, From python-dev@python.org Tue Jan 9 22:02:12 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 14:02:12 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/html Makefile,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory usw-pr-cvs1:/tmp/cvs-serv20761/html Modified Files: Makefile Log Message: Added a --global-module-index option to specify a (possibly relative) URL to the Global Module Index for a set of documents. This is used to include a reference to the global index from the per-document module indexes, so that it is just a little easier to find. (Someone suggested this, but I do not remember who. Please let me know if it was you -- thanks!) Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/Makefile,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** Makefile 2000/10/25 16:12:04 1.40 --- Makefile 2001/01/09 22:02:09 1.41 *************** *** 15,19 **** MKHOWTO= $(TOOLSDIR)/mkhowto --about $(TOPDIR)/html/stdabout.dat \ --address $(PYTHONDOCS) --up-link ../index.html \ ! --up-title "Python Documentation Index" MKHTML= $(MKHOWTO) --html --- 15,20 ---- MKHOWTO= $(TOOLSDIR)/mkhowto --about $(TOPDIR)/html/stdabout.dat \ --address $(PYTHONDOCS) --up-link ../index.html \ ! --up-title "Python Documentation Index" \ ! --global-module-index "../modindex.html" MKHTML= $(MKHOWTO) --html From python-dev@python.org Tue Jan 9 22:02:12 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 14:02:12 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/tools mkhowto,1.18,1.19 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/tools In directory usw-pr-cvs1:/tmp/cvs-serv20761/tools Modified Files: mkhowto Log Message: Added a --global-module-index option to specify a (possibly relative) URL to the Global Module Index for a set of documents. This is used to include a reference to the global index from the per-document module indexes, so that it is just a little easier to find. (Someone suggested this, but I do not remember who. Please let me know if it was you -- thanks!) Index: mkhowto =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/tools/mkhowto,v retrieving revision 1.18 retrieving revision 1.19 diff -C2 -r1.18 -r1.19 *** mkhowto 2000/11/03 02:57:31 1.18 --- mkhowto 2001/01/09 22:02:10 1.19 *************** *** 92,95 **** --- 92,96 ---- runs = 0 numeric = 0 + global_module_index = None style_file = os.path.join(TOPDIR, "html", "style.css") about_file = os.path.join(TOPDIR, "html", "about.dat") *************** *** 118,122 **** "keep", "quiet", "runs=", "image-type=", "about=", "numeric", "style=", ! "up-link=", "up-title="] + list(self.ALL_FORMATS)) for opt, arg in opts: --- 119,124 ---- "keep", "quiet", "runs=", "image-type=", "about=", "numeric", "style=", ! "up-link=", "up-title=", ! "global-module-index="] + list(self.ALL_FORMATS)) for opt, arg in opts: *************** *** 164,167 **** --- 166,171 ---- elif opt == "--up-title": self.up_title = arg + elif opt == "--global-module-index": + self.global_module_index = arg # # Format specifiers: *************** *** 406,409 **** --- 410,414 ---- l2hoption(fp, "EXTERNAL_UP_LINK", options.up_link) l2hoption(fp, "EXTERNAL_UP_TITLE", options.up_title) + l2hoption(fp, "GLOBAL_MODULE_INDEX", options.global_module_index) fp.write("1;\n") fp.close() From python-dev@python.org Tue Jan 9 22:02:12 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 14:02:12 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/perl l2hinit.perl,1.52,1.53 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/perl In directory usw-pr-cvs1:/tmp/cvs-serv20761/perl Modified Files: l2hinit.perl Log Message: Added a --global-module-index option to specify a (possibly relative) URL to the Global Module Index for a set of documents. This is used to include a reference to the global index from the per-document module indexes, so that it is just a little easier to find. (Someone suggested this, but I do not remember who. Please let me know if it was you -- thanks!) Index: l2hinit.perl =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/perl/l2hinit.perl,v retrieving revision 1.52 retrieving revision 1.53 diff -C2 -r1.52 -r1.53 *** l2hinit.perl 2001/01/04 15:16:01 1.52 --- l2hinit.perl 2001/01/09 22:02:10 1.53 *************** *** 333,336 **** --- 333,346 ---- } close(MODIDXFILE); + + if ($GLOBAL_MODULE_INDEX) { + $prefix = < This index only lists modules documented in this manual. + The Global Module + Index lists all modules that are documented in this set + of manuals.

+ MODULE_INDEX_PREFIX + } if (!$allthesame) { $prefix .= < Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv26967 Modified Files: Makefile.deps ACKS Log Message: Added documentation for the xreadlines module & related changes. The documentation was written by Jeff Epler (thanks!). Index: Makefile.deps =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/Makefile.deps,v retrieving revision 1.53 retrieving revision 1.54 diff -C2 -r1.53 -r1.54 *** Makefile.deps 2001/01/09 20:50:02 1.53 --- Makefile.deps 2001/01/09 22:47:45 1.54 *************** *** 191,194 **** --- 191,195 ---- ../lib/libsunaudio.tex \ ../lib/libfileinput.tex \ + ../lib/libxreadlines.tex \ ../lib/libimaplib.tex \ ../lib/libpoplib.tex \ Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** ACKS 2001/01/09 21:38:16 1.13 --- ACKS 2001/01/09 22:47:45 1.14 *************** *** 39,42 **** --- 39,43 ---- Robert Donohue Fred L. Drake, Jr. + Jeff Epler Michael Ernst Blame Andy Eskilsson From python-dev@python.org Tue Jan 9 22:47:48 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 14:47:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxreadlines.tex,NONE,1.1 lib.tex,1.174,1.175 libstdtypes.tex,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26967/lib Modified Files: lib.tex libstdtypes.tex Added Files: libxreadlines.tex Log Message: Added documentation for the xreadlines module & related changes. The documentation was written by Jeff Epler (thanks!). --- NEW FILE: libxreadlines.tex --- \section{\module{xreadlines} --- Efficient iteration over a file} \declaremodule{extension}{xreadlines} \modulesynopsis{Efficient iteration over the lines of a file.} This module defines a new object type which can efficiently iterate over the lines of a file. An xreadlines object is a sequence type which implements simple in-order indexing beginning at \code{0}, as required by \keyword{for} statement or the \function{filter()} function. Thus, the code \begin{verbatim} import xreadlines, sys for line in xreadlines.xreadlines(sys.stdin): pass \end{verbatim} has approximately the same speed and memory consumption as \begin{verbatim} while 1: lines = sys.stdin.readlines(8*1024) if not lines: break for line in lines: pass \end{verbatim} except the clarity of the \keyword{for} statement is retained in the former case. \begin{funcdesc}{xreadlines}{fileobj} Return a new xreadlines object which will iterate over the contents of \var{fileobj}. \var{fileobj} must have a \method{readlines()} method that supports the \var{sizehint} parameter. \end{funcdesc} An xreadlines object \var{s} supports the following sequence operation: \begin{tableii}{c|l}{code}{Operation}{Result} \lineii{\var{s}[\var{i}]}{\var{i}'th line of \var{s}} \end{tableii} If successive values of \var{i} are not sequential starting from \code{0}, this code will raise \exception{RuntimeError}. After the last line of the file is read, this code will raise an \exception{IndexError}. Index: lib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/lib.tex,v retrieving revision 1.174 retrieving revision 1.175 diff -C2 -r1.174 -r1.175 *** lib.tex 2001/01/09 20:52:49 1.174 --- lib.tex 2001/01/09 22:47:45 1.175 *************** *** 122,125 **** --- 122,126 ---- \input{libcfgparser} \input{libfileinput} + \input{libxreadlines} \input{libcalendar} \input{libcmd} Index: libstdtypes.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstdtypes.tex,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -r1.46 -r1.47 *** libstdtypes.tex 2001/01/04 05:16:39 1.46 --- libstdtypes.tex 2001/01/09 22:47:46 1.47 *************** *** 1102,1114 **** \begin{methoddesc}[file]{write}{str} ! Write a string to the file. There is no return value. Note: Due to ! buffering, the string may not actually show up in the file until ! the \method{flush()} or \method{close()} method is called. \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.) \end{methoddesc} --- 1102,1120 ---- \begin{methoddesc}[file]{write}{str} ! Write a string to the file. There is no return value. Note: Due to ! buffering, the string may not actually show up in the file until ! the \method{flush()} or \method{close()} method is called. \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.) ! \end{methoddesc} ! ! \begin{methoddesc}[file]{xreadlines}{} ! Equivalent to ! \function{xreadlines.xreadlines(\var{file})}.\refstmodindex{xreadlines} ! (See the \refmodule{xreadlines} module for more information.) \end{methoddesc} From python-dev@python.org Tue Jan 9 22:50:16 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 14:50:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/html Makefile,1.41,1.42 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/html In directory usw-pr-cvs1:/tmp/cvs-serv27441/html Modified Files: Makefile Log Message: Remove bogus "echo" command. Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/html/Makefile,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** Makefile 2001/01/09 22:02:09 1.41 --- Makefile 2001/01/09 22:50:13 1.42 *************** *** 78,82 **** ext/ext.html: $(EXTFILES) - echo $(EXTFILES) $(MKHTML) $(TOPDIR)/ext/ext.tex --- 78,81 ---- From python-dev@python.org Tue Jan 9 23:26:41 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 15:26:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_xreadline.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv31420/python/dist/src/Lib/test Modified Files: test_xreadline.py Log Message: Assorted xreadlines problems: Wasn't built on Windows; not in config.c either. Module init function missing DL_EXPORT magic. test_xreadline output file obviously wrong (started w/ "test_xrl"). test program very unclear about what was expected. Index: test_xreadline.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_xreadline.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_xreadline.py 2001/01/09 21:47:44 1.1 --- test_xreadline.py 2001/01/09 23:26:39 1.2 *************** *** 19,23 **** xreadlines.xreadlines(Null())[0] except AttributeError, detail: ! print "AttributeError" else: print "Did not throw attribute error" --- 19,23 ---- xreadlines.xreadlines(Null())[0] except AttributeError, detail: ! print "AttributeError (expected)" else: print "Did not throw attribute error" *************** *** 26,30 **** xreadlines.xreadlines(XReader)[0] except TypeError, detail: ! print "TypeError" else: print "Did not throw type error" --- 26,30 ---- xreadlines.xreadlines(XReader)[0] except TypeError, detail: ! print "TypeError (expected)" else: print "Did not throw type error" *************** *** 33,37 **** xreadlines.xreadlines(XReader())[1] except RuntimeError, detail: ! print "RuntimeError", detail else: print "Did not throw runtime error" --- 33,37 ---- xreadlines.xreadlines(XReader())[1] except RuntimeError, detail: ! print "RuntimeError (expected):", detail else: print "Did not throw runtime error" *************** *** 39,42 **** xresult = ['0\n', '1\n', '2\n', '3\n', '0\n', '1\n', '2\n', '0\n', '1\n', '0\n'] for line in xreadlines.xreadlines(XReader()): ! if line != xresult[lineno]: print "line %d differs" % lineno ! lineno = lineno + 1 --- 39,43 ---- xresult = ['0\n', '1\n', '2\n', '3\n', '0\n', '1\n', '2\n', '0\n', '1\n', '0\n'] for line in xreadlines.xreadlines(XReader()): ! if line != xresult[lineno]: ! print "line %d differs" % lineno ! lineno += 1 From python-dev@python.org Tue Jan 9 23:26:41 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 15:26:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_xreadline,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv31420/python/dist/src/Lib/test/output Modified Files: test_xreadline Log Message: Assorted xreadlines problems: Wasn't built on Windows; not in config.c either. Module init function missing DL_EXPORT magic. test_xreadline output file obviously wrong (started w/ "test_xrl"). test program very unclear about what was expected. Index: test_xreadline =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_xreadline,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_xreadline 2001/01/09 21:47:44 1.1 --- test_xreadline 2001/01/09 23:26:39 1.2 *************** *** 1,4 **** ! test_xrl ! AttributeError ! TypeError ! RuntimeError xreadlines object accessed out of order --- 1,4 ---- ! test_xreadline ! AttributeError (expected) ! TypeError (expected) ! RuntimeError (expected): xreadlines object accessed out of order From python-dev@python.org Tue Jan 9 23:26:41 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 15:26:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules xreadlinesmodule.c,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv31420/python/dist/src/Modules Modified Files: xreadlinesmodule.c Log Message: Assorted xreadlines problems: Wasn't built on Windows; not in config.c either. Module init function missing DL_EXPORT magic. test_xreadline output file obviously wrong (started w/ "test_xrl"). test program very unclear about what was expected. Index: xreadlinesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** xreadlinesmodule.c 2001/01/09 21:46:50 1.1 --- xreadlinesmodule.c 2001/01/09 23:26:39 1.2 *************** *** 110,114 **** }; ! void initxreadlines(void) { --- 110,114 ---- }; ! DL_EXPORT(void) initxreadlines(void) { From python-dev@python.org Tue Jan 9 23:26:41 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 15:26:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/PC config.c,1.29,1.30 Message-ID: Update of /cvsroot/python/python/dist/src/PC In directory usw-pr-cvs1:/tmp/cvs-serv31420/python/dist/src/PC Modified Files: config.c Log Message: Assorted xreadlines problems: Wasn't built on Windows; not in config.c either. Module init function missing DL_EXPORT magic. test_xreadline output file obviously wrong (started w/ "test_xrl"). test program very unclear about what was expected. Index: config.c =================================================================== RCS file: /cvsroot/python/python/dist/src/PC/config.c,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** config.c 2000/10/04 20:57:29 1.29 --- config.c 2001/01/09 23:26:39 1.30 *************** *** 43,47 **** --- 43,49 ---- #endif extern void init_codecs(void); + extern void initxreadlines(void); + /* XXX tim: what's the purpose of ADDMODULE MARKER? */ /* -- ADDMODULE MARKER 1 -- */ *************** *** 93,97 **** --- 95,101 ---- {"_codecs", init_codecs}, + {"xreadlines", initxreadlines}, + /* XXX tim: what's the purpose of ADDMODULE MARKER? */ /* -- ADDMODULE MARKER 2 -- */ From python-dev@python.org Tue Jan 9 23:27:14 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 15:27:14 -0800 Subject: [Python-checkins] CVS: python/dist/src/PCbuild python20.dsp,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv31669/python/dist/src/pcbuild Modified Files: python20.dsp Log Message: Make Windows build compile new xreadlinesmodule. Index: python20.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/python20.dsp,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** python20.dsp 2000/10/14 07:35:15 1.14 --- python20.dsp 2001/01/09 23:27:12 1.15 *************** *** 1678,1681 **** --- 1678,1696 ---- # Begin Source File + SOURCE=..\Modules\xreadlinesmodule.c + + !IF "$(CFG)" == "python20 - Win32 Release" + + !ELSEIF "$(CFG)" == "python20 - Win32 Debug" + + !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Debug" + + !ELSEIF "$(CFG)" == "python20 - Win32 Alpha Release" + + !ENDIF + + # End Source File + # Begin Source File + SOURCE=..\Modules\yuvconvert.c From python-dev@python.org Wed Jan 10 05:33:40 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 21:33:40 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc ACKS,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Doc In directory usw-pr-cvs1:/tmp/cvs-serv30332 Modified Files: ACKS Log Message: Fix a typo, remove one copy of a duplicated name. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ACKS,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** ACKS 2001/01/09 22:47:45 1.14 --- ACKS 2001/01/10 05:33:38 1.15 *************** *** 90,94 **** Piers Lauder Glyph Lefkowitz ! Marc-Andre Lemburg Ulf A. Lindgren Everett Lipman --- 90,94 ---- Piers Lauder Glyph Lefkowitz ! Marc-André Lemburg Ulf A. Lindgren Everett Lipman *************** *** 122,126 **** Edward K. Ream Sean Reifschneider - Bernhard Reiter Bernhard Reiter Wes Rishel --- 122,125 ---- From python-dev@python.org Wed Jan 10 05:36:33 2001 From: python-dev@python.org (Fred L. Drake) Date: Tue, 09 Jan 2001 21:36:33 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0205.txt,1.7,1.8 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv30659 Modified Files: pep-0205.txt Log Message: Substantially updated; now includes a description of the proposed API and rough outline of how the implementation should work. Hopefully will be ready for broad posting sometime tomorrow. Index: pep-0205.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0205.txt,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** pep-0205.txt 2000/11/28 22:23:25 1.7 --- pep-0205.txt 2001/01/10 05:36:31 1.8 *************** *** 50,59 **** - DOMs require a huge amount of circular (to parent & document ! nodes), but most of these aren't useful. Using weak ! references allows applications to hold onto less of the tree ! without a lot of difficulty. This might be especially ! useful in the context of something like xml.dom.pulldom. Weak References in Java --- 50,191 ---- - DOMs require a huge amount of circular (to parent & document ! nodes), but these could be eliminated using a weak ! dictionary mapping from each node to it's parent. This ! might be especially useful in the context of something like ! xml.dom.pulldom, allowing the .unlink() operation to become ! a no-op. ! ! This proposal is divided into the following sections: ! ! - Proposed Solution ! - Implementation Strategy ! - Possible Applications ! - Previous Weak Reference Work in Python ! - Weak References in Java ! ! The full text of one early proposal is included as an appendix ! since it does not appear to be available on the net. ! ! ! Proposed Solution ! ! Weak references should be able to point to any Python object that ! may have substantial memory size (directly or indirectly), or hold ! references to external resources (database connections, open ! files, etc.). ! ! A new module, weakref, will contain two new functions used to ! create weak references. weakref.new() will create a "weak ! reference object" and optionally attach a callback which will be ! called when the object is about to be finalized. ! weakref.mapping() will create a "weak dictionary". ! ! A weak reference object will allow access to the referenced object ! if it hasn't been collected, allows application code to either ! "clear" the weak reference and the associated callback, and to ! determine if the object still exists in memory. These operations ! are accessed via the .get(), .clear(), and .islive() methods. If ! the object has been collected, .get() will return None and ! islive() will return false; calling .clear() will produce the same ! result, and is allowed to occur repeatedly. Weak references are ! not hashable. ! ! A weak dictionary maps arbitrary keys to values, but does not own ! a reference to the values. When the values are finalized, the ! (key, value) pairs for which it is a value are removed from all ! the mappings containing such pairs. These mapping objects provide ! an additional method, .setitem(), which accepts a key, value, and ! optional callback which will be called when the object is removed ! from the mapping. If the object is removed from the mapping by ! deleting the entry by key or calling the mapping's .clear() ! method, the callback is not called (since the object is not about ! to be finalized), and will be unregistered from the object. Like ! dictionaries, weak dictionaries are not hashable. ! ! The callbacks registered with weak reference objects or in weak ! dictionaries must accept a single parameter, which will be the ! weak-ly referenced object itself. The object can be resurrected ! by creating some other reference to the object in the callback, in ! which case the weak reference generating the callback will still ! be cleared but no weak references remaining to the object will be ! cleared. ! ! ! Implementation Strategy ! ! The implementation of weak references will include a list of ! reference containers that must be cleared for each weakly- ! referencable object. If the reference is from a weak dictionary, ! the dictionary entry is cleared first. Then, any associated ! callback is called with the object passed as a parameter. If the ! callback generates additional references, no further callbacks are ! called and the object is resurrected. Once all callbacks have ! been called and the object has not been resurrected, it is ! finalized and deallocated. ! ! Many built-in types will participate in the weak-reference ! management, and any extension type can elect to do so. The type ! structure will contain an additional field which provides an ! offset into the instance structure which contains a list of weak ! reference structures. If the value of the field is <= 0, the ! object does not participate. In this case, weakref.new(), ! .setitem(), .setdefault(), and item assignment will ! raise TypeError. If the value of the field is > 0, a new weak ! reference can be generated and added to the list. ! ! This approach is taken to allow arbitrary extension types to ! participate, without taking a memory hit for numbers or other ! small types. ! ! XXX -- Need to determine the exact list of standard types which ! should support weak references. This should include instances and ! dictionaries. Whether it should include strings, buffers, lists, ! files, or sockets is debatable. + Possible Applications + + PyGTK+ bindings? + + Tkinter -- could avoid circular references by using weak + references from widgets to their parents. Objects won't be + discarded any sooner in the typical case, but there won't be so + much dependence on the programmer calling .destroy() before + releasing a reference. This would mostly benefit long-running + applications. + + DOM trees. + + + Previous Weak Reference Work in Python + + Dianne Hackborn has proposed something called "virtual references". + 'vref' objects are very similar to java.lang.ref.WeakReference + objects, except there is no equivalent to the invalidation + queues. Implementing a "weak dictionary" would be just as + difficult as using only weak references (without the invalidation + queue) in Java. Information on this has disappeared from the Web, + but is included below as an Appendix. + + Marc-André Lemburg's mx.Proxy package: + + http://www.lemburg.com/files/python/mxProxy.html + + The weakdict module by Dieter Maurer is implemented in C and + Python. It appears that the Web pages have not been updated since + Python 1.5.2a, so I'm not yet sure if the implementation is + compatible with Python 2.0. + + http://www.handshake.de/~dieter/weakdict.html + + PyWeakReference by Alex Shindich: + + http://sourceforge.net/projects/pyweakreference/ + + Eric Tiedemann has a weak dictionary implementation: + + http://www.hyperreal.org/~est/python/weak/ + + Weak References in Java *************** *** 100,152 **** Unlike the other two reference types, "phantom" references must be associated with an invalidation queue. - - - Previous Weak Reference Work in Python - - Dianne Hackborn has proposed something called "virtual references". - 'vref' objects are very similar to java.lang.ref.WeakReference - objects, except there is no equivalent to the invalidation - queues. Implementing a "weak dictionary" would be just as - difficult as using only weak references (without the invalidation - queue) in Java. Information on this has disappeared from the Web, - but is included below as an Appendix. - - Marc-André Lemburg's mx.Proxy package: - - http://www.lemburg.com/files/python/mxProxy.html - - The weakdict module by Dieter Maurer is implemented in C and - Python. It appears that the Web pages have not been updated since - Python 1.5.2a, so I'm not yet sure if the implementation is - compatible with Python 2.0. - - http://www.handshake.de/~dieter/weakdict.html - - PyWeakReference by Alex Shindich: - - http://sourceforge.net/projects/pyweakreference/ - - Eric Tiedemann has a weak dictionary implementation: - - http://www.hyperreal.org/~est/python/weak/ - - - Possible Applications - - PyGTK+ bindings? - - Tkinter -- could avoid circular references by using weak - references from widgets to their parents. Objects won't be - discarded any sooner in the typical case, but there won't be so - much dependence on the programmer calling .destroy() before - releasing a reference. This would mostly benefit long-running - applications. - - DOM trees? - - - Proposed Implementation - - XXX -- Not yet. --- 232,235 ---- From python-dev@python.org Wed Jan 10 05:42:20 2001 From: python-dev@python.org (Tim Peters) Date: Tue, 09 Jan 2001 21:42:20 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.24,2.25 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv31016/python/dist/src/modules Modified Files: mmapmodule.c Log Message: Windows mmap should (as the docs probably say) create a mapping without a name when the optional tagname arg isn't specified. Was actually creating a mapping with an empty string as the name. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.24 retrieving revision 2.25 diff -C2 -r2.24 -r2.25 *** mmapmodule.c 2000/10/01 17:50:46 2.24 --- mmapmodule.c 2001/01/10 05:42:18 2.25 *************** *** 908,912 **** /* set the tag name */ ! if (tagname != NULL) { m_obj->tagname = PyMem_Malloc(strlen(tagname)+1); if (m_obj->tagname == NULL) { --- 908,912 ---- /* set the tag name */ ! if (tagname != NULL && *tagname != '\0') { m_obj->tagname = PyMem_Malloc(strlen(tagname)+1); if (m_obj->tagname == NULL) { *************** *** 925,929 **** 0, m_obj->size, ! tagname); if (m_obj->map_handle != NULL) { m_obj->data = (char *) MapViewOfFile (m_obj->map_handle, --- 925,929 ---- 0, m_obj->size, ! m_obj->tagname); if (m_obj->map_handle != NULL) { m_obj->data = (char *) MapViewOfFile (m_obj->map_handle, From python-dev@python.org Wed Jan 10 10:21:13 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 10 Jan 2001 02:21:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test testcodec.py,NONE,1.1 test_charmapcodec.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32293 Modified Files: test_charmapcodec.py Added Files: testcodec.py Log Message: Moved the test codec definition to a new module and updated the test and codec to test all charmap codec features. As side-effect of moving the test codec into a new module, the encodings package codec import mechanism is checked as well. --- NEW FILE: testcodec.py --- """ Test Codecs (used by test_charmapcodec) Written by Marc-Andre Lemburg (mal@lemburg.com). (c) Copyright 2000 Guido van Rossum. """#" import codecs ### Codec APIs class Codec(codecs.Codec): def encode(self,input,errors='strict'): return codecs.charmap_encode(input,errors,encoding_map) def decode(self,input,errors='strict'): return codecs.charmap_decode(input,errors,decoding_map) class StreamWriter(Codec,codecs.StreamWriter): pass class StreamReader(Codec,codecs.StreamReader): pass ### encodings module API def getregentry(): return (Codec().encode,Codec().decode,StreamReader,StreamWriter) ### Decoding Map decoding_map = codecs.make_identity_dict(range(256)) decoding_map.update({ 0x78: u"abc", # 1-n decoding mapping "abc": 0x0078,# 1-n encoding mapping 0x01: None, # decoding mapping to 0x79: u"", # decoding mapping to }) ### Encoding Map encoding_map = {} for k,v in decoding_map.items(): encoding_map[v] = k Index: test_charmapcodec.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_charmapcodec.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_charmapcodec.py 2001/01/06 15:09:56 1.1 --- test_charmapcodec.py 2001/01/10 10:21:10 1.2 *************** *** 1,4 **** ! """ Python Character Mapping Codec test Written by Marc-Andre Lemburg (mal@lemburg.com). --- 1,7 ---- ! """ Python character mapping codec test + This uses the test codec in testcodec.py and thus also tests the + encodings package lookup scheme. + Written by Marc-Andre Lemburg (mal@lemburg.com). *************** *** 6,65 **** """#" - import codecs - - ### Codec APIs - - class Codec(codecs.Codec): - - def encode(self,input,errors='strict'): - - return codecs.charmap_encode(input,errors,encoding_map) - - def decode(self,input,errors='strict'): - - return codecs.charmap_decode(input,errors,decoding_map) - - class StreamWriter(Codec,codecs.StreamWriter): - pass - - class StreamReader(Codec,codecs.StreamReader): - pass - - ### encodings module API - - def getregentry(): - return (Codec().encode,Codec().decode,StreamReader,StreamWriter) - - ### Decoding Map - - decoding_map = codecs.make_identity_dict(range(256)) - decoding_map.update({ - 0x0078: u"abc", - "abc": 0x0078, - }) - - ### Encoding Map - - encoding_map = {} - for k,v in decoding_map.items(): - encoding_map[v] = k - - - ### Tests - def check(a, b): if a != b: print '*** check failed: %s != %s' % (repr(a), repr(b)) - check(unicode('abc', 'mycp'), u'abc') - check(unicode('xdef', 'mycp'), u'abcdef') - check(unicode('defx', 'mycp'), u'defabc') - check(unicode('dxf', 'mycp'), u'dabcf') - check(unicode('dxfx', 'mycp'), u'dabcfabc') - - check(u'abc'.encode('mycp'), 'abc') - check(u'xdef'.encode('mycp'), 'abcdef') - check(u'defx'.encode('mycp'), 'defabc') - check(u'dxf'.encode('mycp'), 'dabcf') - check(u'dxfx'.encode('mycp'), 'dabcfabc') --- 9,44 ---- """#" def check(a, b): if a != b: print '*** check failed: %s != %s' % (repr(a), repr(b)) + else: + print '%s == %s: OK' % (repr(a), repr(b)) + + # test codec's full path name (see test/testcodec.py) + codecname = 'testcodec' + + check(unicode('abc', codecname), u'abc') + check(unicode('xdef', codecname), u'abcdef') + check(unicode('defx', codecname), u'defabc') + check(unicode('dxf', codecname), u'dabcf') + check(unicode('dxfx', codecname), u'dabcfabc') + + check(u'abc'.encode(codecname), 'abc') + check(u'xdef'.encode(codecname), 'abcdef') + check(u'defx'.encode(codecname), 'defabc') + check(u'dxf'.encode(codecname), 'dabcf') + check(u'dxfx'.encode(codecname), 'dabcfabc') + + check(unicode('ydef', codecname), u'def') + check(unicode('defy', codecname), u'def') + check(unicode('dyf', codecname), u'df') + check(unicode('dyfy', codecname), u'df') + + try: + unicode('abc\001', codecname) + except UnicodeError: + print '\\001 maps to undefined: OK' + else: + print '*** check failed: \\001 does not map to undefined' From python-dev@python.org Wed Jan 10 10:21:13 2001 From: python-dev@python.org (M.-A. Lemburg) Date: Wed, 10 Jan 2001 02:21:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_charmapcodec,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv32293/output Modified Files: test_charmapcodec Log Message: Moved the test codec definition to a new module and updated the test and codec to test all charmap codec features. As side-effect of moving the test codec into a new module, the encodings package codec import mechanism is checked as well. Index: test_charmapcodec =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_charmapcodec,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_charmapcodec 2001/01/06 15:09:57 1.1 --- test_charmapcodec 2001/01/10 10:21:11 1.2 *************** *** 1 **** --- 1,16 ---- test_charmapcodec + u'abc' == u'abc': OK + u'abcdef' == u'abcdef': OK + u'defabc' == u'defabc': OK + u'dabcf' == u'dabcf': OK + u'dabcfabc' == u'dabcfabc': OK + 'abc' == 'abc': OK + 'abcdef' == 'abcdef': OK + 'defabc' == 'defabc': OK + 'dabcf' == 'dabcf': OK + 'dabcfabc' == 'dabcfabc': OK + u'def' == u'def': OK + u'def' == u'def': OK + u'df' == u'df': OK + u'df' == u'df': OK + \001 maps to undefined: OK From python-dev@python.org Wed Jan 10 14:35:53 2001 From: python-dev@python.org (Moshe Zadka) Date: Wed, 10 Jan 2001 06:35:53 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0206.txt,1.10,1.11 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv8841 Modified Files: pep-0206.txt Log Message: Preparing to have something concrete to show for dev-day However, if you have remarks before the build day, don't hesitate to send them my way. Clarified lots of issues. Index: pep-0206.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0206.txt,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** pep-0206.txt 2000/12/11 23:08:11 1.10 --- pep-0206.txt 2001/01/10 14:35:50 1.11 *************** *** 95,102 **** us. - - Software covered by the GNU Public License - While many Python modules rely on software distributed under the GNU General Public License and the GNU Lesser General Public --- 95,100 ---- us. + Software covered by the GNU General Public License While many Python modules rely on software distributed under the GNU General Public License and the GNU Lesser General Public *************** *** 109,120 **** the benefits. ! Open Issues ! Where does all this source live? ! What should the build procedure look like? ! How are the additional modules tested? ESR also mentioned libpng, but I don't know of a Python module --- 107,127 ---- the benefits. + How It Is Implemented ! Sumo-Python is basically be a set of scripts, which download ! a Python source tarball, and source tarballs for all the modules. ! Then it unpacks everything, modifies Setup.in (or whatever mechanism ! will be in place by Python 2.1, and puts in a little ! shell script which builds everything. Then it will repack it ! into the huge tarball which will be a sumo-python-version.tar.gz, ! which users can then download and install. ! Inside the tarball, running the script ! build-everything [--prefix ...] ! Will compile and install a sumo interpreter into specified prefix. ! ! Open Issues ESR also mentioned libpng, but I don't know of a Python module From python-dev@python.org Wed Jan 10 17:09:04 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 09:09:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Demo/embed demo.c,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv2239 Modified Files: demo.c Log Message: Fix weird typo caused by ANSIfication (nobody bothered to test it since! :-( ). Index: demo.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/embed/demo.c,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** demo.c 2000/07/22 19:25:50 1.5 --- demo.c 2001/01/10 17:09:00 1.6 *************** *** 47,51 **** /* 'self' is not used */ static PyObject * ! xyzzy_foo(PyObject *self, PyObjecT *args) { if (!PyArg_ParseTuple(args, "")) --- 47,51 ---- /* 'self' is not used */ static PyObject * ! xyzzy_foo(PyObject *self, PyObject* args) { if (!PyArg_ParseTuple(args, "")) From python-dev@python.org Wed Jan 10 17:11:54 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 09:11:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Demo/embed loop.c,NONE,1.1 Makefile,1.5,1.6 README,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Demo/embed In directory usw-pr-cvs1:/tmp/cvs-serv2697 Modified Files: Makefile README Added Files: loop.c Log Message: Add loop.c -- a test program for repeatedly calling Py_Initialize() and Py_Finalize(). It seems to dump core right now... --- NEW FILE: loop.c --- /* Simple program that repeatedly calls Py_Initialize(), does something, and then calls Py_Finalize(). This should help finding leaks related to initialization. */ #include "Python.h" main(int argc, char **argv) { char *command; if (argc != 2) { fprintf(stderr, "usage: loop \n"); exit(2); } command = argv[1]; Py_SetProgramName(argv[0]); while (1) { Py_Initialize(); PyRun_SimpleString(command); Py_Finalize(); } /*NOTREACHED*/ } Index: Makefile =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/embed/Makefile,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** Makefile 2000/07/10 16:22:12 1.5 --- Makefile 2001/01/10 17:11:51 1.6 *************** *** 33,36 **** --- 33,39 ---- $(CC) $(LDFLAGS) demo.o $(ALLLIBS) -o demo + loop: loop.o + $(CC) $(LDFLAGS) loop.o $(ALLLIBS) -o loop + # Administrative targets *************** *** 38,44 **** ./demo clean: -rm -f *.o core clobber: clean ! -rm -f *~ @* '#'* demo --- 41,51 ---- ./demo + COMMAND="print 'hello world'" + looptest: loop + ./loop $(COMMAND) + clean: -rm -f *.o core clobber: clean ! -rm -f *~ @* '#'* demo loop Index: README =================================================================== RCS file: /cvsroot/python/python/dist/src/Demo/embed/README,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** README 1995/03/28 09:22:52 1.2 --- README 2001/01/10 17:11:51 1.3 *************** *** 11,12 **** --- 11,19 ---- (MODLIBS, LIBS, SYSLIBS) to link with, to match their definitions in $(blddir)/Modules/Makefile + + An additional test program, loop.c, is used to experiment with memory + leakage caused by repeated initialization and finalization of the + interpreter. It can be build by saying "make loop" and tested with + "make looptest". Command line usage is "./loop ", + e.g. "./loop 'print 2+2'" should spit out an endless number of lines + containing the number 4. From python-dev@python.org Wed Jan 10 18:53:50 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 10:53:50 -0800 Subject: [Python-checkins] CVS: python/dist/src configure,1.175,1.176 configure.in,1.183,1.184 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv17166 Modified Files: configure configure.in Log Message: Adapted version of Eric Raymond's patches to automatically configure curses and readline (for Linux, at least). These are done as shared libraries by default, and so is bsddb -- that seems to make the most sense. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.175 retrieving revision 1.176 diff -C2 -r1.175 -r1.176 *** configure 2001/01/08 17:58:56 1.175 --- configure 2001/01/10 18:53:47 1.176 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.182 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.184 [...2272 lines suppressed...] echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6035: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then --- 6121,6125 ---- echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6124: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then *************** *** 6206,6209 **** --- 6295,6300 ---- s%@CCSHARED@%$CCSHARED%g s%@LINKFORSHARED@%$LINKFORSHARED%g + s%@USE_NCURSES_MODULE@%$USE_NCURSES_MODULE%g + s%@USE_READLINE_MODULE@%$USE_READLINE_MODULE%g s%@USE_THREAD_MODULE@%$USE_THREAD_MODULE%g s%@LDLAST@%$LDLAST%g Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.183 retrieving revision 1.184 diff -C2 -r1.183 -r1.184 *** configure.in 2001/01/08 17:58:56 1.183 --- configure.in 2001/01/10 18:53:48 1.184 *************** *** 735,738 **** --- 735,753 ---- ], AC_MSG_RESULT(no)) + # This is used to generate Setup.config + AC_SUBST(USE_NCURSES_MODULE) + AC_CHECK_LIB(ncurses, initscr, + [USE_NCURSES_MODULE=""], + [USE_NCURSES_MODULE="#"], + -ltermcap) + + # This is used to generate Setup.config + AC_SUBST(USE_READLINE_MODULE) + AC_CHECK_LIB(readline, readline, + [USE_READLINE_MODULE=""], + [USE_READLINE_MODULE="#"], + -ltermcap) + + # This is used to generate Setup.config AC_SUBST(USE_THREAD_MODULE) USE_THREAD_MODULE="" From python-dev@python.org Wed Jan 10 18:53:50 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 10:53:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.dist,1.4,1.5 Setup.config.in,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv17166/Modules Modified Files: Setup.dist Setup.config.in Log Message: Adapted version of Eric Raymond's patches to automatically configure curses and readline (for Linux, at least). These are done as shared libraries by default, and so is bsddb -- that seems to make the most sense. Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** Setup.dist 2001/01/09 21:46:50 1.4 --- Setup.dist 2001/01/10 18:53:48 1.5 *************** *** 121,124 **** --- 121,126 ---- # it, depending on your system -- see the GNU readline instructions. # It's okay for this to be a shared library, too. + # + # First, look at Setup.config; configure may have set this for you. #readline readline.c -lreadline -ltermcap *************** *** 323,326 **** --- 325,330 ---- # instead of -lcurses; on SunOS 4.1.3, insert -I/usr/5include # -L/usr/5lib before -lcurses). + # + # First, look at Setup.config; configure may have set this for you. #_curses _cursesmodule.c -lcurses -ltermcap Index: Setup.config.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.config.in,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** Setup.config.in 2000/10/26 14:57:29 1.5 --- Setup.config.in 2001/01/10 18:53:48 1.6 *************** *** 2,18 **** # The purpose of this file is to conditionally enable certain modules ! # based on configure-time options. Currently thread support, garbage ! # collection support, and the BSD DB modules are the only modules so ! # enabled. - @USE_THREAD_MODULE@thread threadmodule.c - # Garbage collection enabled with --with-cycle-gc @USE_GC_MODULE@gc gcmodule.c ! # You may want this to be built as a dynamically loaded module; uncomment ! # the following line in that case: ! #*shared* # bsddb module enabled by --with-libdb or presence of db.h --- 2,23 ---- # The purpose of this file is to conditionally enable certain modules ! # based on configure-time options. # Garbage collection enabled with --with-cycle-gc @USE_GC_MODULE@gc gcmodule.c + + # Threading + @USE_THREAD_MODULE@thread threadmodule.c + + # You may want the following to be built as statically loaded modules; + # comment out the *shared* line in that case: + + *shared* ! # Readline ! @USE_READLINE_MODULE@readline readline.c -lreadline -ltermcap ! # The ncurses library, under Linux ! @USE_NCURSES_MODULE@_curses _cursesmodule.c -lncurses -ltermcap # bsddb module enabled by --with-libdb or presence of db.h From python-dev@python.org Wed Jan 10 19:14:31 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 11:14:31 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib uu.py,1.13,1.14 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv20098 Modified Files: uu.py Log Message: Adapted version of SF Patch #103173 by pyretic: make uu.decode work with spaces in filename. I changed the module to use string methods instead of the string module. Also, instead of stripping the last character of the filename (assuming this is the linefeed), I strip trailing whitespace (assuming creating files with trailing whitespace in their name cannot possibly be a wise idea). (Note that I believe that /F's "workaround for broken uuencoders" is no longer needed since the recent fix to binascii.c, but I'll leave it in since it appears pretty harmless.) Index: uu.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/uu.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** uu.py 2000/12/12 23:20:45 1.13 --- uu.py 2001/01/10 19:14:28 1.14 *************** *** 33,37 **** import binascii import os - import string import sys --- 33,36 ---- *************** *** 98,112 **** if hdr[:5] != 'begin': continue ! hdrfields = string.split(hdr) if len(hdrfields) == 3 and hdrfields[0] == 'begin': try: ! string.atoi(hdrfields[1], 8) break except ValueError: pass if out_file is None: ! out_file = hdrfields[2] if mode is None: ! mode = string.atoi(hdrfields[1], 8) # # Open the output file --- 97,111 ---- if hdr[:5] != 'begin': continue ! hdrfields = hdr.split(" ", 2) if len(hdrfields) == 3 and hdrfields[0] == 'begin': try: ! int(hdrfields[1], 8) break except ValueError: pass if out_file is None: ! out_file = hdrfields[2].rstrip() if mode is None: ! mode = int(hdrfields[1], 8) # # Open the output file From python-dev@python.org Wed Jan 10 19:34:54 2001 From: python-dev@python.org (Eric S. Raymond) Date: Wed, 10 Jan 2001 11:34:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libascii.tex,1.6,1.7 libcookie.tex,1.3,1.4 libsocket.tex,1.50,1.51 libstat.tex,1.19,1.20 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv24383/Doc/lib Modified Files: libascii.tex libcookie.tex libsocket.tex libstat.tex Log Message: SourceForge patch #103140, checked in at fdrake's invitation. Minor fixes and additions to library docs.# Index: libascii.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libascii.tex,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** libascii.tex 2000/12/26 16:09:37 1.6 --- libascii.tex 2001/01/10 19:34:52 1.7 *************** *** 54,58 **** \end{tableii} ! Note that many of these have little practical use in modern usage. The module supplies the following functions, patterned on those in the --- 54,60 ---- \end{tableii} ! Note that many of these have little practical significance in modern ! usage. The mnemonics derive from teleprinter conventions that predate ! digital computers. The module supplies the following functions, patterned on those in the Index: libcookie.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libcookie.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** libcookie.tex 2000/08/20 23:33:50 1.3 --- libcookie.tex 2001/01/10 19:34:52 1.4 *************** *** 9,13 **** The \module{Cookie} module defines classes for abstracting the concept of ! cookies, an HTTP state management mechanism. It supports both simplistic string-only cookies, and provides an abstraction for having any serializable data-type as cookie value. --- 9,13 ---- The \module{Cookie} module defines classes for abstracting the concept of ! cookies, an HTTP state management mechanism. It supports both simple string-only cookies, and provides an abstraction for having any serializable data-type as cookie value. Index: libsocket.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsocket.tex,v retrieving revision 1.50 retrieving revision 1.51 diff -C2 -r1.50 -r1.51 *** libsocket.tex 2000/10/10 20:36:29 1.50 --- libsocket.tex 2001/01/10 19:34:52 1.51 *************** *** 268,273 **** above.) \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a ! tuple. This was never intentional and will no longer be available in ! Python 1.7. \end{methoddesc} --- 268,273 ---- above.) \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a ! tuple. This was never intentional and is no longer be available in ! Python 2.0. \end{methoddesc} *************** *** 283,288 **** above.) \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a ! tuple. This was never intentional and will no longer be available in ! Python 1.7. \end{methoddesc} --- 283,288 ---- above.) \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a ! tuple. This was never intentional and is no longer available in ! Python 2.0 and later. \end{methoddesc} *************** *** 296,301 **** \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a tuple. ! This was never intentional and will no longer be available in Python ! 1.7. \end{methoddesc} --- 296,301 ---- \strong{Note:} This method has historically accepted a pair of parameters for \constant{AF_INET} addresses instead of only a tuple. ! This was never intentional and is no longer be available in Python ! 2.0 and later. \end{methoddesc} Index: libstat.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstat.tex,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** libstat.tex 1999/08/03 21:52:29 1.19 --- libstat.tex 2001/01/10 19:34:52 1.20 *************** *** 98,102 **** \begin{datadesc}{ST_SIZE} ! File size in bytes. \end{datadesc} --- 98,103 ---- \begin{datadesc}{ST_SIZE} ! Size in bytes of a plain file; amount of data waiting on some special ! files. \end{datadesc} *************** *** 112,115 **** --- 113,126 ---- Time of last status change (see manual pages for details). \end{datadesc} + + The interpretation of ``file size'' changes according to the file + type. For plain files this is the size of the file in bytes. For + FIFOs and sockets under most Unixes (including Linux in particular), + the ``size'' is the number of bytes waiting to be read at the time of + the stat(2)/fstat(2)/lstat(2) call; this can sometimes be useful, + especially for polling one of these special files after a non-blocking + open. The meaning of the size field for other character and block + devices varies more, depending on the local implementation of the + underlying system call. Example: From python-dev@python.org Wed Jan 10 20:13:58 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 12:13:58 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.89,1.90 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29042 Modified Files: NEWS Log Message: Added a whole slew of news items. Not striving for completeness -- I've skipped all bugfixes, Unicode, distutils changes. But this should be a start! Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.89 retrieving revision 1.90 diff -C2 -r1.89 -r1.90 *** NEWS 2001/01/05 08:05:32 1.89 --- NEWS 2001/01/10 20:13:55 1.90 *************** *** 4,7 **** --- 4,37 ---- Core language, builtins, and interpreter + - File objects have a new method, xreadlines(). This is the fastest + way to iterate over all lines in a file: + + for line in file.xreadlines(): + ...do something to line... + + See the xreadlines module (mentioned below) for how to do this for + other file-like objects. + + - Even if you don't use file.xreadlines(), you may expect a speedup on + line-by-line input. The file.readline() method has been optimized + quite a bit in platform-specific ways, both on Windows (using an + incredibly complex, but nevertheless thread-safe), and on systems + (like Linux) that support flockfile(), getc_unlocked(), and + funlockfile(). In addition, the fileinput module, while still slow, + has been sped up too, by using file.readlines(sizehint). + + - Support for run-time warnings has been added, including a new + command line option (-W) to specify the disposition of warnings. + See the description of the warnings module below. + + - Extensive changes have been made to the coercion code. This mostly + affects extension modules (which can now implement mixed-type + numerical operators without having to use coercion), but + occasionally, in boundary cases the coercion semantics have changed + subtly. Since this was a terrible gray area of the language, this + is considered an improvement. Also not that __rcmp__ is no longer + supported -- instead of calling __rcmp__, __cmp__ is called with + reversed arguments. + - The interpreter accepts now bytecode files on the command line even if they do not have a .pyc or .pyo extension. On Linux, after executing *************** *** 43,49 **** using popitem() they can usually be made to run in linear time. - Standard library - The bisect module has new functions bisect_left, insort_left, bisect_right and insort_right. The old names bisect and insort --- 73,102 ---- using popitem() they can usually be made to run in linear time. Standard library + - There's a new module, warnings, which implements a mechanism for + issuing and filtering warnings. There are some new built-in + exceptions that serve as warning categories, and a new command line + option, -W, to control warnings (e.g. -Wi ignores all warnings, -We + turns warnings into errors). warnings.warn(message[, category]) + issues a warning message; this can also be called from C as + PyErr_Warn(category, message). + + - A new module xreadlines was added. This exports a single factory + function, xreadlines(). The intention is that this code is the + absolutely fastest way to iterate over all lines in an open + file(-like) object: + + import xreadlines + for line in xreadlines.xreadlines(file): + ...do something to line... + + This is equivalent to the previous the speed record holder using + file.readlines(sizehint). Note that if file is a real file object + (as opposed to a file-like object), this is equivalent: + + for line in file.xreadlines(): + ...do something to line... + - The bisect module has new functions bisect_left, insort_left, bisect_right and insort_right. The old names bisect and insort *************** *** 55,59 **** --- 108,133 ---- continue to use the old, short names ("bisect" and "insort"). + - The SocketServer module now sets the allow_reuse_address flag by + default in the TCPServer class. + + - A new function, sys._getframe(), returns the stack frame pointer of + the caller. This is intended only as a building block for + higher-level mechanisms such as string interpolation. + + Build issues + + - On Linux (and possibly other Unix platforms), the readline and + _curses modules are automatically configured through + Modules/Setup.config. These, and the bsddb module (which was + already dynamically configured) are now built as shared libraries by + default. + + - Python now always uses its own (renamed) implementation of getopt() + -- there's too much variation among C library getopt() + implementations. + - C++ compilers are better supported; the CXX macro is always set to a + C++ compiler if one is found. + Windows changes *************** *** 63,66 **** --- 137,143 ---- that, see the MS docs (you'll need to #define FD_SETSIZE and recompile Python from source). + + - Support for Windows 3.1, DOS and OS/2 is gone. The Lib/dos-8x3 + subdirectory is no more! From python-dev@python.org Wed Jan 10 20:40:48 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 12:40:48 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python import.c,2.154,2.155 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv31527/Python Modified Files: import.c Log Message: SF Patch #103154 by jlt63: Cygwin Check Import Case Patch. Note: I've reordered acconfig.h and config.h.in to obtain alphabetical order (modulo case and leading _). Index: import.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/import.c,v retrieving revision 2.154 retrieving revision 2.155 diff -C2 -r2.154 -r2.155 *** import.c 2000/11/13 17:26:32 2.154 --- import.c 2001/01/10 20:40:46 2.155 *************** *** 1011,1015 **** #ifdef CHECK_IMPORT_CASE ! #ifdef MS_WIN32 #include #include --- 1011,1015 ---- #ifdef CHECK_IMPORT_CASE ! #if defined(MS_WIN32) || defined(__CYGWIN__) #include #include *************** *** 1040,1043 **** --- 1040,1047 ---- } + #ifdef __CYGWIN__ + #include + #endif + static int check_case(char *buf, int len, int namelen, char *name) *************** *** 1045,1051 **** --- 1049,1063 ---- WIN32_FIND_DATA data; HANDLE h; + #ifdef __CYGWIN__ + char tempbuf[MAX_PATH]; + #endif if (getenv("PYTHONCASEOK") != NULL) return 1; + #ifdef __CYGWIN__ + cygwin32_conv_to_win32_path(buf, tempbuf); + h = FindFirstFile(tempbuf, &data); + #else h = FindFirstFile(buf, &data); + #endif if (h == INVALID_HANDLE_VALUE) { PyErr_Format(PyExc_NameError, From python-dev@python.org Wed Jan 10 20:40:48 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 12:40:48 -0800 Subject: [Python-checkins] CVS: python/dist/src acconfig.h,1.40,1.41 config.h.in,2.82,2.83 configure,1.176,1.177 configure.in,1.184,1.185 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv31527 Modified Files: acconfig.h config.h.in configure configure.in Log Message: SF Patch #103154 by jlt63: Cygwin Check Import Case Patch. Note: I've reordered acconfig.h and config.h.in to obtain alphabetical order (modulo case and leading _). Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** acconfig.h 2001/01/05 14:45:48 1.40 --- acconfig.h 2001/01/10 20:40:46 1.41 *************** *** 2,5 **** --- 2,9 ---- + /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r + and you want support for AIX C++ shared extension modules. */ + #undef AIX_GENUINE_CPLUSPLUS + /* Define if your contains bad prototypes for exec*() (as it does on SGI IRIX 4.x) */ *************** *** 10,17 **** #undef BAD_STATIC_FORWARD - /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r - and you want support for AIX C++ shared extension modules. */ - #undef AIX_GENUINE_CPLUSPLUS - /* Define this if you have BeOS threads */ #undef BEOS_THREADS --- 14,17 ---- *************** *** 20,23 **** --- 20,26 ---- #undef C_THREADS + /* Defined when case of imported modules are checked against case of file. */ + #undef CHECK_IMPORT_CASE + /* Define to `long' if doesn't define. */ #undef clock_t *************** *** 33,36 **** --- 36,42 ---- #undef HAVE_ALTZONE + /* Defined when any dynamic module loading is enabled */ + #undef HAVE_DYNAMIC_LOADING + /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ #undef HAVE_GETC_UNLOCKED *************** *** 51,60 **** #undef HAVE_GETHOSTBYNAME_R_6_ARG /* Define this if you have the type long long */ #undef HAVE_LONG_LONG - /* Define this if you have the type uintptr_t */ - #undef HAVE_UINTPTR_T - /* Define if your compiler supports function prototypes */ #undef HAVE_PROTOTYPES --- 57,72 ---- #undef HAVE_GETHOSTBYNAME_R_6_ARG + /* Defined to enable large file support when an off_t is bigger than a long + and long long is available and at least as big as an off_t. You may need + to add some flags for configuration and compilation to enable this mode. + E.g, for Solaris 2.7: + CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \ + configure + */ + #undef HAVE_LARGEFILE_SUPPORT + /* Define this if you have the type long long */ #undef HAVE_LONG_LONG /* Define if your compiler supports function prototypes */ #undef HAVE_PROTOTYPES *************** *** 67,70 **** --- 79,93 ---- #undef HAVE_STDARG_PROTOTYPES + /* Define this if you have the type uintptr_t */ + #undef HAVE_UINTPTR_T + + /* Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be 16-bit unsigned type. (see + Include/unicodeobject.h). */ + #undef HAVE_USABLE_WCHAR_T + + /* Define if the compiler provides a wchar.h header file. */ + #undef HAVE_WCHAR_H + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 73,76 **** --- 96,102 ---- #undef _POSIX_THREADS + /* Define if you want to build an interpreter with many run-time checks */ + #undef Py_DEBUG + /* Define to force use of thread-safe errno, h_errno, and other functions */ #undef _REENTRANT *************** *** 82,85 **** --- 108,125 ---- #undef signed + /* Define if i>>j for signed int i does not extend the sign bit + when i < 0 + */ + #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS + + /* The number of bytes in an off_t. */ + #undef SIZEOF_OFF_T + + /* The number of bytes in a time_t. */ + #undef SIZEOF_TIME_T + + /* The number of bytes in a pthread_t. */ + #undef SIZEOF_PTHREAD_T + /* sizeof(void *) */ #undef SIZEOF_VOID_P *************** *** 104,125 **** #undef WANT_SIGFPE_HANDLER - /* Define if the compiler provides a wchar.h header file. */ - #undef HAVE_WCHAR_H - - /* Define if you have a useable wchar_t type defined in wchar.h; useable - means wchar_t must be 16-bit unsigned type. (see - Include/unicodeobject.h). */ - #undef HAVE_USABLE_WCHAR_T - /* Define if you want wctype.h functions to be used instead of the one supplied by Python itself. (see Include/unicodectype.h). */ #undef WANT_WCTYPE_FUNCTIONS ! /* Define if you want to use SGI (IRIX 4) dynamic linking. ! This requires the "dl" library by Jack Jansen, ! ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z. ! Don't bother on IRIX 5, it already has dynamic linking using SunOS ! style shared libraries */ ! #undef WITH_SGI_DL /* Define if you want to emulate SGI (IRIX 4) dynamic linking. --- 144,153 ---- #undef WANT_SIGFPE_HANDLER /* Define if you want wctype.h functions to be used instead of the one supplied by Python itself. (see Include/unicodectype.h). */ #undef WANT_WCTYPE_FUNCTIONS ! /* Define if you want to compile in cycle garbage collection */ ! #undef WITH_CYCLE_GC /* Define if you want to emulate SGI (IRIX 4) dynamic linking. *************** *** 138,183 **** linker (rld). Dyld is necessary to support frameworks. */ #undef WITH_DYLD - - /* Define if you want to compile in rudimentary thread support */ - #undef WITH_THREAD ! /* Define if you want to compile in cycle garbage collection */ ! #undef WITH_CYCLE_GC /* Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK - - /* Define if you want to use BSD db. */ - #undef WITH_LIBDB - - /* Define if you want to build an interpreter with many run-time checks */ - #undef Py_DEBUG - - /* The number of bytes in an off_t. */ - #undef SIZEOF_OFF_T - - /* The number of bytes in a time_t. */ - #undef SIZEOF_TIME_T - - /* The number of bytes in a pthread_t. */ - #undef SIZEOF_PTHREAD_T - - /* Defined to enable large file support when an off_t is bigger than a long - and long long is available and at least as big as an off_t. You may need - to add some flags for configuration and compilation to enable this mode. - E.g, for Solaris 2.7: - CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \ - configure - */ - #undef HAVE_LARGEFILE_SUPPORT ! /* Defined when any dynamic module loading is enabled */ ! #undef HAVE_DYNAMIC_LOADING ! /* Define if i>>j for signed int i does not extend the sign bit ! when i < 0 ! */ ! #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS --- 166,186 ---- linker (rld). Dyld is necessary to support frameworks. */ #undef WITH_DYLD ! /* Define if you want to use BSD db. */ ! #undef WITH_LIBDB /* Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK ! /* Define if you want to use SGI (IRIX 4) dynamic linking. ! This requires the "dl" library by Jack Jansen, ! ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z. ! Don't bother on IRIX 5, it already has dynamic linking using SunOS ! style shared libraries */ ! #undef WITH_SGI_DL ! /* Define if you want to compile in rudimentary thread support */ ! #undef WITH_THREAD Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.82 retrieving revision 2.83 diff -C2 -r2.82 -r2.83 *** config.h.in 2001/01/08 17:58:56 2.82 --- config.h.in 2001/01/10 20:40:46 2.83 *************** *** 67,70 **** --- 67,74 ---- #undef WORDS_BIGENDIAN + /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r + and you want support for AIX C++ shared extension modules. */ + #undef AIX_GENUINE_CPLUSPLUS + /* Define if your contains bad prototypes for exec*() (as it does on SGI IRIX 4.x) */ *************** *** 75,82 **** #undef BAD_STATIC_FORWARD - /* Define for AIX if your compiler is a genuine IBM xlC/xlC_r - and you want support for AIX C++ shared extension modules. */ - #undef AIX_GENUINE_CPLUSPLUS - /* Define this if you have BeOS threads */ #undef BEOS_THREADS --- 79,82 ---- *************** *** 85,88 **** --- 85,91 ---- #undef C_THREADS + /* Defined when case of imported modules are checked against case of file. */ + #undef CHECK_IMPORT_CASE + /* Define to `long' if doesn't define. */ #undef clock_t *************** *** 98,101 **** --- 101,107 ---- #undef HAVE_ALTZONE + /* Defined when any dynamic module loading is enabled */ + #undef HAVE_DYNAMIC_LOADING + /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */ #undef HAVE_GETC_UNLOCKED *************** *** 113,122 **** #undef HAVE_GETHOSTBYNAME_R_6_ARG /* Define this if you have the type long long */ #undef HAVE_LONG_LONG - /* Define this if you have the type uintptr_t */ - #undef HAVE_UINTPTR_T - /* Define if your compiler supports function prototypes */ #undef HAVE_PROTOTYPES --- 119,134 ---- #undef HAVE_GETHOSTBYNAME_R_6_ARG + /* Defined to enable large file support when an off_t is bigger than a long + and long long is available and at least as big as an off_t. You may need + to add some flags for configuration and compilation to enable this mode. + E.g, for Solaris 2.7: + CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \ + configure + */ + #undef HAVE_LARGEFILE_SUPPORT + /* Define this if you have the type long long */ #undef HAVE_LONG_LONG /* Define if your compiler supports function prototypes */ #undef HAVE_PROTOTYPES *************** *** 129,132 **** --- 141,155 ---- #undef HAVE_STDARG_PROTOTYPES + /* Define this if you have the type uintptr_t */ + #undef HAVE_UINTPTR_T + + /* Define if you have a useable wchar_t type defined in wchar.h; useable + means wchar_t must be 16-bit unsigned type. (see + Include/unicodeobject.h). */ + #undef HAVE_USABLE_WCHAR_T + + /* Define if the compiler provides a wchar.h header file. */ + #undef HAVE_WCHAR_H + /* Define if malloc(0) returns a NULL pointer */ #undef MALLOC_ZERO_RETURNS_NULL *************** *** 135,138 **** --- 158,164 ---- #undef _POSIX_THREADS + /* Define if you want to build an interpreter with many run-time checks */ + #undef Py_DEBUG + /* Define to force use of thread-safe errno, h_errno, and other functions */ #undef _REENTRANT *************** *** 144,147 **** --- 170,187 ---- #undef signed + /* Define if i>>j for signed int i does not extend the sign bit + when i < 0 + */ + #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS + + /* The number of bytes in an off_t. */ + #undef SIZEOF_OFF_T + + /* The number of bytes in a time_t. */ + #undef SIZEOF_TIME_T + + /* The number of bytes in a pthread_t. */ + #undef SIZEOF_PTHREAD_T + /* Define to `int' if doesn't define. */ #undef socklen_t *************** *** 160,181 **** #undef WANT_SIGFPE_HANDLER - /* Define if the compiler provides a wchar.h header file. */ - #undef HAVE_WCHAR_H - - /* Define if you have a useable wchar_t type defined in wchar.h; useable - means wchar_t must be 16-bit unsigned type. (see - Include/unicodeobject.h). */ - #undef HAVE_USABLE_WCHAR_T - /* Define if you want wctype.h functions to be used instead of the one supplied by Python itself. (see Include/unicodectype.h). */ #undef WANT_WCTYPE_FUNCTIONS ! /* Define if you want to use SGI (IRIX 4) dynamic linking. ! This requires the "dl" library by Jack Jansen, ! ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z. ! Don't bother on IRIX 5, it already has dynamic linking using SunOS ! style shared libraries */ ! #undef WITH_SGI_DL /* Define if you want to emulate SGI (IRIX 4) dynamic linking. --- 200,209 ---- #undef WANT_SIGFPE_HANDLER /* Define if you want wctype.h functions to be used instead of the one supplied by Python itself. (see Include/unicodectype.h). */ #undef WANT_WCTYPE_FUNCTIONS ! /* Define if you want to compile in cycle garbage collection */ ! #undef WITH_CYCLE_GC /* Define if you want to emulate SGI (IRIX 4) dynamic linking. *************** *** 194,239 **** linker (rld). Dyld is necessary to support frameworks. */ #undef WITH_DYLD - - /* Define if you want to compile in rudimentary thread support */ - #undef WITH_THREAD ! /* Define if you want to compile in cycle garbage collection */ ! #undef WITH_CYCLE_GC /* Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK - - /* Define if you want to use BSD db. */ - #undef WITH_LIBDB - - /* Define if you want to build an interpreter with many run-time checks */ - #undef Py_DEBUG - - /* The number of bytes in an off_t. */ - #undef SIZEOF_OFF_T - - /* The number of bytes in a time_t. */ - #undef SIZEOF_TIME_T - - /* The number of bytes in a pthread_t. */ - #undef SIZEOF_PTHREAD_T - - /* Defined to enable large file support when an off_t is bigger than a long - and long long is available and at least as big as an off_t. You may need - to add some flags for configuration and compilation to enable this mode. - E.g, for Solaris 2.7: - CFLAGS="-D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64" OPT="-O2 $CFLAGS" \ - configure - */ - #undef HAVE_LARGEFILE_SUPPORT ! /* Defined when any dynamic module loading is enabled */ ! #undef HAVE_DYNAMIC_LOADING ! /* Define if i>>j for signed int i does not extend the sign bit ! when i < 0 ! */ ! #undef SIGNED_RIGHT_SHIFT_ZERO_FILLS /* The number of bytes in a char. */ --- 222,242 ---- linker (rld). Dyld is necessary to support frameworks. */ #undef WITH_DYLD ! /* Define if you want to use BSD db. */ ! #undef WITH_LIBDB /* Define if you want to produce an OpenStep/Rhapsody framework (shared library plus accessory files). */ #undef WITH_NEXT_FRAMEWORK ! /* Define if you want to use SGI (IRIX 4) dynamic linking. ! This requires the "dl" library by Jack Jansen, ! ftp://ftp.cwi.nl/pub/dynload/dl-1.6.tar.Z. ! Don't bother on IRIX 5, it already has dynamic linking using SunOS ! style shared libraries */ ! #undef WITH_SGI_DL ! /* Define if you want to compile in rudimentary thread support */ ! #undef WITH_THREAD /* The number of bytes in a char. */ Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.176 retrieving revision 1.177 diff -C2 -r1.176 -r1.177 *** configure 2001/01/10 18:53:47 1.176 --- configure 2001/01/10 20:40:46 1.177 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.184 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.185 [...4140 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 < *************** *** 6121,6125 **** echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6124: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then --- 6143,6147 ---- echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6146: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.184 retrieving revision 1.185 diff -C2 -r1.184 -r1.185 *** configure.in 2001/01/10 18:53:48 1.184 --- configure.in 2001/01/10 20:40:46 1.185 *************** *** 1233,1236 **** --- 1233,1248 ---- [AC_MSG_RESULT(default LIBC=\"$LIBC\")]) + # check for --with-check-import-case + AC_ARG_WITH(check-import-case, + [ --with-check-import-case enable imported module name case checking],,) + AC_MSG_CHECKING(for --with-check-import-case) + if test "$with_check_import_case" + then + AC_DEFINE(CHECK_IMPORT_CASE) + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + # check for hypot() in math library LIBS_SAVE=$LIBS From python-dev@python.org Wed Jan 10 21:03:34 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:03:34 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules shamodule.c,2.12,2.13 mmapmodule.c,2.25,2.26 readline.c,2.33,2.34 rotormodule.c,2.29,2.30 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2028 Modified Files: shamodule.c mmapmodule.c readline.c rotormodule.c Log Message: Part of SF patch #102409 by jlt63 to support building these modules under CYGWIN as shared libraries (DLLs). Index: shamodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/shamodule.c,v retrieving revision 2.12 retrieving revision 2.13 diff -C2 -r2.12 -r2.13 *** shamodule.c 2000/09/01 23:29:27 2.12 --- shamodule.c 2001/01/10 21:03:32 2.13 *************** *** 530,534 **** Py_XDECREF(o); } ! void initsha(void) { --- 530,534 ---- Py_XDECREF(o); } ! DL_EXPORT(void) initsha(void) { Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.25 retrieving revision 2.26 diff -C2 -r2.25 -r2.26 *** mmapmodule.c 2001/01/10 05:42:18 2.25 --- mmapmodule.c 2001/01/10 21:03:32 2.26 *************** *** 953,963 **** }; ! #ifdef MS_WIN32 ! __declspec(dllexport) void ! #endif /* MS_WIN32 */ ! #ifdef UNIX ! extern void ! #endif ! initmmap(void) { --- 953,957 ---- }; ! DL_EXPORT(void) initmmap(void) { Index: readline.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/readline.c,v retrieving revision 2.33 retrieving revision 2.34 diff -C2 -r2.33 -r2.34 *** readline.c 2000/10/02 15:53:08 2.33 --- readline.c 2001/01/10 21:03:32 2.34 *************** *** 28,31 **** --- 28,34 ---- #include /* You may need to add an -I option to Setup */ + #ifdef __CYGWIN__ + #include + #else /* !__CYGWIN__ */ extern int rl_parse_and_bind(char *); extern int rl_read_init_file(char *); *************** *** 39,47 **** extern int history_truncate_file(char *, int); extern Function *rl_event_hook; #endif /* Pointers needed from outside (but not declared in a header file). */ ! extern int (*PyOS_InputHook)(void); ! extern char *(*PyOS_ReadlineFunctionPointer)(char *); --- 42,51 ---- extern int history_truncate_file(char *, int); extern Function *rl_event_hook; + #endif /* !__CYGWIN__ */ #endif /* Pointers needed from outside (but not declared in a header file). */ ! extern DL_IMPORT(int) (*PyOS_InputHook)(void); ! extern DL_IMPORT(char) *(*PyOS_ReadlineFunctionPointer)(char *); Index: rotormodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/rotormodule.c,v retrieving revision 2.29 retrieving revision 2.30 diff -C2 -r2.29 -r2.30 *** rotormodule.c 2000/07/31 15:28:04 2.29 --- rotormodule.c 2001/01/10 21:03:32 2.30 *************** *** 577,581 **** statichere PyTypeObject Rotor_Type = { ! PyObject_HEAD_INIT(&PyType_Type) 0, /*ob_size*/ "rotor", /*tp_name*/ --- 577,581 ---- statichere PyTypeObject Rotor_Type = { ! PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "rotor", /*tp_name*/ *************** *** 620,623 **** --- 620,624 ---- initrotor(void) { + Rotor_Type.ob_type = &PyType_Type; (void)Py_InitModule("rotor", rotor_methods); } From python-dev@python.org Wed Jan 10 21:09:14 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:09:14 -0800 Subject: [Python-checkins] CVS: python/dist/src Makefile.in,1.106,1.107 acconfig.h,1.41,1.42 config.h.in,2.83,2.84 configure,1.177,1.178 configure.in,1.185,1.186 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv2426 Modified Files: Makefile.in acconfig.h config.h.in configure configure.in Log Message: Part of SF patch #102409 by jlt63: Cygwin Python DLL and Shared Extension Patch. Note: this could use some testing on NeXT, DG/UX, or BeOS, because of the changes in the Makefile regarding $(LDLIBRARY). Index: Makefile.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Makefile.in,v retrieving revision 1.106 retrieving revision 1.107 diff -C2 -r1.106 -r1.107 *** Makefile.in 2000/10/09 19:31:40 1.106 --- Makefile.in 2001/01/10 21:09:12 1.107 *************** *** 132,135 **** --- 132,136 ---- LIBRARY= libpython$(VERSION).a LDLIBRARY= @LDLIBRARY@ + @SET_DLLLIBRARY@ # Default target *************** *** 248,251 **** --- 249,256 ---- else true; \ fi + if test -f "$(DLLLIBRARY)"; then \ + $(INSTALL_DATA) $(DLLLIBRARY) $(BINDIR); \ + else true; \ + fi # Install the manual page *************** *** 372,378 **** fi; \ done ! @if test -d $(LIBRARY); then :; else \ ! $(INSTALL_DATA) $(LIBRARY) $(LIBPL)/$(LIBRARY) ; \ ! $(RANLIB) $(LIBPL)/$(LIBRARY) ; \ fi $(INSTALL_DATA) Modules/config.c $(LIBPL)/config.c --- 377,383 ---- fi; \ done ! @if test -d $(LDLIBRARY); then :; else \ ! $(INSTALL_DATA) $(LDLIBRARY) $(LIBPL)/$(LDLIBRARY) ; \ ! $(RANLIB) $(LIBPL)/$(LDLIBRARY) ; \ fi $(INSTALL_DATA) Modules/config.c $(LIBPL)/config.c Index: acconfig.h =================================================================== RCS file: /cvsroot/python/python/dist/src/acconfig.h,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** acconfig.h 2001/01/10 20:40:46 1.41 --- acconfig.h 2001/01/10 21:09:12 1.42 *************** *** 186,187 **** --- 186,199 ---- /* Leave that blank line there-- autoheader needs it! */ + + @BOTTOM@ + + #ifdef __CYGWIN__ + #ifdef USE_DL_IMPORT + #define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE + #define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE + #else + #define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE + #define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE + #endif + #endif Index: config.h.in =================================================================== RCS file: /cvsroot/python/python/dist/src/config.h.in,v retrieving revision 2.83 retrieving revision 2.84 diff -C2 -r2.83 -r2.84 *** config.h.in 2001/01/10 20:40:46 2.83 --- config.h.in 2001/01/10 21:09:12 2.84 *************** *** 635,636 **** --- 635,646 ---- /* Define if you have the ieee library (-lieee). */ #undef HAVE_LIBIEEE + + #ifdef __CYGWIN__ + #ifdef USE_DL_IMPORT + #define DL_IMPORT(RTYPE) __declspec(dllimport) RTYPE + #define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE + #else + #define DL_IMPORT(RTYPE) __declspec(dllexport) RTYPE + #define DL_EXPORT(RTYPE) __declspec(dllexport) RTYPE + #endif + #endif Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.177 retrieving revision 1.178 diff -C2 -r1.177 -r1.178 *** configure 2001/01/10 20:40:46 1.177 --- configure 2001/01/10 21:09:12 1.178 *************** *** 1136,1143 **** # name of the library into which to insert object files). On systems # without shared libraries, LDLIBRARY is the same as LIBRARY (defined in ! # the Makefiles). LDLIBRARY='' # LINKCC is the command that links the python executable -- default is $(CC). --- 1136,1146 ---- # name of the library into which to insert object files). On systems [...3959 lines suppressed...] *** 6143,6147 **** echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6146: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then --- 6162,6166 ---- echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6165: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then *************** *** 6303,6306 **** --- 6322,6326 ---- s%@MAKE_LDLIBRARY@%$MAKE_LDLIBRARY%g s%@LDLIBRARY@%$LDLIBRARY%g + s%@SET_DLLLIBRARY@%$SET_DLLLIBRARY%g s%@LINKCC@%$LINKCC%g s%@RANLIB@%$RANLIB%g Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.185 retrieving revision 1.186 diff -C2 -r1.185 -r1.186 *** configure.in 2001/01/10 20:40:46 1.185 --- configure.in 2001/01/10 21:09:12 1.186 *************** *** 238,245 **** # name of the library into which to insert object files). On systems # without shared libraries, LDLIBRARY is the same as LIBRARY (defined in ! # the Makefiles). AC_SUBST(MAKE_LDLIBRARY) AC_SUBST(LDLIBRARY) LDLIBRARY='' # LINKCC is the command that links the python executable -- default is $(CC). --- 238,248 ---- # name of the library into which to insert object files). On systems # without shared libraries, LDLIBRARY is the same as LIBRARY (defined in ! # the Makefiles). On Cygwin LDLIBRARY is the import library, DLLLIBRARY is the ! # shared (i.e., DLL) library. AC_SUBST(MAKE_LDLIBRARY) AC_SUBST(LDLIBRARY) + AC_SUBST(SET_DLLLIBRARY) LDLIBRARY='' + SET_DLLLIBRARY='' # LINKCC is the command that links the python executable -- default is $(CC). *************** *** 284,287 **** --- 287,294 ---- LDLIBRARY='libpython$(VERSION).so' ;; + cygwin*) + LDLIBRARY='libpython$(VERSION).dll.a' + SET_DLLLIBRARY='DLLLIBRARY= $(basename $(LDLIBRARY))' + ;; esac AC_MSG_RESULT($LDLIBRARY) *************** *** 293,297 **** MAKE_LDLIBRARY="true" else ! MAKE_LDLIBRARY='$(MAKE) $(LDLIBRARY)' fi --- 300,307 ---- MAKE_LDLIBRARY="true" else ! case $MACHDEP in ! cygwin*) MAKE_LDLIBRARY='$(MAKE) -C Modules ../$(DLLLIBRARY)';; ! *) MAKE_LDLIBRARY='$(MAKE) $(LDLIBRARY)';; ! esac fi *************** *** 318,321 **** --- 328,332 ---- case $ac_sys_system in BeOS*) LN="ln -s";; + CYGWIN*) LN="ln -s";; *) LN=ln;; esac *************** *** 342,345 **** --- 353,361 ---- esac + # Cygwin does not need PIC compiler option so remove it to prevent warnings + case $ac_sys_system in + CYGWIN*) OPT="`echo $OPT | sed 's/ *-fPIC//'`";; + esac + if test "$ac_arch_flags" then *************** *** 560,564 **** AC_SUBST(LINKFORSHARED) # SO is the extension of shared libraries `(including the dot!) ! # -- usually .so, .sl on HP-UX AC_MSG_CHECKING(SO) if test -z "$SO" --- 576,580 ---- AC_SUBST(LINKFORSHARED) # SO is the extension of shared libraries `(including the dot!) ! # -- usually .so, .sl on HP-UX, .dll on Cygwin AC_MSG_CHECKING(SO) if test -z "$SO" *************** *** 566,569 **** --- 582,586 ---- case $ac_sys_system in hp*|HP*) SO=.sl;; + CYGWIN*) SO=.dll;; *) SO=.so;; esac *************** *** 623,626 **** --- 640,644 ---- SCO_SV*) LDSHARED="cc -G -KPIC -Ki486 -belf -Wl,-Bexport";; Monterey*) LDSHARED="cc -G -dy -Bdynamic -Bexport -L/usr/lib/ia64l64";; + CYGWIN*) LDSHARED="gcc -shared -Wl,--enable-auto-image-base";; *) LDSHARED="ld";; esac *************** *** 647,650 **** --- 665,669 ---- *) CCSHARED="";; esac;; + CYGWIN*) CCSHARED="-DUSE_DL_IMPORT";; esac fi From python-dev@python.org Wed Jan 10 21:12:20 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:12:20 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules makesetup,1.29,1.30 Makefile.pre.in,1.71,1.72 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2991 Modified Files: makesetup Makefile.pre.in Log Message: Final part of SF patch #102409 by jlt63: Cygwin Python DLL and Shared Extension Patch. These are the changes to the Modules Makefile and makesetup script for Cygwin. Index: makesetup =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/makesetup,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** makesetup 2000/12/06 23:46:29 1.29 --- makesetup 2001/01/10 21:12:18 1.30 *************** *** 80,83 **** --- 80,95 ---- ' + # Setup to link with extra libraries when makeing shared extensions. + # Currently, only Cygwin needs this baggage. + case `uname -s` in + CYGWIN*) if test $srcdir = . + then + ExtraLibDir=.. + else + ExtraLibDir='$(LIBPL)' + fi + ExtraLibs="-L$ExtraLibDir -lpython\$(VERSION)";; + esac + # Main loop for i in ${*-Setup} *************** *** 150,153 **** --- 162,166 ---- *.sl) libs="$libs $arg";; /*.o) libs="$libs $arg";; + *.def) libs="$libs $arg";; *.o) srcs="$srcs `basename $arg .o`.c";; *.[cC]) srcs="$srcs $arg";; *************** *** 214,218 **** esac rule="$file: $objs" ! rule="$rule; \$(LDSHARED) $objs $libs -o $file" echo "$rule" >>$rulesf done --- 227,231 ---- esac rule="$file: $objs" ! rule="$rule; \$(LDSHARED) $objs $libs $ExtraLibs -o $file" echo "$rule" >>$rulesf done Index: Makefile.pre.in =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Makefile.pre.in,v retrieving revision 1.71 retrieving revision 1.72 diff -C2 -r1.71 -r1.72 *** Makefile.pre.in 2000/11/28 12:09:18 1.71 --- Makefile.pre.in 2001/01/10 21:12:18 1.72 *************** *** 106,109 **** --- 106,110 ---- LIBRARY= ../libpython$(VERSION).a LDLIBRARY= ../@LDLIBRARY@ + @SET_DLLLIBRARY@ # === Rules === *************** *** 127,130 **** --- 128,139 ---- $(LDLIBRARY) $(MODLIBS) $(LIBS) $(SYSLIBS) -o python$(EXE) $(LDLAST) mv python$(EXE) ../python$(EXE) + + # This rule builds the Cygwin Python DLL + $(DLLLIBRARY): $(LIBRARY) + test -d cygwin || mkdir cygwin + (cd cygwin; ar x ../$^) + dlltool --export-all --output-def $(basename $@).def cygwin/*.o + $(LDSHARED) -Wl,--out-implib=$(LDLIBRARY) -o $@ $(basename $@).def cygwin/*.o $(MODLIBS) $(LIBS) $(SYSLIBS) + rm -fr cygwin clean: From python-dev@python.org Wed Jan 10 21:17:29 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:17:29 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python dynload_shlib.c,2.7,2.8 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv3775 Modified Files: dynload_shlib.c Log Message: Oops, one more part of the cygwin patch (SF patch #102409 by jlt63: Cygwin Python DLL and Shared Extension Patch). Add module.dll as a valid extension. jlt63 writes: Note that his change essentially backs out the fix for bug #115973. Should ".pyd" be retained instead for posterity? Index: dynload_shlib.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/dynload_shlib.c,v retrieving revision 2.7 retrieving revision 2.8 diff -C2 -r2.7 -r2.8 *** dynload_shlib.c 2000/10/25 22:07:45 2.7 --- dynload_shlib.c 2001/01/10 21:17:27 2.8 *************** *** 30,35 **** const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ - {".pyd", "rb", C_EXTENSION}, {".dll", "rb", C_EXTENSION}, #else {".so", "rb", C_EXTENSION}, --- 30,35 ---- const struct filedescr _PyImport_DynLoadFiletab[] = { #ifdef __CYGWIN__ {".dll", "rb", C_EXTENSION}, + {"module.dll", "rb", C_EXTENSION}, #else {".so", "rb", C_EXTENSION}, From python-dev@python.org Wed Jan 10 21:41:18 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:41:18 -0800 Subject: [Python-checkins] CVS: python/dist/src configure,1.178,1.179 configure.in,1.186,1.187 Message-ID: Update of /cvsroot/python/python/dist/src In directory usw-pr-cvs1:/tmp/cvs-serv6799 Modified Files: configure configure.in Log Message: SF Patch #102362 by bbum: Support dynamic module loading under OSX [including support for modules w/Objective-C]. Index: configure =================================================================== RCS file: /cvsroot/python/python/dist/src/configure,v retrieving revision 1.178 retrieving revision 1.179 diff -C2 -r1.178 -r1.179 *** configure 2001/01/10 21:09:12 1.178 --- configure 2001/01/10 21:41:14 1.179 *************** *** 1,5 **** #! /bin/sh ! # From configure.in Revision: 1.185 # Guess values for system-dependent variables and create Makefiles. --- 1,5 ---- #! /bin/sh ! # From configure.in Revision: 1.187 [...2564 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 < *************** *** 6162,6166 **** echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6165: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then --- 6158,6162 ---- echo $ac_n "checking for Modules/Setup""... $ac_c" 1>&6 ! echo "configure:6161: checking for Modules/Setup" >&5 if test ! -f Modules/Setup ; then if test ! -d Modules ; then Index: configure.in =================================================================== RCS file: /cvsroot/python/python/dist/src/configure.in,v retrieving revision 1.186 retrieving revision 1.187 diff -C2 -r1.186 -r1.187 *** configure.in 2001/01/10 21:09:12 1.186 --- configure.in 2001/01/10 21:41:16 1.187 *************** *** 610,618 **** Darwin/*|next/*) if test "$ns_dyld" ! then ! if test "$ac_sys_system" = Darwin ! then LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined suppress' ! else LDSHARED='$(CC) $(LDFLAGS) -bundle -prebind' ! fi else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r'; fi --- 610,614 ---- Darwin/*|next/*) if test "$ns_dyld" ! then LDSHARED='$(CC) $(LDFLAGS) -bundle -undefined suppress' else LDSHARED='$(CC) $(CFLAGS) -nostdlib -r'; fi *************** *** 687,691 **** # loading of any modules which reference it in System.framework next/4*|next/5*) LINKFORSHARED="-u __dummy -framework System" ;; ! Darwin/*) LINKFORSHARED="-framework System" ;; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; --- 683,687 ---- # loading of any modules which reference it in System.framework next/4*|next/5*) LINKFORSHARED="-u __dummy -framework System" ;; ! Darwin/*) LINKFORSHARED="-u __dummy -framework System -framework Foundation" ;; SCO_SV*) LINKFORSHARED="-Bdynamic -dy -Wl,-Bexport";; ReliantUNIX*) LINKFORSHARED="-W1 -Blargedynsym";; From python-dev@python.org Wed Jan 10 21:46:08 2001 From: python-dev@python.org (Guido van Rossum) Date: Wed, 10 Jan 2001 13:46:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules makesetup,1.30,1.31 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv7366 Modified Files: makesetup Log Message: SF Patch #102357 by bbum: Add support for frameworks and objective-c source. Uesful for both GnuStep and for OSXS/OSX/Darwin. (Note: I changed $(CCC) to $(CXX) since that's now the name of the C++ compiler. Please test! Index: makesetup =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/makesetup,v retrieving revision 1.30 retrieving revision 1.31 diff -C2 -r1.30 -r1.31 *** makesetup 2001/01/10 21:12:18 1.30 --- makesetup 2001/01/10 21:46:05 1.31 *************** *** 153,157 **** esac case $arg in ! -[IDUCf]*) cpps="$cpps $arg";; -Xlinker) libs="$libs $arg"; skip=libs;; -rpath) libs="$libs $arg"; skip=libs;; --- 153,160 ---- esac case $arg in ! -framework) libs="$libs $arg"; skip=libs; ! # OSX/OSXS/Darwin framework link cmd ! ;; ! -[IDUCfF]*) cpps="$cpps $arg";; -Xlinker) libs="$libs $arg"; skip=libs;; -rpath) libs="$libs $arg"; skip=libs;; *************** *** 165,168 **** --- 168,172 ---- *.o) srcs="$srcs `basename $arg .o`.c";; *.[cC]) srcs="$srcs $arg";; + *.m) srcs="$srcs $arg";; # Objective-C src *.cc) srcs="$srcs $arg";; *.c++) srcs="$srcs $arg";; *************** *** 198,201 **** --- 202,206 ---- *.cxx) obj=`basename $src .cxx`.o; cc='$(CXX)';; *.cpp) obj=`basename $src .cpp`.o; cc='$(CXX)';; + *.m) obj=`basename $src .m`.o; cc='$(CXX)';; # Obj-C *) continue;; esac From python-dev@python.org Wed Jan 10 22:12:02 2001 From: python-dev@python.org (Charles G Waldman) Date: Wed, 10 Jan 2001 14:12:02 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.215,2.216 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv10673 Modified Files: ceval.c Log Message: Add missing Py_DECREF in fast_cfunction. Partial fix for SF bug #127699. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.215 retrieving revision 2.216 diff -C2 -r2.215 -r2.216 *** ceval.c 2001/01/04 22:33:01 2.215 --- ceval.c 2001/01/10 22:11:59 2.216 *************** *** 2770,2776 **** if (na == 0) return (*meth)(self, NULL); ! else if (na == 1) ! return (*meth)(self, EXT_POP(*pp_stack)); ! else { PyObject *args = load_args(pp_stack, na); PyObject *result = (*meth)(self, args); --- 2770,2779 ---- if (na == 0) return (*meth)(self, NULL); ! else if (na == 1) { ! PyObject *arg = EXT_POP(*pp_stack); ! PyObject *result = (*meth)(self, arg); ! Py_DECREF(arg); ! return result; ! } else { PyObject *args = load_args(pp_stack, na); PyObject *result = (*meth)(self, args); From python-dev@python.org Thu Jan 11 04:19:54 2001 From: python-dev@python.org (Eric S. Raymond) Date: Wed, 10 Jan 2001 20:19:54 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libimaplib.tex,1.16,1.17 libpoplib.tex,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv15465 Modified Files: libimaplib.tex libpoplib.tex Log Message: Corrections and additions to the documentation for POP3 and IMAP library support, based on my fetchmail experience. Index: libimaplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libimaplib.tex,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** libimaplib.tex 2000/07/16 19:01:09 1.16 --- libimaplib.tex 2001/01/11 04:19:52 1.17 *************** *** 9,20 **** % Based on HTML documentation by Piers Lauder ; % converted by Fred L. Drake, Jr. . \indexii{IMAP4}{protocol} This module defines a class, \class{IMAP4}, which encapsulates a ! connection to an IMAP4 server and implements the IMAP4rev1 client ! protocol as defined in \rfc{2060}. It is backward compatible with ! IMAP4 (\rfc{1730}) servers, but note that the \samp{STATUS} command is ! not supported in IMAP4. A single class is provided by the \module{imaplib} module: --- 9,21 ---- % Based on HTML documentation by Piers Lauder ; % converted by Fred L. Drake, Jr. . + % Revised by ESR, January 2000. \indexii{IMAP4}{protocol} This module defines a class, \class{IMAP4}, which encapsulates a ! connection to an IMAP4 server and implements a large subset of the ! IMAP4rev1 client protocol as defined in \rfc{2060}. It is backward ! compatible with IMAP4 (\rfc{1730}) servers, but note that the ! \samp{STATUS} command is not supported in IMAP4. A single class is provided by the \module{imaplib} module: *************** *** 72,77 **** ! Note that IMAP4 message numbers change as the mailbox changes, so it ! is highly advisable to use UIDs instead, with the UID command. At the end of the module, there is a test section that contains a more --- 73,80 ---- ! Note that IMAP4 message numbers change as the mailbox changes; in ! particular, after an \samp{EXPUNGE} command performs deletions the ! remaining messages are renumbered. So it is highly advisable to use ! UIDs instead, with the UID command. At the end of the module, there is a test section that contains a more Index: libpoplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpoplib.tex,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** libpoplib.tex 2000/07/16 19:01:10 1.9 --- libpoplib.tex 2001/01/11 04:19:52 1.10 *************** *** 9,12 **** --- 9,13 ---- %it since I just stole most of it from the poplib.py source code and %the imaplib ``chapter''. + %Revised by ESR, January 2000 \indexii{POP3}{protocol} *************** *** 17,20 **** --- 18,27 ---- optional command sets. + Note that POP3, though widely supported, is obsolescent. The + implementation quality of POP3 servers varies widely, and too many are + quite poor. If your mailserver supports IMAP, you would be better off + using the \refmodule{IMAP} class, as IMAP servers tend to be better + implemented. + A single class is provided by the \module{poplib} module: *************** *** 76,85 **** \begin{methoddesc}{retr}{which} ! Retrieve whole message number \var{which}. Result is in form ! \code{(\var{response}, ['line', ...], \var{octets})}. \end{methoddesc} \begin{methoddesc}{dele}{which} ! Delete message number \var{which}. \end{methoddesc} --- 83,95 ---- \begin{methoddesc}{retr}{which} ! Retrieve whole message number \var{which}, and set its seen flag. ! Result is in form \code{(\var{response}, ['line', ...], \var{octets})}. \end{methoddesc} \begin{methoddesc}{dele}{which} ! Flag message number \var{which} for deletion. On most servers ! deletions are not actually performed until QUIT (the major exception is ! Eudora QPOP, which deliberately violates the RFCs by doing pending ! deletes on any disconnect). \end{methoddesc} *************** *** 100,103 **** --- 110,119 ---- after the header of message number \var{which}. Result is in form \code{(\var{response}, ['line', ...], \var{octets})}. + + The POP3 TOP command this method uses, unlike the RETR command, + doesn't set the message's seen flag; unfortunately, TOP is poorly + specified in the RFCs and is frequently broken in off-brand servers. + Test this method by hand against the POP3 servers you will use before + trusting it. \end{methoddesc} *************** *** 110,113 **** --- 126,132 ---- \end{methoddesc} + \begin{seealso} + \seemodule{imap}{The standard Python IMAP module.} + \end{seealso} \subsection{POP3 Example \label{pop3-example}} From python-dev@python.org Thu Jan 11 05:41:29 2001 From: python-dev@python.org (Moshe Zadka) Date: Wed, 10 Jan 2001 21:41:29 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.216,2.217 sysmodule.c,2.80,2.81 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv21213/Python Modified Files: ceval.c sysmodule.c Log Message: Implementation of PEP-0217. This closes the PEP, and patch 103170 Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.216 retrieving revision 2.217 diff -C2 -r2.216 -r2.217 *** ceval.c 2001/01/10 22:11:59 2.216 --- ceval.c 2001/01/11 05:41:27 2.217 *************** *** 1246,1279 **** case PRINT_EXPR: v = POP(); ! /* Print value except if None */ ! /* After printing, also assign to '_' */ ! /* Before, set '_' to None to avoid recursion */ ! if (v != Py_None && ! (err = PyDict_SetItemString( ! f->f_builtins, "_", Py_None)) == 0) { ! err = Py_FlushLine(); ! if (err == 0) { ! x = PySys_GetObject("stdout"); ! if (x == NULL) { ! PyErr_SetString( ! PyExc_RuntimeError, ! "lost sys.stdout"); ! err = -1; ! } ! } ! if (err == 0) ! err = PyFile_WriteObject(v, x, 0); ! if (err == 0) { ! PyFile_SoftSpace(x, 1); ! err = Py_FlushLine(); ! } ! if (err == 0) { ! err = PyDict_SetItemString( ! f->f_builtins, "_", v); ! } } Py_DECREF(v); break; ! case PRINT_ITEM_TO: w = stream = POP(); --- 1246,1269 ---- case PRINT_EXPR: v = POP(); ! w = PySys_GetObject("displayhook"); ! if (w == NULL) { ! PyErr_SetString(PyExc_RuntimeError, ! "lost sys.displayhook"); ! err = -1; } + if (err == 0) { + x = Py_BuildValue("(O)", v); + if (x == NULL) + err = -1; + } + if (err == 0) { + w = PyEval_CallObject(w, x); + if (w == NULL) + err = -1; + } Py_DECREF(v); + Py_XDECREF(x); break; ! case PRINT_ITEM_TO: w = stream = POP(); Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.80 retrieving revision 2.81 diff -C2 -r2.80 -r2.81 *** sysmodule.c 2000/12/15 22:02:05 2.80 --- sysmodule.c 2001/01/11 05:41:27 2.81 *************** *** 69,72 **** --- 69,116 ---- static PyObject * + sys_displayhook(PyObject *self, PyObject *args) + { + PyObject *o, *stdout; + PyInterpreterState *interp = PyThreadState_Get()->interp; + PyObject *modules = interp->modules; + PyObject *builtins = PyDict_GetItemString(modules, "__builtin__"); + + /* parse arguments */ + if (!PyArg_ParseTuple(args, "O:displayhook", &o)) + return NULL; + + /* Print value except if None */ + /* After printing, also assign to '_' */ + /* Before, set '_' to None to avoid recursion */ + if (o == Py_None) { + Py_INCREF(Py_None); + return Py_None; + } + if (PyObject_SetAttrString(builtins, "_", Py_None) != 0) + return NULL; + if (Py_FlushLine() != 0) + return NULL; + stdout = PySys_GetObject("stdout"); + if (stdout == NULL) { + PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); + return NULL; + } + if (PyFile_WriteObject(o, stdout, 0) != 0) + return NULL; + PyFile_SoftSpace(stdout, 1); + if (Py_FlushLine() != 0) + return NULL; + if (PyObject_SetAttrString(builtins, "_", o) != 0) + return NULL; + Py_INCREF(Py_None); + return Py_None; + } + + static char displayhook_doc[] = + "displayhook(o) -> None\n" + "\n" + "Print o to the stdout, and save it in __builtin__._\n"; + + static PyObject * sys_exc_info(PyObject *self, PyObject *args) { *************** *** 333,336 **** --- 377,381 ---- static PyMethodDef sys_methods[] = { /* Might as well keep this in alphabetic order */ + {"displayhook", sys_displayhook, 1, displayhook_doc}, {"exc_info", sys_exc_info, 1, exc_info_doc}, {"exit", sys_exit, 0, exit_doc}, *************** *** 476,479 **** --- 521,525 ---- Functions:\n\ \n\ + displayhook() -- print an object to the screen, and save it in __builtin__._\n\ exc_info() -- return thread-safe information about the current exception\n\ exit() -- exit the interpreter by raising SystemExit\n\ From python-dev@python.org Thu Jan 11 05:41:29 2001 From: python-dev@python.org (Moshe Zadka) Date: Wed, 10 Jan 2001 21:41:29 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsys.tex,1.43,1.44 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv21213/Doc/lib Modified Files: libsys.tex Log Message: Implementation of PEP-0217. This closes the PEP, and patch 103170 Index: libsys.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsys.tex,v retrieving revision 1.43 retrieving revision 1.44 diff -C2 -r1.43 -r1.44 *** libsys.tex 2000/12/06 21:47:46 1.43 --- libsys.tex 2001/01/11 05:41:27 1.44 *************** *** 45,48 **** --- 45,57 ---- \end{datadesc} + \begin{funcdesc}{displayhook}{\var{value}} + If \var{value} is not \code{None}, this function prints it to + \code{sys.stdout}, and saves it in \code{__builtin__._}. + + This function is called when an expression is entered at the prompt + of an interactive Python session. It exists mainly so it can be + overridden. + \end{funcdesc} + \begin{funcdesc}{exc_info}{} This function returns a tuple of three values that give information From python-dev@python.org Thu Jan 11 05:46:26 2001 From: python-dev@python.org (Moshe Zadka) Date: Wed, 10 Jan 2001 21:46:26 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0217.txt,1.4,1.5 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv22758 Modified Files: pep-0217.txt Log Message: Marking PEP as done. Index: pep-0217.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0217.txt,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** pep-0217.txt 2000/11/02 23:53:51 1.4 --- pep-0217.txt 2001/01/11 05:46:24 1.5 *************** *** 3,7 **** Version: $Revision$ Author: peps@zadka.site.co.il (Moshe Zadka) ! Status: Draft Type: Standards Track Python-Version: 2.1 --- 3,7 ---- Version: $Revision$ Author: peps@zadka.site.co.il (Moshe Zadka) ! Status: Final Type: Standards Track Python-Version: 2.1 From python-dev@python.org Thu Jan 11 07:26:24 2001 From: python-dev@python.org (Moshe Zadka) Date: Wed, 10 Jan 2001 23:26:24 -0800 Subject: [Python-checkins] CVS: python/nondist/peps pep-0000.txt,1.62,1.63 Message-ID: Update of /cvsroot/python/python/nondist/peps In directory usw-pr-cvs1:/tmp/cvs-serv30519 Modified Files: pep-0000.txt Log Message: Final(?) bit of PEP-0217 beuracracy - marking it as finished in PEP 0 Index: pep-0000.txt =================================================================== RCS file: /cvsroot/python/python/nondist/peps/pep-0000.txt,v retrieving revision 1.62 retrieving revision 1.63 diff -C2 -r1.62 -r1.63 *** pep-0000.txt 2001/01/09 15:53:16 1.62 --- pep-0000.txt 2001/01/11 07:26:22 1.63 *************** *** 35,39 **** S 207 pep-0207.txt Rich Comparisons van Rossum, Ascher S 208 pep-0208.txt Reworking the Coercion Model Schemenauer, Lemburg - S 217 pep-0217.txt Display Hook for Interactive Use Zadka I 226 pep-0226.txt Python 2.1 Release Schedule Hylton S 227 pep-0227.txt Statically Nested Scopes Hylton --- 35,38 ---- *************** *** 75,78 **** --- 74,78 ---- SF 203 pep-0203.txt Augmented Assignments Wouters SF 214 pep-0214.txt Extended Print Statement Warsaw + SF 217 pep-0217.txt Display Hook for Interactive Use Zadka SF 221 pep-0221.txt Import As Wouters SF 223 pep-0223.txt Change the Meaning of \x Escapes Peters *************** *** 115,119 **** SD 215 pep-0215.txt String Interpolation Yee I 216 pep-0216.txt Docstring Format Zadka ! S 217 pep-0217.txt Display Hook for Interactive Use Zadka SD 218 pep-0218.txt Adding a Built-In Set Object Type Wilson SD 219 pep-0219.txt Stackless Python McMillan --- 115,119 ---- SD 215 pep-0215.txt String Interpolation Yee I 216 pep-0216.txt Docstring Format Zadka ! SF 217 pep-0217.txt Display Hook for Interactive Use Zadka SD 218 pep-0218.txt Adding a Built-In Set Object Type Wilson SD 219 pep-0219.txt Stackless Python McMillan From python-dev@python.org Thu Jan 11 09:27:37 2001 From: python-dev@python.org (Greg Stein) Date: Thu, 11 Jan 2001 01:27:37 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python sysmodule.c,2.81,2.82 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv14530 Modified Files: sysmodule.c Log Message: stdout is sometimes a macro; use "outf" instead. Submitted by: Mark Favas Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.81 retrieving revision 2.82 diff -C2 -r2.81 -r2.82 *** sysmodule.c 2001/01/11 05:41:27 2.81 --- sysmodule.c 2001/01/11 09:27:34 2.82 *************** *** 71,75 **** sys_displayhook(PyObject *self, PyObject *args) { ! PyObject *o, *stdout; PyInterpreterState *interp = PyThreadState_Get()->interp; PyObject *modules = interp->modules; --- 71,75 ---- sys_displayhook(PyObject *self, PyObject *args) { ! PyObject *o, *outf; PyInterpreterState *interp = PyThreadState_Get()->interp; PyObject *modules = interp->modules; *************** *** 91,102 **** if (Py_FlushLine() != 0) return NULL; ! stdout = PySys_GetObject("stdout"); ! if (stdout == NULL) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; } ! if (PyFile_WriteObject(o, stdout, 0) != 0) return NULL; ! PyFile_SoftSpace(stdout, 1); if (Py_FlushLine() != 0) return NULL; --- 91,102 ---- if (Py_FlushLine() != 0) return NULL; ! outf = PySys_GetObject("stdout"); ! if (outf == NULL) { PyErr_SetString(PyExc_RuntimeError, "lost sys.stdout"); return NULL; } ! if (PyFile_WriteObject(o, outf, 0) != 0) return NULL; ! PyFile_SoftSpace(outf, 1); if (Py_FlushLine() != 0) return NULL; From python-dev@python.org Thu Jan 11 10:22:38 2001 From: python-dev@python.org (Eric S. Raymond) Date: Thu, 11 Jan 2001 02:22:38 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libpoplib.tex,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv25816 Modified Files: libpoplib.tex Log Message: Added pointer on POP3 variations. Index: libpoplib.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libpoplib.tex,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** libpoplib.tex 2001/01/11 04:19:52 1.10 --- libpoplib.tex 2001/01/11 10:22:34 1.11 *************** *** 128,131 **** --- 128,135 ---- \begin{seealso} \seemodule{imap}{The standard Python IMAP module.} + \seetitle{http://www.tuxedo.org/~esr/fetchail/fetchmail-FAQ.html}{ + The FAQ for the fetchmail POP/IMAP client collects information + on POP3 server variations and RFC noncompliance that may be + useful if you need to write an application based on poplib.} \end{seealso} From python-dev@python.org Thu Jan 11 11:55:40 2001 From: python-dev@python.org (Moshe Zadka) Date: Thu, 11 Jan 2001 03:55:40 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.217,2.218 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv6565/Python Modified Files: ceval.c Log Message: Fixed bugs noted by Greg Stein * x wasn't initialized to NULL * Did not DECREF result from displayhook function Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.217 retrieving revision 2.218 diff -C2 -r2.217 -r2.218 *** ceval.c 2001/01/11 05:41:27 2.217 --- ceval.c 2001/01/11 11:55:37 2.218 *************** *** 1251,1254 **** --- 1251,1255 ---- "lost sys.displayhook"); err = -1; + x = NULL; } if (err == 0) { *************** *** 1259,1262 **** --- 1260,1264 ---- if (err == 0) { w = PyEval_CallObject(w, x); + Py_XDECREF(w); if (w == NULL) err = -1; From python-dev@python.org Thu Jan 11 13:02:45 2001 From: python-dev@python.org (Martin v. Löwis) Date: Thu, 11 Jan 2001 05:02:45 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib site.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv17450 Modified Files: site.py Log Message: Patch #103134: Support import lines in pth files. Index: site.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/site.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** site.py 2000/12/12 22:39:04 1.22 --- site.py 2001/01/11 13:02:43 1.23 *************** *** 24,28 **** non-directories) are never added to sys.path; no directory is added to sys.path more than once. Blank lines and lines beginning with ! \code{#} are skipped. For example, suppose sys.prefix and sys.exec_prefix are set to --- 24,28 ---- non-directories) are never added to sys.path; no directory is added to sys.path more than once. Blank lines and lines beginning with ! \code{#} are skipped. Lines starting with \code{import} are executed. For example, suppose sys.prefix and sys.exec_prefix are set to *************** *** 105,108 **** --- 105,111 ---- break if dir[0] == '#': + continue + if dir.startswith("import"): + exec dir continue if dir[-1] == '\n': From python-dev@python.org Thu Jan 11 14:13:55 2001 From: python-dev@python.org (Skip Montanaro) Date: Thu, 11 Jan 2001 08:13:55 -0600 (CST) Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.217,2.218 In-Reply-To: References: Message-ID: <14941.49059.26189.733094@beluga.mojam.com> Moshe> * Did not DECREF result from displayhook function ... Moshe> w = PyEval_CallObject(w, x); Moshe> + Py_XDECREF(w); Moshe> if (w == NULL) ... While it works, is it really kosher to test w's value after the DECREF? Just seems like an odd construct to me. I'm used to seeing the test immediately after it's been set. Skip From python-dev@python.org Thu Jan 11 14:46:43 2001 From: python-dev@python.org (Thomas Wouters) Date: Thu, 11 Jan 2001 06:46:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules Setup.dist,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv2223/Modules Modified Files: Setup.dist Log Message: Move the _socket module closer to the SSL-_socket line (mmap and xreadlines inserted themselves inbetween the two) and clarify that the normal socket module should be commented out. (Someone also suggested the latter on c.l.py some time ago, I forget who, sorry.) Index: Setup.dist =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/Setup.dist,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** Setup.dist 2001/01/10 18:53:48 1.5 --- Setup.dist 2001/01/11 14:46:40 1.6 *************** *** 154,158 **** errno errnomodule.c # posix (UNIX) errno values select selectmodule.c # select(2); not on ancient System V - _socket socketmodule.c # socket(2) # Memory-mapped files (also works on Win32). --- 154,157 ---- *************** *** 162,166 **** xreadlines xreadlinesmodule.c ! # Socket module compiled with SSL support; you must edit the SSL variable: #SSL=/usr/local/ssl #_socket socketmodule.c \ --- 161,169 ---- xreadlines xreadlinesmodule.c ! # for socket(2), without SSL support. ! _socket socketmodule.c ! ! # Socket module compiled with SSL support; you must comment out the other ! # socket line above, and possibly edit the SSL variable: #SSL=/usr/local/ssl #_socket socketmodule.c \ From python-dev@python.org Thu Jan 11 15:00:16 2001 From: python-dev@python.org (Guido van Rossum) Date: Thu, 11 Jan 2001 07:00:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.90,1.91 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv4735 Modified Files: NEWS Log Message: Typo. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.90 retrieving revision 1.91 diff -C2 -r1.90 -r1.91 *** NEWS 2001/01/10 20:13:55 1.90 --- NEWS 2001/01/11 15:00:14 1.91 *************** *** 30,34 **** occasionally, in boundary cases the coercion semantics have changed subtly. Since this was a terrible gray area of the language, this ! is considered an improvement. Also not that __rcmp__ is no longer supported -- instead of calling __rcmp__, __cmp__ is called with reversed arguments. --- 30,34 ---- occasionally, in boundary cases the coercion semantics have changed subtly. Since this was a terrible gray area of the language, this ! is considered an improvement. Also note that __rcmp__ is no longer supported -- instead of calling __rcmp__, __cmp__ is called with reversed arguments. From python-dev@python.org Thu Jan 11 15:35:19 2001 From: python-dev@python.org (A.M. Kuchling) Date: Thu, 11 Jan 2001 07:35:19 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/distutils sysconfig.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/distutils In directory usw-pr-cvs1:/tmp/cvs-serv12433 Modified Files: sysconfig.py Log Message: Delete unused import of pprint module Index: sysconfig.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/distutils/sysconfig.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** sysconfig.py 2000/09/17 00:53:02 1.28 --- sysconfig.py 2001/01/11 15:35:16 1.29 *************** *** 363,367 **** global _config_vars if _config_vars is None: - from pprint import pprint func = globals().get("_init_" + os.name) if func: --- 363,366 ---- From python-dev@python.org Thu Jan 11 15:40:42 2001 From: python-dev@python.org (Thomas Wouters) Date: Thu, 11 Jan 2001 07:40:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules xreadlinesmodule.c,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv14543 Modified Files: xreadlinesmodule.c Log Message: Conform the new module to /the/ C style. Noone but me cares, but Guido said to go ahead and fix it if it bothered me. Index: xreadlinesmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/xreadlinesmodule.c,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** xreadlinesmodule.c 2001/01/09 23:26:39 1.2 --- xreadlinesmodule.c 2001/01/11 15:40:39 1.3 *************** *** 18,22 **** static void ! xreadlines_dealloc(PyXReadlinesObject *op) { Py_XDECREF(op->file); Py_XDECREF(op->lines); --- 18,23 ---- static void ! xreadlines_dealloc(PyXReadlinesObject *op) ! { Py_XDECREF(op->file); Py_XDECREF(op->lines); *************** *** 28,32 **** static PyXReadlinesObject * ! newreadlinesobject(PyObject *file) { PyXReadlinesObject *op; op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type); --- 29,34 ---- static PyXReadlinesObject * ! newreadlinesobject(PyObject *file) ! { PyXReadlinesObject *op; op = PyObject_NEW(PyXReadlinesObject, &XReadlinesObject_Type); *************** *** 41,45 **** static PyObject * ! xreadlines(PyObject *self, PyObject *args) { PyObject *file; PyXReadlinesObject *ret; --- 43,48 ---- static PyObject * ! xreadlines(PyObject *self, PyObject *args) ! { PyObject *file; PyXReadlinesObject *ret; *************** *** 52,57 **** } ! static PyObject* ! xreadlines_item(PyXReadlinesObject *a, int i) { if (i != a->abslineno) { PyErr_SetString(PyExc_RuntimeError, --- 55,61 ---- } ! static PyObject * ! xreadlines_item(PyXReadlinesObject *a, int i) ! { if (i != a->abslineno) { PyErr_SetString(PyExc_RuntimeError, From python-dev@python.org Thu Jan 11 16:02:11 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 11 Jan 2001 08:02:11 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libstat.tex,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv19265/lib Modified Files: libstat.tex Log Message: Fixed minor markup nits for consistency with the rest of the library reference. Index: libstat.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libstat.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** libstat.tex 2001/01/10 19:34:52 1.20 --- libstat.tex 2001/01/11 16:02:08 1.21 *************** *** 118,126 **** FIFOs and sockets under most Unixes (including Linux in particular), the ``size'' is the number of bytes waiting to be read at the time of ! the stat(2)/fstat(2)/lstat(2) call; this can sometimes be useful, ! especially for polling one of these special files after a non-blocking ! open. The meaning of the size field for other character and block ! devices varies more, depending on the local implementation of the ! underlying system call. Example: --- 118,126 ---- FIFOs and sockets under most Unixes (including Linux in particular), the ``size'' is the number of bytes waiting to be read at the time of ! the call to \function{os.stat()}, \function{os.fstat()}, or ! \function{os.lstat()}; this can sometimes be useful, especially for ! polling one of these special files after a non-blocking open. The ! meaning of the size field for other character and block devices varies ! more, depending on the implementation of the underlying system call. Example: From python-dev@python.org Fri Jan 12 02:06:37 2001 From: python-dev@python.org (Moshe Zadka) Date: Fri, 12 Jan 2001 04:06:37 +0200 (IST) Subject: [Python-Dev] Re: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.217,2.218 In-Reply-To: <14941.49059.26189.733094@beluga.mojam.com> References: <14941.49059.26189.733094@beluga.mojam.com>, Message-ID: <20010112020637.EF4D5A82F@darjeeling.zadka.site.co.il> On Thu, 11 Jan 2001 08:13:55 -0600 (CST), Skip Montanaro wrote: > While it works, is it really kosher to test w's value after the DECREF? Yes. It may not point to anything valid, but it won't be NULL. > Just seems like an odd construct to me. I'm used to seeing the test > immediately after it's been set. It was more convenient that way. And I'm pretty certain the _DECREF macros do not change their arguments. -- Moshe Zadka This is a signature anti-virus. Please stop the spread of signature viruses! From python-dev@python.org Thu Jan 11 22:07:27 2001 From: python-dev@python.org (Martin v. Löwis) Date: Thu, 11 Jan 2001 14:07:27 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libsite.tex,1.20,1.21 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6789 Modified Files: libsite.tex Log Message: Document \code{import} in pth files. Index: libsite.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libsite.tex,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** libsite.tex 2000/10/10 22:00:03 1.20 --- libsite.tex 2001/01/11 22:07:25 1.21 *************** *** 34,38 **** refers to a directory (rather than a file). No item is added to \code{sys.path} more than once. Blank lines and lines beginning with ! \code{\#} are skipped. \index{package} \indexiii{path}{configuration}{file} --- 34,38 ---- refers to a directory (rather than a file). No item is added to \code{sys.path} more than once. Blank lines and lines beginning with ! \code{\#} are skipped. Lines starting with \code{import} are executed. \index{package} \indexiii{path}{configuration}{file} From python-dev@python.org Thu Jan 11 22:46:47 2001 From: python-dev@python.org (Tim Peters) Date: Thu, 11 Jan 2001 14:46:47 -0800 Subject: [Python-checkins] CVS: python/dist/src/PCbuild mmap.dsp,1.7,1.8 Message-ID: Update of /cvsroot/python/python/dist/src/PCbuild In directory usw-pr-cvs1:/tmp/cvs-serv12560/python/dist/src/pcbuild Modified Files: mmap.dsp Log Message: Export mmap's entry point under Windows (thanks, MarkH & Guido!). Index: mmap.dsp =================================================================== RCS file: /cvsroot/python/python/dist/src/PCbuild/mmap.dsp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** mmap.dsp 2000/08/13 22:59:26 1.7 --- mmap.dsp 2001/01/11 22:46:45 1.8 *************** *** 55,59 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /machine:I386 /out:"./mmap.pyd" !ELSEIF "$(CFG)" == "mmap - Win32 Debug" --- 55,60 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /machine:I386 /out:"./mmap.pyd" /export:initmmap ! # SUBTRACT LINK32 /pdb:none !ELSEIF "$(CFG)" == "mmap - Win32 Debug" *************** *** 82,86 **** LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /debug /machine:I386 /out:"./mmap_d.pyd" /pdbtype:sept !ENDIF --- 83,88 ---- LINK32=link.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept ! # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /base:"0x1e1F0000" /dll /debug /machine:I386 /out:"./mmap_d.pyd" /pdbtype:sept /export:initmmap ! # SUBTRACT LINK32 /pdb:none !ENDIF From python-dev@python.org Thu Jan 11 22:49:52 2001 From: python-dev@python.org (Fred L. Drake) Date: Thu, 11 Jan 2001 14:49:52 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libmmap.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv13076/lib Modified Files: libmmap.tex Log Message: Updated descriptions to incorporate additional information from Tim Peters. This mostly closes SF bug #128251. Index: libmmap.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libmmap.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** libmmap.tex 2000/09/05 13:50:21 1.3 --- libmmap.tex 2001/01/11 22:49:49 1.4 *************** *** 21,43 **** \strong{(Windows 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. ! \var{tagname}, if specified, is a string giving a tag name for the mapping. ! Windows allows you to have many different mappings against the same ! file. If you specify the name of an existing tag, that tag is opened, ! otherwise a new tag of this name is created. If this parameter is ! None, the mapping is created without a name. Avoiding the use of the ! tag parameter will assist in keeping your code portable between Unix ! and Windows. \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. \var{flags} specifies the nature of the mapping. --- 21,45 ---- \strong{(Windows version)} Maps \var{length} bytes from the file specified by the file handle \var{fileno}, and returns a mmap object. + 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 ! tag name for the mapping. Windows allows you to have many different ! mappings against the same file. If you specify the name of an ! existing tag, that tag is opened, otherwise a new tag of this name is ! created. If this parameter is omitted or \code{None}, the mapping is ! created without a name. Avoiding the use of the tag parameter will ! assist in keeping your code portable between \UNIX{} and Windows. \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. From python-dev@python.org Fri Jan 12 16:03:58 2001 From: python-dev@python.org (Moshe Zadka) Date: Fri, 12 Jan 2001 18:03:58 +0200 (IST) Subject: [Python-checkins] CVS: python/dist/src/Modules xreadlinesmodule.c,1.2,1.3 In-Reply-To: References: Message-ID: <20010112160358.B0AC0A82D@darjeeling.zadka.site.co.il> On Thu, 11 Jan 2001, Thomas Wouters wrote: > Noone but me cares, but Guido said to go ahead and fix it if it bothered me. I think you meant no one. Noone is an archaic spelling of noon. quid-pro-quo-ly y'rs, Z. -- Moshe Zadka This is a signature anti-virus. Please stop the spread of signature viruses! From python-dev@python.org Fri Jan 12 10:02:50 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 12 Jan 2001 02:02:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.22,1.23 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv6739/python/dist/src/Lib Modified Files: tempfile.py Log Message: A variant of SF patch 103028 (Make tempfile.mktemp threadsafe). Tested on Windows. Should be tested on Linux. Should also be tested on some platform without threads (I simulated that by making the "import thread" fail, but that's not the same as actually doing it!). Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.22 retrieving revision 1.23 diff -C2 -r1.22 -r1.23 *** tempfile.py 2000/08/29 14:55:03 1.22 --- tempfile.py 2001/01/12 10:02:46 1.23 *************** *** 5,18 **** # systems so it may have to be changed... - import os - # Parameters that the caller may set to override the defaults - tempdir = None template = None - def gettempdir(): """Function to calculate the directory to use.""" --- 5,14 ---- *************** *** 93,109 **** - # Counter for generating unique names - - counter = 0 - - def mktemp(suffix=""): """User-callable function to return a unique temporary file name.""" - global counter dir = gettempdir() pre = gettempprefix() while 1: ! counter = counter + 1 ! file = os.path.join(dir, pre + `counter` + suffix) if not os.path.exists(file): return file --- 89,99 ---- def mktemp(suffix=""): """User-callable function to return a unique temporary file name.""" dir = gettempdir() pre = gettempprefix() while 1: ! i = _counter.get_next() ! file = os.path.join(dir, pre + str(i) + suffix) if not os.path.exists(file): return file *************** *** 153,154 **** --- 143,187 ---- file = open(name, mode, bufsize) return TemporaryFileWrapper(file, name) + + # In order to generate unique names, mktemp() uses _counter.get_next(). + # This returns a unique integer on each call, in a threadsafe way (i.e., + # multiple threads will never see the same integer). The integer will + # usually be a Python int, but if _counter.get_next() is called often + # enough, it will become a Python long. + # Note that the only name that survives this next block of code + # is "_counter". + + class _ThreadSafeCounter: + def __init__(self, mutex, initialvalue=0): + self.mutex = mutex + self.i = initialvalue + + def get_next(self): + self.mutex.acquire() + result = self.i + try: + newi = result + 1 + except OverflowError: + newi = long(result) + 1 + self.i = newi + self.mutex.release() + return result + + try: + import thread + + except ImportError: + class _DummyMutex: + def acquire(self): + pass + + release = acquire + + _counter = _ThreadSafeCounter(_DummyMutex()) + del _DummyMutex + + else: + _counter = _ThreadSafeCounter(thread.allocate_lock()) + del thread + + del _ThreadSafeCounter From python-dev@python.org Fri Jan 12 15:06:44 2001 From: python-dev@python.org (A.M. Kuchling) Date: Fri, 12 Jan 2001 07:06:44 -0800 Subject: [Python-checkins] CVS: python/dist/src/Include pyport.h,2.22,2.23 Message-ID: Update of /cvsroot/python/python/dist/src/Include In directory usw-pr-cvs1:/tmp/cvs-serv22122 Modified Files: pyport.h Log Message: Change LONG_BIT error warning to mention glibc, too, since this is really a glibc, not a gcc, problem. Index: pyport.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/pyport.h,v retrieving revision 2.22 retrieving revision 2.23 diff -C2 -r2.22 -r2.23 *** pyport.h 2000/10/05 17:25:45 2.22 --- pyport.h 2001/01/12 15:06:28 2.23 *************** *** 388,392 **** * overflows. */ ! #error "LONG_BIT definition appears wrong for platform (bad gcc config?)." #endif --- 388,392 ---- * overflows. */ ! #error "LONG_BIT definition appears wrong for platform (bad gcc/glibc config?)." #endif From python-dev@python.org Fri Jan 12 16:03:08 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 12 Jan 2001 08:03:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.187,2.188 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv31700 Modified Files: bltinmodule.c Log Message: (Modified) patch by Ping - SF Patch #102681. - Make error messages from issubclass() and isinstance() a bit more descriptive (Ping, modified by Guido) - Couple of tiny fixes to other docstrings (Ping) - Get rid of trailing whitespace (Guido) Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.187 retrieving revision 2.188 diff -C2 -r2.187 -r2.188 *** bltinmodule.c 2001/01/04 01:48:42 2.187 --- bltinmodule.c 2001/01/12 16:03:05 2.188 *************** *** 115,119 **** "buffer(object [, offset[, size]]) -> object\n\ \n\ ! Creates a new buffer object which references the given object.\n\ The buffer will reference a slice of the target object from the\n\ start of the object (or at the specified offset). The slice will\n\ --- 115,119 ---- "buffer(object [, offset[, size]]) -> object\n\ \n\ ! Create a new buffer object which references the given object.\n\ The buffer will reference a slice of the target object from the\n\ start of the object (or at the specified offset). The slice will\n\ *************** *** 136,140 **** "unicode(string [, encoding[, errors]]) -> object\n\ \n\ ! Creates a new Unicode object from the given encoded string.\n\ encoding defaults to the current default string encoding and \n\ errors, defining the error handling, to 'strict'."; --- 136,140 ---- "unicode(string [, encoding[, errors]]) -> object\n\ \n\ ! Create a new Unicode object from the given encoded string.\n\ encoding defaults to the current default string encoding and \n\ errors, defining the error handling, to 'strict'."; *************** *** 412,418 **** return NULL; } ! if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), ! s_buffer, NULL)) return NULL; --- 412,418 ---- return NULL; } ! if (PyUnicode_EncodeDecimal(PyUnicode_AS_UNICODE(v), PyUnicode_GET_SIZE(v), ! s_buffer, NULL)) return NULL; *************** *** 439,443 **** sign = 1; do { ! switch (*s) { --- 439,443 ---- sign = 1; do { ! switch (*s) { *************** *** 451,455 **** if(!done) sw_error=1; break; ! case '-': sign = -1; --- 451,455 ---- if(!done) sw_error=1; break; ! case '-': sign = -1; *************** *** 510,514 **** s=end; if (*s=='J' || *s=='j') { ! break; } --- 510,514 ---- s=end; if (*s=='J' || *s=='j') { ! break; } *************** *** 525,529 **** sign = 1; break; ! } /* end of switch */ --- 525,529 ---- sign = 1; break; ! } /* end of switch */ *************** *** 936,940 **** int curlen; PySequenceMethods *sqf; ! if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL) goto Fail_2; --- 936,940 ---- int curlen; PySequenceMethods *sqf; ! if ((sqp->seq = PyTuple_GetItem(args, i + 1)) == NULL) goto Fail_2; *************** *** 1136,1140 **** if (!PyArg_ParseTuple(args, "O:hex", &v)) return NULL; ! if ((nb = v->ob_type->tp_as_number) == NULL || nb->nb_hex == NULL) { --- 1136,1140 ---- if (!PyArg_ParseTuple(args, "O:hex", &v)) return NULL; ! if ((nb = v->ob_type->tp_as_number) == NULL || nb->nb_hex == NULL) { *************** *** 1245,1249 **** PyObject *v; int base = -909; /* unlikely! */ ! if (!PyArg_ParseTuple(args, "O|i:long", &v, &base)) return NULL; --- 1245,1249 ---- PyObject *v; int base = -909; /* unlikely! */ ! if (!PyArg_ParseTuple(args, "O|i:long", &v, &base)) return NULL; *************** *** 1530,1534 **** } ! PyErr_Format(PyExc_TypeError, "ord() expected a character, " "but string of length %d found", --- 1530,1534 ---- } ! PyErr_Format(PyExc_TypeError, "ord() expected a character, " "but string of length %d found", *************** *** 1540,1544 **** "ord(c) -> integer\n\ \n\ ! Return the integer ordinal of a one character string."; --- 1540,1544 ---- "ord(c) -> integer\n\ \n\ ! Return the integer ordinal of a one-character string."; *************** *** 2015,2021 **** bases = PyObject_GetAttr(cls, __bases__); if (bases == NULL || !PyTuple_Check(bases)) { ! Py_XDECREF(bases); ! PyErr_SetString(PyExc_TypeError, ! "arg 2 must be a class or type"); return -1; } --- 2015,2021 ---- bases = PyObject_GetAttr(cls, __bases__); if (bases == NULL || !PyTuple_Check(bases)) { ! Py_XDECREF(bases); ! PyErr_SetString(PyExc_TypeError, ! "issubclass() arg 2 must be a class"); return -1; } *************** *** 2030,2034 **** Py_XDECREF(bases); PyErr_SetString(PyExc_TypeError, ! "arg 2 must be a class or type"); return -1; } --- 2030,2034 ---- Py_XDECREF(bases); PyErr_SetString(PyExc_TypeError, ! "issubclass() arg 1 must be a class"); return -1; } *************** *** 2069,2073 **** } else if (!PyInstance_Check(inst)) { ! if (__class__ == NULL) { __class__ = PyString_FromString("__class__"); if (__class__ == NULL) --- 2069,2073 ---- } else if (!PyInstance_Check(inst)) { ! if (__class__ == NULL) { __class__ = PyString_FromString("__class__"); if (__class__ == NULL) *************** *** 2076,2089 **** icls = PyObject_GetAttr(inst, __class__); if (icls != NULL) { ! retval = abstract_issubclass( icls, cls, 1); Py_DECREF(icls); ! if (retval < 0) return NULL; - } - else { - PyErr_SetString(PyExc_TypeError, - "arg 2 must be a class or type"); - return NULL; } } return PyInt_FromLong(retval); --- 2076,2095 ---- icls = PyObject_GetAttr(inst, __class__); if (icls != NULL) { ! retval = abstract_issubclass(icls, cls, 1); Py_DECREF(icls); ! if (retval < 0 && ! !PyErr_ExceptionMatches(PyExc_TypeError)) return NULL; } + else + retval = -1; + } + else + retval = -1; + + if (retval < 0) { + PyErr_SetString(PyExc_TypeError, + "isinstance() arg 2 must be a class or type"); + return NULL; } return PyInt_FromLong(retval); *************** *** 2109,2113 **** if (!PyClass_Check(derived) || !PyClass_Check(cls)) { retval = abstract_issubclass(derived, cls, 1); ! if (retval < 0) return NULL; } --- 2115,2119 ---- if (!PyClass_Check(derived) || !PyClass_Check(cls)) { retval = abstract_issubclass(derived, cls, 1); ! if (retval < 0) return NULL; } *************** *** 2262,2266 **** if (PyDict_SetItemString(dict, "Ellipsis", Py_Ellipsis) < 0) return NULL; ! if (PyDict_SetItemString(dict, "NotImplemented", Py_NotImplemented) < 0) return NULL; --- 2268,2272 ---- if (PyDict_SetItemString(dict, "Ellipsis", Py_Ellipsis) < 0) return NULL; ! if (PyDict_SetItemString(dict, "NotImplemented", Py_NotImplemented) < 0) return NULL; From python-dev@python.org Fri Jan 12 16:24:05 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 12 Jan 2001 08:24:05 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python ceval.c,2.218,2.219 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv2329 Modified Files: ceval.c Log Message: Two changes to from...import: 1) "from M import X" now works even if M is not a real module; it's basically a getattr() operation with AttributeError exceptions changed into ImportError. 2) "from M import *" now looks for M.__all__ to decide which names to import; if M.__all__ doesn't exist, it uses M.__dict__.keys() but filters out names starting with '_' as before. Whether or not __all__ exists, there's no restriction on the type of M. Index: ceval.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/ceval.c,v retrieving revision 2.218 retrieving revision 2.219 diff -C2 -r2.218 -r2.219 *** ceval.c 2001/01/11 11:55:37 2.218 --- ceval.c 2001/01/12 16:24:03 2.219 *************** *** 3090,3135 **** import_from(PyObject *v, PyObject *name) { ! PyObject *w, *x; ! if (!PyModule_Check(v)) { ! PyErr_SetString(PyExc_TypeError, ! "import-from requires a module object"); ! return NULL; ! } ! w = PyModule_GetDict(v); /* TDB: can this not fail ? */ ! x = PyDict_GetItem(w, name); ! if (x == NULL) { PyErr_Format(PyExc_ImportError, "cannot import name %.230s", PyString_AsString(name)); ! } else ! Py_INCREF(x); return x; } ! static int import_all_from(PyObject *locals, PyObject *v) { ! int pos = 0, err; ! PyObject *name, *value; ! PyObject *w; ! if (!PyModule_Check(v)) { ! PyErr_SetString(PyExc_TypeError, ! "import-from requires a module object"); ! return -1; } - w = PyModule_GetDict(v); /* TBD: can this not fail ? */ ! while (PyDict_Next(w, &pos, &name, &value)) { ! if (!PyString_Check(name) || ! PyString_AsString(name)[0] == '_') ! continue; ! Py_INCREF(value); ! err = PyDict_SetItem(locals, name, value); ! Py_DECREF(value); if (err != 0) ! return -1; } ! return 0; } --- 3090,3159 ---- import_from(PyObject *v, PyObject *name) { ! PyObject *x; ! ! x = PyObject_GetAttr(v, name); ! if (x == NULL && PyErr_ExceptionMatches(PyExc_AttributeError)) { PyErr_Format(PyExc_ImportError, "cannot import name %.230s", PyString_AsString(name)); ! } return x; } ! static int import_all_from(PyObject *locals, PyObject *v) { ! PyObject *all = PyObject_GetAttrString(v, "__all__"); ! PyObject *dict, *name, *value; ! int skip_leading_underscores = 0; ! int pos, err; ! if (all == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return -1; /* Unexpected error */ ! PyErr_Clear(); ! dict = PyObject_GetAttrString(v, "__dict__"); ! if (dict == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_AttributeError)) ! return -1; ! PyErr_SetString(PyExc_ImportError, ! "from-import-* object has no __dict__ and no __all__"); ! return -1; ! } ! all = PyMapping_Keys(dict); ! Py_DECREF(dict); ! if (all == NULL) ! return -1; ! skip_leading_underscores = 1; } ! for (pos = 0, err = 0; ; pos++) { ! name = PySequence_GetItem(all, pos); ! if (name == NULL) { ! if (!PyErr_ExceptionMatches(PyExc_IndexError)) ! err = -1; ! else ! PyErr_Clear(); ! break; ! } ! if (skip_leading_underscores && ! PyString_Check(name) && ! PyString_AS_STRING(name)[0] == '_') ! { ! Py_DECREF(name); ! continue; ! } ! value = PyObject_GetAttr(v, name); ! if (value == NULL) ! err = -1; ! else ! err = PyDict_SetItem(locals, name, value); ! Py_DECREF(name); ! Py_XDECREF(value); if (err != 0) ! break; } ! Py_DECREF(all); ! return err; } From python-dev@python.org Fri Jan 12 16:25:10 2001 From: python-dev@python.org (Guido van Rossum) Date: Fri, 12 Jan 2001 08:25:10 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.91,1.92 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv2518 Modified Files: NEWS Log Message: News about from...import. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.91 retrieving revision 1.92 diff -C2 -r1.91 -r1.92 *** NEWS 2001/01/11 15:00:14 1.91 --- NEWS 2001/01/12 16:25:08 1.92 *************** *** 4,7 **** --- 4,18 ---- Core language, builtins, and interpreter + - Two changes to from...import: + + 1) "from M import X" now works even if M is not a real module; it's + basically a getattr() operation with AttributeError exceptions + changed into ImportError. + + 2) "from M import *" now looks for M.__all__ to decide which names to + import; if M.__all__ doesn't exist, it uses M.__dict__.keys() but + filters out names starting with '_' as before. Whether or not + __all__ exists, there's no restriction on the type of M. + - File objects have a new method, xreadlines(). This is the fastest way to iterate over all lines in a file: From python-dev@python.org Fri Jan 12 17:05:08 2001 From: python-dev@python.org (Fred L. Drake) Date: Fri, 12 Jan 2001 09:05:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python bltinmodule.c,2.188,2.189 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv8655/Python Modified Files: bltinmodule.c Log Message: Update the docstring for apply() so that "args" is marked as optional (since it is). Index: bltinmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/bltinmodule.c,v retrieving revision 2.188 retrieving revision 2.189 diff -C2 -r2.188 -r2.189 *** bltinmodule.c 2001/01/12 16:03:05 2.188 --- bltinmodule.c 2001/01/12 17:05:05 2.189 *************** *** 93,97 **** static char apply_doc[] = ! "apply(object, args[, kwargs]) -> value\n\ \n\ Call a callable object with positional arguments taken from the tuple args,\n\ --- 93,97 ---- static char apply_doc[] = ! "apply(object[, args[, kwargs]]) -> value\n\ \n\ Call a callable object with positional arguments taken from the tuple args,\n\ From python-dev@python.org Fri Jan 12 22:57:34 2001 From: python-dev@python.org (Fred L. Drake) Date: Fri, 12 Jan 2001 14:57:34 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libxreadlines.tex,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv26466/Doc/lib Modified Files: libxreadlines.tex Log Message: Added note that this module was added in Python 2.1. Index: libxreadlines.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libxreadlines.tex,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** libxreadlines.tex 2001/01/09 22:47:46 1.1 --- libxreadlines.tex 2001/01/12 22:57:32 1.2 *************** *** 5,8 **** --- 5,11 ---- \modulesynopsis{Efficient iteration over the lines of a file.} + \versionadded{2.1} + + This module defines a new object type which can efficiently iterate over the lines of a file. An xreadlines object is a sequence type From python-dev@python.org Sat Jan 13 03:04:04 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 12 Jan 2001 19:04:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.23,1.24 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv19969/python/dist/src/lib Modified Files: tempfile.py Log Message: Guido found a brand new race in tempfile on Linux, due to Linux changing pid across threads (but in that case, it's still the same process, and so still sharing the "template" cache in tempfile.py). Repaired that, and added a new std test. On Linux, someone please run that standalone with more files and/or more threads; e.g., python lib/test/test_threadedtempfile.py -f 1000 -t 10 to run with 10 threads each creating (and deleting) 1000 temp files. Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.23 retrieving revision 1.24 diff -C2 -r1.23 -r1.24 *** tempfile.py 2001/01/12 10:02:46 1.23 --- tempfile.py 2001/01/13 03:04:02 1.24 *************** *** 68,90 **** ! _pid = None def gettempprefix(): ! """Function to calculate a prefix of the filename to use.""" ! global template, _pid ! if os.name == 'posix' and _pid and _pid != os.getpid(): ! # Our pid changed; we must have forked -- zap the template ! template = None if template is None: ! if os.name == 'posix': ! _pid = os.getpid() ! template = '@' + `_pid` + '.' ! elif os.name == 'nt': ! template = '~' + `os.getpid()` + '-' ! elif os.name == 'mac': ! template = 'Python-Tmp-' ! else: ! template = 'tmp' # XXX might choose a better one ! return template --- 68,105 ---- ! # template caches the result of gettempprefix, for speed, when possible. ! # XXX unclear why this isn't "_template"; left it "template" for backward ! # compatibility. ! if os.name == "posix": ! # We don't try to cache the template on posix: the pid may change on us ! # between calls due to a fork, and on Linux the pid changes even for ! # another thread in the same process. Since any attempt to keep the ! # cache in synch would have to call os.getpid() anyway in order to make ! # sure the pid hasn't changed between calls, a cache wouldn't save any ! # time. In addition, a cache is difficult to keep correct with the pid ! # changing willy-nilly, and earlier attempts proved buggy (races). ! template = None + # Else the pid never changes, so gettempprefix always returns the same + # string. + elif os.name == "nt": + template = '~' + `os.getpid()` + '-' + elif os.name == 'mac': + template = 'Python-Tmp-' + else: + template = 'tmp' # XXX might choose a better one + def gettempprefix(): ! """Function to calculate a prefix of the filename to use. ! ! This incorporates the current process id on systems that support such a ! notion, so that concurrent processes don't generate the same prefix. ! """ ! ! global template if template is None: ! return '@' + `os.getpid()` + '.' ! else: ! return template From python-dev@python.org Sat Jan 13 03:04:04 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 12 Jan 2001 19:04:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_threadedtempfile.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv19969/python/dist/src/lib/test Added Files: test_threadedtempfile.py Log Message: Guido found a brand new race in tempfile on Linux, due to Linux changing pid across threads (but in that case, it's still the same process, and so still sharing the "template" cache in tempfile.py). Repaired that, and added a new std test. On Linux, someone please run that standalone with more files and/or more threads; e.g., python lib/test/test_threadedtempfile.py -f 1000 -t 10 to run with 10 threads each creating (and deleting) 1000 temp files. --- NEW FILE: test_threadedtempfile.py --- """ Create and delete FILES_PER_THREAD temp files (via tempfile.TemporaryFile) in each of NUM_THREADS threads, recording the number of successes and failures. A failure is a bug in tempfile, and may be due to: + Trying to create more than one tempfile with the same name. + Trying to delete a tempfile that doesn't still exist. + Something we've never seen before. By default, NUM_THREADS == 20 and FILES_PER_THREAD == 50. This is enough to create about 150 failures per run under Win98SE in 2.0, and runs pretty quickly. Guido reports needing to boost FILES_PER_THREAD to 500 before provoking a 2.0 failure under Linux. Run the test alone to boost either via cmdline switches: -f FILES_PER_THREAD (int) -t NUM_THREADS (int) """ NUM_THREADS = 20 # change w/ -t option FILES_PER_THREAD = 50 # change w/ -f option import threading from test.test_support import TestFailed import StringIO from traceback import print_exc startEvent = threading.Event() import tempfile tempfile.gettempdir() # Do this now, to avoid spurious races later class TempFileGreedy(threading.Thread): error_count = 0 ok_count = 0 def run(self): self.errors = StringIO.StringIO() startEvent.wait() for i in range(FILES_PER_THREAD): try: f = tempfile.TemporaryFile("w+b") f.close() except: self.error_count += 1 print_exc(file=self.errors) else: self.ok_count += 1 def _test(): threads = [] print "Creating" for i in range(NUM_THREADS): t = TempFileGreedy() threads.append(t) t.start() print "Starting" startEvent.set() print "Reaping" ok = errors = 0 for t in threads: t.join() ok += t.ok_count errors += t.error_count if t.error_count: print '%s errors:\n%s' % (t.getName(), t.errors.getvalue()) msg = "Done: errors %d ok %d" % (errors, ok) print msg if errors: raise TestFailed(msg) if __name__ == "__main__": import sys, getopt opts, args = getopt.getopt(sys.argv[1:], "t:f:") for o, v in opts: if o == "-f": FILES_PER_THREAD = int(v) elif o == "-t": NUM_THREADS = int(v) _test() From python-dev@python.org Sat Jan 13 03:04:04 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 12 Jan 2001 19:04:04 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_threadedtempfile,NONE,1.1 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv19969/python/dist/src/lib/test/output Added Files: test_threadedtempfile Log Message: Guido found a brand new race in tempfile on Linux, due to Linux changing pid across threads (but in that case, it's still the same process, and so still sharing the "template" cache in tempfile.py). Repaired that, and added a new std test. On Linux, someone please run that standalone with more files and/or more threads; e.g., python lib/test/test_threadedtempfile.py -f 1000 -t 10 to run with 10 threads each creating (and deleting) 1000 temp files. --- NEW FILE: test_threadedtempfile --- test_threadedtempfile Creating Starting Reaping Done: errors 0 ok 1000 From python-dev@python.org Sat Jan 13 03:46:01 2001 From: python-dev@python.org (Tim Peters) Date: Fri, 12 Jan 2001 19:46:01 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_threadedtempfile.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv22911/python/dist/src/lib/test Modified Files: test_threadedtempfile.py Log Message: Fix stupidity. Index: test_threadedtempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_threadedtempfile.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** test_threadedtempfile.py 2001/01/13 03:04:02 1.1 --- test_threadedtempfile.py 2001/01/13 03:45:59 1.2 *************** *** 22,26 **** import threading ! from test.test_support import TestFailed import StringIO from traceback import print_exc --- 22,26 ---- import threading ! from test_support import TestFailed import StringIO from traceback import print_exc From python-dev@python.org Sat Jan 13 09:54:44 2001 From: python-dev@python.org (Martin v. Löwis) Date: Sat, 13 Jan 2001 01:54:44 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.92,1.93 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv21846 Modified Files: NEWS Log Message: Document extensions to .pth files. Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.92 retrieving revision 1.93 diff -C2 -r1.92 -r1.93 *** NEWS 2001/01/12 16:25:08 1.92 --- NEWS 2001/01/13 09:54:41 1.93 *************** *** 86,89 **** --- 86,93 ---- Standard library + - The module site now treats .pth files not only for path configuration, + but also supports extensions to the initialization code: Lines starting + with import are executed. + - There's a new module, warnings, which implements a mechanism for issuing and filtering warnings. There are some new built-in From python-dev@python.org Sat Jan 13 14:53:36 2001 From: python-dev@python.org (A.M. Kuchling) Date: Sat, 13 Jan 2001 06:53:36 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc NEWS,1.93,1.94 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv29888 Modified Files: NEWS Log Message: Mention new curses.panel module Index: NEWS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/NEWS,v retrieving revision 1.93 retrieving revision 1.94 diff -C2 -r1.93 -r1.94 *** NEWS 2001/01/13 09:54:41 1.93 --- NEWS 2001/01/13 14:53:34 1.94 *************** *** 123,126 **** --- 123,129 ---- continue to use the old, short names ("bisect" and "insort"). + - The new curses.panel module wraps the panel library that forms part + of SYSV curses and ncurses. Contributed by Thomas Gellekum. + - The SocketServer module now sets the allow_reuse_address flag by default in the TCPServer class. From python-dev@python.org Sat Jan 13 16:55:35 2001 From: python-dev@python.org (Guido van Rossum) Date: Sat, 13 Jan 2001 08:55:35 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.26,1.27 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv14586 Modified Files: httplib.py Log Message: SF Patch #103225 by Ping: httplib: smallest Python patch ever The ASCII-art diagram at the top of httplib contains a backslash at the end of a line, which causes Python to remove the newline. This one-character patch adds a space after the backslash so it will appear at the end of the line in the docstring as intended. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.26 retrieving revision 1.27 diff -C2 -r1.26 -r1.27 *** httplib.py 2000/12/15 15:09:42 1.26 --- httplib.py 2001/01/13 16:55:33 1.27 *************** *** 26,30 **** Unread-response [Response-headers-read] |\____________________ ! | \ | response.read() | putrequest() v v --- 26,30 ---- Unread-response [Response-headers-read] |\____________________ ! | \ | response.read() | putrequest() v v *************** *** 333,337 **** i = host.find(':') if i >= 0: ! port = int(host[i+1:]) host = host[:i] else: --- 333,340 ---- i = host.find(':') if i >= 0: ! try: ! port = int(host[i+1:]) ! except ValueError, msg: ! raise socket.error, str(msg) host = host[:i] else: From python-dev@python.org Sat Jan 13 19:16:23 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 11:16:23 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.27,1.28 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28008/python/dist/src/lib Modified Files: httplib.py Log Message: No text file relying on significant trailing whitespace is robust under modification. Removed the need for that. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** httplib.py 2001/01/13 16:55:33 1.27 --- httplib.py 2001/01/13 19:16:21 1.28 *************** *** 26,42 **** Unread-response [Response-headers-read] |\____________________ ! | \ ! | response.read() | putrequest() ! v v ! Idle Req-started-unread-response ! _______/| ! / | ! response.read() | | ( putheader() )* endheaders() ! v v ! Request-started Req-sent-unread-response ! | ! | response.read() ! v ! Request-sent This diagram presents the following rules: --- 26,42 ---- Unread-response [Response-headers-read] |\____________________ ! | | ! | response.read() | putrequest() ! v v ! Idle Req-started-unread-response ! ______/| ! / | ! response.read() | | ( putheader() )* endheaders() ! v v ! Request-started Req-sent-unread-response ! | ! | response.read() ! v ! Request-sent This diagram presents the following rules: *************** *** 567,571 **** 'rb' and the bufsize argument is ignored. ! The returned object contains *all* of the file data """ if mode != 'r' and mode != 'rb': --- 567,571 ---- 'rb' and the bufsize argument is ignored. ! The returned object contains *all* of the file data """ if mode != 'r' and mode != 'rb': *************** *** 720,728 **** Python 1.5.2 did not have an HTTPS class, but it defined an interface for sending http requests that is also useful for ! https. """ _connection_class = HTTPSConnection ! class HTTPException(Exception): --- 720,728 ---- Python 1.5.2 did not have an HTTPS class, but it defined an interface for sending http requests that is also useful for ! https. """ _connection_class = HTTPSConnection ! class HTTPException(Exception): From python-dev@python.org Sat Jan 13 22:06:07 2001 From: python-dev@python.org (Guido van Rossum) Date: Sat, 13 Jan 2001 14:06:07 -0800 Subject: [Python-checkins] CVS: python/dist/src/Python sysmodule.c,2.82,2.83 Message-ID: Update of /cvsroot/python/python/dist/src/Python In directory usw-pr-cvs1:/tmp/cvs-serv10721 Modified Files: sysmodule.c Log Message: Neil discovered a bad DECREF on warnoptions, that caused repeated re-initializing Python (Py_Finalize() followed by Py_Initialize()) to blow up quickly. With the DECREF removed I can't get it to fail any more. (Except it still leaks, but that's probably a separate issue.) Index: sysmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Python/sysmodule.c,v retrieving revision 2.82 retrieving revision 2.83 diff -C2 -r2.82 -r2.83 *** sysmodule.c 2001/01/11 09:27:34 2.82 --- sysmodule.c 2001/01/13 22:06:05 2.83 *************** *** 635,640 **** } if (warnoptions != NULL) { ! PyDict_SetItemString(sysdict, "warnoptions", v = warnoptions); ! Py_DECREF(v); } --- 635,639 ---- } if (warnoptions != NULL) { ! PyDict_SetItemString(sysdict, "warnoptions", warnoptions); } From python-dev@python.org Sat Jan 13 22:10:43 2001 From: python-dev@python.org (Guido van Rossum) Date: Sat, 13 Jan 2001 14:10:43 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib code.py,1.10,1.11 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11338 Modified Files: code.py Log Message: SF Patch #103227 by mwh: make code.py appreciate softspace Index: code.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/code.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** code.py 2000/12/27 19:12:58 1.10 --- code.py 2001/01/13 22:10:41 1.11 *************** *** 11,14 **** --- 11,25 ---- from codeop import compile_command + def softspace(file, newvalue): + oldvalue = 0 + try: + oldvalue = file.softspace + except AttributeError: + pass + try: + file.softspace = newvalue + except TypeError: # "attribute-less object" or "read-only attributes" + pass + return oldvalue class InteractiveInterpreter: *************** *** 91,94 **** --- 102,108 ---- except: self.showtraceback() + else: + if softspace(sys.stdout, 0): + print def showsyntaxerror(self, filename=None): From python-dev@python.org Sat Jan 13 22:14:33 2001 From: python-dev@python.org (Guido van Rossum) Date: Sat, 13 Jan 2001 14:14:33 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib traceback.py,1.17,1.18 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11647 Modified Files: traceback.py Log Message: mwh: [ Patch #103228 ] traceback.py nit. When the exception has no message, don't insert a colon after the exception name. Index: traceback.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/traceback.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** traceback.py 2000/08/22 02:04:46 1.17 --- traceback.py 2001/01/13 22:14:31 1.18 *************** *** 167,171 **** list.append('%s^\n' % s) value = msg ! list.append('%s: %s\n' % (str(stype), _some_str(value))) return list --- 167,175 ---- list.append('%s^\n' % s) value = msg ! s = _some_str(value) ! if s: ! list.append('%s: %s\n' % (str(stype), s)) ! else: ! list.append('%s\n' % str(stype)) return list From python-dev@python.org Sun Jan 14 02:26:02 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sat, 13 Jan 2001 18:26:02 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help - New directory Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv2453/help Log Message: Directory /cvsroot/python/python/nondist/sandbox/help added to the repository From python-dev@python.org Sun Jan 14 02:27:12 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sat, 13 Jan 2001 18:27:12 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help htmldoc.py,NONE,1.1 inspect.py,NONE,1.1 pydoc.py,NONE,1.1 textdoc.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv2565/help Added Files: htmldoc.py inspect.py pydoc.py textdoc.py Log Message: Added a first pass at an interactive / shell-command / web-based doc system. --- NEW FILE: htmldoc.py --- #!/usr/bin/env python """Generate HTML documentation from live Python objects.""" __version__ = 'Ka-Ping Yee , 29 May 2000' import sys, os, re, inspect from string import join, replace, expandtabs, rstrip # ---------------------------------------------------- formatting utilities def serialize(stuff): """Combine a list containing strings and nested lists into a single string. This lets us manipulate lists until the last moment, since rearranging lists is faster than rearranging strings.""" if type(stuff) is type(''): return stuff results = [] for item in stuff: if type(item) is type(''): results.append(item) else: results.append(serialize(item)) return join(results, '') def htmlescape(text): return replace(replace(replace(text, '&', '&'), '<', '<'), '>', '>') def htmlrepr(object): return htmlescape(repr(object)) def preformat(text): text = htmlescape(expandtabs(text)) return replace(replace(replace(replace(text, '\n\n', '\n \n'), '\n\n', '\n \n'), ' ', ' '), '\n', '
\n') def multicolumn(list, format, cols=4): results = [''] rows = (len(list)+cols-1)/cols for col in range(cols): results.append('') results.append('
' % (100/cols)) for i in range(rows*col, rows*col+rows): if i < len(list): results.append(format(list[i]) + '
') results.append('
') return results def heading(title, fgcol, bgcol, extras=''): return ["""

""" % (bgcol, fgcol, title, fgcol, extras), '

 %s
 %s
'] def section(title, fgcol, bgcol, contents, width=20, prelude='', marginalia=None, gap='   '): if marginalia is None: marginalia = ' ' * width results = [] results.append("""

""" % (bgcol, fgcol, title)) if prelude: results.append(""" """ % (bgcol, marginalia, bgcol, prelude)) results.append(""" """ % (bgcol, marginalia, gap)) # Alas, this horrible hack seems to be the only way to force Netscape # to expand the main cell consistently to the maximum available width. results.append('

 %s
%s %s
%s%s' + '  '*100 + '') results.append(contents) results.append('
') return results def footer(): return """
generated with htmldoc by Ka-Ping Yee
""" # -------------------------------------------------------- automatic markup def namelink(name, *dicts): for dict in dicts: if dict.has_key(name): return '%s' % (dict[name], name) return name def classlink(object, modname, *dicts): name = object.__name__ if object.__module__ != modname: name = object.__module__ + '.' + name for dict in dicts: if dict.has_key(object): return '%s' % (dict[object], name) return name def modulelink(object): return '%s' % (object.__name__, object.__name__) def markup(text, functions={}, classes={}, methods={}, escape=htmlescape): """Mark up some plain text, given a context of symbols to look for. Each context dictionary maps object names to named anchor identifiers.""" results = [] here = 0 pattern = re.compile('(self\.)?(\w+)') while 1: match = pattern.search(text, here) if not match: break start, end = match.regs[2] found, name = match.group(0), match.group(2) results.append(escape(text[here:start])) if text[end:end+1] == '(': results.append(namelink(name, methods, functions, classes)) elif match.group(1): results.append('%s' % name) else: results.append(namelink(name, classes)) here = end results.append(text[here:]) return join(results, '') def getdoc(object): result = inspect.getdoc(object) if not result: try: result = inspect.getcomments(object) except: pass return result and rstrip(result) + '\n' or '' # -------------------------------------------------- type-specific routines def document_tree(tree, modname, classes={}, parent=None): """Produce HTML for a class tree as returned by inspect.getclasstree().""" results = ['

\n'] for entry in tree: if type(entry) is type(()): c, bases = entry results.append('
') results.append(classlink(c, modname, classes)) if bases and bases != (parent,): parents = [] for base in bases: parents.append(classlink(base, modname, classes)) results.append('(' + join(parents, ', ') + ')') results.append('\n
') elif type(entry) is type([]): results.append('
\n') results.append(document_tree(entry, modname, classes, c)) results.append('
\n') results.append('
\n') return results def document_module(object): """Produce HTML documentation for a given module object.""" name = object.__name__ results = [] head = '
 %s' % name try: file = inspect.getsourcefile(object) filelink = '%s' % (file, file) except TypeError: filelink = '(built-in)' if hasattr(object, '__version__'): head = head + ' (version: %s)' % htmlescape(object.__version__) results.append(heading(head, '#ffffff', '#7799ee', filelink)) cadr = lambda list: list[1] modules = map(cadr, inspect.getmembers(object, inspect.ismodule)) classes, cdict = [], {} for key, value in inspect.getmembers(object, inspect.isclass): if (inspect.getmodule(value) or object) is object: classes.append(value) cdict[key] = cdict[value] = '#' + key functions, fdict = [], {} for key, value in inspect.getmembers(object, inspect.isroutine): if inspect.isbuiltin(value) or inspect.getmodule(value) is object: functions.append(value) fdict[key] = '#-' + key if inspect.isfunction(value): fdict[value] = fdict[key] for c in classes: for base in c.__bases__: key, modname = base.__name__, base.__module__ if modname != name and sys.modules.has_key(modname): module = sys.modules[modname] if hasattr(module, key) and getattr(module, key) is base: if not cdict.has_key(key): cdict[key] = cdict[base] = modname + '.html#' + key doc = markup(getdoc(object), fdict, cdict, escape=preformat) if doc: doc = '

' + doc + '\n\n' else: doc = '

no doc string\n' results.append(doc) if modules: contents = multicolumn(modules, modulelink) results.append(section('Modules', '#fffff', '#aa55cc', contents)) if classes: contents = document_tree(inspect.getclasstree(classes, 1), name, cdict) for item in classes: contents.append(document_class(item, fdict, cdict)) results.append(section('Classes', '#ffffff', '#ee77aa', contents)) if functions: contents = [] for item in functions: contents.append(document_function(item, fdict, cdict)) results.append(section('Functions', '#ffffff', '#eeaa77', contents)) return results def document_class(object, functions={}, classes={}): """Produce HTML documentation for a given class object.""" name = object.__name__ bases = object.__bases__ results = [] methods, mdict = [], {} for key, value in inspect.getmembers(object, inspect.ismethod): methods.append(value) mdict[key] = mdict[value] = '#' + name + '-' + key if methods: for item in methods: results.append(document_method( item, functions, classes, mdict, name)) title = 'class %s' % (name, name) if bases: parents = [] for base in bases: parents.append(classlink(base, object.__module__, classes)) title = title + '(%s)' % join(parents, ', ') doc = markup(getdoc(object), functions, classes, mdict, escape=preformat) if doc: doc = '' + doc + '
 
' else: doc = 'no doc string' return section(title, '#000000', '#ffc8d8', results, 10, doc) def document_method(object, functions={}, classes={}, methods={}, clname=''): """Produce HTML documentation for a given method object.""" return document_function( object.im_func, functions, classes, methods, clname) def defaultformat(object): return '=' + \ htmlrepr(object) + '' def document_function(object, functions={}, classes={}, methods={}, clname=''): """Produce HTML documentation for a given function object.""" try: args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec( args, varargs, varkw, defaults, defaultformat=defaultformat) except TypeError: argspec = '(...)' if object.__name__ == '': decl = ['lambda ', argspec[1:-1]] else: anchor = clname + '-' + object.__name__ decl = ['' % anchor, '%s' % object.__name__, argspec, '\n'] doc = markup(getdoc(object), functions, classes, methods, escape=preformat) if doc: doc = replace(doc, '
\n', '

') doc = ['
', doc, ''] else: doc = '
no doc string' return ['
', decl, doc, '
'] def document_builtin(object): """Produce HTML documentation for a given built-in function.""" return ('%s' % object.__name__ + '(...)') # --------------------------------------------------- main dispatch routine def document(object): """Generate documentation for a given object.""" if inspect.ismodule(object): results = document_module(object) elif inspect.isclass(object): results = document_class(object) elif inspect.ismethod(object): results = document_method(object) elif inspect.isfunction(object): results = document_function(object) elif inspect.isbuiltin(object): results = document_builtin(object) else: raise TypeError, 'don\'t know how to document this kind of object' return serialize(results) def index(dir): modules = [] packages = [] for file in os.listdir(dir): path = dir + '/' + file if os.path.isfile(path): if file[-3:] == '.py': modules.append(file[:-3]) elif file[-11:] == 'module.so': modules.append(file[:-11]) elif file[-13:] == 'module.so.1': modules.append(file[:-13]) elif os.path.isdir(path): if os.path.exists(path + '/__init__.py'): packages.append(file) def modulelink(name): return '%s' % (name, name) modules.sort() contents = multicolumn(modules, modulelink) results = section('%s' % dir, '#ffffff', '#ee77aa', contents) return serialize(results) if __name__ == '__main__': import os modnames = [] for arg in sys.argv[1:]: if os.path.isdir(arg): for file in os.listdir(arg): if file[-3:] == '.py': modnames.append(file[:-3]) elif file[-9:] == 'module.so': modnames.append(file[:-9]) else: if arg[-3:] == '.py': modnames.append(arg[:-3]) else: modnames.append(arg) for modname in modnames: try: module = __import__(modname) except: print 'failed to import %s' % modname else: file = open(modname + '.html', 'w') file.write( """ %s """ % modname) file.write(document(module)) file.write('') file.close() print 'wrote %s.html' % modname --- NEW FILE: inspect.py --- """Get useful information from live Python objects. This module encapsulates the interface provided by the internal special attributes (func_*, co_*, im_*, tb_*, etc.) in a friendlier fashion. It also provides some help for examining source code and class layout. Here are some of the useful functions provided by this module: getdoc(), getcomments() - get documentation on an object getclasstree() - arrange classes so as to represent their hierarchy getfile(), getsourcefile(), getsource() - find an object's source code getargspec(), getargvalues() - get info about function arguments formatargspec(), formatargvalues() - format an argument spec stack(), trace() - get info about frames on the stack or in a traceback """ # This module is in the public domain. No warranties. __version__ = 'Ka-Ping Yee , 1 Jan 2001' import sys, types, string, dis, imp # ----------------------------------------------------------- type-checking def ismodule(object): """Return true if the object is a module. Module objects provide these attributes: __doc__ documentation string __file__ filename (missing for built-in modules)""" return type(object) is types.ModuleType def isclass(object): """Return true if the object is a class. Class objects provide these attributes: __doc__ documentation string __module__ name of module in which this class was defined""" return type(object) is types.ClassType def ismethod(object): """Return true if the object is an instance method. Instance method objects provide these attributes: __doc__ documentation string __name__ name with which this method was defined im_class class object in which this method belongs im_func function object containing implementation of method im_self instance to which this method is bound, or None""" return type(object) is types.MethodType def isfunction(object): """Return true if the object is a user-defined function. Function objects provide these attributes: __doc__ documentation string __name__ name with which this function was defined func_code code object containing compiled function bytecode func_defaults tuple of any default values for arguments func_doc (same as __doc__) func_globals global namespace in which this function was defined func_name (same as __name__)""" return type(object) in [types.FunctionType, types.LambdaType] def istraceback(object): """Return true if the object is a traceback. Traceback objects provide these attributes: tb_frame frame object at this level tb_lasti index of last attempted instruction in bytecode tb_lineno current line number in Python source code tb_next next inner traceback object (called by this level)""" return type(object) is types.TracebackType def isframe(object): """Return true if the object is a frame object. Frame objects provide these attributes: f_back next outer frame object (this frame's caller) f_builtins built-in namespace seen by this frame f_code code object being executed in this frame f_exc_traceback traceback if raised in this frame, or None f_exc_type exception type if raised in this frame, or None f_exc_value exception value if raised in this frame, or None f_globals global namespace seen by this frame f_lasti index of last attempted instruction in bytecode f_lineno current line number in Python source code f_locals local namespace seen by this frame f_restricted 0 or 1 if frame is in restricted execution mode f_trace tracing function for this frame, or None""" return type(object) is types.FrameType def iscode(object): """Return true if the object is a code object. Code objects provide these attributes: co_argcount number of arguments (not including * or ** args) co_code string of raw compiled bytecode co_consts tuple of constants used in the bytecode co_filename name of file in which this code object was created co_firstlineno number of first line in Python source code co_flags bitmap: 1=optimized | 2=newlocals | 4=*arg | 8=**arg co_lnotab encoded mapping of line numbers to bytecode indices co_name name with which this code object was defined co_names tuple of names of local variables co_nlocals number of local variables co_stacksize virtual machine stack space required co_varnames tuple of names of arguments and local variables""" return type(object) is types.CodeType def isbuiltin(object): """Return true if the object is a built-in function or method. Built-in functions and methods provide these attributes: __doc__ documentation string __name__ original name of this function or method __self__ instance to which a method is bound, or None""" return type(object) in [types.BuiltinFunctionType, types.BuiltinMethodType] def isroutine(object): """Return true if the object is any kind of function or method.""" return type(object) in [types.FunctionType, types.LambdaType, types.MethodType, types.BuiltinFunctionType, types.BuiltinMethodType] def getmembers(object, predicate=None): """Return all members of an object as (key, value) pairs sorted by key. Optionally, only return members that satisfy a given predicate.""" results = [] for key in dir(object): value = getattr(object, key) if not predicate or predicate(value): results.append((key, value)) results.sort() return results # -------------------------------------------------- source code extraction def indentsize(line): """Return the indent size, in spaces, at the start of a line of text.""" expline = string.expandtabs(line) return len(expline) - len(string.lstrip(expline)) def getdoc(object): """Get the documentation string for an object. All tabs are expanded to spaces. To clean up docstrings that are indented to line up with blocks of code, any whitespace than can be uniformly removed from the second line onwards is removed.""" if hasattr(object, '__doc__') and object.__doc__: lines = string.split(string.expandtabs(object.__doc__), '\n') margin = None for line in lines[1:]: content = len(string.lstrip(line)) if not content: continue indent = len(line) - content if margin is None: margin = indent else: margin = min(margin, indent) if margin is not None: for i in range(1, len(lines)): lines[i] = lines[i][margin:] return string.join(lines, '\n') def getfile(object): """Try to guess which (text or binary) file an object was defined in.""" if ismodule(object): if hasattr(object, '__file__'): return object.__file__ raise TypeError, 'arg is a built-in module' if isclass(object): object = sys.modules[object.__module__] if hasattr(object, '__file__'): return object.__file__ raise TypeError, 'arg is a built-in class' if ismethod(object): object = object.im_func if isfunction(object): object = object.func_code if istraceback(object): object = object.tb_frame if isframe(object): object = object.f_code if iscode(object): return object.co_filename raise TypeError, 'arg is not a module, class, method, ' \ 'function, traceback, frame, or code object' modulesbyfile = {} def getmodule(object): """Try to guess which module an object was defined in.""" try: file = getsourcefile(object) except TypeError: return None if modulesbyfile.has_key(file): return sys.modules[modulesbyfile[file]] for module in sys.modules.values(): if hasattr(module, '__file__'): modulesbyfile[getsourcefile(module)] = module.__name__ if modulesbyfile.has_key(file): return sys.modules[modulesbyfile[file]] main = sys.modules['__main__'] try: mainobject = getattr(main, object.__name__) if mainobject is object: return main except AttributeError: pass builtin = sys.modules['__builtin__'] try: builtinobject = getattr(builtin, object.__name__) if builtinobject is object: return builtin except AttributeError: pass def getsourcefile(object): """Try to guess which Python source file an object was defined in.""" filename = getfile(object) if filename[-4:] == '.pyc': filename = filename[:-4] + '.py' return filename def findsource(object): """Find the first line of code corresponding to a given module, class, method, function, traceback, frame, or code object; return the entire contents of the source file and the starting line number. An IOError exception is raised if the source code cannot be retrieved.""" try: file = open(getsourcefile(object)) lines = file.readlines() file.close() except (TypeError, IOError): raise IOError, 'could not get source code' if ismodule(object): return lines, 0 if isclass(object): name = object.__name__ matches = (['class', name], ['class', name + ':']) for i in range(len(lines)): if string.split(lines[i])[:2] in matches: return lines, i else: raise IOError, 'could not find class definition' if ismethod(object): object = object.im_func if isfunction(object): object = object.func_code if istraceback(object): object = object.tb_frame if isframe(object): object = object.f_code if iscode(object): try: lnum = object.co_firstlineno - 1 except AttributeError: raise IOError, 'could not find function definition' else: while lnum > 0: if string.split(lines[lnum])[:1] == ['def']: break lnum = lnum - 1 return lines, lnum def getcomments(object): """Get lines of comments immediately preceding an object's source code.""" try: lines, lnum = findsource(object) except: return None if ismodule(object): # Look for a comment block at the top of the file. start = 0 if lines[0][:2] == '#!': start = 1 while start < len(lines) and string.strip(lines[start]) in ['', '#']: start = start + 1 if lines[start][:1] == '#': comments = [] end = start while end < len(lines) and lines[end][:1] == '#': comments.append(string.expandtabs(lines[end])) end = end + 1 return string.join(comments, '') # Look for a preceding block of comments at the same indentation. elif lnum > 0: indent = indentsize(lines[lnum]) end = lnum - 1 if string.strip(lines[end]) == '': while end >= 0 and string.strip(lines[end]) == '': end = end - 1 else: while string.lstrip(lines[end])[:1] != '#' and \ indentsize(lines[end]) == indent: end = end - 1 if end >= 0 and string.lstrip(lines[end])[:1] == '#' and \ indentsize(lines[end]) == indent: comments = [string.lstrip(string.expandtabs(lines[end]))] if end > 0: end = end - 1 comment = string.lstrip(string.expandtabs(lines[end])) while comment[:1] == '#' and indentsize(lines[end]) == indent: comments[:0] = [comment] end = end - 1 if end < 0: break comment = string.lstrip(string.expandtabs(lines[end])) return string.join(comments, '') import tokenize class ListReader: """Provide a readline() method to return lines from a list of strings.""" def __init__(self, lines): self.lines = lines self.index = 0 def readline(self): i = self.index if i < len(self.lines): self.index = i + 1 return self.lines[i] else: return '' class EndOfBlock(Exception): pass class BlockFinder: """Provide a tokeneater() method to detect the end of a code block.""" def __init__(self): self.indent = 0 self.started = 0 self.last = 0 def tokeneater(self, type, token, (srow, scol), (erow, ecol), line): if not self.started: if type == tokenize.NAME: self.started = 1 elif type == tokenize.NEWLINE: self.last = srow elif type == tokenize.INDENT: self.indent = self.indent + 1 elif type == tokenize.DEDENT: self.indent = self.indent - 1 if self.indent == 0: raise EndOfBlock, self.last def getblock(lines): """Extract the block of code at the top of the given list of lines.""" try: tokenize.tokenize(ListReader(lines).readline, BlockFinder().tokeneater) except EndOfBlock, eob: return lines[:eob.args[0]] def getsourcelines(object): """Try to get the source code corresponding to a module, class, method, function, traceback, frame, or code object. Return a list of lines and the line number of the first line, or raise an IOError exception if the source code cannot be retrieved.""" lines, lnum = findsource(object) if ismodule(object): return lines, 0 else: return getblock(lines[lnum:]), lnum def getsource(object): """Try to get the source code corresponding to a module, class, method, function, traceback, frame, or code object. Return a string, or raise an IOError exception if the source code cannot be retrieved.""" lines, lnum = getsourcelines(object) return string.join(lines, '') # --------------------------------------------------- class tree extraction def walktree(classes, children, parent): """Recursive helper function for getclasstree().""" results = [] classes.sort(lambda a, b: cmp(a.__name__, b.__name__)) for c in classes: results.append((c, c.__bases__)) if children.has_key(c): results.append(walktree(children[c], children, c)) return results def getclasstree(classes, unique=0): """Arrange the given list of classes into a hierarchy of nested lists. Where a nested list appears, it contains classes derived from the class whose entry immediately precedes the list. Each entry is a 2-tuple containing a class and a tuple of its base classes. If the 'unique' argument is true, exactly one entry appears in the returned structure for each class in the given list. Otherwise, classes that multiply inherit, and their descendants, will appear multiple times.""" children = {} roots = [] for c in classes: if c.__bases__: for parent in c.__bases__: if not children.has_key(parent): children[parent] = [] children[parent].append(c) if unique and parent in classes: break elif c not in roots: roots.append(c) for parent in children.keys(): if parent not in classes: roots.append(parent) return walktree(roots, children, None) # ------------------------------------------------ argument list extraction # These constants are from Python's compile.h. CO_OPTIMIZED, CO_NEWLOCALS, CO_VARARGS, CO_VARKEYWORDS = 1, 2, 4, 8 def getargs(co): """Get information about the arguments accepted by a code object. Three things are returned: (args, varargs, varkw), where 'args' is a list of argument names (possibly containing nested lists), and 'varargs' and 'varkw' are the names of the * and ** arguments or None.""" if not iscode(co): raise TypeError, 'arg is not a code object' code = co.co_code nargs = co.co_argcount names = co.co_varnames args = list(names[:nargs]) step = 0 # The following acrobatics are for anonymous (tuple) arguments. for i in range(nargs): if args[i][:1] in ['', '.']: stack, remain, count = [], [], [] while step < len(code): op = ord(code[step]) step = step + 1 if op >= dis.HAVE_ARGUMENT: opname = dis.opname[op] value = ord(code[step]) + ord(code[step+1])*256 step = step + 2 if opname == 'UNPACK_TUPLE': remain.append(value) count.append(value) elif opname == 'STORE_FAST': stack.append(names[value]) remain[-1] = remain[-1] - 1 while remain[-1] == 0: remain.pop() size = count.pop() stack[-size:] = [stack[-size:]] if not remain: break remain[-1] = remain[-1] - 1 if not remain: break args[i] = stack[0] varargs = None if co.co_flags & CO_VARARGS: varargs = co.co_varnames[nargs] nargs = nargs + 1 varkw = None if co.co_flags & CO_VARKEYWORDS: varkw = co.co_varnames[nargs] return args, varargs, varkw def getargspec(func): """Get the names and default values of a function's arguments. A tuple of four things is returned: (args, varargs, varkw, defaults). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'defaults' is an n-tuple of the default values of the last n arguments.""" if not isfunction(func): raise TypeError, 'arg is not a Python function' args, varargs, varkw = getargs(func.func_code) return args, varargs, varkw, func.func_defaults def getargvalues(frame): """Get information about arguments passed into a particular frame. A tuple of four things is returned: (args, varargs, varkw, locals). 'args' is a list of the argument names (it may contain nested lists). 'varargs' and 'varkw' are the names of the * and ** arguments or None. 'locals' is the locals dictionary of the given frame.""" args, varargs, varkw = getargs(frame.f_code) return args, varargs, varkw, frame.f_locals def strseq(object, convert=str): """Recursively walk a sequence, stringifying each element.""" if type(object) in [types.ListType, types.TupleType]: results = map(lambda o, c=convert: strseq(o, c), object) if len(results) == 1: return '(' + results[0] + ',)' else: return '(' + string.join(results, ', ') + ')' else: return convert(object) def formatargspec(args, varargs=None, varkw=None, defaults=None, argformat=str, defaultformat=lambda x: '=' + repr(x), varargsformat=lambda name: '*' + name, varkwformat=lambda name: '**' + name): """Format a pretty argument spec from the 4-tuple returned by getargspec. The arguments are (args, varargs, varkw, defaults).""" specs = [] if defaults: firstdefault = len(args) - len(defaults) for i in range(len(args)): spec = strseq(args[i], argformat) if defaults and i >= firstdefault: spec = spec + defaultformat(defaults[i - firstdefault]) specs.append(spec) if varargs: specs.append(varargsformat(varargs)) if varkw: specs.append(varkwformat(varkw)) return '(' + string.join(specs, ', ') + ')' def formatargvalues(args, varargs, varkw, locals, argformat=str, valueformat=repr, varargsformat=lambda name: '*' + name, varkwformat=lambda name: '**' + name): """Format a pretty argument spec from the 4-tuple returned by getargvalues. The arguments are (args, varargs, varkw, locals).""" def convert(name, locals=locals, argformat=argformat, valueformat=valueformat): return argformat(name) + '=' + valueformat(locals[name]) specs = [] for i in range(len(args)): specs.append(strseq(args[i], convert)) if varargs: specs.append(varargsformat(varargs) + '=' + valueformat(locals[varargs])) if varkw: specs.append(varkwformat(varkw) + '=' + valueformat(locals[varkw])) return '(' + string.join(specs, ', ') + ')' # -------------------------------------------------- stack frame extraction def getframe(frame, context=1): """For a given frame or traceback object, return the filename, line number, function name, a given number of lines of context from the source code, and the index of the line within the lines of context.""" if istraceback(frame): frame = frame.tb_frame if not isframe(frame): raise TypeError, 'arg is not a frame or traceback object' filename = getsourcefile(frame) if context > 0: start = frame.f_lineno - 1 - context/2 try: lines, lnum = findsource(frame) start = max(start, 1) start = min(start, len(lines) - context) lines = lines[start:start+context] index = frame.f_lineno - 1 - start except: lines = index = None else: lines = index = None return (filename, frame.f_lineno, frame.f_code.co_name, lines, index) def getouterframes(frame, context=1): """Get a list of records for a frame and all higher (calling) frames. Each record contains a frame object, filename, line number, function name, the requested amount of context, and index within the context.""" framelist = [] while frame: framelist.append((frame,) + getframe(frame, context)) frame = frame.f_back return framelist def getinnerframes(traceback, context=1): """Get a list of records for a traceback's frame and all lower frames. Each record contains a frame object, filename, line number, function name, the requested amount of context, and index within the context.""" traceback = traceback.tb_next framelist = [] while traceback: framelist.append((traceback.tb_frame,) + getframe(traceback, context)) traceback = traceback.tb_next return framelist def currentframe(): """Return the frame object for the caller's stack frame.""" try: raise 'catch me' except: return sys.exc_traceback.tb_frame.f_back if hasattr(sys, '_getframe'): currentframe = sys._getframe def stack(context=1): """Return a list of records for the stack above the caller's frame.""" return getouterframes(currentframe().f_back, context) def trace(context=1): """Return a list of records for the stack below the current exception.""" return getinnerframes(sys.exc_traceback, context) --- NEW FILE: pydoc.py --- #!/usr/bin/env python """Format Python documentation for interactive use. At the shell command line outside of Python, run "pydoc " to show documentation on something. may be the name of a Python function, module, package, or a dotted reference to a class or function within a module or module in a package. Or, at the shell prompt, run "pydoc -k " to search for a keyword in the one-line descriptions of modules. Or, at the shell prompt, run "pydoc -p " to start an HTTP server on a given port on the local machine to generate documentation web pages. In the Python interpreter, do "from pydoc import help" to provide online help. Calling help(thing) on a Python object documents the object.""" __author__ = "Ka-Ping Yee " __version__ = "10 January 2001" import sys, os, string, types, getopt import inspect, htmldoc, textdoc def precis(filename): """Get the one-line summary out of a module file.""" file = open(filename) line = file.readline() while line[:1] in ['#', '\n']: line = file.readline() if line[-2:] == '\\\n': line = line[:-2] + file.readline() file.close() line = string.strip(line) if line[:3] == '"""': i = string.find(line, '"""', 3) if i >= 0: return line[3:i] return line[3:] identchars = string.letters + string.digits + '_' def index(dir): """Return a list of (module-name, precis) pairs for a given directory.""" results = [] for entry in os.listdir(dir): path = os.path.join(dir, entry) init = os.path.join(path, '__init__.py') if os.path.isdir(path) and os.path.exists(init): results.extend(map( lambda (m, s), pkg=entry: (pkg + '.' + m, s), index(path))) elif os.path.isfile(path) and entry[-3:] == '.py': results.append((entry[:-3], precis(path))) return results def pager(text): """The first time this is called, determine what kind of pager to use.""" global pager pager = getpager() pager(text) def getpager(): """Decide what method to use for paging through text.""" if not sys.stdin.isatty() or type(sys.stdout) is not types.FileType: return plainpager if os.environ.has_key('PAGER'): return lambda text: pipepager(text, os.environ['PAGER']) if hasattr(sys, 'winver'): return lambda text: tempfilepager(text, 'more') if hasattr(os, 'system') and os.system('less 2>/dev/null') == 0: return lambda text: pipepager(text, 'less') import tempfile filename = tempfile.mktemp() open(filename, 'w').close() try: if hasattr(os, 'system') and os.system('more %s' % filename) == 0: return lambda text: pipepager(text, 'more') else: return ttypager finally: os.unlink(filename) def pipepager(text, cmd): """Page through text by feeding it to another program.""" pipe = os.popen(cmd, 'w') try: pipe.write(text) except IOError: # Ignore broken pipes caused by quitting the pager program. pass pipe.close() def tempfilepager(text, cmd): """Page through text by invoking a program on a temporary file.""" import tempfile filename = tempfile.mktemp() file = open(filename, 'w') file.write(text) file.close() try: os.system(cmd + ' ' + filename) finally: os.unlink(filename) def plain(text): """Remove boldface formatting from text.""" import re return re.sub('.\b', '', text) def ttypager(text): """Page through text on a text terminal.""" lines = string.split(plain(text), '\n') try: import tty except ImportError: tty = None try: if tty: fd = sys.stdin.fileno() old = tty.tcgetattr(fd) tty.setcbreak(fd) getchar = lambda: sys.stdin.read(1) else: getchar = lambda: sys.stdin.readline()[:-1][:1] r = inc = 24 sys.stdout.write(string.join(lines[:inc], '\n') + '\n') while lines[r:]: sys.stdout.write('-- more --') sys.stdout.flush() c = getchar() if c in ['q', 'Q']: sys.stdout.write('\r \r') break elif c in ['\r', '\n']: sys.stdout.write('\r \r' + lines[r] + '\n') r = r + 1 continue if c in ['b', 'B', '\x1b']: r = r - inc - inc if r < 0: r = 0 sys.stdout.write('\n' + string.join(lines[r:r+inc], '\n') + '\n') r = r + inc finally: if tty: tty.tcsetattr(fd, tty.TCSAFLUSH, old) def plainpager(text): sys.stdout.write(plain(text)) def describe(thing): """Produce a short description of the given kind of thing.""" if inspect.ismodule(thing): if thing.__name__ in sys.builtin_module_names: return 'built-in module ' + thing.__name__ if hasattr(thing, '__path__'): return 'package ' + thing.__name__ else: return 'module ' + thing.__name__ if inspect.isbuiltin(thing): return 'built-in function ' + thing.__name__ if inspect.isclass(thing): return 'class ' + thing.__name__ if inspect.isfunction(thing): return 'function ' + thing.__name__ if inspect.ismethod(thing): return 'method ' + thing.__name__ return repr(thing) def find(name): """Locate an object by name (or dotted path), importing as necessary.""" if hasattr(__builtins__, name): return None, getattr(__builtins__, name) parts = string.split(name, '.') n = 1 while n <= len(parts): name = string.join(parts[:n], '.') try: mod = __import__(name) except ImportError: break try: mod = reload(mod) except ImportError: pass try: x = mod for p in parts[1:]: x = getattr(x, p) return string.join(parts[:-1], '.'), x except AttributeError: n = n + 1 continue return None, None # ------------------------------------------------------ external interface def doc(thing): """Display documentation on an object (for interactive use).""" if type(thing) is type(""): path, x = find(thing) if x: thing = x else: print 'could not import or find %s' % thing return desc = describe(thing) module = inspect.getmodule(thing) if module and module is not thing: desc = desc + ' in module ' + module.__name__ pager('Help on %s:\n\n' % desc + textdoc.document(thing)) class Helper: def __repr__(self): return """To get help on a Python object, call help(object). To get help on a module or package, either import it before calling help(module) or call help('modulename').""" def __call__(self, object): doc(object) help = Helper() def man(key): """Display documentation on an object in a form similar to man(1).""" path, x = find(key) if x: title = 'Python Library Documentation: ' + describe(x) if path: title = title + ' in ' + path pager('\n' + title + '\n\n' + textdoc.document(x)) found = 1 else: print 'no Python documentation found for %s' % key def apropos(key): for module in sys.builtin_module_names: desc = __import__(module).__doc__ if desc: desc = string.split(desc, '\n')[0] if (string.find(string.lower(module), key) >= 0 or desc and string.find(string.lower(desc), key) >= 0): print module, '-', desc seen = {} for dir in sys.path: for module, desc in index(dir or '.'): desc = desc or '(no description)' if not seen.has_key(module): seen[module] = 1 if (string.find(string.lower(module), key) >= 0 or desc and string.find(string.lower(desc), key) >= 0): if module[-9:] == '.__init__': print module[:-9], '(package) -', desc else: print module, '-', desc def server(port): print 'starting server on port', port import BaseHTTPServer class DocReqHandler(BaseHTTPServer.BaseHTTPRequestHandler): def send_document(self, title, contents): self.send_response(200) self.send_header('Content-Type', 'text/html') self.end_headers() self.wfile.write( ''' Python: %s''' % title) self.wfile.write(contents) self.wfile.write('') def do_GET(self): path = self.path if path[-5:] == '.html': path = path[:-5] if path[:1] == '/': path = path[1:] if path: p, x = find(path) if x: self.send_document(describe(x), htmldoc.document(x)) else: self.send_document(path, 'There is no Python module or object named "%s".' % path) else: contents = htmldoc.heading( '
 ' 'Python: Index of Modules' '', '#ffffff', '#7799ee') builtins = [] for name in sys.builtin_module_names: builtins.append('%s' % (name, name)) contents.append('

Built-in modules: ') contents.append(string.join(builtins, ', ')) contents.extend(map(htmldoc.index, sys.path)) contents = htmldoc.serialize(contents) self.send_document('Index of Modules', contents) def log_message(self, *args): pass BaseHTTPServer.HTTPServer(('', port), DocReqHandler).serve_forever() def usage(): print """%s ... Show documentation on something. may be the name of a Python function, module, package, or a dotted reference to a class or function within a module or module in a package. %s -k Search for a keyword in the short descriptions of modules. %s -p Start an HTTP server on the given port on the local machine. """ % ((sys.argv[0],) * 3) if __name__ == '__main__': try: opts, args = getopt.getopt(sys.argv[1:], 'k:p:') except getopt.error: usage() else: for opt, val in opts: if opt == '-k': apropos(string.lower(val)) break if opt == '-p': try: port = int(val) except ValueError: usage() else: server(port) break else: if args: for arg in args: man(arg) else: usage() --- NEW FILE: textdoc.py --- """Generate text documentation from live Python objects.""" __version__ = 'Ka-Ping Yee , 10 Jan 2001' import sys, inspect from string import join, split, strip, rstrip # ---------------------------------------------------- formatting utilities def serialize(stuff): """Combine a list containing strings and nested lists into a single string. This lets us manipulate lists until the last moment, since rearranging lists is faster than rearranging strings.""" if type(stuff) is type(''): return stuff results = [] for item in stuff: if type(item) is type(''): results.append(item) else: results.append(serialize(item)) return join(results, '') def bold(text): result = '' for char in text: result = result + char + '\b' + char return result def section(title, contents): return bold(title) + '\n' + rstrip(indent(contents)) + '\n\n' def indent(text, spaces=4): """Indent text a given number of spaces.""" if type(text) is type([]): text = serialize(text) lines = split(text, '\n') lines = map(lambda line, prefix=' ' * spaces: prefix + line, lines) if lines: lines[-1] = rstrip(lines[-1]) return join(lines, '\n') def classname(object, modname): name = object.__name__ if object.__module__ != modname: name = object.__module__ + '.' + name return name def getdoc(object): result = inspect.getdoc(object) if not result: try: result = inspect.getcomments(object) except: pass return result and rstrip(result) + '\n' or '' # -------------------------------------------------- type-specific routines def document_tree(tree, modname, parent=None, prefix=''): """Render in text a class tree as returned by inspect.getclasstree().""" results = [] for entry in tree: if type(entry) is type(()): c, bases = entry results.append(prefix + classname(c, modname)) if bases and bases != (parent,): parents = map(lambda c, m=modname: classname(c, m), bases) results.append('(%s)' % join(parents, ', ')) results.append('\n') elif type(entry) is type([]): results.append(document_tree(entry, modname, c, prefix + ' ')) return results def document_module(object): """Produce text documentation for a given module object.""" results = [] name = object.__name__ lines = split(strip(getdoc(object)), '\n') if len(lines) == 1: name = name + ' - ' + lines[0] lines = [] elif len(lines) >= 2 and not rstrip(lines[1]): name = name + ' - ' + lines[0] lines = lines[2:] results.append(section('NAME', name)) try: file = inspect.getsourcefile(object) except TypeError: file = None results.append(section('FILE', file or '(built-in)')) if lines: results.append(section('DESCRIPTION', join(lines, '\n'))) classes = [] for key, value in inspect.getmembers(object, inspect.isclass): if (inspect.getmodule(value) or object) is object: classes.append(value) functions = [] for key, value in inspect.getmembers(object, inspect.isroutine): if inspect.isbuiltin(value) or inspect.getmodule(value) is object: functions.append(value) if classes: contents = document_tree( inspect.getclasstree(classes, 1), object.__name__) contents.append('\n') for item in classes: contents.append([document_class(item), '\n']) results.append(section('CLASSES', contents)) if functions: contents = [] for item in functions: contents.append([document_function(item), '\n']) results.append(section('FUNCTIONS', contents)) if hasattr(object, '__version__'): version = object.__version__ if hasattr(object, '__date__'): version = version + ', ' + object.__date__ results.append(section('VERSION', version)) if hasattr(object, '__author__'): author = object.__author__ if hasattr(object, '__email__'): author = author + ' <' + object.__email__ + '>' results.append(section('AUTHOR', author)) return results def document_class(object): """Produce text documentation for a given class object.""" name = object.__name__ bases = object.__bases__ doc = getdoc(object) if doc: results = [doc, '\n'] else: results = [doc] methods = map(lambda (key, value): value, inspect.getmembers(object, inspect.ismethod)) for item in methods: results.append([document_method(item), '\n']) title = 'class ' + bold(name) if bases: parents = map(lambda c, m=object.__module__: classname(c, m), bases) title = title + '(%s)' % join(parents, ', ') return title + '\n' + rstrip(indent(results)) + '\n' def document_method(object): return document_function(object.im_func) def document_function(object): """Produce text documentation for a given function object.""" try: args, varargs, varkw, defaults = inspect.getargspec(object) argspec = inspect.formatargspec(args, varargs, varkw, defaults) except TypeError: argspec = '(...)' if object.__name__ == '': decl = [' ', argspec[1:-1]] else: decl = bold(object.__name__) + argspec doc = getdoc(object) if doc: return decl + '\n' + rstrip(indent(doc)) + '\n' else: return decl + '\n' def document_builtin(object): return [bold(object.__name__) + '(...)\n', rstrip(indent(object.__doc__)) + '\n'] # --------------------------------------------------- main dispatch routine def document(object): """Generate documentation for a given object.""" if inspect.ismodule(object): results = document_module(object) elif inspect.isclass(object): results = document_class(object) elif inspect.ismethod(object): results = document_method(object) elif inspect.isfunction(object): results = document_function(object) elif inspect.isbuiltin(object): results = document_builtin(object) else: raise TypeError, 'don\'t know how to document this kind of object' return serialize(results) From python-dev@python.org Sun Jan 14 02:57:17 2001 From: python-dev@python.org (Fred L. Drake) Date: Sat, 13 Jan 2001 18:57:17 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/ref ref5.tex,1.40,1.41 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/ref In directory usw-pr-cvs1:/tmp/cvs-serv4514/ref Modified Files: ref5.tex Log Message: Fix a variety of minor nits and typos caught by Chris Ryland . Index: ref5.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/ref/ref5.tex,v retrieving revision 1.40 retrieving revision 1.41 diff -C2 -r1.40 -r1.41 *** ref5.tex 2000/12/11 22:39:24 1.40 --- ref5.tex 2001/01/14 02:57:14 1.41 *************** *** 265,271 **** The primary must evaluate to an object of a type that supports ! attribute references, e.g., a module or a list. This object is then ! asked to produce the attribute whose name is the identifier. If this ! attribute is not available, the exception \exception{AttributeError}\exindex{AttributeError} is raised. Otherwise, the type and value of the object produced is determined by --- 265,271 ---- The primary must evaluate to an object of a type that supports ! attribute references, e.g., a module, list, or an instance. This ! object is then asked to produce the attribute whose name is the ! identifier. If this attribute is not available, the exception \exception{AttributeError}\exindex{AttributeError} is raised. Otherwise, the type and value of the object produced is determined by *************** *** 759,769 **** The operators \keyword{in} and \keyword{not in} test for set membership: every type can define membership in whatever way is ! appropriate. Traditionally, this interface has been tightly bound the sequence interface, which is related in that presence in a sequence can be usefully interpreted as membership in a set. ! For the list, tuple types, \code{\var{x} in \var{y}} is true if and only ! if there exists such an index \var{i} such that ! \code{var{x} == \var{y}[\var{i}]} is true. For the Unicode and string types, \code{\var{x} in \var{y}} is true if --- 759,769 ---- The operators \keyword{in} and \keyword{not in} test for set membership: every type can define membership in whatever way is ! appropriate. Traditionally, this interface has been tightly bound to the sequence interface, which is related in that presence in a sequence can be usefully interpreted as membership in a set. ! For the list and tuple types, \code{\var{x} in \var{y}} is true if and ! only if there exists such an index \var{i} such that ! \code{\var{x} == \var{y}[\var{i}]} is true. For the Unicode and string types, \code{\var{x} in \var{y}} is true if From python-dev@python.org Sun Jan 14 05:04:42 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:04:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Misc ACKS,1.69,1.70 Message-ID: Update of /cvsroot/python/python/dist/src/Misc In directory usw-pr-cvs1:/tmp/cvs-serv12914/python/dist/src/misc Modified Files: ACKS Log Message: Added Jeffery Collins. Index: ACKS =================================================================== RCS file: /cvsroot/python/python/dist/src/Misc/ACKS,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -r1.69 -r1.70 *** ACKS 2001/01/03 23:51:26 1.69 --- ACKS 2001/01/14 05:04:40 1.70 *************** *** 70,73 **** --- 70,74 ---- Mike Clarkson Steve Clift + Jeffery Collins Matt Conway Scott Cotton From python-dev@python.org Sun Jan 14 05:05:53 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:05:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.24,1.25 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv12935/python/dist/src/Lib Modified Files: tempfile.py Log Message: SF bug 128713: type(mmap_object) blew up on Linux. Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.24 retrieving revision 1.25 diff -C2 -r1.24 -r1.25 *** tempfile.py 2001/01/13 03:04:02 1.24 --- tempfile.py 2001/01/14 05:05:51 1.25 *************** *** 90,93 **** --- 90,94 ---- template = 'tmp' # XXX might choose a better one + _pidcache = {} def gettempprefix(): """Function to calculate a prefix of the filename to use. *************** *** 97,103 **** """ - global template if template is None: ! return '@' + `os.getpid()` + '.' else: return template --- 98,110 ---- """ if template is None: ! p = os.getpid() ! t = _pidcache.get(p, 0) ! if t: ! return t ! if len(_pidcache) > 100: # stop unbounded growth ! _pidcache.clear() ! t = _pidcache[p] = '@' + `p` + '.' ! return t else: return template From python-dev@python.org Sun Jan 14 05:05:53 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:05:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test/output test_mmap,1.4,1.5 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test/output In directory usw-pr-cvs1:/tmp/cvs-serv12935/python/dist/src/Lib/test/output Modified Files: test_mmap Log Message: SF bug 128713: type(mmap_object) blew up on Linux. Index: test_mmap =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/output/test_mmap,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** test_mmap 2000/09/04 07:34:06 1.4 --- test_mmap 2001/01/14 05:05:51 1.5 *************** *** 1,3 **** --- 1,4 ---- test_mmap + Position of foo: 1.0 pages Length of file: 2.0 pages From python-dev@python.org Sun Jan 14 05:05:53 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:05:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_mmap.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv12935/python/dist/src/Lib/test Modified Files: test_mmap.py Log Message: SF bug 128713: type(mmap_object) blew up on Linux. Index: test_mmap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_mmap.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** test_mmap.py 2000/12/12 23:11:42 1.12 --- test_mmap.py 2001/01/14 05:05:51 1.13 *************** *** 19,22 **** --- 19,24 ---- # Simple sanity checks + + print type(m) # SF bug 128713: segfaulted on Linux print ' Position of foo:', string.find(m, 'foo') / float(PAGESIZE), 'pages' assert string.find(m, 'foo') == PAGESIZE From python-dev@python.org Sun Jan 14 05:05:53 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:05:53 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules mmapmodule.c,2.26,2.27 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv12935/python/dist/src/Modules Modified Files: mmapmodule.c Log Message: SF bug 128713: type(mmap_object) blew up on Linux. Index: mmapmodule.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/mmapmodule.c,v retrieving revision 2.26 retrieving revision 2.27 diff -C2 -r2.26 -r2.27 *** mmapmodule.c 2001/01/10 21:03:32 2.26 --- mmapmodule.c 2001/01/14 05:05:51 2.27 *************** *** 842,848 **** HANDLE fh = 0; - /* Patch the object type */ - mmap_object_type.ob_type = &PyType_Type; - if (!PyArg_ParseTuple(args, "iO|z", --- 842,845 ---- *************** *** 957,960 **** --- 954,961 ---- { PyObject *dict, *module; + + /* Patch the object type */ + mmap_object_type.ob_type = &PyType_Type; + module = Py_InitModule ("mmap", mmap_functions); dict = PyModule_GetDict (module); From python-dev@python.org Sun Jan 14 05:12:42 2001 From: python-dev@python.org (Tim Peters) Date: Sat, 13 Jan 2001 21:12:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib tempfile.py,1.25,1.26 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv13436 Modified Files: tempfile.py Log Message: Reverting a dumb experimental version I checked in by mistake. Index: tempfile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/tempfile.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** tempfile.py 2001/01/14 05:05:51 1.25 --- tempfile.py 2001/01/14 05:12:40 1.26 *************** *** 90,94 **** template = 'tmp' # XXX might choose a better one - _pidcache = {} def gettempprefix(): """Function to calculate a prefix of the filename to use. --- 90,93 ---- *************** *** 98,110 **** """ if template is None: ! p = os.getpid() ! t = _pidcache.get(p, 0) ! if t: ! return t ! if len(_pidcache) > 100: # stop unbounded growth ! _pidcache.clear() ! t = _pidcache[p] = '@' + `p` + '.' ! return t else: return template --- 97,103 ---- """ + global template if template is None: ! return '@' + `os.getpid()` + '.' else: return template From python-dev@python.org Sun Jan 14 11:16:14 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 03:16:14 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help inspect.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv14352 Modified Files: inspect.py Log Message: Add opcode UNPACK_SEQUENCE to getargs for Python 2.0. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/inspect.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** inspect.py 2001/01/14 02:27:10 1.1 --- inspect.py 2001/01/14 11:16:11 1.2 *************** *** 424,428 **** value = ord(code[step]) + ord(code[step+1])*256 step = step + 2 ! if opname == 'UNPACK_TUPLE': remain.append(value) count.append(value) --- 424,428 ---- value = ord(code[step]) + ord(code[step+1])*256 step = step + 2 ! if opname in ['UNPACK_TUPLE', 'UNPACK_SEQUENCE']: remain.append(value) count.append(value) From python-dev@python.org Sun Jan 14 11:39:38 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 03:39:38 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help test_inspect.py,NONE,1.1 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv17596 Added Files: test_inspect.py Log Message: Added test suite for inspect.py. --- NEW FILE: test_inspect.py --- source = '''# line 1 'A module docstring.' import sys, inspect # line 5 # line 7 def spam(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h): eggs(b + d, c + f) # line 11 def eggs(x, y): "A docstring." global fr, st fr = inspect.currentframe() st = inspect.stack() p = x q = y / 0 # line 20 class StupidGit: """A longer, indented docstring.""" # line 27 def abuse(self, a, b, c): """Another \tdocstring containing \ttabs \t """ self.argue(a, b, c) # line 40 def argue(self, a, b, c): try: spam(a, b, c) except: self.ex = sys.exc_info() self.tr = inspect.trace() # line 48 class MalodorousPervert(StupidGit): pass class ParrotDroppings: pass class FesteringGob(MalodorousPervert, ParrotDroppings): pass ''' from test_support import TestFailed, TESTFN import sys, imp, os, string def test(assertion, message, *args): if not assertion: raise TestFailed, message % args import inspect file = open(TESTFN, 'w') file.write(source) file.close() mod = imp.load_source('testmod', TESTFN) def istest(func, exp): obj = eval(exp) test(func(obj), '%s(%s)' % (func.__name__, exp)) for other in [inspect.isbuiltin, inspect.isclass, inspect.iscode, inspect.isframe, inspect.isfunction, inspect.ismethod, inspect.ismodule, inspect.istraceback]: if other is not func: test(not other(obj), 'not %s(%s)' % (other.__name__, exp)) git = mod.StupidGit() try: 1/0 except: tb = sys.exc_traceback istest(inspect.isbuiltin, 'sys.exit') istest(inspect.isbuiltin, '[].append') istest(inspect.isclass, 'mod.StupidGit') istest(inspect.iscode, 'mod.spam.func_code') istest(inspect.isframe, 'tb.tb_frame') istest(inspect.isfunction, 'mod.spam') istest(inspect.ismethod, 'mod.StupidGit.abuse') istest(inspect.ismethod, 'git.argue') istest(inspect.ismodule, 'mod') istest(inspect.istraceback, 'tb') classes = inspect.getmembers(mod, inspect.isclass) test(classes == [('FesteringGob', mod.FesteringGob), ('MalodorousPervert', mod.MalodorousPervert), ('ParrotDroppings', mod.ParrotDroppings), ('StupidGit', mod.StupidGit)], 'class list') tree = inspect.getclasstree(map(lambda x: x[1], classes), 1) test(tree == [(mod.ParrotDroppings, ()), (mod.StupidGit, ()), [(mod.MalodorousPervert, (mod.StupidGit,)), [(mod.FesteringGob, (mod.MalodorousPervert, mod.ParrotDroppings)) ] ] ], 'class tree') functions = inspect.getmembers(mod, inspect.isfunction) test(functions == [('eggs', mod.eggs), ('spam', mod.spam)], 'function list') test(inspect.getdoc(mod) == 'A module docstring.', 'getdoc(mod)') test(inspect.getcomments(mod) == '# line 1\n', 'getcomments(mod)') test(inspect.getmodule(mod.StupidGit) == mod, 'getmodule(mod.StupidGit)') test(inspect.getfile(mod.StupidGit) == TESTFN, 'getfile(mod.StupidGit)') test(inspect.getsourcefile(mod.spam) == TESTFN, 'getsourcefile(mod.spam)') test(inspect.getsourcefile(git.abuse) == TESTFN, 'getsourcefile(git.abuse)') def sourcerange(top, bottom): lines = string.split(source, '\n') return string.join(lines[top-1:bottom], '\n') + '\n' test(inspect.getsource(git.abuse) == sourcerange(29, 39), 'getsource(git.abuse)') test(inspect.getsource(mod.StupidGit) == sourcerange(21, 46), 'getsource(mod.StupidGit)') test(inspect.getdoc(mod.StupidGit) == 'A longer,\n\nindented\n\ndocstring.', 'getdoc(mod.StupidGit)') test(inspect.getdoc(git.abuse) == 'Another\n\ndocstring\n\ncontaining\n\ntabs\n\n', 'getdoc(git.abuse)') test(inspect.getcomments(mod.StupidGit) == '# line 20\n', 'getcomments(mod.StupidGit)') args, varargs, varkw, defaults = inspect.getargspec(mod.eggs) test(args == ['x', 'y'], 'mod.eggs args') test(varargs == None, 'mod.eggs varargs') test(varkw == None, 'mod.eggs varkw') test(defaults == None, 'mod.eggs defaults') test(inspect.formatargspec(args, varargs, varkw, defaults) == '(x, y)', 'mod.eggs formatted argspec') args, varargs, varkw, defaults = inspect.getargspec(mod.spam) test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.spam args') test(varargs == 'g', 'mod.spam varargs') test(varkw == 'h', 'mod.spam varkw') test(defaults == (3, (4, (5,))), 'mod.spam defaults') test(inspect.formatargspec(args, varargs, varkw, defaults) == '(a, b, c, d=3, (e, (f,))=(4, (5,)), *g, **h)', 'mod.spam formatted argspec') git.abuse(7, 8, 9) istest(inspect.istraceback, 'git.ex[2]') istest(inspect.isframe, 'mod.fr') test(len(git.tr) == 2, 'trace()') test(git.tr[0][1:] == ('@test', 9, 'spam', [' eggs(b + d, c + f)\n'], 0), 'trace() row 1') test(git.tr[1][1:] == ('@test', 18, 'eggs', [' q = y / 0\n'], 0), 'trace() row 2') test(len(mod.st) == 5, 'stack()') test(mod.st[0][1:] == ('@test', 16, 'eggs', [' st = inspect.stack()\n'], 0), 'stack() row 1') test(mod.st[1][1:] == ('@test', 9, 'spam', [' eggs(b + d, c + f)\n'], 0), 'stack() row 2') test(mod.st[2][1:] == ('@test', 43, 'argue', [' spam(a, b, c)\n'], 0), 'stack() row 3') test(mod.st[3][1:] == ('@test', 39, 'abuse', [' self.argue(a, b, c)\n'], 0), 'stack() row 4') # row 4 is in test_inspect.py args, varargs, varkw, locals = inspect.getargvalues(mod.fr) test(args == ['x', 'y'], 'mod.fr args') test(varargs == None, 'mod.fr varargs') test(varkw == None, 'mod.fr varkw') test(locals == {'x': 11, 'p': 11, 'y': 14}, 'mod.fr locals') test(inspect.formatargvalues(args, varargs, varkw, locals) == '(x=11, y=14)', 'mod.fr formatted argvalues') args, varargs, varkw, locals = inspect.getargvalues(mod.fr.f_back) test(args == ['a', 'b', 'c', 'd', ['e', ['f']]], 'mod.fr.f_back args') test(varargs == 'g', 'mod.fr.f_back varargs') test(varkw == 'h', 'mod.fr.f_back varkw') test(inspect.formatargvalues(args, varargs, varkw, locals) == '(a=7, b=8, c=9, d=3, (e=4, (f=5,)), *g=(), **h={})', 'mod.fr.f_back formatted argvalues') os.unlink(TESTFN) From python-dev@python.org Sun Jan 14 11:40:40 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 03:40:40 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help htmldoc.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv17865 Modified Files: htmldoc.py Log Message: Display module constants Index: htmldoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/htmldoc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** htmldoc.py 2001/01/14 02:27:10 1.1 --- htmldoc.py 2001/01/14 11:40:38 1.2 *************** *** 4,8 **** __version__ = 'Ka-Ping Yee , 29 May 2000' ! import sys, os, re, inspect from string import join, replace, expandtabs, rstrip --- 4,8 ---- __version__ = 'Ka-Ping Yee , 29 May 2000' ! import sys, os, re, types, inspect from string import join, replace, expandtabs, rstrip *************** *** 179,182 **** --- 179,190 ---- modules = map(cadr, inspect.getmembers(object, inspect.ismodule)) + constants = [] + for key, value in inspect.getmembers(object): + if key[:1] != '_' and type(value) in [types.FloatType, + types.IntType, types.ListType, types.LongType, + types.StringType, types.TupleType, types.TypeType, + types.UnicodeType]: + constants.append((key, value)) + classes, cdict = [], {} for key, value in inspect.getmembers(object, inspect.isclass): *************** *** 222,225 **** --- 230,242 ---- results.append(section('Functions', '#ffffff', '#eeaa77', contents)) + + if constants: + contents = [] + for key, value in constants: + contents.append('
%s = %s' % + (key, htmlrepr(value))) + results.append(section('Constants', + '#ffffff', '#55aa55', contents)) + return results From python-dev@python.org Sun Jan 14 11:49:54 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 03:49:54 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help htmldoc.py,1.2,1.3 textdoc.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv19284 Modified Files: htmldoc.py textdoc.py Log Message: Show constants in documentation pages. Index: htmldoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/htmldoc.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** htmldoc.py 2001/01/14 11:40:38 1.2 --- htmldoc.py 2001/01/14 11:49:50 1.3 *************** *** 162,165 **** --- 162,171 ---- return results + def isconstant(object): + """Check if an object is of a type that probably means it's a constant.""" + return type(object) in [ + types.FloatType, types.IntType, types.ListType, types.LongType, + types.StringType, types.TupleType, types.TypeType, types.UnicodeType] + def document_module(object): """Produce HTML documentation for a given module object.""" *************** *** 179,190 **** modules = map(cadr, inspect.getmembers(object, inspect.ismodule)) - constants = [] - for key, value in inspect.getmembers(object): - if key[:1] != '_' and type(value) in [types.FloatType, - types.IntType, types.ListType, types.LongType, - types.StringType, types.TupleType, types.TypeType, - types.UnicodeType]: - constants.append((key, value)) - classes, cdict = [], {} for key, value in inspect.getmembers(object, inspect.isclass): --- 185,188 ---- *************** *** 198,201 **** --- 196,203 ---- fdict[key] = '#-' + key if inspect.isfunction(value): fdict[value] = fdict[key] + constants = [] + for key, value in inspect.getmembers(object, isconstant): + if key[:1] != '_': + constants.append((key, value)) for c in classes: Index: textdoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/textdoc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** textdoc.py 2001/01/14 02:27:10 1.1 --- textdoc.py 2001/01/14 11:49:50 1.2 *************** *** 3,7 **** __version__ = 'Ka-Ping Yee , 10 Jan 2001' ! import sys, inspect from string import join, split, strip, rstrip --- 3,7 ---- __version__ = 'Ka-Ping Yee , 10 Jan 2001' ! import sys, types, inspect from string import join, split, strip, rstrip *************** *** 64,67 **** --- 64,73 ---- return results + def isconstant(object): + """Check if an object is of a type that probably means it's a constant.""" + return type(object) in [ + types.FloatType, types.IntType, types.ListType, types.LongType, + types.StringType, types.TupleType, types.TypeType, types.UnicodeType] + def document_module(object): """Produce text documentation for a given module object.""" *************** *** 71,78 **** lines = split(strip(getdoc(object)), '\n') if len(lines) == 1: ! name = name + ' - ' + lines[0] lines = [] elif len(lines) >= 2 and not rstrip(lines[1]): ! name = name + ' - ' + lines[0] lines = lines[2:] results.append(section('NAME', name)) --- 77,84 ---- lines = split(strip(getdoc(object)), '\n') if len(lines) == 1: ! if lines[0]: name = name + ' - ' + lines[0] lines = [] elif len(lines) >= 2 and not rstrip(lines[1]): ! if lines[0]: name = name + ' - ' + lines[0] lines = lines[2:] results.append(section('NAME', name)) *************** *** 91,94 **** --- 97,104 ---- if inspect.isbuiltin(value) or inspect.getmodule(value) is object: functions.append(value) + constants = [] + for key, value in inspect.getmembers(object, isconstant): + if key[:1] != '_': + constants.append((key, value)) if classes: *************** *** 105,108 **** --- 115,128 ---- contents.append([document_function(item), '\n']) results.append(section('FUNCTIONS', contents)) + + if constants: + contents = [] + for key, value in constants: + line = key + ' = ' + repr(value) + chop = 70 - len(line) + line = bold(key) + ' = ' + repr(value) + if chop < 0: line = line[:chop] + '...' + contents.append(line + '\n') + results.append(section('CONSTANTS', contents)) if hasattr(object, '__version__'): From python-dev@python.org Sun Jan 14 11:58:20 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 03:58:20 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help inspect.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv20592 Modified Files: inspect.py Log Message: Fix getmodule() to look at __module__ on classes. Index: inspect.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/inspect.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** inspect.py 2001/01/14 11:16:11 1.2 --- inspect.py 2001/01/14 11:58:17 1.3 *************** *** 188,191 **** --- 188,193 ---- def getmodule(object): """Try to guess which module an object was defined in.""" + if isclass(object): + return sys.modules[object.__module__] try: file = getsourcefile(object) From python-dev@python.org Sun Jan 14 14:08:42 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 06:08:42 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib warnings.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv5843 Modified Files: warnings.py Log Message: - Added keyword argument 'append' to filterwarnings(); if true, this appends to list of filters instead of inserting at the front. This is useful to add a filter with a lower priority than -W options. - Cosmetic improvements to a docstring and an error message. Index: warnings.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/warnings.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** warnings.py 2000/12/19 03:04:50 1.2 --- warnings.py 2001/01/14 14:08:40 1.3 *************** *** 86,90 **** def formatwarning(message, category, filename, lineno): ! """Hook to format a warning the standard way.""" import linecache s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) --- 86,90 ---- def formatwarning(message, category, filename, lineno): ! """Function to format a warning the standard way.""" import linecache s = "%s:%s: %s: %s\n" % (filename, lineno, category.__name__, message) *************** *** 94,98 **** return s ! def filterwarnings(action, message="", category=Warning, module="", lineno=0): """Insert an entry into the list of warnings filters (at the front). --- 94,99 ---- return s ! def filterwarnings(action, message="", category=Warning, module="", lineno=0, ! append=0): """Insert an entry into the list of warnings filters (at the front). *************** *** 106,111 **** assert type(lineno) is types.IntType and lineno >= 0, \ "lineno must be an int >= 0" ! filters.insert(0, (action, re.compile(message, re.I), category, ! re.compile(module), lineno)) def resetwarnings(): --- 107,116 ---- assert type(lineno) is types.IntType and lineno >= 0, \ "lineno must be an int >= 0" ! item = (action, re.compile(message, re.I), category, ! re.compile(module), lineno) ! if append: ! filters.append(item) ! else: ! filters.insert(0, item) def resetwarnings(): *************** *** 129,133 **** parts = arg.split(':') if len(parts) > 5: ! raise _OptionError("unparsable -W option %s" % `arg`) while len(parts) < 5: parts.append('') --- 134,138 ---- parts = arg.split(':') if len(parts) > 5: ! raise _OptionError("too many fields (max 5): %s" % `arg`) while len(parts) < 5: parts.append('') From python-dev@python.org Sun Jan 14 14:10:20 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 06:10:20 -0800 Subject: [Python-checkins] CVS: python/dist/src/Doc/lib libwarnings.tex,1.3,1.4 Message-ID: Update of /cvsroot/python/python/dist/src/Doc/lib In directory usw-pr-cvs1:/tmp/cvs-serv6500 Modified Files: libwarnings.tex Log Message: Document filterwarnings(..., append=). Index: libwarnings.tex =================================================================== RCS file: /cvsroot/python/python/dist/src/Doc/lib/libwarnings.tex,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** libwarnings.tex 2001/01/04 05:59:37 1.3 --- libwarnings.tex 2001/01/14 14:10:18 1.4 *************** *** 179,184 **** \begin{funcdesc}{filterwarnings}{action\optional{, message\optional{, category\optional{, ! module\optional{, lineno}}}}} ! Insert an entry into the list of warnings filters (at the front). This checks the types of the arguments, compiles the message and module regular expressions, and inserts them as a tuple in front --- 179,186 ---- \begin{funcdesc}{filterwarnings}{action\optional{, message\optional{, category\optional{, ! module\optional{, lineno\optional{, append}}}}}} ! Insert an entry into the list of warnings filters. The entry is ! inserted at the front by default; if \var{append} is true, it is ! inserted at the end. This checks the types of the arguments, compiles the message and module regular expressions, and inserts them as a tuple in front From python-dev@python.org Sun Jan 14 15:06:13 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 07:06:13 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.47,2.48 sre_constants.h,2.9,2.10 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv26795/Modules Modified Files: _sre.c sre_constants.h Log Message: SRE fixes for 2.1 alpha: -- added some more docstrings -- fixed typo in scanner class (#125531) -- the multiline flag (?m) should't affect the \Z operator (#127259) -- fixed non-greedy backtracking bug (#123769, #127259) -- added sre.DEBUG flag (currently dumps the parsed pattern structure) -- fixed a couple of glitches in groupdict (the #126587 memory leak had already been fixed by AMK) Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.47 retrieving revision 2.48 diff -C2 -r2.47 -r2.48 *** _sre.c 2000/12/22 14:39:10 2.47 --- _sre.c 2001/01/14 15:06:10 2.48 *************** *** 23,28 **** * 2000-10-03 fl fixed assert_not primitive; support keyword arguments * 2000-10-24 fl really fixed assert_not; reset groups in findall * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * This version of the SRE library can be redistributed under CNRI's --- 23,30 ---- * 2000-10-03 fl fixed assert_not primitive; support keyword arguments * 2000-10-24 fl really fixed assert_not; reset groups in findall + * 2000-12-21 fl fixed memory leak in groupdict + * 2001-01-02 fl properly reset pointer after failed assertion in MIN_UNTIL * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * This version of the SRE library can be redistributed under CNRI's *************** *** 356,359 **** --- 358,362 ---- case SRE_AT_BEGINNING: + case SRE_AT_BEGINNING_STRING: return ((void*) ptr == state->beginning); *************** *** 371,374 **** --- 374,380 ---- SRE_IS_LINEBREAK((int) ptr[0])); + case SRE_AT_END_STRING: + return ((void*) ptr == state->end); + case SRE_AT_BOUNDARY: if (state->beginning == state->end) *************** *** 827,831 **** exactly one character wide, and we're not already collecting backtracking points. for other cases, ! use the MAX_REPEAT operator instead */ /* <1=min> <2=max> item tail */ --- 833,837 ---- exactly one character wide, and we're not already collecting backtracking points. for other cases, ! use the MAX_REPEAT operator */ /* <1=min> <2=max> item tail */ *************** *** 901,905 **** case SRE_OP_REPEAT: /* create repeat context. all the hard work is done ! by the UNTIL operator */ /* <1=min> <2=max> item tail */ TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr, --- 907,911 ---- case SRE_OP_REPEAT: /* create repeat context. all the hard work is done ! by the UNTIL operator (MAX_UNTIL, MIN_UNTIL) */ /* <1=min> <2=max> item tail */ TRACE(("|%p|%p|REPEAT %d %d\n", pattern, ptr, *************** *** 975,978 **** --- 981,985 ---- return i; state->repeat = rp; + state->ptr = ptr; return 0; *************** *** 987,991 **** count = rp->count + 1; ! TRACE(("|%p|%p|MIN_UNTIL %d\n", pattern, ptr, count)); state->ptr = ptr; --- 994,999 ---- count = rp->count + 1; ! TRACE(("|%p|%p|MIN_UNTIL %d %p\n", pattern, ptr, count, ! rp->pattern)); state->ptr = ptr; *************** *** 1010,1013 **** --- 1018,1022 ---- return i; } + state->ptr = ptr; state->repeat = rp; *************** *** 1021,1024 **** --- 1030,1034 ---- return i; rp->count = count - 1; + state->ptr = ptr; return 0; *************** *** 1966,1970 **** PyObject* def = Py_None; static char* kwlist[] = { "default", NULL }; ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groups", kwlist, &def)) return NULL; --- 1976,1980 ---- PyObject* def = Py_None; static char* kwlist[] = { "default", NULL }; ! if (!PyArg_ParseTupleAndKeywords(args, kw, "|O:groupdict", kwlist, &def)) return NULL; *************** *** 1974,2001 **** keys = PyMapping_Keys(self->pattern->groupindex); ! if (!keys) { ! Py_DECREF(result); ! return NULL; ! } for (index = 0; index < PyList_GET_SIZE(keys); index++) { PyObject* key; ! PyObject* item; key = PyList_GET_ITEM(keys, index); ! if (!key) { ! Py_DECREF(keys); ! Py_DECREF(result); ! return NULL; ! } ! item = match_getslice(self, key, def); ! if (!item) { Py_DECREF(key); ! Py_DECREF(keys); ! Py_DECREF(result); ! return NULL; } ! /* FIXME: this can fail, right? */ ! PyDict_SetItem(result, key, item); ! Py_DECREF(item); } --- 1984,2006 ---- keys = PyMapping_Keys(self->pattern->groupindex); ! if (!keys) ! goto failed; for (index = 0; index < PyList_GET_SIZE(keys); index++) { + int status; PyObject* key; ! PyObject* value; key = PyList_GET_ITEM(keys, index); ! if (!key) ! goto failed; ! value = match_getslice(self, key, def); ! if (!value) { Py_DECREF(key); ! goto failed; } ! status = PyDict_SetItem(result, key, value); ! Py_DECREF(value); ! if (status < 0) ! goto failed; } *************** *** 2003,2006 **** --- 2008,2016 ---- return result; + + failed: + Py_DECREF(keys); + Py_DECREF(result); + return NULL; } Index: sre_constants.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/sre_constants.h,v retrieving revision 2.9 retrieving revision 2.10 diff -C2 -r2.9 -r2.10 *** sre_constants.h 2000/08/01 22:47:49 2.9 --- sre_constants.h 2001/01/14 15:06:11 2.10 *************** *** 7,11 **** * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. --- 7,11 ---- * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. *************** *** 43,50 **** #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 ! #define SRE_AT_BOUNDARY 2 ! #define SRE_AT_NON_BOUNDARY 3 ! #define SRE_AT_END 4 ! #define SRE_AT_END_LINE 5 #define SRE_CATEGORY_DIGIT 0 #define SRE_CATEGORY_NOT_DIGIT 1 --- 43,52 ---- #define SRE_AT_BEGINNING 0 #define SRE_AT_BEGINNING_LINE 1 ! #define SRE_AT_BEGINNING_STRING 2 ! #define SRE_AT_BOUNDARY 3 ! #define SRE_AT_NON_BOUNDARY 4 ! #define SRE_AT_END 5 ! #define SRE_AT_END_LINE 6 ! #define SRE_AT_END_STRING 7 #define SRE_CATEGORY_DIGIT 0 #define SRE_CATEGORY_NOT_DIGIT 1 From python-dev@python.org Sun Jan 14 15:06:14 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 07:06:14 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.14,1.15 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv26795/Lib/test Modified Files: test_sre.py Log Message: SRE fixes for 2.1 alpha: -- added some more docstrings -- fixed typo in scanner class (#125531) -- the multiline flag (?m) should't affect the \Z operator (#127259) -- fixed non-greedy backtracking bug (#123769, #127259) -- added sre.DEBUG flag (currently dumps the parsed pattern structure) -- fixed a couple of glitches in groupdict (the #126587 memory leak had already been fixed by AMK) Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** test_sre.py 2000/12/12 23:11:42 1.14 --- test_sre.py 2001/01/14 15:06:11 1.15 *************** *** 48,57 **** for i in [0, 8, 16, 32, 64, 127, 128, 255]: ! test(r"""sre.match(r"\%03o" % i, chr(i)) is not None""", 1) ! test(r"""sre.match(r"\%03o0" % i, chr(i)+"0") is not None""", 1) ! test(r"""sre.match(r"\%03o8" % i, chr(i)+"8") is not None""", 1) ! test(r"""sre.match(r"\x%02x" % i, chr(i)) is not None""", 1) ! test(r"""sre.match(r"\x%02x0" % i, chr(i)+"0") is not None""", 1) ! test(r"""sre.match(r"\x%02xz" % i, chr(i)+"z") is not None""", 1) test(r"""sre.match("\911", "")""", None, sre.error) --- 48,57 ---- for i in [0, 8, 16, 32, 64, 127, 128, 255]: ! test(r"""sre.match(r"\%03o" % i, chr(i)) != None""", 1) ! test(r"""sre.match(r"\%03o0" % i, chr(i)+"0") != None""", 1) ! test(r"""sre.match(r"\%03o8" % i, chr(i)+"8") != None""", 1) ! test(r"""sre.match(r"\x%02x" % i, chr(i)) != None""", 1) ! test(r"""sre.match(r"\x%02x0" % i, chr(i)+"0") != None""", 1) ! test(r"""sre.match(r"\x%02xz" % i, chr(i)+"z") != None""", 1) test(r"""sre.match("\911", "")""", None, sre.error) *************** *** 198,206 **** for i in range(0, 256): p = p + chr(i) ! test(r"""sre.match(sre.escape(chr(i)), chr(i)) is not None""", 1) test(r"""sre.match(sre.escape(chr(i)), chr(i)).span()""", (0,1)) pat = sre.compile(sre.escape(p)) ! test(r"""pat.match(p) is not None""", 1) test(r"""pat.match(p).span()""", (0,256)) --- 198,206 ---- for i in range(0, 256): p = p + chr(i) ! test(r"""sre.match(sre.escape(chr(i)), chr(i)) != None""", 1) test(r"""sre.match(sre.escape(chr(i)), chr(i)).span()""", (0,1)) pat = sre.compile(sre.escape(p)) ! test(r"""pat.match(p) != None""", 1) test(r"""pat.match(p).span()""", (0,256)) From python-dev@python.org Sun Jan 14 15:06:14 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 07:06:14 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib sre.py,1.25,1.26 sre_compile.py,1.31,1.32 sre_parse.py,1.38,1.39 sre_constants.py,1.21,1.22 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26795/Lib Modified Files: sre.py sre_compile.py sre_parse.py sre_constants.py Log Message: SRE fixes for 2.1 alpha: -- added some more docstrings -- fixed typo in scanner class (#125531) -- the multiline flag (?m) should't affect the \Z operator (#127259) -- fixed non-greedy backtracking bug (#123769, #127259) -- added sre.DEBUG flag (currently dumps the parsed pattern structure) -- fixed a couple of glitches in groupdict (the #126587 memory leak had already been fixed by AMK) Index: sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** sre.py 2000/09/21 17:03:24 1.25 --- sre.py 2001/01/14 15:06:11 1.26 *************** *** 4,8 **** # re-compatible interface for the sre matching engine # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's --- 4,8 ---- # re-compatible interface for the sre matching engine # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # This version of the SRE library can be redistributed under CNRI's *************** *** 15,20 **** # - # FIXME: change all FIXME's to XXX ;-) - import sre_compile import sre_parse --- 15,18 ---- *************** *** 23,35 **** # flags ! I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE ! L = LOCALE = sre_compile.SRE_FLAG_LOCALE ! M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE ! S = DOTALL = sre_compile.SRE_FLAG_DOTALL ! X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE ! ! # sre extensions (may or may not be in 1.6/2.0 final) ! T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE ! U = UNICODE = sre_compile.SRE_FLAG_UNICODE # sre exception --- 21,34 ---- # flags ! I = IGNORECASE = sre_compile.SRE_FLAG_IGNORECASE # ignore case ! L = LOCALE = sre_compile.SRE_FLAG_LOCALE # assume current 8-bit locale ! U = UNICODE = sre_compile.SRE_FLAG_UNICODE # assume unicode locale ! M = MULTILINE = sre_compile.SRE_FLAG_MULTILINE # make anchors look for newline ! S = DOTALL = sre_compile.SRE_FLAG_DOTALL # make dot match newline ! X = VERBOSE = sre_compile.SRE_FLAG_VERBOSE # ignore whitespace and comments ! ! # sre extensions (experimental, don't rely on these) ! T = TEMPLATE = sre_compile.SRE_FLAG_TEMPLATE # disable backtracking ! DEBUG = sre_compile.SRE_FLAG_DEBUG # dump pattern after compilation # sre exception *************** *** 39,72 **** # public interface - # FIXME: add docstrings - def match(pattern, string, flags=0): return _compile(pattern, flags).match(string) def search(pattern, string, flags=0): return _compile(pattern, flags).search(string) def sub(pattern, repl, string, count=0): return _compile(pattern, 0).sub(repl, string, count) def subn(pattern, repl, string, count=0): return _compile(pattern, 0).subn(repl, string, count) def split(pattern, string, maxsplit=0): return _compile(pattern, 0).split(string, maxsplit) def findall(pattern, string, maxsplit=0): return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): return _compile(pattern, flags) def purge(): _cache.clear() def template(pattern, flags=0): return _compile(pattern, flags|T) def escape(pattern): s = list(pattern) for i in range(len(pattern)): --- 38,95 ---- # public interface def match(pattern, string, flags=0): + """Try to apply the pattern at the start of the string, returning + a match object, or None if no match was found.""" return _compile(pattern, flags).match(string) def search(pattern, string, flags=0): + """Scan through string looking for a match to the pattern, returning + a match object, or None if no match was found.""" return _compile(pattern, flags).search(string) def sub(pattern, repl, string, count=0): + """Return the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in string by the + replacement repl""" return _compile(pattern, 0).sub(repl, string, count) def subn(pattern, repl, string, count=0): + """Return a 2-tuple containing (new_string, number). + new_string is the string obtained by replacing the leftmost + non-overlapping occurrences of the pattern in the source + string by the replacement repl. number is the number of + substitutions that were made.""" return _compile(pattern, 0).subn(repl, string, count) def split(pattern, string, maxsplit=0): + """Split the source string by the occurrences of the pattern, + returning a list containing the resulting substrings.""" return _compile(pattern, 0).split(string, maxsplit) def findall(pattern, string, maxsplit=0): + """Return a list of all non-overlapping matches in the string. + + If one or more groups are present in the pattern, return a + list of groups; this will be a list of tuples if the pattern + has more than one group. + + Empty matches are included in the result.""" return _compile(pattern, 0).findall(string, maxsplit) def compile(pattern, flags=0): + "Compile a regular expression pattern, returning a pattern object." return _compile(pattern, flags) def purge(): + "Clear the regular expression cache" _cache.clear() def template(pattern, flags=0): + "Compile a template pattern, returning a pattern object" + return _compile(pattern, flags|T) def escape(pattern): + "Escape all non-alphanumeric characters in pattern." s = list(pattern) for i in range(len(pattern)): *************** *** 205,209 **** action = self.lexicon[m.lastindex][1] if callable(action): ! self.match = match action = action(self, m.group()) if action is not None: --- 228,232 ---- action = self.lexicon[m.lastindex][1] if callable(action): ! self.match = m action = action(self, m.group()) if action is not None: Index: sre_compile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_compile.py,v retrieving revision 1.31 retrieving revision 1.32 diff -C2 -r1.31 -r1.32 *** sre_compile.py 2000/10/07 17:38:22 1.31 --- sre_compile.py 2001/01/14 15:06:11 1.32 *************** *** 4,8 **** # convert template to internal format # ! # Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. --- 4,8 ---- # convert template to internal format # ! # Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. *************** *** 177,181 **** charmap[i] = 1 elif op is CATEGORY: ! # FIXME: could append to charmap tail return charset # cannot compress except IndexError: --- 177,181 ---- charmap[i] = 1 elif op is CATEGORY: ! # XXX: could append to charmap tail return charset # cannot compress except IndexError: *************** *** 365,369 **** # print code ! # FIXME: get rid of this limitation! assert p.pattern.groups <= 100,\ "sorry, but this version only supports 100 named groups" --- 365,369 ---- # print code ! # XXX: get rid of this limitation! assert p.pattern.groups <= 100,\ "sorry, but this version only supports 100 named groups" Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** sre_parse.py 2000/10/28 19:30:41 1.38 --- sre_parse.py 2001/01/14 15:06:11 1.39 *************** *** 4,8 **** # convert re-style regular expression to sre pattern # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. --- 4,8 ---- # convert re-style regular expression to sre pattern # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. *************** *** 35,39 **** CATEGORIES = { ! r"\A": (AT, AT_BEGINNING), # start of string r"\b": (AT, AT_BOUNDARY), r"\B": (AT, AT_NON_BOUNDARY), --- 35,39 ---- CATEGORIES = { ! r"\A": (AT, AT_BEGINNING_STRING), # start of string r"\b": (AT, AT_BOUNDARY), r"\B": (AT, AT_NON_BOUNDARY), *************** *** 44,48 **** r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), ! r"\Z": (AT, AT_END), # end of string } --- 44,48 ---- r"\w": (IN, [(CATEGORY, CATEGORY_WORD)]), r"\W": (IN, [(CATEGORY, CATEGORY_NOT_WORD)]), ! r"\Z": (AT, AT_END_STRING), # end of string } *************** *** 422,426 **** set.append(code1) ! # FIXME: move set optimization to compiler! if len(set)==1 and set[0][0] is LITERAL: subpattern.append(set[0]) # optimization --- 422,426 ---- set.append(code1) ! # XXX: should move set optimization to compiler! if len(set)==1 and set[0][0] is LITERAL: subpattern.append(set[0]) # optimization *************** *** 428,432 **** subpattern.append((NOT_LITERAL, set[1][1])) # optimization else: ! # FIXME: add charmap optimization subpattern.append((IN, set)) --- 428,432 ---- subpattern.append((NOT_LITERAL, set[1][1])) # optimization else: ! # XXX: should add charmap optimization here subpattern.append((IN, set)) *************** *** 458,462 **** if hi: max = int(hi) ! # FIXME: check that hi >= lo! else: raise error, "not supported" --- 458,462 ---- if hi: max = int(hi) ! # XXX: check that hi >= lo ??? else: raise error, "not supported" *************** *** 602,606 **** raise error, "bogus characters at end of regular expression" ! # p.dump() if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE: --- 602,607 ---- raise error, "bogus characters at end of regular expression" ! if flags & SRE_FLAG_DEBUG: ! p.dump() if not (flags & SRE_FLAG_VERBOSE) and p.pattern.flags & SRE_FLAG_VERBOSE: *************** *** 673,678 **** def expand_template(template, match): ! # FIXME: this is sooooo slow. drop in the slicelist ! # code instead p = [] a = p.append --- 674,678 ---- def expand_template(template, match): ! # XXX: this is sooooo slow. drop in the slicelist code instead p = [] a = p.append Index: sre_constants.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_constants.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** sre_constants.py 2000/10/07 17:38:22 1.21 --- sre_constants.py 2001/01/14 15:06:11 1.22 *************** *** 5,9 **** # run this script to update the _sre include files! # ! # Copyright (c) 1998-2000 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. --- 5,9 ---- # run this script to update the _sre include files! # ! # Copyright (c) 1998-2001 by Secret Labs AB. All rights reserved. # # See the sre.py file for information on usage and redistribution. *************** *** 55,62 **** --- 55,64 ---- AT_BEGINNING = "at_beginning" AT_BEGINNING_LINE = "at_beginning_line" + AT_BEGINNING_STRING = "at_beginning_string" AT_BOUNDARY = "at_boundary" AT_NON_BOUNDARY = "at_non_boundary" AT_END = "at_end" AT_END_LINE = "at_end_line" + AT_END_STRING = "at_end_string" # categories *************** *** 110,115 **** ATCODES = [ ! AT_BEGINNING, AT_BEGINNING_LINE, AT_BOUNDARY, ! AT_NON_BOUNDARY, AT_END, AT_END_LINE ] --- 112,117 ---- ATCODES = [ ! AT_BEGINNING, AT_BEGINNING_LINE, AT_BEGINNING_STRING, AT_BOUNDARY, ! AT_NON_BOUNDARY, AT_END, AT_END_LINE, AT_END_STRING ] *************** *** 179,182 **** --- 181,185 ---- SRE_FLAG_UNICODE = 32 # use unicode locale SRE_FLAG_VERBOSE = 64 # ignore whitespace and comments + SRE_FLAG_DEBUG = 128 # debugging # flags for INFO primitive *************** *** 202,206 **** * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2000 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. --- 205,209 ---- * to change anything in here, edit sre_constants.py and run it. * ! * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. * * See the _sre.c file for information on usage and redistribution. From python-dev@python.org Sun Jan 14 15:15:41 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 07:15:41 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.15,1.16 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv32767/Lib/test Modified Files: test_sre.py Log Message: reapplied Fred's "recommended style" patch... Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** test_sre.py 2001/01/14 15:06:11 1.15 --- test_sre.py 2001/01/14 15:15:37 1.16 *************** *** 48,57 **** for i in [0, 8, 16, 32, 64, 127, 128, 255]: ! test(r"""sre.match(r"\%03o" % i, chr(i)) != None""", 1) ! test(r"""sre.match(r"\%03o0" % i, chr(i)+"0") != None""", 1) ! test(r"""sre.match(r"\%03o8" % i, chr(i)+"8") != None""", 1) ! test(r"""sre.match(r"\x%02x" % i, chr(i)) != None""", 1) ! test(r"""sre.match(r"\x%02x0" % i, chr(i)+"0") != None""", 1) ! test(r"""sre.match(r"\x%02xz" % i, chr(i)+"z") != None""", 1) test(r"""sre.match("\911", "")""", None, sre.error) --- 48,57 ---- for i in [0, 8, 16, 32, 64, 127, 128, 255]: ! test(r"""sre.match(r"\%03o" % i, chr(i)) is not None""", 1) ! test(r"""sre.match(r"\%03o0" % i, chr(i)+"0") is not None""", 1) ! test(r"""sre.match(r"\%03o8" % i, chr(i)+"8") is not None""", 1) ! test(r"""sre.match(r"\x%02x" % i, chr(i)) is not None""", 1) ! test(r"""sre.match(r"\x%02x0" % i, chr(i)+"0") is not None""", 1) ! test(r"""sre.match(r"\x%02xz" % i, chr(i)+"z") is not None""", 1) test(r"""sre.match("\911", "")""", None, sre.error) *************** *** 198,206 **** for i in range(0, 256): p = p + chr(i) ! test(r"""sre.match(sre.escape(chr(i)), chr(i)) != None""", 1) test(r"""sre.match(sre.escape(chr(i)), chr(i)).span()""", (0,1)) pat = sre.compile(sre.escape(p)) ! test(r"""pat.match(p) != None""", 1) test(r"""pat.match(p).span()""", (0,256)) --- 198,206 ---- for i in range(0, 256): p = p + chr(i) ! test(r"""sre.match(sre.escape(chr(i)), chr(i)) is not None""", 1) test(r"""sre.match(sre.escape(chr(i)), chr(i)).span()""", (0,1)) pat = sre.compile(sre.escape(p)) ! test(r"""pat.match(p) is not None""", 1) test(r"""pat.match(p).span()""", (0,256)) From python-dev@python.org Sun Jan 14 18:09:26 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 14 Jan 2001 10:09:26 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib aifc.py,1.38,1.39 anydbm.py,1.7,1.8 asynchat.py,1.7,1.8 asyncore.py,1.7,1.8 atexit.py,1.1,1.2 audiodev.py,1.9,1.10 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv24429/python/dist/src/lib Modified Files: aifc.py anydbm.py asynchat.py asyncore.py atexit.py audiodev.py Log Message: Whitespace standardization. Index: aifc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/aifc.py,v retrieving revision 1.38 retrieving revision 1.39 diff -C2 -r1.38 -r1.39 *** aifc.py 2000/08/17 05:06:49 1.38 --- aifc.py 2001/01/14 18:09:23 1.39 *************** *** 703,707 **** return None return self._markers ! def tell(self): return self._nframeswritten --- 703,707 ---- return None return self._markers ! def tell(self): return self._nframeswritten Index: anydbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/anydbm.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** anydbm.py 1998/04/28 15:23:09 1.7 --- anydbm.py 2001/01/14 18:09:23 1.8 *************** *** 3,13 **** Instead of ! import dbm ! d = dbm.open(file, 'w', 0666) use ! import anydbm ! d = anydbm.open(file, 'w') The returned object is a dbhash, gdbm, dbm or dumbdbm object, --- 3,13 ---- Instead of ! import dbm ! d = dbm.open(file, 'w', 0666) use ! import anydbm ! d = anydbm.open(file, 'w') The returned object is a dbhash, gdbm, dbm or dumbdbm object, *************** *** 20,31 **** It has the following interface (key and data are strings): ! d[key] = data # store data at key (may override data at ! # existing key) ! data = d[key] # retrieve data at key (raise KeyError if no ! # such key) ! del d[key] # delete data stored at key (raises KeyError ! # if no such key) ! flag = d.has_key(key) # true if the key exists ! list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are --- 20,31 ---- It has the following interface (key and data are strings): ! d[key] = data # store data at key (may override data at ! # existing key) ! data = d[key] # retrieve data at key (raise KeyError if no ! # such key) ! del d[key] # delete data stored at key (raises KeyError ! # if no such key) ! flag = d.has_key(key) # true if the key exists ! list = d.keys() # return a list of all existing keys (slow!) Future versions may change the order in which implementations are *************** *** 44,51 **** try: ! class error(Exception): ! pass except: ! error = "anydbm.error" _names = ['dbhash', 'gdbm', 'dbm', 'dumbdbm'] --- 44,51 ---- try: ! class error(Exception): ! pass except: ! error = "anydbm.error" _names = ['dbhash', 'gdbm', 'dbm', 'dumbdbm'] *************** *** 54,86 **** for _name in _names: ! try: ! _mod = __import__(_name) ! except ImportError: ! continue ! if not _defaultmod: ! _defaultmod = _mod ! _errors.append(_mod.error) if not _defaultmod: ! raise ImportError, "no dbm clone found; tried %s" % _names error = tuple(_errors) def open(file, flag = 'r', mode = 0666): ! # guess the type of an existing database ! from whichdb import whichdb ! result=whichdb(file) ! if result is None: ! # db doesn't exist ! if 'c' in flag or 'n' in flag: ! # file doesn't exist and the new ! # flag was used so use default type ! mod = _defaultmod ! else: ! raise error, "need 'c' or 'n' flag to open new db" ! elif result == "": ! # db type cannot be determined ! raise error, "db type could not be determined" ! else: ! mod = __import__(result) ! return mod.open(file, flag, mode) --- 54,86 ---- for _name in _names: ! try: ! _mod = __import__(_name) ! except ImportError: ! continue ! if not _defaultmod: ! _defaultmod = _mod ! _errors.append(_mod.error) if not _defaultmod: ! raise ImportError, "no dbm clone found; tried %s" % _names error = tuple(_errors) def open(file, flag = 'r', mode = 0666): ! # guess the type of an existing database ! from whichdb import whichdb ! result=whichdb(file) ! if result is None: ! # db doesn't exist ! if 'c' in flag or 'n' in flag: ! # file doesn't exist and the new ! # flag was used so use default type ! mod = _defaultmod ! else: ! raise error, "need 'c' or 'n' flag to open new db" ! elif result == "": ! # db type cannot be determined ! raise error, "db type could not be determined" ! else: ! mod = __import__(result) ! return mod.open(file, flag, mode) Index: asynchat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asynchat.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** asynchat.py 2000/09/08 20:30:39 1.7 --- asynchat.py 2001/01/14 18:09:23 1.8 *************** *** 1,11 **** # -*- Mode: Python; tab-width: 4 -*- ! # Id: asynchat.py,v 2.25 1999/11/18 11:01:08 rushing Exp ! # Author: Sam Rushing # ====================================================================== # Copyright 1996 by Sam Rushing ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby --- 1,11 ---- # -*- Mode: Python; tab-width: 4 -*- ! # Id: asynchat.py,v 2.25 1999/11/18 11:01:08 rushing Exp ! # Author: Sam Rushing # ====================================================================== # Copyright 1996 by Sam Rushing ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby *************** *** 16,20 **** # distribution of the software without specific, written prior # permission. ! # # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN --- 16,20 ---- # distribution of the software without specific, written prior # permission. ! # # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN *************** *** 52,273 **** class async_chat (asyncore.dispatcher): ! """This is an abstract class. You must derive from this class, and add ! the two methods collect_incoming_data() and found_terminator()""" ! # these are overridable defaults ! ac_in_buffer_size = 4096 ! ac_out_buffer_size = 4096 ! def __init__ (self, conn=None): ! self.ac_in_buffer = '' ! self.ac_out_buffer = '' ! self.producer_fifo = fifo() ! asyncore.dispatcher.__init__ (self, conn) ! ! def set_terminator (self, term): ! "Set the input delimiter. Can be a fixed string of any length, an integer, or None" ! self.terminator = term ! ! def get_terminator (self): ! return self.terminator ! ! # grab some more data from the socket, ! # throw it to the collector method, ! # check for the terminator, ! # if found, transition to the next state. ! ! def handle_read (self): ! ! try: ! data = self.recv (self.ac_in_buffer_size) ! except socket.error, why: ! self.handle_error() ! return ! ! self.ac_in_buffer = self.ac_in_buffer + data ! ! # Continue to search for self.terminator in self.ac_in_buffer, ! # while calling self.collect_incoming_data. The while loop ! # is necessary because we might read several data+terminator ! # combos with a single recv(1024). ! ! while self.ac_in_buffer: ! lb = len(self.ac_in_buffer) ! terminator = self.get_terminator() ! if terminator is None: ! # no terminator, collect it all ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! elif type(terminator) == type(0): ! # numeric terminator ! n = terminator ! if lb < n: ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! self.terminator = self.terminator - lb ! else: ! self.collect_incoming_data (self.ac_in_buffer[:n]) ! self.ac_in_buffer = self.ac_in_buffer[n:] ! self.terminator = 0 ! self.found_terminator() ! else: ! # 3 cases: ! # 1) end of buffer matches terminator exactly: ! # collect data, transition ! # 2) end of buffer matches some prefix: ! # collect data to the prefix ! # 3) end of buffer does not match any prefix: ! # collect data ! terminator_len = len(terminator) ! index = string.find (self.ac_in_buffer, terminator) ! if index != -1: ! # we found the terminator ! if index > 0: ! # don't bother reporting the empty string (source of subtle bugs) ! self.collect_incoming_data (self.ac_in_buffer[:index]) ! self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] ! # This does the Right Thing if the terminator is changed here. ! self.found_terminator() ! else: ! # check for a prefix of the terminator ! index = find_prefix_at_end (self.ac_in_buffer, terminator) ! if index: ! if index != lb: ! # we found a prefix, collect up to the prefix ! self.collect_incoming_data (self.ac_in_buffer[:-index]) ! self.ac_in_buffer = self.ac_in_buffer[-index:] ! break ! else: ! # no prefix, collect it all ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! ! def handle_write (self): ! self.initiate_send () ! ! def handle_close (self): ! self.close() ! ! def push (self, data): ! self.producer_fifo.push (simple_producer (data)) ! self.initiate_send() ! ! def push_with_producer (self, producer): ! self.producer_fifo.push (producer) ! self.initiate_send() ! ! def readable (self): ! "predicate for inclusion in the readable for select()" ! return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) ! ! def writable (self): ! "predicate for inclusion in the writable for select()" ! # return len(self.ac_out_buffer) or len(self.producer_fifo) or (not self.connected) ! # this is about twice as fast, though not as clear. ! return not ( ! (self.ac_out_buffer is '') and ! self.producer_fifo.is_empty() and ! self.connected ! ) ! ! def close_when_done (self): ! "automatically close this channel once the outgoing queue is empty" ! self.producer_fifo.push (None) ! ! # refill the outgoing buffer by calling the more() method ! # of the first producer in the queue ! def refill_buffer (self): ! _string_type = type('') ! while 1: ! if len(self.producer_fifo): ! p = self.producer_fifo.first() ! # a 'None' in the producer fifo is a sentinel, ! # telling us to close the channel. ! if p is None: ! if not self.ac_out_buffer: ! self.producer_fifo.pop() ! self.close() ! return ! elif type(p) is _string_type: ! self.producer_fifo.pop() ! self.ac_out_buffer = self.ac_out_buffer + p ! return ! data = p.more() ! if data: ! self.ac_out_buffer = self.ac_out_buffer + data ! return ! else: ! self.producer_fifo.pop() ! else: ! return ! ! def initiate_send (self): ! obs = self.ac_out_buffer_size ! # try to refill the buffer ! if (len (self.ac_out_buffer) < obs): ! self.refill_buffer() ! ! if self.ac_out_buffer and self.connected: ! # try to send the buffer ! try: ! num_sent = self.send (self.ac_out_buffer[:obs]) ! if num_sent: ! self.ac_out_buffer = self.ac_out_buffer[num_sent:] ! ! except socket.error, why: ! self.handle_error() ! return ! ! def discard_buffers (self): ! # Emergencies only! ! self.ac_in_buffer = '' ! self.ac_out_buffer = '' ! while self.producer_fifo: ! self.producer_fifo.pop() class simple_producer: ! def __init__ (self, data, buffer_size=512): ! self.data = data ! self.buffer_size = buffer_size ! ! def more (self): ! if len (self.data) > self.buffer_size: ! result = self.data[:self.buffer_size] ! self.data = self.data[self.buffer_size:] ! return result ! else: ! result = self.data ! self.data = '' ! return result class fifo: ! def __init__ (self, list=None): ! if not list: ! self.list = [] ! else: ! self.list = list ! ! def __len__ (self): ! return len(self.list) ! ! def is_empty (self): ! return self.list == [] ! ! def first (self): ! return self.list[0] ! ! def push (self, data): ! self.list.append (data) ! ! def pop (self): ! if self.list: ! result = self.list[0] ! del self.list[0] ! return (1, result) ! else: ! return (0, None) # Given 'haystack', see if any prefix of 'needle' is at its end. This --- 52,273 ---- class async_chat (asyncore.dispatcher): ! """This is an abstract class. You must derive from this class, and add ! the two methods collect_incoming_data() and found_terminator()""" ! # these are overridable defaults ! ac_in_buffer_size = 4096 ! ac_out_buffer_size = 4096 ! def __init__ (self, conn=None): ! self.ac_in_buffer = '' ! self.ac_out_buffer = '' ! self.producer_fifo = fifo() ! asyncore.dispatcher.__init__ (self, conn) ! ! def set_terminator (self, term): ! "Set the input delimiter. Can be a fixed string of any length, an integer, or None" ! self.terminator = term ! ! def get_terminator (self): ! return self.terminator ! ! # grab some more data from the socket, ! # throw it to the collector method, ! # check for the terminator, ! # if found, transition to the next state. ! ! def handle_read (self): ! ! try: ! data = self.recv (self.ac_in_buffer_size) ! except socket.error, why: ! self.handle_error() ! return ! ! self.ac_in_buffer = self.ac_in_buffer + data ! ! # Continue to search for self.terminator in self.ac_in_buffer, ! # while calling self.collect_incoming_data. The while loop ! # is necessary because we might read several data+terminator ! # combos with a single recv(1024). ! ! while self.ac_in_buffer: ! lb = len(self.ac_in_buffer) ! terminator = self.get_terminator() ! if terminator is None: ! # no terminator, collect it all ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! elif type(terminator) == type(0): ! # numeric terminator ! n = terminator ! if lb < n: ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! self.terminator = self.terminator - lb ! else: ! self.collect_incoming_data (self.ac_in_buffer[:n]) ! self.ac_in_buffer = self.ac_in_buffer[n:] ! self.terminator = 0 ! self.found_terminator() ! else: ! # 3 cases: ! # 1) end of buffer matches terminator exactly: ! # collect data, transition ! # 2) end of buffer matches some prefix: ! # collect data to the prefix ! # 3) end of buffer does not match any prefix: ! # collect data ! terminator_len = len(terminator) ! index = string.find (self.ac_in_buffer, terminator) ! if index != -1: ! # we found the terminator ! if index > 0: ! # don't bother reporting the empty string (source of subtle bugs) ! self.collect_incoming_data (self.ac_in_buffer[:index]) ! self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:] ! # This does the Right Thing if the terminator is changed here. ! self.found_terminator() ! else: ! # check for a prefix of the terminator ! index = find_prefix_at_end (self.ac_in_buffer, terminator) ! if index: ! if index != lb: ! # we found a prefix, collect up to the prefix ! self.collect_incoming_data (self.ac_in_buffer[:-index]) ! self.ac_in_buffer = self.ac_in_buffer[-index:] ! break ! else: ! # no prefix, collect it all ! self.collect_incoming_data (self.ac_in_buffer) ! self.ac_in_buffer = '' ! ! def handle_write (self): ! self.initiate_send () ! ! def handle_close (self): ! self.close() ! ! def push (self, data): ! self.producer_fifo.push (simple_producer (data)) ! self.initiate_send() ! ! def push_with_producer (self, producer): ! self.producer_fifo.push (producer) ! self.initiate_send() ! ! def readable (self): ! "predicate for inclusion in the readable for select()" ! return (len(self.ac_in_buffer) <= self.ac_in_buffer_size) ! ! def writable (self): ! "predicate for inclusion in the writable for select()" ! # return len(self.ac_out_buffer) or len(self.producer_fifo) or (not self.connected) ! # this is about twice as fast, though not as clear. ! return not ( ! (self.ac_out_buffer is '') and ! self.producer_fifo.is_empty() and ! self.connected ! ) ! ! def close_when_done (self): ! "automatically close this channel once the outgoing queue is empty" ! self.producer_fifo.push (None) ! ! # refill the outgoing buffer by calling the more() method ! # of the first producer in the queue ! def refill_buffer (self): ! _string_type = type('') ! while 1: ! if len(self.producer_fifo): ! p = self.producer_fifo.first() ! # a 'None' in the producer fifo is a sentinel, ! # telling us to close the channel. ! if p is None: ! if not self.ac_out_buffer: ! self.producer_fifo.pop() ! self.close() ! return ! elif type(p) is _string_type: ! self.producer_fifo.pop() ! self.ac_out_buffer = self.ac_out_buffer + p ! return ! data = p.more() ! if data: ! self.ac_out_buffer = self.ac_out_buffer + data ! return ! else: ! self.producer_fifo.pop() ! else: ! return ! ! def initiate_send (self): ! obs = self.ac_out_buffer_size ! # try to refill the buffer ! if (len (self.ac_out_buffer) < obs): ! self.refill_buffer() ! ! if self.ac_out_buffer and self.connected: ! # try to send the buffer ! try: ! num_sent = self.send (self.ac_out_buffer[:obs]) ! if num_sent: ! self.ac_out_buffer = self.ac_out_buffer[num_sent:] ! ! except socket.error, why: ! self.handle_error() ! return ! ! def discard_buffers (self): ! # Emergencies only! ! self.ac_in_buffer = '' ! self.ac_out_buffer = '' ! while self.producer_fifo: ! self.producer_fifo.pop() class simple_producer: ! def __init__ (self, data, buffer_size=512): ! self.data = data ! self.buffer_size = buffer_size ! ! def more (self): ! if len (self.data) > self.buffer_size: ! result = self.data[:self.buffer_size] ! self.data = self.data[self.buffer_size:] ! return result ! else: ! result = self.data ! self.data = '' ! return result class fifo: ! def __init__ (self, list=None): ! if not list: ! self.list = [] ! else: ! self.list = list ! ! def __len__ (self): ! return len(self.list) ! ! def is_empty (self): ! return self.list == [] ! ! def first (self): ! return self.list[0] ! ! def push (self, data): ! self.list.append (data) ! ! def pop (self): ! if self.list: ! result = self.list[0] ! del self.list[0] ! return (1, result) ! else: ! return (0, None) # Given 'haystack', see if any prefix of 'needle' is at its end. This *************** *** 282,292 **** ##def find_prefix_at_end (haystack, needle): ! ## nl = len(needle) ! ## result = 0 ! ## for i in range (1,nl): ! ## if haystack[-(nl-i):] == needle[:(nl-i)]: ! ## result = nl-i ! ## break ! ## return result # yes, this is about twice as fast, but still seems --- 282,292 ---- ##def find_prefix_at_end (haystack, needle): ! ## nl = len(needle) ! ## result = 0 ! ## for i in range (1,nl): ! ## if haystack[-(nl-i):] == needle[:(nl-i)]: ! ## result = nl-i ! ## break ! ## return result # yes, this is about twice as fast, but still seems *************** *** 299,318 **** def prefix_regex (needle): ! if prefix_cache.has_key (needle): ! return prefix_cache[needle] ! else: ! reg = needle[-1] ! for i in range(1,len(needle)): ! reg = '%c\(%s\)?' % (needle[-(i+1)], reg) ! reg = regex.compile (reg+'$') ! prefix_cache[needle] = reg, len(needle) ! return reg, len(needle) def find_prefix_at_end (haystack, needle): ! reg, length = prefix_regex (needle) ! lh = len(haystack) ! result = reg.search (haystack, max(0,lh-length)) ! if result >= 0: ! return (lh - result) ! else: ! return 0 --- 299,318 ---- def prefix_regex (needle): ! if prefix_cache.has_key (needle): ! return prefix_cache[needle] ! else: ! reg = needle[-1] ! for i in range(1,len(needle)): ! reg = '%c\(%s\)?' % (needle[-(i+1)], reg) ! reg = regex.compile (reg+'$') ! prefix_cache[needle] = reg, len(needle) ! return reg, len(needle) def find_prefix_at_end (haystack, needle): ! reg, length = prefix_regex (needle) ! lh = len(haystack) ! result = reg.search (haystack, max(0,lh-length)) ! if result >= 0: ! return (lh - result) ! else: ! return 0 Index: asyncore.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** asyncore.py 2000/09/11 04:00:46 1.7 --- asyncore.py 2001/01/14 18:09:23 1.8 *************** *** 1,11 **** # -*- Mode: Python -*- ! # Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing # ====================================================================== # Copyright 1996 by Sam Rushing ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby --- 1,11 ---- # -*- Mode: Python -*- ! # Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp # Author: Sam Rushing # ====================================================================== # Copyright 1996 by Sam Rushing ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software and # its documentation for any purpose and without fee is hereby *************** *** 16,20 **** # distribution of the software without specific, written prior # permission. ! # # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN --- 16,20 ---- # distribution of the software without specific, written prior # permission. ! # # SAM RUSHING DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, # INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN *************** *** 29,33 **** There are only two ways to have a program on a single processor do "more ! than one thing at a time". Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without --- 29,33 ---- There are only two ways to have a program on a single processor do "more ! than one thing at a time". Multi-threaded programming is the simplest and most popular way to do it, but there is another very different technique, that lets you have nearly all the advantages of multi-threading, without *************** *** 35,41 **** is largely I/O bound. If your program is CPU bound, then pre-emptive scheduled threads are probably what you really need. Network servers are ! rarely CPU-bound, however. ! If your operating system supports the select() system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking --- 35,41 ---- is largely I/O bound. If your program is CPU bound, then pre-emptive scheduled threads are probably what you really need. Network servers are ! rarely CPU-bound, however. ! If your operating system supports the select() system call in its I/O library (and nearly all do), then you can use it to juggle multiple communication channels at once; doing other work while your I/O is taking *************** *** 44,48 **** control than multi-threaded programming. The module documented here solves many of the difficult problems for you, making the task of building ! sophisticated high-performance network servers and clients a snap. """ --- 44,48 ---- control than multi-threaded programming. The module documented here solves many of the difficult problems for you, making the task of building ! sophisticated high-performance network servers and clients a snap. """ *************** *** 192,196 **** except: ar = 'no self.addr!' ! return '<__repr__ (self) failed for object at %x (addr=%s)>' % (id(self),ar) --- 192,196 ---- except: ar = 'no self.addr!' ! return '<__repr__ (self) failed for object at %x (addr=%s)>' % (id(self),ar) *************** *** 325,329 **** # log and log_info maybe overriden to provide more sophisitcated # logging and warning methods. In general, log is for 'hit' logging ! # and 'log_info' is for informational, warning and error logging. def log (self, message): --- 325,329 ---- # log and log_info maybe overriden to provide more sophisitcated # logging and warning methods. In general, log is for 'hit' logging ! # and 'log_info' is for informational, warning and error logging. def log (self, message): *************** *** 434,438 **** tbinfo.append (( tb.tb_frame.f_code.co_filename, ! tb.tb_frame.f_code.co_name, str(tb.tb_lineno) )) --- 434,438 ---- tbinfo.append (( tb.tb_frame.f_code.co_filename, ! tb.tb_frame.f_code.co_name, str(tb.tb_lineno) )) Index: atexit.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/atexit.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** atexit.py 2000/06/28 15:07:31 1.1 --- atexit.py 2001/01/14 18:09:23 1.2 *************** *** 3,7 **** upon normal program termination. ! One public function, register, is defined. """ --- 3,7 ---- upon normal program termination. ! One public function, register, is defined. """ *************** *** 13,17 **** last in, first out. """ ! while _exithandlers: func, targs, kargs = _exithandlers[-1] --- 13,17 ---- last in, first out. """ ! while _exithandlers: func, targs, kargs = _exithandlers[-1] *************** *** 52,54 **** register(x3, 5, "bar") register(x3, "no kwd args") - --- 52,53 ---- Index: audiodev.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/audiodev.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** audiodev.py 2000/08/17 05:06:49 1.9 --- audiodev.py 2001/01/14 18:09:23 1.10 *************** *** 2,254 **** class error(Exception): ! pass class Play_Audio_sgi: ! # Private instance variables ! ## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \ ! ## params, config, inited_outrate, inited_width, \ ! ## inited_nchannels, port, converter, classinited: private ! ! classinited = 0 ! frameratelist = nchannelslist = sampwidthlist = None ! ! def initclass(self): ! import AL ! self.frameratelist = [ ! (48000, AL.RATE_48000), ! (44100, AL.RATE_44100), ! (32000, AL.RATE_32000), ! (22050, AL.RATE_22050), ! (16000, AL.RATE_16000), ! (11025, AL.RATE_11025), ! ( 8000, AL.RATE_8000), ! ] ! self.nchannelslist = [ ! (1, AL.MONO), ! (2, AL.STEREO), ! (4, AL.QUADRO), ! ] ! self.sampwidthlist = [ ! (1, AL.SAMPLE_8), ! (2, AL.SAMPLE_16), ! (3, AL.SAMPLE_24), ! ] ! self.classinited = 1 ! ! def __init__(self): ! import al, AL ! if not self.classinited: ! self.initclass() ! self.oldparams = [] ! self.params = [AL.OUTPUT_RATE, 0] ! self.config = al.newconfig() ! self.inited_outrate = 0 ! self.inited_width = 0 ! self.inited_nchannels = 0 ! self.converter = None ! self.port = None ! return ! ! def __del__(self): ! if self.port: ! self.stop() ! if self.oldparams: ! import al, AL ! al.setparams(AL.DEFAULT_DEVICE, self.oldparams) ! self.oldparams = [] ! ! def wait(self): ! if not self.port: ! return ! import time ! while self.port.getfilled() > 0: ! time.sleep(0.1) ! self.stop() ! ! def stop(self): ! if self.port: ! self.port.closeport() ! self.port = None ! if self.oldparams: ! import al, AL ! al.setparams(AL.DEFAULT_DEVICE, self.oldparams) ! self.oldparams = [] ! ! def setoutrate(self, rate): ! for (raw, cooked) in self.frameratelist: ! if rate == raw: ! self.params[1] = cooked ! self.inited_outrate = 1 ! break ! else: ! raise error, 'bad output rate' ! ! def setsampwidth(self, width): ! for (raw, cooked) in self.sampwidthlist: ! if width == raw: ! self.config.setwidth(cooked) ! self.inited_width = 1 ! break ! else: ! if width == 0: ! import AL ! self.inited_width = 0 ! self.config.setwidth(AL.SAMPLE_16) ! self.converter = self.ulaw2lin ! else: ! raise error, 'bad sample width' ! ! def setnchannels(self, nchannels): ! for (raw, cooked) in self.nchannelslist: ! if nchannels == raw: ! self.config.setchannels(cooked) ! self.inited_nchannels = 1 ! break ! else: ! raise error, 'bad # of channels' ! ! def writeframes(self, data): ! if not (self.inited_outrate and self.inited_nchannels): ! raise error, 'params not specified' ! if not self.port: ! import al, AL ! self.port = al.openport('Python', 'w', self.config) ! self.oldparams = self.params[:] ! al.getparams(AL.DEFAULT_DEVICE, self.oldparams) ! al.setparams(AL.DEFAULT_DEVICE, self.params) ! if self.converter: ! data = self.converter(data) ! self.port.writesamps(data) ! ! def getfilled(self): ! if self.port: ! return self.port.getfilled() ! else: ! return 0 ! ! def getfillable(self): ! if self.port: ! return self.port.getfillable() ! else: ! return self.config.getqueuesize() ! ! # private methods ! ## if 0: access *: private ! ! def ulaw2lin(self, data): ! import audioop ! return audioop.ulaw2lin(data, 2) class Play_Audio_sun: ! ## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \ ! ## inited_nchannels, converter: private ! def __init__(self): ! self.outrate = 0 ! self.sampwidth = 0 ! self.nchannels = 0 ! self.inited_outrate = 0 ! self.inited_width = 0 ! self.inited_nchannels = 0 ! self.converter = None ! self.port = None ! return ! ! def __del__(self): ! self.stop() ! ! def setoutrate(self, rate): ! self.outrate = rate ! self.inited_outrate = 1 ! ! def setsampwidth(self, width): ! self.sampwidth = width ! self.inited_width = 1 ! ! def setnchannels(self, nchannels): ! self.nchannels = nchannels ! self.inited_nchannels = 1 ! ! def writeframes(self, data): ! if not (self.inited_outrate and self.inited_width and self.inited_nchannels): ! raise error, 'params not specified' ! if not self.port: ! import sunaudiodev, SUNAUDIODEV ! self.port = sunaudiodev.open('w') ! info = self.port.getinfo() ! info.o_sample_rate = self.outrate ! info.o_channels = self.nchannels ! if self.sampwidth == 0: ! info.o_precision = 8 ! self.o_encoding = SUNAUDIODEV.ENCODING_ULAW ! # XXX Hack, hack -- leave defaults ! else: ! info.o_precision = 8 * self.sampwidth ! info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR ! self.port.setinfo(info) ! if self.converter: ! data = self.converter(data) ! self.port.write(data) ! ! def wait(self): ! if not self.port: ! return ! self.port.drain() ! self.stop() ! ! def stop(self): ! if self.port: ! self.port.flush() ! self.port.close() ! self.port = None ! ! def getfilled(self): ! if self.port: ! return self.port.obufcount() ! else: ! return 0 ! def getfillable(self): ! return BUFFERSIZE - self.getfilled() def AudioDev(): ! # Dynamically try to import and use a platform specific module. ! try: ! import al ! except ImportError: ! try: ! import sunaudiodev ! return Play_Audio_sun() ! except ImportError: ! try: ! import Audio_mac ! except ImportError: ! raise error, 'no audio device' ! else: ! return Audio_mac.Play_Audio_mac() ! else: ! return Play_Audio_sgi() def test(fn = None): ! import sys ! if sys.argv[1:]: ! fn = sys.argv[1] ! else: ! fn = 'f:just samples:just.aif' ! import aifc ! af = aifc.open(fn, 'r') ! print fn, af.getparams() ! p = AudioDev() ! p.setoutrate(af.getframerate()) ! p.setsampwidth(af.getsampwidth()) ! p.setnchannels(af.getnchannels()) ! BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels() ! while 1: ! data = af.readframes(BUFSIZ) ! if not data: break ! print len(data) ! p.writeframes(data) ! p.wait() if __name__ == '__main__': ! test() --- 2,254 ---- class error(Exception): ! pass class Play_Audio_sgi: ! # Private instance variables ! ## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \ ! ## params, config, inited_outrate, inited_width, \ ! ## inited_nchannels, port, converter, classinited: private ! ! classinited = 0 ! frameratelist = nchannelslist = sampwidthlist = None ! ! def initclass(self): ! import AL ! self.frameratelist = [ ! (48000, AL.RATE_48000), ! (44100, AL.RATE_44100), ! (32000, AL.RATE_32000), ! (22050, AL.RATE_22050), ! (16000, AL.RATE_16000), ! (11025, AL.RATE_11025), ! ( 8000, AL.RATE_8000), ! ] ! self.nchannelslist = [ ! (1, AL.MONO), ! (2, AL.STEREO), ! (4, AL.QUADRO), ! ] ! self.sampwidthlist = [ ! (1, AL.SAMPLE_8), ! (2, AL.SAMPLE_16), ! (3, AL.SAMPLE_24), ! ] ! self.classinited = 1 ! ! def __init__(self): ! import al, AL ! if not self.classinited: ! self.initclass() ! self.oldparams = [] ! self.params = [AL.OUTPUT_RATE, 0] ! self.config = al.newconfig() ! self.inited_outrate = 0 ! self.inited_width = 0 ! self.inited_nchannels = 0 ! self.converter = None ! self.port = None ! return ! ! def __del__(self): ! if self.port: ! self.stop() ! if self.oldparams: ! import al, AL ! al.setparams(AL.DEFAULT_DEVICE, self.oldparams) ! self.oldparams = [] ! ! def wait(self): ! if not self.port: ! return ! import time ! while self.port.getfilled() > 0: ! time.sleep(0.1) ! self.stop() ! ! def stop(self): ! if self.port: ! self.port.closeport() ! self.port = None ! if self.oldparams: ! import al, AL ! al.setparams(AL.DEFAULT_DEVICE, self.oldparams) ! self.oldparams = [] ! ! def setoutrate(self, rate): ! for (raw, cooked) in self.frameratelist: ! if rate == raw: ! self.params[1] = cooked ! self.inited_outrate = 1 ! break ! else: ! raise error, 'bad output rate' ! ! def setsampwidth(self, width): ! for (raw, cooked) in self.sampwidthlist: ! if width == raw: ! self.config.setwidth(cooked) ! self.inited_width = 1 ! break ! else: ! if width == 0: ! import AL ! self.inited_width = 0 ! self.config.setwidth(AL.SAMPLE_16) ! self.converter = self.ulaw2lin ! else: ! raise error, 'bad sample width' ! ! def setnchannels(self, nchannels): ! for (raw, cooked) in self.nchannelslist: ! if nchannels == raw: ! self.config.setchannels(cooked) ! self.inited_nchannels = 1 ! break ! else: ! raise error, 'bad # of channels' ! ! def writeframes(self, data): ! if not (self.inited_outrate and self.inited_nchannels): ! raise error, 'params not specified' ! if not self.port: ! import al, AL ! self.port = al.openport('Python', 'w', self.config) ! self.oldparams = self.params[:] ! al.getparams(AL.DEFAULT_DEVICE, self.oldparams) ! al.setparams(AL.DEFAULT_DEVICE, self.params) ! if self.converter: ! data = self.converter(data) ! self.port.writesamps(data) ! ! def getfilled(self): ! if self.port: ! return self.port.getfilled() ! else: ! return 0 ! ! def getfillable(self): ! if self.port: ! return self.port.getfillable() ! else: ! return self.config.getqueuesize() ! ! # private methods ! ## if 0: access *: private ! ! def ulaw2lin(self, data): ! import audioop ! return audioop.ulaw2lin(data, 2) class Play_Audio_sun: ! ## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \ ! ## inited_nchannels, converter: private ! def __init__(self): ! self.outrate = 0 ! self.sampwidth = 0 ! self.nchannels = 0 ! self.inited_outrate = 0 ! self.inited_width = 0 ! self.inited_nchannels = 0 ! self.converter = None ! self.port = None ! return ! ! def __del__(self): ! self.stop() ! ! def setoutrate(self, rate): ! self.outrate = rate ! self.inited_outrate = 1 ! ! def setsampwidth(self, width): ! self.sampwidth = width ! self.inited_width = 1 ! ! def setnchannels(self, nchannels): ! self.nchannels = nchannels ! self.inited_nchannels = 1 ! ! def writeframes(self, data): ! if not (self.inited_outrate and self.inited_width and self.inited_nchannels): ! raise error, 'params not specified' ! if not self.port: ! import sunaudiodev, SUNAUDIODEV ! self.port = sunaudiodev.open('w') ! info = self.port.getinfo() ! info.o_sample_rate = self.outrate ! info.o_channels = self.nchannels ! if self.sampwidth == 0: ! info.o_precision = 8 ! self.o_encoding = SUNAUDIODEV.ENCODING_ULAW ! # XXX Hack, hack -- leave defaults ! else: ! info.o_precision = 8 * self.sampwidth ! info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR ! self.port.setinfo(info) ! if self.converter: ! data = self.converter(data) ! self.port.write(data) ! ! def wait(self): ! if not self.port: ! return ! self.port.drain() ! self.stop() ! ! def stop(self): ! if self.port: ! self.port.flush() ! self.port.close() ! self.port = None ! ! def getfilled(self): ! if self.port: ! return self.port.obufcount() ! else: ! return 0 ! def getfillable(self): ! return BUFFERSIZE - self.getfilled() def AudioDev(): ! # Dynamically try to import and use a platform specific module. ! try: ! import al ! except ImportError: ! try: ! import sunaudiodev ! return Play_Audio_sun() ! except ImportError: ! try: ! import Audio_mac ! except ImportError: ! raise error, 'no audio device' ! else: ! return Audio_mac.Play_Audio_mac() ! else: ! return Play_Audio_sgi() def test(fn = None): ! import sys ! if sys.argv[1:]: ! fn = sys.argv[1] ! else: ! fn = 'f:just samples:just.aif' ! import aifc ! af = aifc.open(fn, 'r') ! print fn, af.getparams() ! p = AudioDev() ! p.setoutrate(af.getframerate()) ! p.setsampwidth(af.getsampwidth()) ! p.setnchannels(af.getnchannels()) ! BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels() ! while 1: ! data = af.readframes(BUFSIZ) ! if not data: break ! print len(data) ! p.writeframes(data) ! p.wait() if __name__ == '__main__': ! test() From python-dev@python.org Sun Jan 14 21:00:46 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 13:00:46 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib sre_parse.py,1.39,1.40 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11051/Lib Modified Files: sre_parse.py Log Message: SRE: stricter pattern syntax checking (covers parts of bug #115900) Index: sre_parse.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/sre_parse.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** sre_parse.py 2001/01/14 15:06:11 1.39 --- sre_parse.py 2001/01/14 21:00:44 1.40 *************** *** 9,12 **** --- 9,14 ---- # + # XXX: show string offset and offending character for all errors + import string, sys *************** *** 411,419 **** code2 = LITERAL, ord(this) if code1[0] != LITERAL or code2[0] != LITERAL: ! raise error, "illegal range" lo = code1[1] hi = code2[1] if hi < lo: ! raise error, "illegal range" set.append((RANGE, (lo, hi))) else: --- 413,421 ---- code2 = LITERAL, ord(this) if code1[0] != LITERAL or code2[0] != LITERAL: ! raise error, "bad character range" lo = code1[1] hi = code2[1] if hi < lo: ! raise error, "bad character range" set.append((RANGE, (lo, hi))) else: *************** *** 458,462 **** if hi: max = int(hi) ! # XXX: check that hi >= lo ??? else: raise error, "not supported" --- 460,465 ---- if hi: max = int(hi) ! if max < min: ! raise error, "bad repeat interval" else: raise error, "not supported" *************** *** 466,469 **** --- 469,474 ---- else: raise error, "nothing to repeat" + if item[0][0] in (MIN_REPEAT, MAX_REPEAT): + raise error, "multiple repeat" if source.match("?"): subpattern[-1] = (MIN_REPEAT, (min, max, item)) *************** *** 494,498 **** group = 1 if not isname(name): ! raise error, "illegal character in group name" elif source.match("="): # named backreference --- 499,503 ---- group = 1 if not isname(name): ! raise error, "bad character in group name" elif source.match("="): # named backreference *************** *** 506,510 **** name = name + char if not isname(name): ! raise error, "illegal character in group name" gid = state.groupdict.get(name) if gid is None: --- 511,515 ---- name = name + char if not isname(name): ! raise error, "bad character in group name" gid = state.groupdict.get(name) if gid is None: *************** *** 548,551 **** --- 553,558 ---- else: # flags + if not FLAGS.has_key(source.next): + raise error, "unexpected end of pattern" while FLAGS.has_key(source.next): state.flags = state.flags | FLAGS[source.get()] *************** *** 566,570 **** while 1: char = source.get() ! if char is None or char == ")": break raise error, "unknown extension" --- 573,579 ---- while 1: char = source.get() ! if char is None: ! raise error, "unexpected end of pattern" ! if char == ")": break raise error, "unknown extension" *************** *** 593,596 **** --- 602,606 ---- pattern = Pattern() pattern.flags = flags + pattern.str = str p = _parse_sub(source, pattern, 0) *************** *** 640,644 **** except ValueError: if not isname(name): ! raise error, "illegal character in group name" try: index = pattern.groupindex[name] --- 650,654 ---- except ValueError: if not isname(name): ! raise error, "bad character in group name" try: index = pattern.groupindex[name] From python-dev@python.org Sun Jan 14 21:03:03 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 13:03:03 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib httplib.py,1.28,1.29 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv11923 Modified Files: httplib.py Log Message: SF Patch #103232 by dougfort: Preserve Nonstandard Port Number in Host Header Dougfort's comments: httplib does not include ':port ' in the HTTP 1.1 'Host:' header. This causes problems if the server is not listening on Port 80. The test case I use is the login to /manage under Zope, with Zope listening on port 8080. Zope returns a with the source URLs lacking the :8080. Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.28 retrieving revision 1.29 diff -C2 -r1.28 -r1.29 *** httplib.py 2001/01/13 19:16:21 1.28 --- httplib.py 2001/01/14 21:03:01 1.29 *************** *** 442,446 **** # themselves. we should NOT issue it twice; some web servers (such # as Apache) barf when they see two Host: headers ! self.putheader('Host', self.host) # note: we are assuming that clients will not attempt to set these --- 442,451 ---- # themselves. we should NOT issue it twice; some web servers (such # as Apache) barf when they see two Host: headers ! ! # if we need a non-standard port,include it in the header ! if self.port == HTTP_PORT: ! self.putheader('Host', self.host) ! else: ! self.putheader('Host', "%s:%s" % (self.host, self.port)) # note: we are assuming that clients will not attempt to set these From python-dev@python.org Sun Jan 14 21:48:14 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 13:48:14 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help pydoc.py,1.1,1.2 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv16819 Modified Files: pydoc.py Log Message: Look for both __init__.py and __init__.pyc. Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/pydoc.py,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -r1.1 -r1.2 *** pydoc.py 2001/01/14 02:27:10 1.1 --- pydoc.py 2001/01/14 21:48:12 1.2 *************** *** 45,49 **** path = os.path.join(dir, entry) init = os.path.join(path, '__init__.py') ! if os.path.isdir(path) and os.path.exists(init): results.extend(map( lambda (m, s), pkg=entry: (pkg + '.' + m, s), index(path))) --- 45,50 ---- path = os.path.join(dir, entry) init = os.path.join(path, '__init__.py') ! initc = os.path.join(path, '__init__.pyc') ! if os.path.isfile(init) or os.path.isfile(initc): results.extend(map( lambda (m, s), pkg=entry: (pkg + '.' + m, s), index(path))) From python-dev@python.org Sun Jan 14 21:48:26 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 13:48:26 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help htmldoc.py,1.3,1.4 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv16861 Modified Files: htmldoc.py Log Message: Show packages in index. Index: htmldoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/htmldoc.py,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -r1.3 -r1.4 *** htmldoc.py 2001/01/14 11:49:50 1.3 --- htmldoc.py 2001/01/14 21:48:24 1.4 *************** *** 107,110 **** --- 107,121 ---- return name + def modpkglink((name, ispackage, path)): + if path: + url = '%s.%s.html' % (path, name) + else: + url = '%s.html' % name + if ispackage: + text = '%s (package)' % name + else: + text = name + return '%s' % (url, text) + def modulelink(object): return '%s' % (object.__name__, object.__name__) *************** *** 214,219 **** else: doc = '

no doc string\n' results.append(doc) ! if modules: contents = multicolumn(modules, modulelink) results.append(section('Modules', --- 225,252 ---- else: doc = '

no doc string\n' results.append(doc) + + if hasattr(object, '__path__'): + modpkgs = [] + modnames = [] + for file in os.listdir(object.__path__[0]): + if file[:1] != '_': + path = os.path.join(object.__path__[0], file) + if file[-3:] == '.py' and file[:-3] not in modnames: + modpkgs.append((file[:-3], 0, name)) + modnames.append(file[:-3]) + elif file[-4:] == '.pyc' and file[:-4] not in modnames: + modpkgs.append((file[:-4], 0, name)) + modnames.append(file[:-4]) + elif os.path.isdir(path): + init = os.path.join(path, '__init__.py') + initc = os.path.join(path, '__init__.pyc') + if os.path.isfile(init) or os.path.isfile(initc): + modpkgs.append((file, 1, name)) + modpkgs.sort() + contents = multicolumn(modpkgs, modpkglink) + results.append(section('Package Contents', + '#ffffff', '#aa55cc', contents)) ! elif modules: contents = multicolumn(modules, modulelink) results.append(section('Modules', *************** *** 319,341 **** def index(dir): ! modules = [] ! packages = [] for file in os.listdir(dir): ! path = dir + '/' + file ! if os.path.isfile(path): ! if file[-3:] == '.py': ! modules.append(file[:-3]) ! elif file[-11:] == 'module.so': ! modules.append(file[:-11]) ! elif file[-13:] == 'module.so.1': ! modules.append(file[:-13]) ! elif os.path.isdir(path): ! if os.path.exists(path + '/__init__.py'): ! packages.append(file) ! ! def modulelink(name): ! return '%s' % (name, name) ! modules.sort() ! contents = multicolumn(modules, modulelink) results = section('%s' % dir, '#ffffff', '#ee77aa', contents) --- 352,379 ---- def index(dir): ! modpkgs = [] ! modnames = [] for file in os.listdir(dir): ! if file[:1] != '_': ! path = os.path.join(dir, file) ! if os.path.isfile(path): ! if file[-3:] == '.py' and file[:-3] not in modnames: ! modpkgs.append((file[:-3], 0, '')) ! modnames.append(file[:-3]) ! elif file[-4:] == '.pyc' and file[:-4] not in modnames: ! modpkgs.append((file[:-4], 0, '')) ! modnames.append(file[:-4]) ! elif file[-11:] == 'module.so': ! modpkgs.append((file[:-11], 0, '')) ! elif file[-13:] == 'module.so.1': ! modpkgs.append((file[:-13], 0, '')) ! elif os.path.isdir(path): ! init = os.path.join(path, '__init__.py') ! initc = os.path.join(path, '__init__.pyc') ! if os.path.isfile(init) or os.path.isfile(initc): ! modpkgs.append((file, 1, '')) ! ! modpkgs.sort() ! contents = multicolumn(modpkgs, modpkglink) results = section('%s' % dir, '#ffffff', '#ee77aa', contents) *************** *** 348,358 **** if os.path.isdir(arg): for file in os.listdir(arg): ! if file[-3:] == '.py': modnames.append(file[:-3]) elif file[-9:] == 'module.so': modnames.append(file[:-9]) else: ! if arg[-3:] == '.py': modnames.append(arg[:-3]) else: modnames.append(arg) --- 386,400 ---- if os.path.isdir(arg): for file in os.listdir(arg): ! if file[-3:] == '.py' and file[:-3] not in modnames: modnames.append(file[:-3]) + elif file[-4:] == '.pyc' and file[:-4] not in modnames: + modnames.append(file[:-4]) elif file[-9:] == 'module.so': modnames.append(file[:-9]) else: ! if arg[-3:] == '.py' and file[:-3] not in modnames: modnames.append(arg[:-3]) + elif arg[-4:] == '.pyc' and file[:-4] not in modnames: + modnames.append(arg[:-4]) else: modnames.append(arg) From python-dev@python.org Sun Jan 14 21:54:22 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 14 Jan 2001 13:54:22 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib BaseHTTPServer.py,1.11,1.12 bdb.py,1.27,1.28 binhex.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv17934/python/dist/src/lib Modified Files: BaseHTTPServer.py bdb.py binhex.py Log Message: Whitespace normalization. Index: BaseHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/BaseHTTPServer.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** BaseHTTPServer.py 2000/08/16 20:30:21 1.11 --- BaseHTTPServer.py 2001/01/14 21:54:20 1.12 *************** *** 33,61 **** # Log files # --------- ! # # Here's a quote from the NCSA httpd docs about log file format. ! # ! # | The logfile format is as follows. Each line consists of: ! # | ! # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb ! # | ! # | host: Either the DNS name or the IP number of the remote client # | rfc931: Any information returned by identd for this person, ! # | - otherwise. # | authuser: If user sent a userid for authentication, the user name, ! # | - otherwise. ! # | DD: Day ! # | Mon: Month (calendar name) ! # | YYYY: Year ! # | hh: hour (24-hour format, the machine's timezone) ! # | mm: minutes ! # | ss: seconds ! # | request: The first line of the HTTP request as sent by the client. ! # | ddd: the status code returned by the server, - if not available. # | bbbb: the total number of bytes sent, ! # | *not including the HTTP/1.0 header*, - if not available ! # | # | You can determine the name of the file accessed through request. ! # # (Actually, the latter is only true if you know the server configuration # at the time the request was made!) --- 33,61 ---- # Log files # --------- ! # # Here's a quote from the NCSA httpd docs about log file format. ! # ! # | The logfile format is as follows. Each line consists of: ! # | ! # | host rfc931 authuser [DD/Mon/YYYY:hh:mm:ss] "request" ddd bbbb ! # | ! # | host: Either the DNS name or the IP number of the remote client # | rfc931: Any information returned by identd for this person, ! # | - otherwise. # | authuser: If user sent a userid for authentication, the user name, ! # | - otherwise. ! # | DD: Day ! # | Mon: Month (calendar name) ! # | YYYY: Year ! # | hh: hour (24-hour format, the machine's timezone) ! # | mm: minutes ! # | ss: seconds ! # | request: The first line of the HTTP request as sent by the client. ! # | ddd: the status code returned by the server, - if not available. # | bbbb: the total number of bytes sent, ! # | *not including the HTTP/1.0 header*, - if not available ! # | # | You can determine the name of the file accessed through request. ! # # (Actually, the latter is only true if you know the server configuration # at the time the request was made!) *************** *** 430,434 **** 203: ('Partial information', 'Request fulfilled from cache'), 204: ('No response', 'Request fulfilled, nothing follows'), ! 301: ('Moved', 'Object moved permanently -- see URI list'), 302: ('Found', 'Object moved temporarily -- see URI list'), --- 430,434 ---- 203: ('Partial information', 'Request fulfilled from cache'), 204: ('No response', 'Request fulfilled, nothing follows'), ! 301: ('Moved', 'Object moved permanently -- see URI list'), 302: ('Found', 'Object moved temporarily -- see URI list'), *************** *** 436,440 **** 304: ('Not modified', 'Document has not changed singe given time'), ! 400: ('Bad request', 'Bad request syntax or unsupported method'), --- 436,440 ---- 304: ('Not modified', 'Document has not changed singe given time'), ! 400: ('Bad request', 'Bad request syntax or unsupported method'), *************** *** 446,450 **** 'Request forbidden -- authorization will not help'), 404: ('Not found', 'Nothing matches the given URI'), ! 500: ('Internal error', 'Server got itself in trouble'), 501: ('Not implemented', --- 446,450 ---- 'Request forbidden -- authorization will not help'), 404: ('Not found', 'Nothing matches the given URI'), ! 500: ('Internal error', 'Server got itself in trouble'), 501: ('Not implemented', *************** *** 454,458 **** 503: ('Gateway timeout', 'The gateway server did not receive a timely response'), ! } --- 454,458 ---- 503: ('Gateway timeout', 'The gateway server did not receive a timely response'), ! } Index: bdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/bdb.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** bdb.py 2000/02/02 15:10:14 1.27 --- bdb.py 2001/01/14 21:54:20 1.28 *************** *** 9,13 **** class Bdb: ! """Generic Python debugger base class. --- 9,13 ---- class Bdb: ! """Generic Python debugger base class. *************** *** 27,31 **** self.fncache[filename] = canonic return canonic ! def reset(self): import linecache --- 27,31 ---- self.fncache[filename] = canonic return canonic ! def reset(self): import linecache *************** *** 35,39 **** self.returnframe = None self.quitting = 0 ! def trace_dispatch(self, frame, event, arg): if self.quitting: --- 35,39 ---- self.returnframe = None self.quitting = 0 ! def trace_dispatch(self, frame, event, arg): if self.quitting: *************** *** 49,53 **** print 'bdb.Bdb.dispatch: unknown debugging event:', `event` return self.trace_dispatch ! def dispatch_line(self, frame): if self.stop_here(frame) or self.break_here(frame): --- 49,53 ---- print 'bdb.Bdb.dispatch: unknown debugging event:', `event` return self.trace_dispatch ! def dispatch_line(self, frame): if self.stop_here(frame) or self.break_here(frame): *************** *** 55,59 **** if self.quitting: raise BdbQuit return self.trace_dispatch ! def dispatch_call(self, frame, arg): # XXX 'arg' is no longer used --- 55,59 ---- if self.quitting: raise BdbQuit return self.trace_dispatch ! def dispatch_call(self, frame, arg): # XXX 'arg' is no longer used *************** *** 68,77 **** if self.quitting: raise BdbQuit return self.trace_dispatch ! def dispatch_return(self, frame, arg): if self.stop_here(frame) or frame == self.returnframe: self.user_return(frame, arg) if self.quitting: raise BdbQuit ! def dispatch_exception(self, frame, arg): if self.stop_here(frame): --- 68,77 ---- if self.quitting: raise BdbQuit return self.trace_dispatch ! def dispatch_return(self, frame, arg): if self.stop_here(frame) or frame == self.returnframe: self.user_return(frame, arg) if self.quitting: raise BdbQuit ! def dispatch_exception(self, frame, arg): if self.stop_here(frame): *************** *** 79,87 **** if self.quitting: raise BdbQuit return self.trace_dispatch ! # Normally derived classes don't override the following # methods, but they may if they want to redefine the # definition of stopping and breakpoints. ! def stop_here(self, frame): if self.stopframe is None: --- 79,87 ---- if self.quitting: raise BdbQuit return self.trace_dispatch ! # Normally derived classes don't override the following # methods, but they may if they want to redefine the # definition of stopping and breakpoints. ! def stop_here(self, frame): if self.stopframe is None: *************** *** 111,143 **** else: return 0 ! def break_anywhere(self, frame): return self.breaks.has_key( self.canonic(frame.f_code.co_filename)) ! # Derived classes should override the user_* methods # to gain control. ! def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" pass ! def user_line(self, frame): """This method is called when we stop or break at this line.""" pass ! def user_return(self, frame, return_value): """This method is called when a return trap is set here.""" pass ! def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): """This method is called if an exception occurs, but only if we are to stop at or just below this level.""" pass ! # Derived classes and clients can call the following methods # to affect the stepping state. ! def set_step(self): """Stop after one line of code.""" --- 111,143 ---- else: return 0 ! def break_anywhere(self, frame): return self.breaks.has_key( self.canonic(frame.f_code.co_filename)) ! # Derived classes should override the user_* methods # to gain control. ! def user_call(self, frame, argument_list): """This method is called when there is the remote possibility that we ever need to stop in this function.""" pass ! def user_line(self, frame): """This method is called when we stop or break at this line.""" pass ! def user_return(self, frame, return_value): """This method is called when a return trap is set here.""" pass ! def user_exception(self, frame, (exc_type, exc_value, exc_traceback)): """This method is called if an exception occurs, but only if we are to stop at or just below this level.""" pass ! # Derived classes and clients can call the following methods # to affect the stepping state. ! def set_step(self): """Stop after one line of code.""" *************** *** 145,149 **** self.returnframe = None self.quitting = 0 ! def set_next(self, frame): """Stop on the next line in or below the given frame.""" --- 145,149 ---- self.returnframe = None self.quitting = 0 ! def set_next(self, frame): """Stop on the next line in or below the given frame.""" *************** *** 151,155 **** self.returnframe = None self.quitting = 0 ! def set_return(self, frame): """Stop when returning from the given frame.""" --- 151,155 ---- self.returnframe = None self.quitting = 0 ! def set_return(self, frame): """Stop when returning from the given frame.""" *************** *** 157,161 **** self.returnframe = frame self.quitting = 0 ! def set_trace(self): """Start debugging from here.""" --- 157,161 ---- self.returnframe = frame self.quitting = 0 ! def set_trace(self): """Start debugging from here.""" *************** *** 187,191 **** del frame.f_trace frame = frame.f_back ! def set_quit(self): self.stopframe = self.botframe --- 187,191 ---- del frame.f_trace frame = frame.f_back ! def set_quit(self): self.stopframe = self.botframe *************** *** 193,197 **** self.quitting = 1 sys.settrace(None) ! # Derived classes and clients can call the following methods # to manipulate breakpoints. These methods return an --- 193,197 ---- self.quitting = 1 sys.settrace(None) ! # Derived classes and clients can call the following methods # to manipulate breakpoints. These methods return an *************** *** 200,204 **** # Call self.get_*break*() to see the breakpoints or better # for bp in Breakpoint.bpbynumber: if bp: bp.bpprint(). ! def set_break(self, filename, lineno, temporary=0, cond = None): filename = self.canonic(filename) --- 200,204 ---- # Call self.get_*break*() to see the breakpoints or better # for bp in Breakpoint.bpbynumber: if bp: bp.bpprint(). ! def set_break(self, filename, lineno, temporary=0, cond = None): filename = self.canonic(filename) *************** *** 230,234 **** if not self.breaks[filename]: del self.breaks[filename] ! def clear_bpbynumber(self, arg): try: --- 230,234 ---- if not self.breaks[filename]: del self.breaks[filename] ! def clear_bpbynumber(self, arg): try: *************** *** 253,257 **** bp.deleteMe() del self.breaks[filename] ! def clear_all_breaks(self): if not self.breaks: --- 253,257 ---- bp.deleteMe() del self.breaks[filename] ! def clear_all_breaks(self): if not self.breaks: *************** *** 261,270 **** bp.deleteMe() self.breaks = {} ! def get_break(self, filename, lineno): filename = self.canonic(filename) return self.breaks.has_key(filename) and \ lineno in self.breaks[filename] ! def get_breaks(self, filename, lineno): filename = self.canonic(filename) --- 261,270 ---- bp.deleteMe() self.breaks = {} ! def get_break(self, filename, lineno): filename = self.canonic(filename) return self.breaks.has_key(filename) and \ lineno in self.breaks[filename] ! def get_breaks(self, filename, lineno): filename = self.canonic(filename) *************** *** 272,276 **** lineno in self.breaks[filename] and \ Breakpoint.bplist[filename, lineno] or [] ! def get_file_breaks(self, filename): filename = self.canonic(filename) --- 272,276 ---- lineno in self.breaks[filename] and \ Breakpoint.bplist[filename, lineno] or [] ! def get_file_breaks(self, filename): filename = self.canonic(filename) *************** *** 279,289 **** else: return [] ! def get_all_breaks(self): return self.breaks ! # Derived classes and clients can call the following method # to get a data structure representing a stack trace. ! def get_stack(self, f, t): stack = [] --- 279,289 ---- else: return [] ! def get_all_breaks(self): return self.breaks ! # Derived classes and clients can call the following method # to get a data structure representing a stack trace. ! def get_stack(self, f, t): stack = [] *************** *** 301,307 **** t = t.tb_next return stack, i ! ! # ! def format_stack_entry(self, frame_lineno, lprefix=': '): import linecache, repr, string --- 301,307 ---- t = t.tb_next return stack, i ! ! # ! def format_stack_entry(self, frame_lineno, lprefix=': '): import linecache, repr, string *************** *** 328,335 **** if line: s = s + lprefix + string.strip(line) return s ! # The following two methods can be called by clients to use # a debugger to debug a statement, given as a string. ! def run(self, cmd, globals=None, locals=None): if globals is None: --- 328,335 ---- if line: s = s + lprefix + string.strip(line) return s ! # The following two methods can be called by clients to use # a debugger to debug a statement, given as a string. ! def run(self, cmd, globals=None, locals=None): if globals is None: *************** *** 350,354 **** self.quitting = 1 sys.settrace(None) ! def runeval(self, expr, globals=None, locals=None): if globals is None: --- 350,354 ---- self.quitting = 1 sys.settrace(None) ! def runeval(self, expr, globals=None, locals=None): if globals is None: *************** *** 435,440 **** else: self.bplist[file, line] = [self] - def deleteMe(self): index = (self.file, self.line) --- 435,440 ---- else: self.bplist[file, line] = [self] + def deleteMe(self): index = (self.file, self.line) *************** *** 453,463 **** def bpprint(self): if self.temporary: ! disp = 'del ' else: ! disp = 'keep ' if self.enabled: ! disp = disp + 'yes' else: ! disp = disp + 'no ' print '%-4dbreakpoint %s at %s:%d' % (self.number, disp, self.file, self.line) --- 453,463 ---- def bpprint(self): if self.temporary: ! disp = 'del ' else: ! disp = 'keep ' if self.enabled: ! disp = disp + 'yes' else: ! disp = disp + 'no ' print '%-4dbreakpoint %s at %s:%d' % (self.number, disp, self.file, self.line) *************** *** 507,511 **** try: val = eval(b.cond, frame.f_globals, ! frame.f_locals) if val: if b.ignore > 0: --- 507,511 ---- try: val = eval(b.cond, frame.f_globals, ! frame.f_locals) if val: if b.ignore > 0: *************** *** 519,523 **** # if eval fails, most conservative # thing is to stop on breakpoint ! # regardless of ignore count. # Don't delete temporary, # as another hint to user. --- 519,523 ---- # if eval fails, most conservative # thing is to stop on breakpoint ! # regardless of ignore count. # Don't delete temporary, # as another hint to user. Index: binhex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/binhex.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** binhex.py 2000/12/12 23:20:44 1.16 --- binhex.py 2001/01/14 21:54:20 1.17 *************** *** 27,31 **** import string import binascii ! class Error(Exception): pass --- 27,31 ---- import string import binascii ! class Error(Exception): pass *************** *** 52,59 **** # Backward compatibility openrf = open ! def FInfo(): return macfs.FInfo() ! def getfileinfo(name): finfo = macfs.FSSpec(name).GetFInfo() --- 52,59 ---- # Backward compatibility openrf = open ! def FInfo(): return macfs.FInfo() ! def getfileinfo(name): finfo = macfs.FSSpec(name).GetFInfo() *************** *** 67,71 **** rlen = fp.tell() return file, finfo, dlen, rlen ! def openrsrc(name, *mode): if not mode: --- 67,71 ---- rlen = fp.tell() return file, finfo, dlen, rlen ! def openrsrc(name, *mode): if not mode: *************** *** 79,83 **** # Glue code for non-macintosh usage # ! class FInfo: def __init__(self): --- 79,83 ---- # Glue code for non-macintosh usage # ! class FInfo: def __init__(self): *************** *** 107,123 **** def __init__(self, *args): pass ! def read(self, *args): return '' ! def write(self, *args): pass ! def close(self): pass ! class _Hqxcoderengine: """Write data to the coder in 3-byte chunks""" ! def __init__(self, ofp): self.ofp = ofp --- 107,123 ---- def __init__(self, *args): pass ! def read(self, *args): return '' ! def write(self, *args): pass ! def close(self): pass ! class _Hqxcoderengine: """Write data to the coder in 3-byte chunks""" ! def __init__(self, ofp): self.ofp = ofp *************** *** 254,263 **** self.state = None del self.ofp ! def binhex(inp, out): """(infilename, outfilename) - Create binhex-encoded copy of a file""" finfo = getfileinfo(inp) ofp = BinHex(finfo, out) ! ifp = open(inp, 'rb') # XXXX Do textfile translation on non-mac systems --- 254,263 ---- self.state = None del self.ofp ! def binhex(inp, out): """(infilename, outfilename) - Create binhex-encoded copy of a file""" finfo = getfileinfo(inp) ofp = BinHex(finfo, out) ! ifp = open(inp, 'rb') # XXXX Do textfile translation on non-mac systems *************** *** 275,283 **** ofp.write_rsrc(d) ofp.close() ! ifp.close() class _Hqxdecoderengine: """Read data via the decoder in 4-byte chunks""" ! def __init__(self, ifp): self.ifp = ifp --- 275,283 ---- ofp.write_rsrc(d) ofp.close() ! ifp.close() class _Hqxdecoderengine: """Read data via the decoder in 4-byte chunks""" ! def __init__(self, ifp): self.ifp = ifp *************** *** 289,293 **** wtd = totalwtd # ! # The loop here is convoluted, since we don't really now how # much to decode: there may be newlines in the incoming data. while wtd > 0: --- 289,293 ---- wtd = totalwtd # ! # The loop here is convoluted, since we don't really now how # much to decode: there may be newlines in the incoming data. while wtd > 0: *************** *** 344,348 **** self.pre_buffer = '' return ! # # Obfuscated code ahead. We have to take care that we don't --- 344,348 ---- self.pre_buffer = '' return ! # # Obfuscated code ahead. We have to take care that we don't *************** *** 394,408 **** if ch != '\n': dummy = ifp.readline() ! hqxifp = _Hqxdecoderengine(ifp) self.ifp = _Rledecoderengine(hqxifp) self.crc = 0 self._readheader() ! def _read(self, len): data = self.ifp.read(len) self.crc = binascii.crc_hqx(data, self.crc) return data ! def _checkcrc(self): filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff --- 394,408 ---- if ch != '\n': dummy = ifp.readline() ! hqxifp = _Hqxdecoderengine(ifp) self.ifp = _Rledecoderengine(hqxifp) self.crc = 0 self._readheader() ! def _read(self, len): data = self.ifp.read(len) self.crc = binascii.crc_hqx(data, self.crc) return data ! def _checkcrc(self): filecrc = struct.unpack('>h', self.ifp.read(2))[0] & 0xffff *************** *** 420,424 **** rest = self._read(1+4+4+2+4+4) self._checkcrc() ! type = rest[1:5] creator = rest[5:9] --- 420,424 ---- rest = self._read(1+4+4+2+4+4) self._checkcrc() ! type = rest[1:5] creator = rest[5:9] *************** *** 426,430 **** self.dlen = struct.unpack('>l', rest[11:15])[0] self.rlen = struct.unpack('>l', rest[15:19])[0] ! self.FName = fname self.FInfo = FInfo() --- 426,430 ---- self.dlen = struct.unpack('>l', rest[11:15])[0] self.rlen = struct.unpack('>l', rest[15:19])[0] ! self.FName = fname self.FInfo = FInfo() *************** *** 432,438 **** self.FInfo.Type = type self.FInfo.Flags = flags ! self.state = _DID_HEADER ! def read(self, *n): if self.state != _DID_HEADER: --- 432,438 ---- self.FInfo.Type = type self.FInfo.Flags = flags ! self.state = _DID_HEADER ! def read(self, *n): if self.state != _DID_HEADER: *************** *** 448,452 **** self.dlen = self.dlen - n return rv ! def close_data(self): if self.state != _DID_HEADER: --- 448,452 ---- self.dlen = self.dlen - n return rv ! def close_data(self): if self.state != _DID_HEADER: *************** *** 456,460 **** self._checkcrc() self.state = _DID_DATA ! def read_rsrc(self, *n): if self.state == _DID_HEADER: --- 456,460 ---- self._checkcrc() self.state = _DID_DATA ! def read_rsrc(self, *n): if self.state == _DID_HEADER: *************** *** 469,473 **** self.rlen = self.rlen - n return self._read(n) ! def close(self): if self.rlen: --- 469,473 ---- self.rlen = self.rlen - n return self._read(n) ! def close(self): if self.rlen: *************** *** 476,480 **** self.state = _DID_RSRC self.ifp.close() ! def hexbin(inp, out): """(infilename, outfilename) - Decode binhexed file""" --- 476,480 ---- self.state = _DID_RSRC self.ifp.close() ! def hexbin(inp, out): """(infilename, outfilename) - Decode binhexed file""" *************** *** 495,499 **** ofp.close() ifp.close_data() ! d = ifp.read_rsrc(128000) if d: --- 495,499 ---- ofp.close() ifp.close_data() ! d = ifp.read_rsrc(128000) if d: *************** *** 512,516 **** nfinfo.Flags = finfo.Flags ofss.SetFInfo(nfinfo) ! ifp.close() --- 512,516 ---- nfinfo.Flags = finfo.Flags ofss.SetFInfo(nfinfo) ! ifp.close() *************** *** 527,531 **** #hexbin(fname, fname+'.unpacked') sys.exit(1) ! if __name__ == '__main__': _test() --- 527,531 ---- #hexbin(fname, fname+'.unpacked') sys.exit(1) ! if __name__ == '__main__': _test() From python-dev@python.org Sun Jan 14 21:55:24 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 13:55:24 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help textdoc.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv18159 Modified Files: textdoc.py Log Message: Show package contents. Index: textdoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/textdoc.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** textdoc.py 2001/01/14 11:49:50 1.2 --- textdoc.py 2001/01/14 21:55:22 1.3 *************** *** 3,7 **** __version__ = 'Ka-Ping Yee , 10 Jan 2001' ! import sys, types, inspect from string import join, split, strip, rstrip --- 3,7 ---- __version__ = 'Ka-Ping Yee , 10 Jan 2001' ! import sys, os, string, types, inspect from string import join, split, strip, rstrip *************** *** 101,104 **** --- 101,121 ---- if key[:1] != '_': constants.append((key, value)) + + if hasattr(object, '__path__'): + modpkgs = [] + for file in os.listdir(object.__path__[0]): + if file[:1] != '_': + path = os.path.join(object.__path__[0], file) + if file[-3:] == '.py' and file[:-3] not in modpkgs: + modpkgs.append(file[:-3]) + elif file[-4:] == '.pyc' and file[:-4] not in modpkgs: + modpkgs.append(file[:-4]) + elif os.path.isdir(path): + init = os.path.join(path, '__init__.py') + initc = os.path.join(path, '__init__.pyc') + if os.path.isfile(init) or os.path.isfile(initc): + modpkgs.append(file + ' (package)') + modpkgs.sort() + results.append(section('PACKAGE CONTENTS', string.join(modpkgs, '\n'))) if classes: From python-dev@python.org Sun Jan 14 22:18:46 2001 From: python-dev@python.org (Ka-Ping Yee) Date: Sun, 14 Jan 2001 14:18:46 -0800 Subject: [Python-checkins] CVS: python/nondist/sandbox/help htmldoc.py,1.4,1.5 pydoc.py,1.2,1.3 Message-ID: Update of /cvsroot/python/python/nondist/sandbox/help In directory usw-pr-cvs1:/tmp/cvs-serv21038 Modified Files: htmldoc.py pydoc.py Log Message: Grey out modules and packages that are shadowed by things earlier in sys.path. Index: htmldoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/htmldoc.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** htmldoc.py 2001/01/14 21:48:24 1.4 --- htmldoc.py 2001/01/14 22:18:44 1.5 *************** *** 107,111 **** return name ! def modpkglink((name, ispackage, path)): if path: url = '%s.%s.html' % (path, name) --- 107,113 ---- return name ! def modpkglink((name, path, ispackage, shadowed)): ! if shadowed: ! return '%s' % name if path: url = '%s.%s.html' % (path, name) *************** *** 233,240 **** path = os.path.join(object.__path__[0], file) if file[-3:] == '.py' and file[:-3] not in modnames: ! modpkgs.append((file[:-3], 0, name)) modnames.append(file[:-3]) elif file[-4:] == '.pyc' and file[:-4] not in modnames: ! modpkgs.append((file[:-4], 0, name)) modnames.append(file[:-4]) elif os.path.isdir(path): --- 235,242 ---- path = os.path.join(object.__path__[0], file) if file[-3:] == '.py' and file[:-3] not in modnames: ! modpkgs.append((file[:-3], 0, name, 0)) modnames.append(file[:-3]) elif file[-4:] == '.pyc' and file[:-4] not in modnames: ! modpkgs.append((file[:-4], 0, name, 0)) modnames.append(file[:-4]) elif os.path.isdir(path): *************** *** 242,246 **** initc = os.path.join(path, '__init__.pyc') if os.path.isfile(init) or os.path.isfile(initc): ! modpkgs.append((file, 1, name)) modpkgs.sort() contents = multicolumn(modpkgs, modpkglink) --- 244,248 ---- initc = os.path.join(path, '__init__.pyc') if os.path.isfile(init) or os.path.isfile(initc): ! modpkgs.append((file, 1, name, 0)) modpkgs.sort() contents = multicolumn(modpkgs, modpkglink) *************** *** 351,376 **** return serialize(results) ! def index(dir): modpkgs = [] ! modnames = [] ! for file in os.listdir(dir): ! if file[:1] != '_': ! path = os.path.join(dir, file) ! if os.path.isfile(path): ! if file[-3:] == '.py' and file[:-3] not in modnames: ! modpkgs.append((file[:-3], 0, '')) ! modnames.append(file[:-3]) ! elif file[-4:] == '.pyc' and file[:-4] not in modnames: ! modpkgs.append((file[:-4], 0, '')) ! modnames.append(file[:-4]) ! elif file[-11:] == 'module.so': ! modpkgs.append((file[:-11], 0, '')) ! elif file[-13:] == 'module.so.1': ! modpkgs.append((file[:-13], 0, '')) ! elif os.path.isdir(path): ! init = os.path.join(path, '__init__.py') ! initc = os.path.join(path, '__init__.pyc') ! if os.path.isfile(init) or os.path.isfile(initc): ! modpkgs.append((file, 1, '')) modpkgs.sort() --- 353,387 ---- return serialize(results) ! def index(dir, shadowed=None): modpkgs = [] ! if shadowed is None: shadowed = {} ! seen = {} ! files = os.listdir(dir) ! ! def found(name, ispackage, modpkgs=modpkgs, shadowed=shadowed, seen=seen): ! if not seen.has_key(name): ! modpkgs.append((name, '', ispackage, shadowed.has_key(name))) ! seen[name] = 1 ! shadowed[name] = 1 ! ! # Package spam/__init__.py takes precedence over module spam.py. ! for file in files: ! path = os.path.join(dir, file) ! if os.path.isdir(path): ! init = os.path.join(path, '__init__.py') ! initc = os.path.join(path, '__init__.pyc') ! if os.path.isfile(init) or os.path.isfile(initc): ! found(file, 1) ! for file in files: ! path = os.path.join(dir, file) ! if file[:1] != '_' and os.path.isfile(path): ! if file[-3:] == '.py': ! found(file[:-3], 0) ! elif file[-4:] == '.pyc': ! found(file[:-4], 0) ! elif file[-11:] == 'module.so': ! found(file[:-11], 0) ! elif file[-13:] == 'module.so.1': ! found(file[:-13], 0) modpkgs.sort() Index: pydoc.py =================================================================== RCS file: /cvsroot/python/python/nondist/sandbox/help/pydoc.py,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -r1.2 -r1.3 *** pydoc.py 2001/01/14 21:48:12 1.2 --- pydoc.py 2001/01/14 22:18:44 1.3 *************** *** 295,299 **** contents.append('

Built-in modules: ') contents.append(string.join(builtins, ', ')) ! contents.extend(map(htmldoc.index, sys.path)) contents = htmldoc.serialize(contents) self.send_document('Index of Modules', contents) --- 295,301 ---- contents.append('

Built-in modules: ') contents.append(string.join(builtins, ', ')) ! seen = {} ! for dir in sys.path: ! contents.append(htmldoc.index(dir, seen)) contents = htmldoc.serialize(contents) self.send_document('Index of Modules', contents) From python-dev@python.org Sun Jan 14 23:04:24 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 15:04:24 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib code.py,1.11,1.12 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv25988 Modified Files: code.py Log Message: Make the copyright message the same as for the "real" interpreter. Index: code.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/code.py,v retrieving revision 1.11 retrieving revision 1.12 diff -C2 -r1.11 -r1.12 *** code.py 2001/01/13 22:10:41 1.11 --- code.py 2001/01/14 23:04:22 1.12 *************** *** 217,223 **** except AttributeError: sys.ps2 = "... " if banner is None: self.write("Python %s on %s\n%s\n(%s)\n" % ! (sys.version, sys.platform, sys.copyright, self.__class__.__name__)) else: --- 217,224 ---- except AttributeError: sys.ps2 = "... " + cprt = 'Type "copyright", "credits" or "license" for more information.' if banner is None: self.write("Python %s on %s\n%s\n(%s)\n" % ! (sys.version, sys.platform, cprt, self.__class__.__name__)) else: From python-dev@python.org Sun Jan 14 23:09:37 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 15:09:37 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib webbrowser.py,1.5,1.6 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv26544 Modified Files: webbrowser.py Log Message: SF Patch #103211. Ping apparently doesn't check in Accepted patches, so I'm doing this for him. According to Ping: The name of the controller class should be "Konqueror", not "Konquerer". (See the website http://www.konqueror.org/.) Index: webbrowser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/webbrowser.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** webbrowser.py 2000/11/13 20:30:57 1.5 --- webbrowser.py 2001/01/14 23:09:35 1.6 *************** *** 105,113 **** ! class Konquerer: ! """Controller for the KDE File Manager (kfm, or Konquerer). See http://developer.kde.org/documentation/other/kfmclient.html ! for more information on the Konquerer remote-control interface. """ --- 105,113 ---- ! class Konqueror: ! """Controller for the KDE File Manager (kfm, or Konqueror). See http://developer.kde.org/documentation/other/kfmclient.html ! for more information on the Konqueror remote-control interface. """ *************** *** 129,133 **** self._remote("openURL %s" % url) ! register("kfm", Konquerer) --- 129,133 ---- self._remote("openURL %s" % url) ! register("kfm", Konqueror) From python-dev@python.org Sun Jan 14 23:21:27 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 15:21:27 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib SimpleHTTPServer.py,1.12,1.13 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv27790 Modified Files: SimpleHTTPServer.py Log Message: - Use mimetypes.types_map to initialize extensions_map. - Change the default file type to application/octet-stream. - Add support to recognize .py, .c, .h files as text/plain (this is what I use most :-). Index: SimpleHTTPServer.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/SimpleHTTPServer.py,v retrieving revision 1.12 retrieving revision 1.13 diff -C2 -r1.12 -r1.13 *** SimpleHTTPServer.py 2000/09/04 15:55:31 1.12 --- SimpleHTTPServer.py 2001/01/14 23:21:25 1.13 *************** *** 7,11 **** ! __version__ = "0.5" --- 7,11 ---- ! __version__ = "0.6" *************** *** 17,20 **** --- 17,21 ---- import cgi import shutil + import mimetypes from StringIO import StringIO *************** *** 180,191 **** return self.extensions_map[''] ! extensions_map = { ! '': 'text/plain', # Default, *must* be present ! '.html': 'text/html', ! '.htm': 'text/html', ! '.gif': 'image/gif', ! '.jpg': 'image/jpeg', ! '.jpeg': 'image/jpeg', ! } --- 181,191 ---- return self.extensions_map[''] ! extensions_map = mimetypes.types_map.copy() ! extensions_map.update({ ! '': 'application/octet-stream', # Default ! '.py': 'text/plain', ! '.c': 'text/plain', ! '.h': 'text/plain', ! }) From python-dev@python.org Sun Jan 14 23:29:50 2001 From: python-dev@python.org (Guido van Rossum) Date: Sun, 14 Jan 2001 15:29:50 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib pdb.py,1.45,1.46 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv28588 Modified Files: pdb.py Log Message: - Don't hardcode Unix filename syntax when opening ~/.pdbrc. - Conform to standard coding style in a few more places. Index: pdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pdb.py,v retrieving revision 1.45 retrieving revision 1.46 diff -C2 -r1.45 -r1.46 *** pdb.py 2000/12/12 23:20:45 1.45 --- pdb.py 2001/01/14 23:29:48 1.46 *************** *** 60,77 **** envHome = os.environ['HOME'] try: ! rcFile = open (envHome + "/.pdbrc") except IOError: pass else: for line in rcFile.readlines(): ! self.rcLines.append (line) rcFile.close() try: ! rcFile = open ("./.pdbrc") except IOError: pass else: for line in rcFile.readlines(): ! self.rcLines.append (line) rcFile.close() --- 60,77 ---- envHome = os.environ['HOME'] try: ! rcFile = open(os.path.join(envHome, ".pdbrc")) except IOError: pass else: for line in rcFile.readlines(): ! self.rcLines.append(line) rcFile.close() try: ! rcFile = open(".pdbrc") except IOError: pass else: for line in rcFile.readlines(): ! self.rcLines.append(line) rcFile.close() From python-dev@python.org Sun Jan 14 23:36:08 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 14 Jan 2001 15:36:08 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib ConfigParser.py,1.25,1.26 Cookie.py,1.4,1.5 calendar.py,1.19,1.20 cgi.py,1.57,1.58 chunk.py,1.5,1.6 codecs.py,1.14,1.15 commands.py,1.13,1.14 copy.py,1.17,1.18 dis.py,1.27,1.28 dospath.py,1.20,1.21 dumbdbm.py,1.6,1.7 filecmp.py,1.8,1.9 fnmatch.py,1.8,1.9 formatter.py,1.15,1.16 fpformat.py,1.7,1.8 ftplib.py,1.46,1.47 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv29400/python/dist/src/lib Modified Files: ConfigParser.py Cookie.py calendar.py cgi.py chunk.py codecs.py commands.py copy.py dis.py dospath.py dumbdbm.py filecmp.py fnmatch.py formatter.py fpformat.py ftplib.py Log Message: Whitespace normalization. Index: ConfigParser.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ConfigParser.py,v retrieving revision 1.25 retrieving revision 1.26 diff -C2 -r1.25 -r1.26 *** ConfigParser.py 2000/12/11 18:13:19 1.25 --- ConfigParser.py 2001/01/14 23:36:05 1.26 *************** *** 74,81 **** remove_section(section) ! remove the given file section and all its options remove_option(section, option) ! remove the given option from the given section set(section, option, value) --- 74,81 ---- remove_section(section) ! remove the given file section and all its options remove_option(section, option) ! remove the given option from the given section set(section, option, value) *************** *** 83,87 **** write(fp) ! write the configuration state in .ini format """ --- 83,87 ---- write(fp) ! write the configuration state in .ini format """ *************** *** 95,99 **** ! # exception classes class Error(Exception): --- 95,99 ---- ! # exception classes class Error(Exception): *************** *** 166,171 **** self.line = line - class ConfigParser: def __init__(self, defaults=None): --- 166,171 ---- self.line = line + class ConfigParser: def __init__(self, defaults=None): *************** *** 218,222 **** def read(self, filenames): """Read and parse a filename or a list of filenames. ! Files that cannot be opened are silently ignored; this is designed so that you can specify a list of potential --- 218,222 ---- def read(self, filenames): """Read and parse a filename or a list of filenames. ! Files that cannot be opened are silently ignored; this is designed so that you can specify a list of potential *************** *** 286,290 **** # do the string interpolation value = rawval # Make it a pretty variable name ! depth = 0 while depth < 10: # Loop through this until it's done depth = depth + 1 --- 286,290 ---- # do the string interpolation value = rawval # Make it a pretty variable name ! depth = 0 while depth < 10: # Loop through this until it's done depth = depth + 1 *************** *** 299,303 **** raise InterpolationDepthError(option, section, rawval) return value ! def __get(self, section, conv, option): return conv(self.get(section, option)) --- 299,303 ---- raise InterpolationDepthError(option, section, rawval) return value ! def __get(self, section, conv, option): return conv(self.get(section, option)) Index: Cookie.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/Cookie.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** Cookie.py 2000/12/12 23:20:44 1.4 --- Cookie.py 2001/01/14 23:36:05 1.5 *************** *** 4,10 **** #### # Copyright 2000 by Timothy O'Malley ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software # and its documentation for any purpose and without fee is hereby --- 4,10 ---- #### # Copyright 2000 by Timothy O'Malley ! # # All Rights Reserved ! # # Permission to use, copy, modify, and distribute this software # and its documentation for any purpose and without fee is hereby *************** *** 14,19 **** # Timothy O'Malley not be used in advertising or publicity # pertaining to distribution of the software without specific, written ! # prior permission. ! # # Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY --- 14,19 ---- # Timothy O'Malley not be used in advertising or publicity # pertaining to distribution of the software without specific, written ! # prior permission. ! # # Timothy O'Malley DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS # SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY *************** *** 23,31 **** # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ! # PERFORMANCE OF THIS SOFTWARE. # #### ! # ! # Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp # by Timothy O'Malley # --- 23,31 ---- # WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS # ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ! # PERFORMANCE OF THIS SOFTWARE. # #### ! # ! # Id: Cookie.py,v 2.29 2000/08/23 05:28:49 timo Exp # by Timothy O'Malley # *************** *** 117,121 **** Each dictionary element has a 'value' attribute, which gives you ! back the value associated with the key. >>> C = Cookie.SmartCookie() --- 117,121 ---- Each dictionary element has a 'value' attribute, which gives you ! back the value associated with the key. >>> C = Cookie.SmartCookie() *************** *** 149,153 **** Set-Cookie: string=seven; ! SerialCookie --- 149,153 ---- Set-Cookie: string=seven; ! SerialCookie *************** *** 215,219 **** # # Import our required modules ! # import string, sys from UserDict import UserDict --- 215,219 ---- # # Import our required modules ! # import string, sys from UserDict import UserDict *************** *** 243,247 **** # three-digit octal equivalent of the character. Any '\' or '"' is # quoted with a preceeding '\' slash. ! # # These are taken from RFC2068 and RFC2109. # _LegalChars is the list of chars which don't require "'s --- 243,247 ---- # three-digit octal equivalent of the character. Any '\' or '"' is # quoted with a preceeding '\' slash. ! # # These are taken from RFC2068 and RFC2109. # _LegalChars is the list of chars which don't require "'s *************** *** 320,324 **** return str else: ! return '"' + join( map(_Translator.get, str, str), "" ) + '"' # end _quote --- 320,324 ---- return str else: ! return '"' + join( map(_Translator.get, str, str), "" ) + '"' # end _quote *************** *** 371,375 **** # The _getdate() routine is used to set the expiration time in # the cookie's HTTP header. By default, _getdate() returns the ! # current time in the appropriate "expires" format for a # Set-Cookie header. The one optional argument is an offset from # now, in seconds. For example, an offset of -3600 means "one hour ago". --- 371,375 ---- # The _getdate() routine is used to set the expiration time in # the cookie's HTTP header. By default, _getdate() returns the ! # current time in the appropriate "expires" format for a # Set-Cookie header. The one optional argument is an offset from # now, in seconds. For example, an offset of -3600 means "one hour ago". *************** *** 406,410 **** # path comment domain # max-age secure version ! # # For historical reasons, these attributes are also reserved: # expires --- 406,410 ---- # path comment domain # max-age secure version ! # # For historical reasons, these attributes are also reserved: # expires Index: calendar.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/calendar.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** calendar.py 2000/12/12 23:20:44 1.19 --- calendar.py 2001/01/14 23:36:05 1.20 *************** *** 132,136 **** w = max(2, w) l = max(1, l) ! s = (_center(month_name[themonth] + ' ' + `theyear`, 7 * (w + 1) - 1).rstrip() + '\n' * l + weekheader(w).rstrip() + '\n' * l) --- 132,136 ---- w = max(2, w) l = max(1, l) ! s = (_center(month_name[themonth] + ' ' + `theyear`, 7 * (w + 1) - 1).rstrip() + '\n' * l + weekheader(w).rstrip() + '\n' * l) *************** *** 168,172 **** s = (s + '\n' * l + format3cstring(month_name[q], month_name[q+1], month_name[q+2], ! colwidth, c).rstrip() + '\n' * l + header + '\n' * l) data = [] --- 168,172 ---- s = (s + '\n' * l + format3cstring(month_name[q], month_name[q+1], month_name[q+2], ! colwidth, c).rstrip() + '\n' * l + header + '\n' * l) data = [] *************** *** 184,188 **** else: weeks.append(week(cal[i], w)) ! s = s + format3cstring(weeks[0], weeks[1], weeks[2], colwidth, c).rstrip() + '\n' * l return s[:-l] + '\n' --- 184,188 ---- else: weeks.append(week(cal[i], w)) ! s = s + format3cstring(weeks[0], weeks[1], weeks[2], colwidth, c).rstrip() + '\n' * l return s[:-l] + '\n' Index: cgi.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/cgi.py,v retrieving revision 1.57 retrieving revision 1.58 diff -C2 -r1.57 -r1.58 *** cgi.py 2000/12/27 19:12:40 1.57 --- cgi.py 2001/01/14 23:36:05 1.58 *************** *** 12,16 **** # History # ------- ! # # Michael McLay started this module. Steve Majewski changed the # interface to SvFormContentDict and FormContentDict. The multipart --- 12,16 ---- # History # ------- ! # # Michael McLay started this module. Steve Majewski changed the # interface to SvFormContentDict and FormContentDict. The multipart *************** *** 18,22 **** # Rossum rewrote, reformatted and documented the module and is currently # responsible for its maintenance. ! # __version__ = "2.5" --- 18,22 ---- # Rossum rewrote, reformatted and documented the module and is currently # responsible for its maintenance. ! # __version__ = "2.5" *************** *** 105,110 **** keep_blank_values: flag indicating whether blank values in ! URL encoded forms should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were --- 105,110 ---- keep_blank_values: flag indicating whether blank values in ! URL encoded forms should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were *************** *** 130,137 **** else: qs = '' # Unknown content-type ! if environ.has_key('QUERY_STRING'): if qs: qs = qs + '&' qs = qs + environ['QUERY_STRING'] ! elif sys.argv[1:]: if qs: qs = qs + '&' qs = qs + sys.argv[1] --- 130,137 ---- else: qs = '' # Unknown content-type ! if environ.has_key('QUERY_STRING'): if qs: qs = qs + '&' qs = qs + environ['QUERY_STRING'] ! elif sys.argv[1:]: if qs: qs = qs + '&' qs = qs + sys.argv[1] *************** *** 156,161 **** keep_blank_values: flag indicating whether blank values in ! URL encoded queries should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were --- 156,161 ---- keep_blank_values: flag indicating whether blank values in ! URL encoded queries should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were *************** *** 189,193 **** strict_parsing: flag indicating what to do with parsing errors. If false (the default), errors are silently ignored. If true, ! errors raise a ValueError exception. Returns a list, as G-d intended. --- 189,193 ---- strict_parsing: flag indicating what to do with parsing errors. If false (the default), errors are silently ignored. If true, ! errors raise a ValueError exception. Returns a list, as G-d intended. *************** *** 216,230 **** pdict: dictionary containing other parameters of conten-type header ! Returns a dictionary just like parse_qs(): keys are the field names, each ! value is a list of values for that field. This is easy to use but not ! much good if you are expecting megabytes to be uploaded -- in that case, ! use the FieldStorage class instead which is much more flexible. Note ! that content-type is the raw, unparsed contents of the content-type header. ! ! XXX This does not parse nested multipart parts -- use FieldStorage for that. ! ! XXX This should really be subsumed by FieldStorage altogether -- no point in having two implementations of the same parsing algorithm. --- 216,230 ---- pdict: dictionary containing other parameters of conten-type header ! Returns a dictionary just like parse_qs(): keys are the field names, each ! value is a list of values for that field. This is easy to use but not ! much good if you are expecting megabytes to be uploaded -- in that case, ! use the FieldStorage class instead which is much more flexible. Note ! that content-type is the raw, unparsed contents of the content-type header. ! ! XXX This does not parse nested multipart parts -- use FieldStorage for that. ! ! XXX This should really be subsumed by FieldStorage altogether -- no point in having two implementations of the same parsing algorithm. *************** *** 410,415 **** keep_blank_values: flag indicating whether blank values in ! URL encoded forms should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were --- 410,415 ---- keep_blank_values: flag indicating whether blank values in ! URL encoded forms should be treated as blank strings. ! A true value indicates that blanks should be retained as blank strings. The default false value indicates that blank values are to be ignored and treated as if they were *************** *** 708,714 **** import tempfile return tempfile.TemporaryFile("w+b") - # Backwards Compatibility Classes # =============================== --- 708,714 ---- import tempfile return tempfile.TemporaryFile("w+b") + # Backwards Compatibility Classes # =============================== *************** *** 745,750 **** """ def __getitem__(self, key): ! if len(self.dict[key]) > 1: ! raise IndexError, 'expecting a single value' return self.dict[key][0] def getlist(self, key): --- 745,750 ---- """ def __getitem__(self, key): ! if len(self.dict[key]) > 1: ! raise IndexError, 'expecting a single value' return self.dict[key][0] def getlist(self, key): *************** *** 767,771 **** class InterpFormContentDict(SvFormContentDict): ! """This class is present for backwards compatibility only.""" def __getitem__(self, key): v = SvFormContentDict.__getitem__(self, key) --- 767,771 ---- class InterpFormContentDict(SvFormContentDict): ! """This class is present for backwards compatibility only.""" def __getitem__(self, key): v = SvFormContentDict.__getitem__(self, key) *************** *** 795,799 **** class FormContent(FormContentDict): ! """This class is present for backwards compatibility only.""" def values(self, key): if self.dict.has_key(key) :return self.dict[key] --- 795,799 ---- class FormContent(FormContentDict): ! """This class is present for backwards compatibility only.""" def values(self, key): if self.dict.has_key(key) :return self.dict[key] *************** *** 883,887 **** for key in keys: print "

", escape(key), "
", escape(environ[key]) ! print "" print --- 883,887 ---- for key in keys: print "
", escape(key), "
", escape(environ[key]) ! print "" print *************** *** 983,986 **** # Call test() when this file is run as a script (not imported as a module) ! if __name__ == '__main__': test() --- 983,986 ---- # Call test() when this file is run as a script (not imported as a module) ! if __name__ == '__main__': test() Index: chunk.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/chunk.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** chunk.py 1999/08/26 15:50:43 1.5 --- chunk.py 2001/01/14 23:36:05 1.6 *************** *** 19,23 **** Usually an IFF-type file consists of one or more chunks. The proposed ! usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end --- 19,23 ---- Usually an IFF-type file consists of one or more chunks. The proposed ! usage of the Chunk class defined here is to instantiate an instance at the start of each chunk and read from the instance until it reaches the end, after which a new instance can be instantiated. At the end *************** *** 45,49 **** The __init__ method has one required argument, a file-like object (including a chunk instance), and one optional argument, a flag which ! specifies whether or not chunks are aligned on 2-byte boundaries. The default is 1, i.e. aligned. """ --- 45,49 ---- The __init__ method has one required argument, a file-like object (including a chunk instance), and one optional argument, a flag which ! specifies whether or not chunks are aligned on 2-byte boundaries. The default is 1, i.e. aligned. """ *************** *** 53,57 **** import struct self.closed = 0 ! self.align = align # whether to align to word (2-byte) boundaries if bigendian: strflag = '>' --- 53,57 ---- import struct self.closed = 0 ! self.align = align # whether to align to word (2-byte) boundaries if bigendian: strflag = '>' *************** *** 98,102 **** Default position is 0 (start of chunk). If the file is not seekable, this will result in an error. ! """ if self.closed: --- 98,102 ---- Default position is 0 (start of chunk). If the file is not seekable, this will result in an error. ! """ if self.closed: *************** *** 122,126 **** If size is omitted or negative, read until the end of the chunk. ! """ if self.closed: --- 122,126 ---- If size is omitted or negative, read until the end of the chunk. ! """ if self.closed: *************** *** 131,135 **** size = self.chunksize - self.size_read if size > self.chunksize - self.size_read: ! size = self.chunksize - self.size_read data = self.file.read(size) self.size_read = self.size_read + len(data) --- 131,135 ---- size = self.chunksize - self.size_read if size > self.chunksize - self.size_read: ! size = self.chunksize - self.size_read data = self.file.read(size) self.size_read = self.size_read + len(data) *************** *** 146,150 **** this method should be called so that the file points to the start of the next chunk. ! """ if self.closed: --- 146,150 ---- this method should be called so that the file points to the start of the next chunk. ! """ if self.closed: *************** *** 166,168 **** if not dummy: raise EOFError - --- 166,167 ---- Index: codecs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/codecs.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** codecs.py 2001/01/03 21:29:13 1.14 --- codecs.py 2001/01/14 23:36:05 1.15 *************** *** 26,34 **** # BOM_BE = BOM32_BE = '\376\377' ! # corresponds to Unicode U+FEFF in UTF-16 on big endian ! # platforms == ZERO WIDTH NO-BREAK SPACE BOM_LE = BOM32_LE = '\377\376' ! # corresponds to Unicode U+FFFE in UTF-16 on little endian ! # platforms == defined as being an illegal Unicode character # --- 26,34 ---- # BOM_BE = BOM32_BE = '\376\377' ! # corresponds to Unicode U+FEFF in UTF-16 on big endian ! # platforms == ZERO WIDTH NO-BREAK SPACE BOM_LE = BOM32_LE = '\377\376' ! # corresponds to Unicode U+FFFE in UTF-16 on little endian ! # platforms == defined as being an illegal Unicode character # *************** *** 36,42 **** # BOM64_BE = '\000\000\376\377' ! # corresponds to Unicode U+0000FEFF in UCS-4 BOM64_LE = '\377\376\000\000' ! # corresponds to Unicode U+0000FFFE in UCS-4 --- 36,42 ---- # BOM64_BE = '\000\000\376\377' ! # corresponds to Unicode U+0000FEFF in UCS-4 BOM64_LE = '\377\376\000\000' ! # corresponds to Unicode U+0000FFFE in UCS-4 *************** *** 548,552 **** Return a dictionary where elements of the rng sequence are mapped to themselves. ! """ res = {} --- 548,552 ---- Return a dictionary where elements of the rng sequence are mapped to themselves. ! """ res = {} Index: commands.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/commands.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** commands.py 2000/12/12 23:20:44 1.13 --- commands.py 2001/01/14 23:36:05 1.14 *************** *** 2,8 **** Interface summary: ! import commands ! outtext = commands.getoutput(cmd) (exitstatus, outtext) = commands.getstatusoutput(cmd) --- 2,8 ---- Interface summary: ! import commands ! outtext = commands.getoutput(cmd) (exitstatus, outtext) = commands.getstatusoutput(cmd) *************** *** 12,16 **** Encapsulates the basic operation: ! pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') text = pipe.read() --- 12,16 ---- Encapsulates the basic operation: ! pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r') text = pipe.read() Index: copy.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/copy.py,v retrieving revision 1.17 retrieving revision 1.18 diff -C2 -r1.17 -r1.18 *** copy.py 2000/11/27 21:53:14 1.17 --- copy.py 2001/01/14 23:36:05 1.18 *************** *** 3,10 **** Interface summary: ! import copy ! x = copy.copy(y) # make a shallow copy of y ! x = copy.deepcopy(y) # make a deep copy of y For module specific errors, copy.error is raised. --- 3,10 ---- Interface summary: ! import copy ! x = copy.copy(y) # make a shallow copy of y ! x = copy.deepcopy(y) # make a deep copy of y For module specific errors, copy.error is raised. *************** *** 54,59 **** class Error(Exception): ! pass ! error = Error # backward compatibility try: --- 54,59 ---- class Error(Exception): ! pass ! error = Error # backward compatibility try: *************** *** 63,88 **** def copy(x): ! """Shallow copy operation on arbitrary Python objects. ! See the module's __doc__ string for more info. ! """ ! try: ! copierfunction = _copy_dispatch[type(x)] ! except KeyError: ! try: ! copier = x.__copy__ ! except AttributeError: ! raise error, \ ! "un(shallow)copyable object of type %s" % type(x) ! y = copier() ! else: ! y = copierfunction(x) ! return y _copy_dispatch = d = {} def _copy_atomic(x): ! return x d[types.NoneType] = _copy_atomic d[types.IntType] = _copy_atomic --- 63,88 ---- def copy(x): ! """Shallow copy operation on arbitrary Python objects. ! See the module's __doc__ string for more info. ! """ ! try: ! copierfunction = _copy_dispatch[type(x)] ! except KeyError: ! try: ! copier = x.__copy__ ! except AttributeError: ! raise error, \ ! "un(shallow)copyable object of type %s" % type(x) ! y = copier() ! else: ! y = copierfunction(x) ! return y _copy_dispatch = d = {} def _copy_atomic(x): ! return x d[types.NoneType] = _copy_atomic d[types.IntType] = _copy_atomic *************** *** 92,98 **** d[types.UnicodeType] = _copy_atomic try: ! d[types.CodeType] = _copy_atomic except AttributeError: ! pass d[types.TypeType] = _copy_atomic d[types.XRangeType] = _copy_atomic --- 92,98 ---- d[types.UnicodeType] = _copy_atomic try: ! d[types.CodeType] = _copy_atomic except AttributeError: ! pass d[types.TypeType] = _copy_atomic d[types.XRangeType] = _copy_atomic *************** *** 100,112 **** def _copy_list(x): ! return x[:] d[types.ListType] = _copy_list def _copy_tuple(x): ! return x[:] d[types.TupleType] = _copy_tuple def _copy_dict(x): ! return x.copy() d[types.DictionaryType] = _copy_dict if PyStringMap is not None: --- 100,112 ---- def _copy_list(x): ! return x[:] d[types.ListType] = _copy_list def _copy_tuple(x): ! return x[:] d[types.TupleType] = _copy_tuple def _copy_dict(x): ! return x.copy() d[types.DictionaryType] = _copy_dict if PyStringMap is not None: *************** *** 114,134 **** def _copy_inst(x): ! if hasattr(x, '__copy__'): ! return x.__copy__() ! if hasattr(x, '__getinitargs__'): ! args = x.__getinitargs__() ! y = apply(x.__class__, args) ! else: ! y = _EmptyClass() ! y.__class__ = x.__class__ ! if hasattr(x, '__getstate__'): ! state = x.__getstate__() ! else: ! state = x.__dict__ ! if hasattr(y, '__setstate__'): ! y.__setstate__(state) ! else: ! y.__dict__.update(state) ! return y d[types.InstanceType] = _copy_inst --- 114,134 ---- def _copy_inst(x): ! if hasattr(x, '__copy__'): ! return x.__copy__() ! if hasattr(x, '__getinitargs__'): ! args = x.__getinitargs__() ! y = apply(x.__class__, args) ! else: ! y = _EmptyClass() ! y.__class__ = x.__class__ ! if hasattr(x, '__getstate__'): ! state = x.__getstate__() ! else: ! state = x.__dict__ ! if hasattr(y, '__setstate__'): ! y.__setstate__(state) ! else: ! y.__dict__.update(state) ! return y d[types.InstanceType] = _copy_inst *************** *** 136,167 **** def deepcopy(x, memo = None): ! """Deep copy operation on arbitrary Python objects. ! See the module's __doc__ string for more info. ! """ ! if memo is None: ! memo = {} ! d = id(x) ! if memo.has_key(d): ! return memo[d] ! try: ! copierfunction = _deepcopy_dispatch[type(x)] ! except KeyError: ! try: ! copier = x.__deepcopy__ ! except AttributeError: ! raise error, \ ! "un-deep-copyable object of type %s" % type(x) ! y = copier(memo) ! else: ! y = copierfunction(x, memo) ! memo[d] = y ! return y _deepcopy_dispatch = d = {} def _deepcopy_atomic(x, memo): ! return x d[types.NoneType] = _deepcopy_atomic d[types.IntType] = _deepcopy_atomic --- 136,167 ---- def deepcopy(x, memo = None): ! """Deep copy operation on arbitrary Python objects. ! See the module's __doc__ string for more info. ! """ ! if memo is None: ! memo = {} ! d = id(x) ! if memo.has_key(d): ! return memo[d] ! try: ! copierfunction = _deepcopy_dispatch[type(x)] ! except KeyError: ! try: ! copier = x.__deepcopy__ ! except AttributeError: ! raise error, \ ! "un-deep-copyable object of type %s" % type(x) ! y = copier(memo) ! else: ! y = copierfunction(x, memo) ! memo[d] = y ! return y _deepcopy_dispatch = d = {} def _deepcopy_atomic(x, memo): ! return x d[types.NoneType] = _deepcopy_atomic d[types.IntType] = _deepcopy_atomic *************** *** 175,210 **** def _deepcopy_list(x, memo): ! y = [] ! memo[id(x)] = y ! for a in x: ! y.append(deepcopy(a, memo)) ! return y d[types.ListType] = _deepcopy_list def _deepcopy_tuple(x, memo): ! y = [] ! for a in x: ! y.append(deepcopy(a, memo)) ! d = id(x) ! try: ! return memo[d] ! except KeyError: ! pass ! for i in range(len(x)): ! if x[i] is not y[i]: ! y = tuple(y) ! break ! else: ! y = x ! memo[d] = y ! return y d[types.TupleType] = _deepcopy_tuple def _deepcopy_dict(x, memo): ! y = {} ! memo[id(x)] = y ! for key in x.keys(): ! y[deepcopy(key, memo)] = deepcopy(x[key], memo) ! return y d[types.DictionaryType] = _deepcopy_dict if PyStringMap is not None: --- 175,210 ---- def _deepcopy_list(x, memo): ! y = [] ! memo[id(x)] = y ! for a in x: ! y.append(deepcopy(a, memo)) ! return y d[types.ListType] = _deepcopy_list def _deepcopy_tuple(x, memo): ! y = [] ! for a in x: ! y.append(deepcopy(a, memo)) ! d = id(x) ! try: ! return memo[d] ! except KeyError: ! pass ! for i in range(len(x)): ! if x[i] is not y[i]: ! y = tuple(y) ! break ! else: ! y = x ! memo[d] = y ! return y d[types.TupleType] = _deepcopy_tuple def _deepcopy_dict(x, memo): ! y = {} ! memo[id(x)] = y ! for key in x.keys(): ! y[deepcopy(key, memo)] = deepcopy(x[key], memo) ! return y d[types.DictionaryType] = _deepcopy_dict if PyStringMap is not None: *************** *** 212,253 **** def _keep_alive(x, memo): ! """Keeps a reference to the object x in the memo. ! Because we remember objects by their id, we have ! to assure that possibly temporary objects are kept ! alive by referencing them. ! We store a reference at the id of the memo, which should ! normally not be used unless someone tries to deepcopy ! the memo itself... ! """ ! try: ! memo[id(memo)].append(x) ! except KeyError: ! # aha, this is the first one :-) ! memo[id(memo)]=[x] def _deepcopy_inst(x, memo): ! if hasattr(x, '__deepcopy__'): ! return x.__deepcopy__(memo) ! if hasattr(x, '__getinitargs__'): ! args = x.__getinitargs__() ! _keep_alive(args, memo) ! args = deepcopy(args, memo) ! y = apply(x.__class__, args) ! else: ! y = _EmptyClass() ! y.__class__ = x.__class__ ! memo[id(x)] = y ! if hasattr(x, '__getstate__'): ! state = x.__getstate__() ! _keep_alive(state, memo) ! else: ! state = x.__dict__ ! state = deepcopy(state, memo) ! if hasattr(y, '__setstate__'): ! y.__setstate__(state) ! else: ! y.__dict__.update(state) ! return y d[types.InstanceType] = _deepcopy_inst --- 212,253 ---- def _keep_alive(x, memo): ! """Keeps a reference to the object x in the memo. ! Because we remember objects by their id, we have ! to assure that possibly temporary objects are kept ! alive by referencing them. ! We store a reference at the id of the memo, which should ! normally not be used unless someone tries to deepcopy ! the memo itself... ! """ ! try: ! memo[id(memo)].append(x) ! except KeyError: ! # aha, this is the first one :-) ! memo[id(memo)]=[x] def _deepcopy_inst(x, memo): ! if hasattr(x, '__deepcopy__'): ! return x.__deepcopy__(memo) ! if hasattr(x, '__getinitargs__'): ! args = x.__getinitargs__() ! _keep_alive(args, memo) ! args = deepcopy(args, memo) ! y = apply(x.__class__, args) ! else: ! y = _EmptyClass() ! y.__class__ = x.__class__ ! memo[id(x)] = y ! if hasattr(x, '__getstate__'): ! state = x.__getstate__() ! _keep_alive(state, memo) ! else: ! state = x.__dict__ ! state = deepcopy(state, memo) ! if hasattr(y, '__setstate__'): ! y.__setstate__(state) ! else: ! y.__dict__.update(state) ! return y d[types.InstanceType] = _deepcopy_inst *************** *** 261,316 **** def _test(): ! l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], ! {'abc': 'ABC'}, (), [], {}] ! l1 = copy(l) ! print l1==l ! l1 = map(copy, l) ! print l1==l ! l1 = deepcopy(l) ! print l1==l ! class C: ! def __init__(self, arg=None): ! self.a = 1 ! self.arg = arg ! if __name__ == '__main__': ! import sys ! file = sys.argv[0] ! else: ! file = __file__ ! self.fp = open(file) ! self.fp.close() ! def __getstate__(self): ! return {'a': self.a, 'arg': self.arg} ! def __setstate__(self, state): ! for key in state.keys(): ! setattr(self, key, state[key]) ! def __deepcopy__(self, memo = None): ! new = self.__class__(deepcopy(self.arg, memo)) ! new.a = self.a ! return new ! c = C('argument sketch') ! l.append(c) ! l2 = copy(l) ! print l == l2 ! print l ! print l2 ! l2 = deepcopy(l) ! print l == l2 ! print l ! print l2 ! l.append({l[1]: l, 'xyz': l[2]}) ! l3 = copy(l) ! import repr ! print map(repr.repr, l) ! print map(repr.repr, l1) ! print map(repr.repr, l2) ! print map(repr.repr, l3) ! l3 = deepcopy(l) ! import repr ! print map(repr.repr, l) ! print map(repr.repr, l1) ! print map(repr.repr, l2) ! print map(repr.repr, l3) if __name__ == '__main__': ! _test() --- 261,316 ---- def _test(): ! l = [None, 1, 2L, 3.14, 'xyzzy', (1, 2L), [3.14, 'abc'], ! {'abc': 'ABC'}, (), [], {}] ! l1 = copy(l) ! print l1==l ! l1 = map(copy, l) ! print l1==l ! l1 = deepcopy(l) ! print l1==l ! class C: ! def __init__(self, arg=None): ! self.a = 1 ! self.arg = arg ! if __name__ == '__main__': ! import sys ! file = sys.argv[0] ! else: ! file = __file__ ! self.fp = open(file) ! self.fp.close() ! def __getstate__(self): ! return {'a': self.a, 'arg': self.arg} ! def __setstate__(self, state): ! for key in state.keys(): ! setattr(self, key, state[key]) ! def __deepcopy__(self, memo = None): ! new = self.__class__(deepcopy(self.arg, memo)) ! new.a = self.a ! return new ! c = C('argument sketch') ! l.append(c) ! l2 = copy(l) ! print l == l2 ! print l ! print l2 ! l2 = deepcopy(l) ! print l == l2 ! print l ! print l2 ! l.append({l[1]: l, 'xyz': l[2]}) ! l3 = copy(l) ! import repr ! print map(repr.repr, l) ! print map(repr.repr, l1) ! print map(repr.repr, l2) ! print map(repr.repr, l3) ! l3 = deepcopy(l) ! import repr ! print map(repr.repr, l) ! print map(repr.repr, l1) ! print map(repr.repr, l2) ! print map(repr.repr, l3) if __name__ == '__main__': ! _test() Index: dis.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dis.py,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -r1.27 -r1.28 *** dis.py 2000/08/24 22:44:53 1.27 --- dis.py 2001/01/14 23:36:05 1.28 *************** *** 6,118 **** def dis(x=None): ! """Disassemble classes, methods, functions, or code. ! With no argument, disassemble the last traceback. ! """ ! if not x: ! distb() ! return ! if type(x) is types.InstanceType: ! x = x.__class__ ! if hasattr(x, '__dict__'): ! items = x.__dict__.items() ! items.sort() ! for name, x1 in items: ! if type(x1) in (types.MethodType, ! types.FunctionType, ! types.CodeType): ! print "Disassembly of %s:" % name ! try: ! dis(x1) ! except TypeError, msg: ! print "Sorry:", msg ! print ! else: ! if hasattr(x, 'im_func'): ! x = x.im_func ! if hasattr(x, 'func_code'): ! x = x.func_code ! if hasattr(x, 'co_code'): ! disassemble(x) ! else: ! raise TypeError, \ ! "don't know how to disassemble %s objects" % \ ! type(x).__name__ def distb(tb=None): ! """Disassemble a traceback (default: last traceback).""" ! if not tb: ! try: ! tb = sys.last_traceback ! except AttributeError: ! raise RuntimeError, "no last traceback to disassemble" ! while tb.tb_next: tb = tb.tb_next ! disassemble(tb.tb_frame.f_code, tb.tb_lasti) def disassemble(co, lasti=-1): ! """Disassemble a code object.""" ! code = co.co_code ! labels = findlabels(code) ! n = len(code) ! i = 0 ! extended_arg = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! if op == SET_LINENO and i > 0: print # Extra blank line ! if i == lasti: print '-->', ! else: print ' ', ! if i in labels: print '>>', ! else: print ' ', ! print string.rjust(`i`, 4), ! print string.ljust(opname[op], 20), ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg ! extended_arg = 0 ! i = i+2 ! if op == EXTENDED_ARG: ! extended_arg = oparg*65536L ! print string.rjust(`oparg`, 5), ! if op in hasconst: ! print '(' + `co.co_consts[oparg]` + ')', ! elif op in hasname: ! print '(' + co.co_names[oparg] + ')', ! elif op in hasjrel: ! print '(to ' + `i + oparg` + ')', ! elif op in haslocal: ! print '(' + co.co_varnames[oparg] + ')', ! elif op in hascompare: ! print '(' + cmp_op[oparg] + ')', ! print ! disco = disassemble # XXX For backwards compatibility def findlabels(code): ! """Detect all offsets in a byte code which are jump targets. ! Return the list of offsets. ! """ ! labels = [] ! n = len(code) ! i = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 ! i = i+2 ! label = -1 ! if op in hasjrel: ! label = i+oparg ! elif op in hasjabs: ! label = oparg ! if label >= 0: ! if label not in labels: ! labels.append(label) ! return labels cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', --- 6,118 ---- def dis(x=None): ! """Disassemble classes, methods, functions, or code. ! With no argument, disassemble the last traceback. ! """ ! if not x: ! distb() ! return ! if type(x) is types.InstanceType: ! x = x.__class__ ! if hasattr(x, '__dict__'): ! items = x.__dict__.items() ! items.sort() ! for name, x1 in items: ! if type(x1) in (types.MethodType, ! types.FunctionType, ! types.CodeType): ! print "Disassembly of %s:" % name ! try: ! dis(x1) ! except TypeError, msg: ! print "Sorry:", msg ! print ! else: ! if hasattr(x, 'im_func'): ! x = x.im_func ! if hasattr(x, 'func_code'): ! x = x.func_code ! if hasattr(x, 'co_code'): ! disassemble(x) ! else: ! raise TypeError, \ ! "don't know how to disassemble %s objects" % \ ! type(x).__name__ def distb(tb=None): ! """Disassemble a traceback (default: last traceback).""" ! if not tb: ! try: ! tb = sys.last_traceback ! except AttributeError: ! raise RuntimeError, "no last traceback to disassemble" ! while tb.tb_next: tb = tb.tb_next ! disassemble(tb.tb_frame.f_code, tb.tb_lasti) def disassemble(co, lasti=-1): ! """Disassemble a code object.""" ! code = co.co_code ! labels = findlabels(code) ! n = len(code) ! i = 0 ! extended_arg = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! if op == SET_LINENO and i > 0: print # Extra blank line ! if i == lasti: print '-->', ! else: print ' ', ! if i in labels: print '>>', ! else: print ' ', ! print string.rjust(`i`, 4), ! print string.ljust(opname[op], 20), ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 + extended_arg ! extended_arg = 0 ! i = i+2 ! if op == EXTENDED_ARG: ! extended_arg = oparg*65536L ! print string.rjust(`oparg`, 5), ! if op in hasconst: ! print '(' + `co.co_consts[oparg]` + ')', ! elif op in hasname: ! print '(' + co.co_names[oparg] + ')', ! elif op in hasjrel: ! print '(to ' + `i + oparg` + ')', ! elif op in haslocal: ! print '(' + co.co_varnames[oparg] + ')', ! elif op in hascompare: ! print '(' + cmp_op[oparg] + ')', ! print ! disco = disassemble # XXX For backwards compatibility def findlabels(code): ! """Detect all offsets in a byte code which are jump targets. ! Return the list of offsets. ! """ ! labels = [] ! n = len(code) ! i = 0 ! while i < n: ! c = code[i] ! op = ord(c) ! i = i+1 ! if op >= HAVE_ARGUMENT: ! oparg = ord(code[i]) + ord(code[i+1])*256 ! i = i+2 ! label = -1 ! if op in hasjrel: ! label = i+oparg ! elif op in hasjabs: ! label = oparg ! if label >= 0: ! if label not in labels: ! labels.append(label) ! return labels cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', *************** *** 130,146 **** def def_op(name, op): ! opname[op] = name def name_op(name, op): ! opname[op] = name ! hasname.append(op) def jrel_op(name, op): ! opname[op] = name ! hasjrel.append(op) def jabs_op(name, op): ! opname[op] = name ! hasjabs.append(op) # Instruction opcodes for compiled code --- 130,146 ---- def def_op(name, op): ! opname[op] = name def name_op(name, op): ! opname[op] = name ! hasname.append(op) def jrel_op(name, op): ! opname[op] = name ! hasjrel.append(op) def jabs_op(name, op): ! opname[op] = name ! hasjabs.append(op) # Instruction opcodes for compiled code *************** *** 220,266 **** def_op('BUILD_CLASS', 89) ! HAVE_ARGUMENT = 90 # Opcodes from here have an argument: ! name_op('STORE_NAME', 90) # Index in name list ! name_op('DELETE_NAME', 91) # "" ! def_op('UNPACK_SEQUENCE', 92) # Number of tuple items ! ! name_op('STORE_ATTR', 95) # Index in name list ! name_op('DELETE_ATTR', 96) # "" ! name_op('STORE_GLOBAL', 97) # "" ! name_op('DELETE_GLOBAL', 98) # "" ! def_op('DUP_TOPX', 99) # number of items to duplicate ! def_op('LOAD_CONST', 100) # Index in const list hasconst.append(100) ! name_op('LOAD_NAME', 101) # Index in name list ! def_op('BUILD_TUPLE', 102) # Number of tuple items ! def_op('BUILD_LIST', 103) # Number of list items ! def_op('BUILD_MAP', 104) # Always zero for now ! name_op('LOAD_ATTR', 105) # Index in name list ! def_op('COMPARE_OP', 106) # Comparison operator hascompare.append(106) ! name_op('IMPORT_NAME', 107) # Index in name list ! name_op('IMPORT_FROM', 108) # Index in name list ! jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip ! jrel_op('JUMP_IF_FALSE', 111) # "" ! jrel_op('JUMP_IF_TRUE', 112) # "" ! jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code ! jrel_op('FOR_LOOP', 114) # Number of bytes to skip ! ! name_op('LOAD_GLOBAL', 116) # Index in name list ! ! jrel_op('SETUP_LOOP', 120) # Distance to target address ! jrel_op('SETUP_EXCEPT', 121) # "" ! jrel_op('SETUP_FINALLY', 122) # "" ! def_op('LOAD_FAST', 124) # Local variable number haslocal.append(124) ! def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) ! def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) ! def_op('SET_LINENO', 127) # Current line number SET_LINENO = 127 --- 220,266 ---- def_op('BUILD_CLASS', 89) ! HAVE_ARGUMENT = 90 # Opcodes from here have an argument: ! name_op('STORE_NAME', 90) # Index in name list ! name_op('DELETE_NAME', 91) # "" ! def_op('UNPACK_SEQUENCE', 92) # Number of tuple items ! ! name_op('STORE_ATTR', 95) # Index in name list ! name_op('DELETE_ATTR', 96) # "" ! name_op('STORE_GLOBAL', 97) # "" ! name_op('DELETE_GLOBAL', 98) # "" ! def_op('DUP_TOPX', 99) # number of items to duplicate ! def_op('LOAD_CONST', 100) # Index in const list hasconst.append(100) ! name_op('LOAD_NAME', 101) # Index in name list ! def_op('BUILD_TUPLE', 102) # Number of tuple items ! def_op('BUILD_LIST', 103) # Number of list items ! def_op('BUILD_MAP', 104) # Always zero for now ! name_op('LOAD_ATTR', 105) # Index in name list ! def_op('COMPARE_OP', 106) # Comparison operator hascompare.append(106) ! name_op('IMPORT_NAME', 107) # Index in name list ! name_op('IMPORT_FROM', 108) # Index in name list ! jrel_op('JUMP_FORWARD', 110) # Number of bytes to skip ! jrel_op('JUMP_IF_FALSE', 111) # "" ! jrel_op('JUMP_IF_TRUE', 112) # "" ! jabs_op('JUMP_ABSOLUTE', 113) # Target byte offset from beginning of code ! jrel_op('FOR_LOOP', 114) # Number of bytes to skip ! ! name_op('LOAD_GLOBAL', 116) # Index in name list ! ! jrel_op('SETUP_LOOP', 120) # Distance to target address ! jrel_op('SETUP_EXCEPT', 121) # "" ! jrel_op('SETUP_FINALLY', 122) # "" ! def_op('LOAD_FAST', 124) # Local variable number haslocal.append(124) ! def_op('STORE_FAST', 125) # Local variable number haslocal.append(125) ! def_op('DELETE_FAST', 126) # Local variable number haslocal.append(126) ! def_op('SET_LINENO', 127) # Current line number SET_LINENO = 127 *************** *** 274,303 **** def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8) ! def_op('EXTENDED_ARG', 143) EXTENDED_ARG = 143 def _test(): ! """Simple test program to disassemble a file.""" ! if sys.argv[1:]: ! if sys.argv[2:]: ! sys.stderr.write("usage: python dis.py [-|file]\n") ! sys.exit(2) ! fn = sys.argv[1] ! if not fn or fn == "-": ! fn = None ! else: ! fn = None ! if not fn: ! f = sys.stdin ! else: ! f = open(fn) ! source = f.read() ! if fn: ! f.close() ! else: ! fn = "" ! code = compile(source, fn, "exec") ! dis(code) if __name__ == "__main__": ! _test() --- 274,303 ---- def_op('CALL_FUNCTION_VAR_KW', 142) # #args + (#kwargs << 8) ! def_op('EXTENDED_ARG', 143) EXTENDED_ARG = 143 def _test(): ! """Simple test program to disassemble a file.""" ! if sys.argv[1:]: ! if sys.argv[2:]: ! sys.stderr.write("usage: python dis.py [-|file]\n") ! sys.exit(2) ! fn = sys.argv[1] ! if not fn or fn == "-": ! fn = None ! else: ! fn = None ! if not fn: ! f = sys.stdin ! else: ! f = open(fn) ! source = f.read() ! if fn: ! f.close() ! else: ! fn = "" ! code = compile(source, fn, "exec") ! dis(code) if __name__ == "__main__": ! _test() Index: dospath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dospath.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** dospath.py 2000/12/12 23:20:44 1.20 --- dospath.py 2001/01/14 23:36:05 1.21 *************** *** 11,16 **** Other normalizations (such as optimizing '../' away) are not allowed (this is done by normpath). ! Previously, this version mapped invalid consecutive characters to a ! single '_', but this has been removed. This functionality should possibly be added as a new function.""" --- 11,16 ---- Other normalizations (such as optimizing '../' away) are not allowed (this is done by normpath). ! Previously, this version mapped invalid consecutive characters to a ! single '_', but this has been removed. This functionality should possibly be added as a new function.""" Index: dumbdbm.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/dumbdbm.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** dumbdbm.py 2000/12/11 20:33:52 1.6 --- dumbdbm.py 2001/01/14 23:36:05 1.7 *************** *** 29,144 **** _BLOCKSIZE = 512 ! error = IOError # For anydbm class _Database: ! def __init__(self, file): ! self._dirfile = file + '.dir' ! self._datfile = file + '.dat' ! self._bakfile = file + '.bak' ! # Mod by Jack: create data file if needed ! try: ! f = _open(self._datfile, 'r') ! except IOError: ! f = _open(self._datfile, 'w') ! f.close() ! self._update() ! ! def _update(self): ! self._index = {} ! try: ! f = _open(self._dirfile) ! except IOError: ! pass ! else: ! while 1: ! line = f.readline().rstrip() ! if not line: break ! key, (pos, siz) = eval(line) ! self._index[key] = (pos, siz) ! f.close() ! ! def _commit(self): ! try: _os.unlink(self._bakfile) ! except _os.error: pass ! try: _os.rename(self._dirfile, self._bakfile) ! except _os.error: pass ! f = _open(self._dirfile, 'w') ! for key, (pos, siz) in self._index.items(): ! f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`)) ! f.close() ! ! def __getitem__(self, key): ! pos, siz = self._index[key] # may raise KeyError ! f = _open(self._datfile, 'rb') ! f.seek(pos) ! dat = f.read(siz) ! f.close() ! return dat ! ! def _addval(self, val): ! f = _open(self._datfile, 'rb+') ! f.seek(0, 2) ! pos = int(f.tell()) ## Does not work under MW compiler ! ## pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ! ## f.seek(pos) ! npos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ! f.write('\0'*(npos-pos)) ! pos = npos ! ! f.write(val) ! f.close() ! return (pos, len(val)) ! ! def _setval(self, pos, val): ! f = _open(self._datfile, 'rb+') ! f.seek(pos) ! f.write(val) ! f.close() ! return (pos, len(val)) ! ! def _addkey(self, key, (pos, siz)): ! self._index[key] = (pos, siz) ! f = _open(self._dirfile, 'a') ! f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`)) ! f.close() ! ! def __setitem__(self, key, val): ! if not type(key) == type('') == type(val): ! raise TypeError, "keys and values must be strings" ! if not self._index.has_key(key): ! (pos, siz) = self._addval(val) ! self._addkey(key, (pos, siz)) ! else: ! pos, siz = self._index[key] ! oldblocks = (siz + _BLOCKSIZE - 1) / _BLOCKSIZE ! newblocks = (len(val) + _BLOCKSIZE - 1) / _BLOCKSIZE ! if newblocks <= oldblocks: ! pos, siz = self._setval(pos, val) ! self._index[key] = pos, siz ! else: ! pos, siz = self._addval(val) ! self._index[key] = pos, siz ! ! def __delitem__(self, key): ! del self._index[key] ! self._commit() ! ! def keys(self): ! return self._index.keys() ! ! def has_key(self, key): ! return self._index.has_key(key) ! ! def __len__(self): ! return len(self._index) ! ! def close(self): ! self._index = None ! self._datfile = self._dirfile = self._bakfile = None def open(file, flag = None, mode = None): ! # flag, mode arguments are currently ignored ! return _Database(file) --- 29,144 ---- _BLOCKSIZE = 512 ! error = IOError # For anydbm class _Database: ! def __init__(self, file): ! self._dirfile = file + '.dir' ! self._datfile = file + '.dat' ! self._bakfile = file + '.bak' ! # Mod by Jack: create data file if needed ! try: ! f = _open(self._datfile, 'r') ! except IOError: ! f = _open(self._datfile, 'w') ! f.close() ! self._update() ! ! def _update(self): ! self._index = {} ! try: ! f = _open(self._dirfile) ! except IOError: ! pass ! else: ! while 1: ! line = f.readline().rstrip() ! if not line: break ! key, (pos, siz) = eval(line) ! self._index[key] = (pos, siz) ! f.close() ! ! def _commit(self): ! try: _os.unlink(self._bakfile) ! except _os.error: pass ! try: _os.rename(self._dirfile, self._bakfile) ! except _os.error: pass ! f = _open(self._dirfile, 'w') ! for key, (pos, siz) in self._index.items(): ! f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`)) ! f.close() ! ! def __getitem__(self, key): ! pos, siz = self._index[key] # may raise KeyError ! f = _open(self._datfile, 'rb') ! f.seek(pos) ! dat = f.read(siz) ! f.close() ! return dat ! ! def _addval(self, val): ! f = _open(self._datfile, 'rb+') ! f.seek(0, 2) ! pos = int(f.tell()) ## Does not work under MW compiler ! ## pos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ! ## f.seek(pos) ! npos = ((pos + _BLOCKSIZE - 1) / _BLOCKSIZE) * _BLOCKSIZE ! f.write('\0'*(npos-pos)) ! pos = npos ! ! f.write(val) ! f.close() ! return (pos, len(val)) ! ! def _setval(self, pos, val): ! f = _open(self._datfile, 'rb+') ! f.seek(pos) ! f.write(val) ! f.close() ! return (pos, len(val)) ! ! def _addkey(self, key, (pos, siz)): ! self._index[key] = (pos, siz) ! f = _open(self._dirfile, 'a') ! f.write("%s, (%s, %s)\n" % (`key`, `pos`, `siz`)) ! f.close() ! ! def __setitem__(self, key, val): ! if not type(key) == type('') == type(val): ! raise TypeError, "keys and values must be strings" ! if not self._index.has_key(key): ! (pos, siz) = self._addval(val) ! self._addkey(key, (pos, siz)) ! else: ! pos, siz = self._index[key] ! oldblocks = (siz + _BLOCKSIZE - 1) / _BLOCKSIZE ! newblocks = (len(val) + _BLOCKSIZE - 1) / _BLOCKSIZE ! if newblocks <= oldblocks: ! pos, siz = self._setval(pos, val) ! self._index[key] = pos, siz ! else: ! pos, siz = self._addval(val) ! self._index[key] = pos, siz ! ! def __delitem__(self, key): ! del self._index[key] ! self._commit() ! ! def keys(self): ! return self._index.keys() ! ! def has_key(self, key): ! return self._index.has_key(key) ! ! def __len__(self): ! return len(self._index) ! ! def close(self): ! self._index = None ! self._datfile = self._dirfile = self._bakfile = None def open(file, flag = None, mode = None): ! # flag, mode arguments are currently ignored ! return _Database(file) Index: filecmp.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/filecmp.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** filecmp.py 2000/12/12 23:20:44 1.8 --- filecmp.py 2001/01/14 23:36:05 1.9 *************** *** 292,298 **** # Compare two files. # Return: ! # 0 for equal ! # 1 for different ! # 2 for funny cases (can't stat, etc.) # def _cmp(a, b, sh, st): --- 292,298 ---- # Compare two files. # Return: ! # 0 for equal ! # 1 for different ! # 2 for funny cases (can't stat, etc.) # def _cmp(a, b, sh, st): Index: fnmatch.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fnmatch.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** fnmatch.py 2000/06/28 14:48:01 1.8 --- fnmatch.py 2001/01/14 23:36:05 1.9 *************** *** 16,89 **** def fnmatch(name, pat): ! """Test whether FILENAME matches PATTERN. ! ! Patterns are Unix shell style: ! ! * matches everything ! ? matches any single character ! [seq] matches any character in seq ! [!seq] matches any char not in seq ! ! An initial period in FILENAME is not special. ! Both FILENAME and PATTERN are first case-normalized ! if the operating system requires it. ! If you don't want this, use fnmatchcase(FILENAME, PATTERN). ! """ ! ! import os ! name = os.path.normcase(name) ! pat = os.path.normcase(pat) ! return fnmatchcase(name, pat) def fnmatchcase(name, pat): ! """Test whether FILENAME matches PATTERN, including case. ! ! This is a version of fnmatch() which doesn't case-normalize ! its arguments. ! """ ! ! if not _cache.has_key(pat): ! res = translate(pat) ! _cache[pat] = re.compile(res) ! return _cache[pat].match(name) is not None def translate(pat): ! """Translate a shell PATTERN to a regular expression. ! ! There is no way to quote meta-characters. ! """ ! ! i, n = 0, len(pat) ! res = '' ! while i < n: ! c = pat[i] ! i = i+1 ! if c == '*': ! res = res + '.*' ! elif c == '?': ! res = res + '.' ! elif c == '[': ! j = i ! if j < n and pat[j] == '!': ! j = j+1 ! if j < n and pat[j] == ']': ! j = j+1 ! while j < n and pat[j] != ']': ! j = j+1 ! if j >= n: ! res = res + '\\[' ! else: ! stuff = pat[i:j] ! i = j+1 ! if stuff[0] == '!': ! stuff = '[^' + stuff[1:] + ']' ! elif stuff == '^'*len(stuff): ! stuff = '\\^' ! else: ! while stuff[0] == '^': ! stuff = stuff[1:] + stuff[0] ! stuff = '[' + stuff + ']' ! res = res + stuff ! else: ! res = res + re.escape(c) ! return res + "$" --- 16,89 ---- def fnmatch(name, pat): ! """Test whether FILENAME matches PATTERN. + Patterns are Unix shell style: + + * matches everything + ? matches any single character + [seq] matches any character in seq + [!seq] matches any char not in seq + + An initial period in FILENAME is not special. + Both FILENAME and PATTERN are first case-normalized + if the operating system requires it. + If you don't want this, use fnmatchcase(FILENAME, PATTERN). + """ + + import os + name = os.path.normcase(name) + pat = os.path.normcase(pat) + return fnmatchcase(name, pat) + def fnmatchcase(name, pat): ! """Test whether FILENAME matches PATTERN, including case. + This is a version of fnmatch() which doesn't case-normalize + its arguments. + """ + + if not _cache.has_key(pat): + res = translate(pat) + _cache[pat] = re.compile(res) + return _cache[pat].match(name) is not None + def translate(pat): ! """Translate a shell PATTERN to a regular expression. ! ! There is no way to quote meta-characters. ! """ ! ! i, n = 0, len(pat) ! res = '' ! while i < n: ! c = pat[i] ! i = i+1 ! if c == '*': ! res = res + '.*' ! elif c == '?': ! res = res + '.' ! elif c == '[': ! j = i ! if j < n and pat[j] == '!': ! j = j+1 ! if j < n and pat[j] == ']': ! j = j+1 ! while j < n and pat[j] != ']': ! j = j+1 ! if j >= n: ! res = res + '\\[' ! else: ! stuff = pat[i:j] ! i = j+1 ! if stuff[0] == '!': ! stuff = '[^' + stuff[1:] + ']' ! elif stuff == '^'*len(stuff): ! stuff = '\\^' ! else: ! while stuff[0] == '^': ! stuff = stuff[1:] + stuff[0] ! stuff = '[' + stuff + ']' ! res = res + stuff ! else: ! res = res + re.escape(c) ! return res + "$" Index: formatter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/formatter.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** formatter.py 2000/02/04 15:39:29 1.15 --- formatter.py 2001/01/14 23:36:05 1.16 *************** *** 10,14 **** arbitrary, non-exclusive style settings to a writer as well. Additional interfaces facilitate formatting events which are not reversible, such as ! paragraph separation. Writer objects encapsulate device interfaces. Abstract devices, such as --- 10,14 ---- arbitrary, non-exclusive style settings to a writer as well. Additional interfaces facilitate formatting events which are not reversible, such as ! paragraph separation. Writer objects encapsulate device interfaces. Abstract devices, such as *************** *** 16,20 **** implementations all work with abstract devices. The interface makes available mechanisms for setting the properties which formatter objects ! manage and inserting data into the output. """ --- 16,20 ---- implementations all work with abstract devices. The interface makes available mechanisms for setting the properties which formatter objects ! manage and inserting data into the output. """ Index: fpformat.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/fpformat.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** fpformat.py 2000/02/04 15:10:32 1.7 --- fpformat.py 2001/01/14 23:36:06 1.8 *************** *** 139,141 **** except (EOFError, KeyboardInterrupt): pass - --- 139,140 ---- Index: ftplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ftplib.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -r1.46 -r1.47 *** ftplib.py 2000/12/12 23:20:44 1.46 --- ftplib.py 2001/01/14 23:36:06 1.47 *************** *** 23,27 **** >>> ftp.quit() '221 Goodbye.' ! >>> A nice test that reveals some of the network dialogue would be: --- 23,27 ---- >>> ftp.quit() '221 Goodbye.' ! >>> [...1350 lines suppressed...] ! sys.stderr.write( ! "No account -- using anonymous login.") ! ftp.login(userid, passwd, acct) ! for file in sys.argv[2:]: ! if file[:2] == '-l': ! ftp.dir(file[2:]) ! elif file[:2] == '-d': ! cmd = 'CWD' ! if file[2:]: cmd = cmd + ' ' + file[2:] ! resp = ftp.sendcmd(cmd) ! elif file == '-p': ! ftp.set_pasv(not ftp.passiveserver) ! else: ! ftp.retrbinary('RETR ' + file, \ ! sys.stdout.write, 1024) ! ftp.quit() if __name__ == '__main__': ! test() From python-dev@python.org Sun Jan 14 23:47:16 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 14 Jan 2001 15:47:16 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib MimeWriter.py,1.4,1.5 getpass.py,1.9,1.10 gettext.py,1.9,1.10 glob.py,1.7,1.8 gzip.py,1.19,1.20 htmlentitydefs.py,1.5,1.6 htmllib.py,1.14,1.15 httplib.py,1.29,1.30 ihooks.py,1.10,1.11 imaplib.py,1.21,1.22 imghdr.py,1.9,1.10 imputil.py,1.15,1.16 macurl2path.py,1.8,1.9 mailcap.py,1.6,1.7 mimetools.py,1.20,1.21 mimify.py,1.15,1.16 multifile.py,1.13,1.14 mutex.py,1.6,1.7 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv30612/python/dist/src/lib Modified Files: MimeWriter.py getpass.py gettext.py glob.py gzip.py htmlentitydefs.py htmllib.py httplib.py ihooks.py imaplib.py imghdr.py imputil.py macurl2path.py mailcap.py mimetools.py mimify.py multifile.py mutex.py Log Message: Whitespace normalization. Index: MimeWriter.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/MimeWriter.py,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -r1.4 -r1.5 *** MimeWriter.py 1998/04/23 13:34:57 1.4 --- MimeWriter.py 2001/01/14 23:47:14 1.5 *************** *** 31,35 **** order they should occur on the output file. It does buffer the headers you add, allowing you to rearrange their order. ! General usage is: --- 31,35 ---- order they should occur on the output file. It does buffer the headers you add, allowing you to rearrange their order. ! General usage is: Index: getpass.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/getpass.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** getpass.py 2000/02/28 15:12:25 1.9 --- getpass.py 2001/01/14 23:47:14 1.10 *************** *** 15,119 **** def unix_getpass(prompt='Password: '): ! """Prompt for a password, with echo turned off. ! Restore terminal settings at end. ! """ ! try: ! fd = sys.stdin.fileno() ! except: ! return default_getpass(prompt) ! ! getpass = default_getpass ! old = termios.tcgetattr(fd) # a copy to save ! new = old[:] ! ! new[3] = new[3] & ~TERMIOS.ECHO # 3 == 'lflags' ! try: ! termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new) ! passwd = _raw_input(prompt) ! finally: ! termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old) ! sys.stdout.write('\n') ! return passwd def win_getpass(prompt='Password: '): ! """Prompt for password with echo off, using Windows getch().""" ! import msvcrt ! for c in prompt: ! msvcrt.putch(c) ! pw = "" ! while 1: ! c = msvcrt.getch() ! if c == '\r' or c == '\n': ! break ! if c == '\003': ! raise KeyboardInterrupt ! if c == '\b': ! pw = pw[:-1] ! else: ! pw = pw + c ! msvcrt.putch('\r') ! msvcrt.putch('\n') ! return pw def default_getpass(prompt='Password: '): ! print "Warning: Problem with getpass. Passwords may be echoed." ! return _raw_input(prompt) def _raw_input(prompt=""): ! # A raw_input() replacement that doesn't save the string in the ! # GNU readline history. ! import sys ! prompt = str(prompt) ! if prompt: ! sys.stdout.write(prompt) ! line = sys.stdin.readline() ! if not line: ! raise EOFError ! if line[-1] == '\n': ! line = line[:-1] ! return line def getuser(): ! """Get the username from the environment or password database. ! First try various environment variables, then the password ! database. This works on Windows as long as USERNAME is set. ! """ ! import os ! for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): ! user = os.environ.get(name) ! if user: ! return user ! # If this fails, the exception will "explain" why ! import pwd ! return pwd.getpwuid(os.getuid())[0] # Bind the name getpass to the appropriate function try: ! import termios, TERMIOS except ImportError: ! try: ! import msvcrt ! except ImportError: ! try: ! from EasyDialogs import AskPassword ! except ImportError: ! getpass = default_getpass ! else: ! getpass = AskPassword ! else: ! getpass = win_getpass else: ! getpass = unix_getpass ! --- 15,118 ---- def unix_getpass(prompt='Password: '): ! """Prompt for a password, with echo turned off. ! Restore terminal settings at end. ! """ ! try: ! fd = sys.stdin.fileno() ! except: ! return default_getpass(prompt) ! ! getpass = default_getpass ! old = termios.tcgetattr(fd) # a copy to save ! new = old[:] ! ! new[3] = new[3] & ~TERMIOS.ECHO # 3 == 'lflags' ! try: ! termios.tcsetattr(fd, TERMIOS.TCSADRAIN, new) ! passwd = _raw_input(prompt) ! finally: ! termios.tcsetattr(fd, TERMIOS.TCSADRAIN, old) ! sys.stdout.write('\n') ! return passwd def win_getpass(prompt='Password: '): ! """Prompt for password with echo off, using Windows getch().""" ! import msvcrt ! for c in prompt: ! msvcrt.putch(c) ! pw = "" ! while 1: ! c = msvcrt.getch() ! if c == '\r' or c == '\n': ! break ! if c == '\003': ! raise KeyboardInterrupt ! if c == '\b': ! pw = pw[:-1] ! else: ! pw = pw + c ! msvcrt.putch('\r') ! msvcrt.putch('\n') ! return pw def default_getpass(prompt='Password: '): ! print "Warning: Problem with getpass. Passwords may be echoed." ! return _raw_input(prompt) def _raw_input(prompt=""): ! # A raw_input() replacement that doesn't save the string in the ! # GNU readline history. ! import sys ! prompt = str(prompt) ! if prompt: ! sys.stdout.write(prompt) ! line = sys.stdin.readline() ! if not line: ! raise EOFError ! if line[-1] == '\n': ! line = line[:-1] ! return line def getuser(): ! """Get the username from the environment or password database. ! First try various environment variables, then the password ! database. This works on Windows as long as USERNAME is set. ! """ ! import os ! for name in ('LOGNAME', 'USER', 'LNAME', 'USERNAME'): ! user = os.environ.get(name) ! if user: ! return user ! # If this fails, the exception will "explain" why ! import pwd ! return pwd.getpwuid(os.getuid())[0] # Bind the name getpass to the appropriate function try: ! import termios, TERMIOS except ImportError: ! try: ! import msvcrt ! except ImportError: ! try: ! from EasyDialogs import AskPassword ! except ImportError: ! getpass = default_getpass ! else: ! getpass = AskPassword ! else: ! getpass = win_getpass else: ! getpass = unix_getpass Index: gettext.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/gettext.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** gettext.py 2000/10/16 15:47:50 1.9 --- gettext.py 2001/01/14 23:47:14 1.10 *************** *** 52,56 **** ! def _expand_lang(locale): from locale import normalize --- 52,56 ---- ! def _expand_lang(locale): from locale import normalize *************** *** 94,99 **** return ret - class NullTranslations: def __init__(self, fp=None): --- 94,99 ---- return ret + class NullTranslations: def __init__(self, fp=None): *************** *** 193,197 **** ! # Locate a .mo file using the gettext strategy def find(domain, localedir=None, languages=None): --- 193,197 ---- ! # Locate a .mo file using the gettext strategy def find(domain, localedir=None, languages=None): *************** *** 223,228 **** return None - # a mapping between absolute .mo file path and Translation object _translations = {} --- 223,228 ---- return None + # a mapping between absolute .mo file path and Translation object _translations = {} *************** *** 244,253 **** ! def install(domain, localedir=None, unicode=0): translation(domain, localedir).install(unicode) - # a mapping b/w domains and locale directories _localedirs = {} --- 244,253 ---- ! def install(domain, localedir=None, unicode=0): translation(domain, localedir).install(unicode) + # a mapping b/w domains and locale directories _localedirs = {} *************** *** 276,280 **** return message return t.gettext(message) ! def gettext(message): --- 276,280 ---- return message return t.gettext(message) ! def gettext(message): Index: glob.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/glob.py,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -r1.7 -r1.8 *** glob.py 1997/10/22 20:57:46 1.7 --- glob.py 2001/01/14 23:47:14 1.8 *************** *** 7,52 **** def glob(pathname): ! """Return a list of paths matching a pathname pattern. ! The pattern may contain simple shell-style wildcards a la fnmatch. ! """ ! if not has_magic(pathname): ! if os.path.exists(pathname): ! return [pathname] ! else: ! return [] ! dirname, basename = os.path.split(pathname) ! if has_magic(dirname): ! list = glob(dirname) ! else: ! list = [dirname] ! if not has_magic(basename): ! result = [] ! for dirname in list: ! if basename or os.path.isdir(dirname): ! name = os.path.join(dirname, basename) ! if os.path.exists(name): ! result.append(name) ! else: ! result = [] ! for dirname in list: ! sublist = glob1(dirname, basename) ! for name in sublist: ! result.append(os.path.join(dirname, name)) ! return result def glob1(dirname, pattern): ! if not dirname: dirname = os.curdir ! try: ! names = os.listdir(dirname) ! except os.error: ! return [] ! result = [] ! for name in names: ! if name[0] != '.' or pattern[0] == '.': ! if fnmatch.fnmatch(name, pattern): ! result.append(name) ! return result --- 7,52 ---- def glob(pathname): ! """Return a list of paths matching a pathname pattern. ! The pattern may contain simple shell-style wildcards a la fnmatch. ! """ ! if not has_magic(pathname): ! if os.path.exists(pathname): ! return [pathname] ! else: ! return [] ! dirname, basename = os.path.split(pathname) ! if has_magic(dirname): ! list = glob(dirname) ! else: ! list = [dirname] ! if not has_magic(basename): ! result = [] ! for dirname in list: ! if basename or os.path.isdir(dirname): ! name = os.path.join(dirname, basename) ! if os.path.exists(name): ! result.append(name) ! else: ! result = [] ! for dirname in list: ! sublist = glob1(dirname, basename) ! for name in sublist: ! result.append(os.path.join(dirname, name)) ! return result def glob1(dirname, pattern): ! if not dirname: dirname = os.curdir ! try: ! names = os.listdir(dirname) ! except os.error: ! return [] ! result = [] ! for name in names: ! if name[0] != '.' or pattern[0] == '.': ! if fnmatch.fnmatch(name, pattern): ! result.append(name) ! return result *************** *** 54,56 **** def has_magic(s): ! return magic_check.search(s) is not None --- 54,56 ---- def has_magic(s): ! return magic_check.search(s) is not None Index: gzip.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/gzip.py,v retrieving revision 1.19 retrieving revision 1.20 diff -C2 -r1.19 -r1.20 *** gzip.py 2000/07/29 20:15:26 1.19 --- gzip.py 2001/01/14 23:47:14 1.20 *************** *** 16,20 **** def write32(output, value): output.write(struct.pack(" self.extrasize: size = self.extrasize ! chunk = self.extrabuf[:size] self.extrabuf = self.extrabuf[size:] --- 159,163 ---- if size > self.extrasize: size = self.extrasize ! chunk = self.extrabuf[:size] self.extrabuf = self.extrabuf[size:] *************** *** 172,180 **** def _read(self, size=1024): if self.fileobj is None: raise EOFError, "Reached EOF" ! if self._new_member: # If the _new_member flag is set, we have to # jump to the next member, if there is one. ! # # First, check if we're at the end of the file; # if so, it's time to stop; no more members to read. --- 172,180 ---- def _read(self, size=1024): if self.fileobj is None: raise EOFError, "Reached EOF" ! if self._new_member: # If the _new_member flag is set, we have to # jump to the next member, if there is one. ! # # First, check if we're at the end of the file; # if so, it's time to stop; no more members to read. *************** *** 184,201 **** self.fileobj = None raise EOFError, "Reached EOF" ! else: self.fileobj.seek( pos ) # Return to original position ! ! self._init_read() self._read_gzip_header() self.decompress = zlib.decompressobj(-zlib.MAX_WBITS) self._new_member = 0 ! # Read a chunk of data from the file buf = self.fileobj.read(size) ! # If the EOF has been reached, flush the decompression object # and mark this object as finished. ! if buf == "": uncompress = self.decompress.flush() --- 184,201 ---- self.fileobj = None raise EOFError, "Reached EOF" ! else: self.fileobj.seek( pos ) # Return to original position ! ! self._init_read() self._read_gzip_header() self.decompress = zlib.decompressobj(-zlib.MAX_WBITS) self._new_member = 0 ! # Read a chunk of data from the file buf = self.fileobj.read(size) ! # If the EOF has been reached, flush the decompression object # and mark this object as finished. ! if buf == "": uncompress = self.decompress.flush() *************** *** 204,208 **** self._add_read_data( uncompress ) raise EOFError, 'Reached EOF' ! uncompress = self.decompress.decompress(buf) self._add_read_data( uncompress ) --- 204,208 ---- self._add_read_data( uncompress ) raise EOFError, 'Reached EOF' ! uncompress = self.decompress.decompress(buf) self._add_read_data( uncompress ) *************** *** 217,225 **** # Check the CRC and file size, and set the flag so we read ! # a new member on the next call self._read_eof() ! self._new_member = 1 ! ! def _add_read_data(self, data): self.crc = zlib.crc32(data, self.crc) self.extrabuf = self.extrabuf + data --- 217,225 ---- # Check the CRC and file size, and set the flag so we read ! # a new member on the next call self._read_eof() ! self._new_member = 1 ! ! def _add_read_data(self, data): self.crc = zlib.crc32(data, self.crc) self.extrabuf = self.extrabuf + data *************** *** 229,233 **** def _read_eof(self): # We've read to the end of the file, so we have to rewind in order ! # to reread the 8 bytes containing the CRC and the file size. # We check the that the computed CRC and size of the # uncompressed data matches the stored values. --- 229,233 ---- def _read_eof(self): # We've read to the end of the file, so we have to rewind in order ! # to reread the 8 bytes containing the CRC and the file size. # We check the that the computed CRC and size of the # uncompressed data matches the stored values. *************** *** 239,243 **** elif isize != self.size: raise ValueError, "Incorrect length of data produced" ! def close(self): if self.mode == WRITE: --- 239,243 ---- elif isize != self.size: raise ValueError, "Incorrect length of data produced" ! def close(self): if self.mode == WRITE: *************** *** 260,264 **** return self.close() ! def flush(self): self.fileobj.flush() --- 260,264 ---- return self.close() ! def flush(self): self.fileobj.flush() *************** *** 286,290 **** if size is not None: # We set i=size to break out of the loop under two ! # conditions: 1) there's no newline, and the chunk is # larger than size, or 2) there is a newline, but the # resulting line would be longer than 'size'. --- 286,290 ---- if size is not None: # We set i=size to break out of the loop under two ! # conditions: 1) there's no newline, and the chunk is # larger than size, or 2) there is a newline, but the # resulting line would be longer than 'size'. *************** *** 301,305 **** size = size - len(c) readsize = min(size, readsize * 2) ! def readlines(self, sizehint=0): # Negative numbers result in reading all the lines --- 301,305 ---- size = size - len(c) readsize = min(size, readsize * 2) ! def readlines(self, sizehint=0): # Negative numbers result in reading all the lines Index: htmlentitydefs.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/htmlentitydefs.py,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -r1.5 -r1.6 *** htmlentitydefs.py 2000/02/04 15:10:33 1.5 --- htmlentitydefs.py 2001/01/14 23:47:14 1.6 *************** *** 2,257 **** entitydefs = { ! 'AElig': '\306', # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 ! 'Aacute': '\301', # latin capital letter A with acute, U+00C1 ISOlat1 ! 'Acirc': '\302', # latin capital letter A with circumflex, U+00C2 ISOlat1 ! 'Agrave': '\300', # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 ! 'Alpha': 'Α', # greek capital letter alpha, U+0391 ! 'Aring': '\305', # latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 ! 'Atilde': '\303', # latin capital letter A with tilde, U+00C3 ISOlat1 ! 'Auml': '\304', # latin capital letter A with diaeresis, U+00C4 ISOlat1 ! 'Beta': 'Β', # greek capital letter beta, U+0392 ! 'Ccedil': '\307', # latin capital letter C with cedilla, U+00C7 ISOlat1 ! 'Chi': 'Χ', # greek capital letter chi, U+03A7 ! 'Dagger': '‡', # double dagger, U+2021 ISOpub ! 'Delta': 'Δ', # greek capital letter delta, U+0394 ISOgrk3 ! 'ETH': '\320', # latin capital letter ETH, U+00D0 ISOlat1 ! 'Eacute': '\311', # latin capital letter E with acute, U+00C9 ISOlat1 ! 'Ecirc': '\312', # latin capital letter E with circumflex, U+00CA ISOlat1 ! 'Egrave': '\310', # latin capital letter E with grave, U+00C8 ISOlat1 ! 'Epsilon': 'Ε', # greek capital letter epsilon, U+0395 ! 'Eta': 'Η', # greek capital letter eta, U+0397 ! 'Euml': '\313', # latin capital letter E with diaeresis, U+00CB ISOlat1 ! 'Gamma': 'Γ', # greek capital letter gamma, U+0393 ISOgrk3 ! 'Iacute': '\315', # latin capital letter I with acute, U+00CD ISOlat1 ! 'Icirc': '\316', # latin capital letter I with circumflex, U+00CE ISOlat1 ! 'Igrave': '\314', # latin capital letter I with grave, U+00CC ISOlat1 ! 'Iota': 'Ι', # greek capital letter iota, U+0399 ! 'Iuml': '\317', # latin capital letter I with diaeresis, U+00CF ISOlat1 ! 'Kappa': 'Κ', # greek capital letter kappa, U+039A ! 'Lambda': 'Λ', # greek capital letter lambda, U+039B ISOgrk3 ! 'Mu': 'Μ', # greek capital letter mu, U+039C ! 'Ntilde': '\321', # latin capital letter N with tilde, U+00D1 ISOlat1 ! 'Nu': 'Ν', # greek capital letter nu, U+039D ! 'OElig': 'Œ', # latin capital ligature OE, U+0152 ISOlat2 ! 'Oacute': '\323', # latin capital letter O with acute, U+00D3 ISOlat1 ! 'Ocirc': '\324', # latin capital letter O with circumflex, U+00D4 ISOlat1 ! 'Ograve': '\322', # latin capital letter O with grave, U+00D2 ISOlat1 ! 'Omega': 'Ω', # greek capital letter omega, U+03A9 ISOgrk3 ! 'Omicron': 'Ο', # greek capital letter omicron, U+039F ! 'Oslash': '\330', # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 ! 'Otilde': '\325', # latin capital letter O with tilde, U+00D5 ISOlat1 ! 'Ouml': '\326', # latin capital letter O with diaeresis, U+00D6 ISOlat1 ! 'Phi': 'Φ', # greek capital letter phi, U+03A6 ISOgrk3 ! 'Pi': 'Π', # greek capital letter pi, U+03A0 ISOgrk3 ! 'Prime': '″', # double prime = seconds = inches, U+2033 ISOtech ! 'Psi': 'Ψ', # greek capital letter psi, U+03A8 ISOgrk3 ! 'Rho': 'Ρ', # greek capital letter rho, U+03A1 ! 'Scaron': 'Š', # latin capital letter S with caron, U+0160 ISOlat2 ! 'Sigma': 'Σ', # greek capital letter sigma, U+03A3 ISOgrk3 ! 'THORN': '\336', # latin capital letter THORN, U+00DE ISOlat1 ! 'Tau': 'Τ', # greek capital letter tau, U+03A4 ! 'Theta': 'Θ', # greek capital letter theta, U+0398 ISOgrk3 ! 'Uacute': '\332', # latin capital letter U with acute, U+00DA ISOlat1 ! 'Ucirc': '\333', # latin capital letter U with circumflex, U+00DB ISOlat1 ! 'Ugrave': '\331', # latin capital letter U with grave, U+00D9 ISOlat1 ! 'Upsilon': 'Υ', # greek capital letter upsilon, U+03A5 ISOgrk3 ! 'Uuml': '\334', # latin capital letter U with diaeresis, U+00DC ISOlat1 ! 'Xi': 'Ξ', # greek capital letter xi, U+039E ISOgrk3 ! 'Yacute': '\335', # latin capital letter Y with acute, U+00DD ISOlat1 ! 'Yuml': 'Ÿ', # latin capital letter Y with diaeresis, U+0178 ISOlat2 ! 'Zeta': 'Ζ', # greek capital letter zeta, U+0396 ! 'aacute': '\341', # latin small letter a with acute, U+00E1 ISOlat1 ! 'acirc': '\342', # latin small letter a with circumflex, U+00E2 ISOlat1 ! 'acute': '\264', # acute accent = spacing acute, U+00B4 ISOdia ! 'aelig': '\346', # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 ! 'agrave': '\340', # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 ! 'alefsym': 'ℵ', # alef symbol = first transfinite cardinal, U+2135 NEW ! 'alpha': 'α', # greek small letter alpha, U+03B1 ISOgrk3 ! 'amp': '\46', # ampersand, U+0026 ISOnum ! 'and': '∧', # logical and = wedge, U+2227 ISOtech ! 'ang': '∠', # angle, U+2220 ISOamso ! 'aring': '\345', # latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 ! 'asymp': '≈', # almost equal to = asymptotic to, U+2248 ISOamsr ! 'atilde': '\343', # latin small letter a with tilde, U+00E3 ISOlat1 ! 'auml': '\344', # latin small letter a with diaeresis, U+00E4 ISOlat1 ! 'bdquo': '„', # double low-9 quotation mark, U+201E NEW ! 'beta': 'β', # greek small letter beta, U+03B2 ISOgrk3 ! 'brvbar': '\246', # broken bar = broken vertical bar, U+00A6 ISOnum ! 'bull': '•', # bullet = black small circle, U+2022 ISOpub ! 'cap': '∩', # intersection = cap, U+2229 ISOtech ! 'ccedil': '\347', # latin small letter c with cedilla, U+00E7 ISOlat1 ! 'cedil': '\270', # cedilla = spacing cedilla, U+00B8 ISOdia ! 'cent': '\242', # cent sign, U+00A2 ISOnum ! 'chi': 'χ', # greek small letter chi, U+03C7 ISOgrk3 ! 'circ': 'ˆ', # modifier letter circumflex accent, U+02C6 ISOpub ! 'clubs': '♣', # black club suit = shamrock, U+2663 ISOpub ! 'cong': '≅', # approximately equal to, U+2245 ISOtech ! 'copy': '\251', # copyright sign, U+00A9 ISOnum ! 'crarr': '↵', # downwards arrow with corner leftwards = carriage return, U+21B5 NEW ! 'cup': '∪', # union = cup, U+222A ISOtech ! 'curren': '\244', # currency sign, U+00A4 ISOnum ! 'dArr': '⇓', # downwards double arrow, U+21D3 ISOamsa ! 'dagger': '†', # dagger, U+2020 ISOpub ! 'darr': '↓', # downwards arrow, U+2193 ISOnum ! 'deg': '\260', # degree sign, U+00B0 ISOnum ! 'delta': 'δ', # greek small letter delta, U+03B4 ISOgrk3 ! 'diams': '♦', # black diamond suit, U+2666 ISOpub ! 'divide': '\367', # division sign, U+00F7 ISOnum ! 'eacute': '\351', # latin small letter e with acute, U+00E9 ISOlat1 ! 'ecirc': '\352', # latin small letter e with circumflex, U+00EA ISOlat1 ! 'egrave': '\350', # latin small letter e with grave, U+00E8 ISOlat1 ! 'empty': '∅', # empty set = null set = diameter, U+2205 ISOamso ! 'emsp': ' ', # em space, U+2003 ISOpub ! 'ensp': ' ', # en space, U+2002 ISOpub ! 'epsilon': 'ε', # greek small letter epsilon, U+03B5 ISOgrk3 ! 'equiv': '≡', # identical to, U+2261 ISOtech ! 'eta': 'η', # greek small letter eta, U+03B7 ISOgrk3 ! 'eth': '\360', # latin small letter eth, U+00F0 ISOlat1 ! 'euml': '\353', # latin small letter e with diaeresis, U+00EB ISOlat1 ! 'euro': '€', # euro sign, U+20AC NEW ! 'exist': '∃', # there exists, U+2203 ISOtech ! 'fnof': 'ƒ', # latin small f with hook = function = florin, U+0192 ISOtech ! 'forall': '∀', # for all, U+2200 ISOtech ! 'frac12': '\275', # vulgar fraction one half = fraction one half, U+00BD ISOnum ! 'frac14': '\274', # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum ! 'frac34': '\276', # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum ! 'frasl': '⁄', # fraction slash, U+2044 NEW ! 'gamma': 'γ', # greek small letter gamma, U+03B3 ISOgrk3 ! 'ge': '≥', # greater-than or equal to, U+2265 ISOtech ! 'gt': '\76', # greater-than sign, U+003E ISOnum ! 'hArr': '⇔', # left right double arrow, U+21D4 ISOamsa ! 'harr': '↔', # left right arrow, U+2194 ISOamsa ! 'hearts': '♥', # black heart suit = valentine, U+2665 ISOpub ! 'hellip': '…', # horizontal ellipsis = three dot leader, U+2026 ISOpub ! 'iacute': '\355', # latin small letter i with acute, U+00ED ISOlat1 ! 'icirc': '\356', # latin small letter i with circumflex, U+00EE ISOlat1 ! 'iexcl': '\241', # inverted exclamation mark, U+00A1 ISOnum ! 'igrave': '\354', # latin small letter i with grave, U+00EC ISOlat1 ! 'image': 'ℑ', # blackletter capital I = imaginary part, U+2111 ISOamso ! 'infin': '∞', # infinity, U+221E ISOtech ! 'int': '∫', # integral, U+222B ISOtech ! 'iota': 'ι', # greek small letter iota, U+03B9 ISOgrk3 ! 'iquest': '\277', # inverted question mark = turned question mark, U+00BF ISOnum ! 'isin': '∈', # element of, U+2208 ISOtech ! 'iuml': '\357', # latin small letter i with diaeresis, U+00EF ISOlat1 ! 'kappa': 'κ', # greek small letter kappa, U+03BA ISOgrk3 ! 'lArr': '⇐', # leftwards double arrow, U+21D0 ISOtech ! 'lambda': 'λ', # greek small letter lambda, U+03BB ISOgrk3 ! 'lang': '〈', # left-pointing angle bracket = bra, U+2329 ISOtech ! 'laquo': '\253', # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum ! 'larr': '←', # leftwards arrow, U+2190 ISOnum ! 'lceil': '⌈', # left ceiling = apl upstile, U+2308 ISOamsc ! 'ldquo': '“', # left double quotation mark, U+201C ISOnum ! 'le': '≤', # less-than or equal to, U+2264 ISOtech ! 'lfloor': '⌊', # left floor = apl downstile, U+230A ISOamsc ! 'lowast': '∗', # asterisk operator, U+2217 ISOtech ! 'loz': '◊', # lozenge, U+25CA ISOpub ! 'lrm': '‎', # left-to-right mark, U+200E NEW RFC 2070 ! 'lsaquo': '‹', # single left-pointing angle quotation mark, U+2039 ISO proposed ! 'lsquo': '‘', # left single quotation mark, U+2018 ISOnum ! 'lt': '\74', # less-than sign, U+003C ISOnum ! 'macr': '\257', # macron = spacing macron = overline = APL overbar, U+00AF ISOdia ! 'mdash': '—', # em dash, U+2014 ISOpub ! 'micro': '\265', # micro sign, U+00B5 ISOnum ! 'middot': '\267', # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum ! 'minus': '−', # minus sign, U+2212 ISOtech ! 'mu': 'μ', # greek small letter mu, U+03BC ISOgrk3 ! 'nabla': '∇', # nabla = backward difference, U+2207 ISOtech ! 'nbsp': '\240', # no-break space = non-breaking space, U+00A0 ISOnum ! 'ndash': '–', # en dash, U+2013 ISOpub ! 'ne': '≠', # not equal to, U+2260 ISOtech ! 'ni': '∋', # contains as member, U+220B ISOtech ! 'not': '\254', # not sign, U+00AC ISOnum ! 'notin': '∉', # not an element of, U+2209 ISOtech ! 'nsub': '⊄', # not a subset of, U+2284 ISOamsn ! 'ntilde': '\361', # latin small letter n with tilde, U+00F1 ISOlat1 ! 'nu': 'ν', # greek small letter nu, U+03BD ISOgrk3 ! 'oacute': '\363', # latin small letter o with acute, U+00F3 ISOlat1 ! 'ocirc': '\364', # latin small letter o with circumflex, U+00F4 ISOlat1 ! 'oelig': 'œ', # latin small ligature oe, U+0153 ISOlat2 ! 'ograve': '\362', # latin small letter o with grave, U+00F2 ISOlat1 ! 'oline': '‾', # overline = spacing overscore, U+203E NEW ! 'omega': 'ω', # greek small letter omega, U+03C9 ISOgrk3 ! 'omicron': 'ο', # greek small letter omicron, U+03BF NEW ! 'oplus': '⊕', # circled plus = direct sum, U+2295 ISOamsb ! 'or': '∨', # logical or = vee, U+2228 ISOtech ! 'ordf': '\252', # feminine ordinal indicator, U+00AA ISOnum ! 'ordm': '\272', # masculine ordinal indicator, U+00BA ISOnum ! 'oslash': '\370', # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 ! 'otilde': '\365', # latin small letter o with tilde, U+00F5 ISOlat1 ! 'otimes': '⊗', # circled times = vector product, U+2297 ISOamsb ! 'ouml': '\366', # latin small letter o with diaeresis, U+00F6 ISOlat1 ! 'para': '\266', # pilcrow sign = paragraph sign, U+00B6 ISOnum ! 'part': '∂', # partial differential, U+2202 ISOtech ! 'permil': '‰', # per mille sign, U+2030 ISOtech ! 'perp': '⊥', # up tack = orthogonal to = perpendicular, U+22A5 ISOtech ! 'phi': 'φ', # greek small letter phi, U+03C6 ISOgrk3 ! 'pi': 'π', # greek small letter pi, U+03C0 ISOgrk3 ! 'piv': 'ϖ', # greek pi symbol, U+03D6 ISOgrk3 ! 'plusmn': '\261', # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum ! 'pound': '\243', # pound sign, U+00A3 ISOnum ! 'prime': '′', # prime = minutes = feet, U+2032 ISOtech ! 'prod': '∏', # n-ary product = product sign, U+220F ISOamsb ! 'prop': '∝', # proportional to, U+221D ISOtech ! 'psi': 'ψ', # greek small letter psi, U+03C8 ISOgrk3 ! 'quot': '\42', # quotation mark = APL quote, U+0022 ISOnum ! 'rArr': '⇒', # rightwards double arrow, U+21D2 ISOtech ! 'radic': '√', # square root = radical sign, U+221A ISOtech ! 'rang': '〉', # right-pointing angle bracket = ket, U+232A ISOtech ! 'raquo': '\273', # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum ! 'rarr': '→', # rightwards arrow, U+2192 ISOnum ! 'rceil': '⌉', # right ceiling, U+2309 ISOamsc ! 'rdquo': '”', # right double quotation mark, U+201D ISOnum ! 'real': 'ℜ', # blackletter capital R = real part symbol, U+211C ISOamso ! 'reg': '\256', # registered sign = registered trade mark sign, U+00AE ISOnum ! 'rfloor': '⌋', # right floor, U+230B ISOamsc ! 'rho': 'ρ', # greek small letter rho, U+03C1 ISOgrk3 ! 'rlm': '‏', # right-to-left mark, U+200F NEW RFC 2070 ! 'rsaquo': '›', # single right-pointing angle quotation mark, U+203A ISO proposed ! 'rsquo': '’', # right single quotation mark, U+2019 ISOnum ! 'sbquo': '‚', # single low-9 quotation mark, U+201A NEW ! 'scaron': 'š', # latin small letter s with caron, U+0161 ISOlat2 ! 'sdot': '⋅', # dot operator, U+22C5 ISOamsb ! 'sect': '\247', # section sign, U+00A7 ISOnum ! 'shy': '\255', # soft hyphen = discretionary hyphen, U+00AD ISOnum ! 'sigma': 'σ', # greek small letter sigma, U+03C3 ISOgrk3 ! 'sigmaf': 'ς', # greek small letter final sigma, U+03C2 ISOgrk3 ! 'sim': '∼', # tilde operator = varies with = similar to, U+223C ISOtech ! 'spades': '♠', # black spade suit, U+2660 ISOpub ! 'sub': '⊂', # subset of, U+2282 ISOtech ! 'sube': '⊆', # subset of or equal to, U+2286 ISOtech ! 'sum': '∑', # n-ary sumation, U+2211 ISOamsb ! 'sup': '⊃', # superset of, U+2283 ISOtech ! 'sup1': '\271', # superscript one = superscript digit one, U+00B9 ISOnum ! 'sup2': '\262', # superscript two = superscript digit two = squared, U+00B2 ISOnum ! 'sup3': '\263', # superscript three = superscript digit three = cubed, U+00B3 ISOnum ! 'supe': '⊇', # superset of or equal to, U+2287 ISOtech ! 'szlig': '\337', # latin small letter sharp s = ess-zed, U+00DF ISOlat1 ! 'tau': 'τ', # greek small letter tau, U+03C4 ISOgrk3 ! 'there4': '∴', # therefore, U+2234 ISOtech ! 'theta': 'θ', # greek small letter theta, U+03B8 ISOgrk3 ! 'thetasym': 'ϑ', # greek small letter theta symbol, U+03D1 NEW ! 'thinsp': ' ', # thin space, U+2009 ISOpub ! 'thorn': '\376', # latin small letter thorn with, U+00FE ISOlat1 ! 'tilde': '˜', # small tilde, U+02DC ISOdia ! 'times': '\327', # multiplication sign, U+00D7 ISOnum ! 'trade': '™', # trade mark sign, U+2122 ISOnum ! 'uArr': '⇑', # upwards double arrow, U+21D1 ISOamsa ! 'uacute': '\372', # latin small letter u with acute, U+00FA ISOlat1 ! 'uarr': '↑', # upwards arrow, U+2191 ISOnum ! 'ucirc': '\373', # latin small letter u with circumflex, U+00FB ISOlat1 ! 'ugrave': '\371', # latin small letter u with grave, U+00F9 ISOlat1 ! 'uml': '\250', # diaeresis = spacing diaeresis, U+00A8 ISOdia ! 'upsih': 'ϒ', # greek upsilon with hook symbol, U+03D2 NEW ! 'upsilon': 'υ', # greek small letter upsilon, U+03C5 ISOgrk3 ! 'uuml': '\374', # latin small letter u with diaeresis, U+00FC ISOlat1 ! 'weierp': '℘', # script capital P = power set = Weierstrass p, U+2118 ISOamso ! 'xi': 'ξ', # greek small letter xi, U+03BE ISOgrk3 ! 'yacute': '\375', # latin small letter y with acute, U+00FD ISOlat1 ! 'yen': '\245', # yen sign = yuan sign, U+00A5 ISOnum ! 'yuml': '\377', # latin small letter y with diaeresis, U+00FF ISOlat1 ! 'zeta': 'ζ', # greek small letter zeta, U+03B6 ISOgrk3 ! 'zwj': '‍', # zero width joiner, U+200D NEW RFC 2070 ! 'zwnj': '‌', # zero width non-joiner, U+200C NEW RFC 2070 } --- 2,257 ---- entitydefs = { ! 'AElig': '\306', # latin capital letter AE = latin capital ligature AE, U+00C6 ISOlat1 ! 'Aacute': '\301', # latin capital letter A with acute, U+00C1 ISOlat1 ! 'Acirc': '\302', # latin capital letter A with circumflex, U+00C2 ISOlat1 ! 'Agrave': '\300', # latin capital letter A with grave = latin capital letter A grave, U+00C0 ISOlat1 ! 'Alpha': 'Α', # greek capital letter alpha, U+0391 ! 'Aring': '\305', # latin capital letter A with ring above = latin capital letter A ring, U+00C5 ISOlat1 ! 'Atilde': '\303', # latin capital letter A with tilde, U+00C3 ISOlat1 ! 'Auml': '\304', # latin capital letter A with diaeresis, U+00C4 ISOlat1 ! 'Beta': 'Β', # greek capital letter beta, U+0392 ! 'Ccedil': '\307', # latin capital letter C with cedilla, U+00C7 ISOlat1 ! 'Chi': 'Χ', # greek capital letter chi, U+03A7 ! 'Dagger': '‡', # double dagger, U+2021 ISOpub ! 'Delta': 'Δ', # greek capital letter delta, U+0394 ISOgrk3 ! 'ETH': '\320', # latin capital letter ETH, U+00D0 ISOlat1 ! 'Eacute': '\311', # latin capital letter E with acute, U+00C9 ISOlat1 ! 'Ecirc': '\312', # latin capital letter E with circumflex, U+00CA ISOlat1 ! 'Egrave': '\310', # latin capital letter E with grave, U+00C8 ISOlat1 ! 'Epsilon': 'Ε', # greek capital letter epsilon, U+0395 ! 'Eta': 'Η', # greek capital letter eta, U+0397 ! 'Euml': '\313', # latin capital letter E with diaeresis, U+00CB ISOlat1 ! 'Gamma': 'Γ', # greek capital letter gamma, U+0393 ISOgrk3 ! 'Iacute': '\315', # latin capital letter I with acute, U+00CD ISOlat1 ! 'Icirc': '\316', # latin capital letter I with circumflex, U+00CE ISOlat1 ! 'Igrave': '\314', # latin capital letter I with grave, U+00CC ISOlat1 ! 'Iota': 'Ι', # greek capital letter iota, U+0399 ! 'Iuml': '\317', # latin capital letter I with diaeresis, U+00CF ISOlat1 ! 'Kappa': 'Κ', # greek capital letter kappa, U+039A ! 'Lambda': 'Λ', # greek capital letter lambda, U+039B ISOgrk3 ! 'Mu': 'Μ', # greek capital letter mu, U+039C ! 'Ntilde': '\321', # latin capital letter N with tilde, U+00D1 ISOlat1 ! 'Nu': 'Ν', # greek capital letter nu, U+039D ! 'OElig': 'Œ', # latin capital ligature OE, U+0152 ISOlat2 ! 'Oacute': '\323', # latin capital letter O with acute, U+00D3 ISOlat1 ! 'Ocirc': '\324', # latin capital letter O with circumflex, U+00D4 ISOlat1 ! 'Ograve': '\322', # latin capital letter O with grave, U+00D2 ISOlat1 ! 'Omega': 'Ω', # greek capital letter omega, U+03A9 ISOgrk3 ! 'Omicron': 'Ο', # greek capital letter omicron, U+039F ! 'Oslash': '\330', # latin capital letter O with stroke = latin capital letter O slash, U+00D8 ISOlat1 ! 'Otilde': '\325', # latin capital letter O with tilde, U+00D5 ISOlat1 ! 'Ouml': '\326', # latin capital letter O with diaeresis, U+00D6 ISOlat1 ! 'Phi': 'Φ', # greek capital letter phi, U+03A6 ISOgrk3 ! 'Pi': 'Π', # greek capital letter pi, U+03A0 ISOgrk3 ! 'Prime': '″', # double prime = seconds = inches, U+2033 ISOtech ! 'Psi': 'Ψ', # greek capital letter psi, U+03A8 ISOgrk3 ! 'Rho': 'Ρ', # greek capital letter rho, U+03A1 ! 'Scaron': 'Š', # latin capital letter S with caron, U+0160 ISOlat2 ! 'Sigma': 'Σ', # greek capital letter sigma, U+03A3 ISOgrk3 ! 'THORN': '\336', # latin capital letter THORN, U+00DE ISOlat1 ! 'Tau': 'Τ', # greek capital letter tau, U+03A4 ! 'Theta': 'Θ', # greek capital letter theta, U+0398 ISOgrk3 ! 'Uacute': '\332', # latin capital letter U with acute, U+00DA ISOlat1 ! 'Ucirc': '\333', # latin capital letter U with circumflex, U+00DB ISOlat1 ! 'Ugrave': '\331', # latin capital letter U with grave, U+00D9 ISOlat1 ! 'Upsilon': 'Υ', # greek capital letter upsilon, U+03A5 ISOgrk3 ! 'Uuml': '\334', # latin capital letter U with diaeresis, U+00DC ISOlat1 ! 'Xi': 'Ξ', # greek capital letter xi, U+039E ISOgrk3 ! 'Yacute': '\335', # latin capital letter Y with acute, U+00DD ISOlat1 ! 'Yuml': 'Ÿ', # latin capital letter Y with diaeresis, U+0178 ISOlat2 ! 'Zeta': 'Ζ', # greek capital letter zeta, U+0396 ! 'aacute': '\341', # latin small letter a with acute, U+00E1 ISOlat1 ! 'acirc': '\342', # latin small letter a with circumflex, U+00E2 ISOlat1 ! 'acute': '\264', # acute accent = spacing acute, U+00B4 ISOdia ! 'aelig': '\346', # latin small letter ae = latin small ligature ae, U+00E6 ISOlat1 ! 'agrave': '\340', # latin small letter a with grave = latin small letter a grave, U+00E0 ISOlat1 ! 'alefsym': 'ℵ', # alef symbol = first transfinite cardinal, U+2135 NEW ! 'alpha': 'α', # greek small letter alpha, U+03B1 ISOgrk3 ! 'amp': '\46', # ampersand, U+0026 ISOnum ! 'and': '∧', # logical and = wedge, U+2227 ISOtech ! 'ang': '∠', # angle, U+2220 ISOamso ! 'aring': '\345', # latin small letter a with ring above = latin small letter a ring, U+00E5 ISOlat1 ! 'asymp': '≈', # almost equal to = asymptotic to, U+2248 ISOamsr ! 'atilde': '\343', # latin small letter a with tilde, U+00E3 ISOlat1 ! 'auml': '\344', # latin small letter a with diaeresis, U+00E4 ISOlat1 ! 'bdquo': '„', # double low-9 quotation mark, U+201E NEW ! 'beta': 'β', # greek small letter beta, U+03B2 ISOgrk3 ! 'brvbar': '\246', # broken bar = broken vertical bar, U+00A6 ISOnum ! 'bull': '•', # bullet = black small circle, U+2022 ISOpub ! 'cap': '∩', # intersection = cap, U+2229 ISOtech ! 'ccedil': '\347', # latin small letter c with cedilla, U+00E7 ISOlat1 ! 'cedil': '\270', # cedilla = spacing cedilla, U+00B8 ISOdia ! 'cent': '\242', # cent sign, U+00A2 ISOnum ! 'chi': 'χ', # greek small letter chi, U+03C7 ISOgrk3 ! 'circ': 'ˆ', # modifier letter circumflex accent, U+02C6 ISOpub ! 'clubs': '♣', # black club suit = shamrock, U+2663 ISOpub ! 'cong': '≅', # approximately equal to, U+2245 ISOtech ! 'copy': '\251', # copyright sign, U+00A9 ISOnum ! 'crarr': '↵', # downwards arrow with corner leftwards = carriage return, U+21B5 NEW ! 'cup': '∪', # union = cup, U+222A ISOtech ! 'curren': '\244', # currency sign, U+00A4 ISOnum ! 'dArr': '⇓', # downwards double arrow, U+21D3 ISOamsa ! 'dagger': '†', # dagger, U+2020 ISOpub ! 'darr': '↓', # downwards arrow, U+2193 ISOnum ! 'deg': '\260', # degree sign, U+00B0 ISOnum ! 'delta': 'δ', # greek small letter delta, U+03B4 ISOgrk3 ! 'diams': '♦', # black diamond suit, U+2666 ISOpub ! 'divide': '\367', # division sign, U+00F7 ISOnum ! 'eacute': '\351', # latin small letter e with acute, U+00E9 ISOlat1 ! 'ecirc': '\352', # latin small letter e with circumflex, U+00EA ISOlat1 ! 'egrave': '\350', # latin small letter e with grave, U+00E8 ISOlat1 ! 'empty': '∅', # empty set = null set = diameter, U+2205 ISOamso ! 'emsp': ' ', # em space, U+2003 ISOpub ! 'ensp': ' ', # en space, U+2002 ISOpub ! 'epsilon': 'ε', # greek small letter epsilon, U+03B5 ISOgrk3 ! 'equiv': '≡', # identical to, U+2261 ISOtech ! 'eta': 'η', # greek small letter eta, U+03B7 ISOgrk3 ! 'eth': '\360', # latin small letter eth, U+00F0 ISOlat1 ! 'euml': '\353', # latin small letter e with diaeresis, U+00EB ISOlat1 ! 'euro': '€', # euro sign, U+20AC NEW ! 'exist': '∃', # there exists, U+2203 ISOtech ! 'fnof': 'ƒ', # latin small f with hook = function = florin, U+0192 ISOtech ! 'forall': '∀', # for all, U+2200 ISOtech ! 'frac12': '\275', # vulgar fraction one half = fraction one half, U+00BD ISOnum ! 'frac14': '\274', # vulgar fraction one quarter = fraction one quarter, U+00BC ISOnum ! 'frac34': '\276', # vulgar fraction three quarters = fraction three quarters, U+00BE ISOnum ! 'frasl': '⁄', # fraction slash, U+2044 NEW ! 'gamma': 'γ', # greek small letter gamma, U+03B3 ISOgrk3 ! 'ge': '≥', # greater-than or equal to, U+2265 ISOtech ! 'gt': '\76', # greater-than sign, U+003E ISOnum ! 'hArr': '⇔', # left right double arrow, U+21D4 ISOamsa ! 'harr': '↔', # left right arrow, U+2194 ISOamsa ! 'hearts': '♥', # black heart suit = valentine, U+2665 ISOpub ! 'hellip': '…', # horizontal ellipsis = three dot leader, U+2026 ISOpub ! 'iacute': '\355', # latin small letter i with acute, U+00ED ISOlat1 ! 'icirc': '\356', # latin small letter i with circumflex, U+00EE ISOlat1 ! 'iexcl': '\241', # inverted exclamation mark, U+00A1 ISOnum ! 'igrave': '\354', # latin small letter i with grave, U+00EC ISOlat1 ! 'image': 'ℑ', # blackletter capital I = imaginary part, U+2111 ISOamso ! 'infin': '∞', # infinity, U+221E ISOtech ! 'int': '∫', # integral, U+222B ISOtech ! 'iota': 'ι', # greek small letter iota, U+03B9 ISOgrk3 ! 'iquest': '\277', # inverted question mark = turned question mark, U+00BF ISOnum ! 'isin': '∈', # element of, U+2208 ISOtech ! 'iuml': '\357', # latin small letter i with diaeresis, U+00EF ISOlat1 ! 'kappa': 'κ', # greek small letter kappa, U+03BA ISOgrk3 ! 'lArr': '⇐', # leftwards double arrow, U+21D0 ISOtech ! 'lambda': 'λ', # greek small letter lambda, U+03BB ISOgrk3 ! 'lang': '〈', # left-pointing angle bracket = bra, U+2329 ISOtech ! 'laquo': '\253', # left-pointing double angle quotation mark = left pointing guillemet, U+00AB ISOnum ! 'larr': '←', # leftwards arrow, U+2190 ISOnum ! 'lceil': '⌈', # left ceiling = apl upstile, U+2308 ISOamsc ! 'ldquo': '“', # left double quotation mark, U+201C ISOnum ! 'le': '≤', # less-than or equal to, U+2264 ISOtech ! 'lfloor': '⌊', # left floor = apl downstile, U+230A ISOamsc ! 'lowast': '∗', # asterisk operator, U+2217 ISOtech ! 'loz': '◊', # lozenge, U+25CA ISOpub ! 'lrm': '‎', # left-to-right mark, U+200E NEW RFC 2070 ! 'lsaquo': '‹', # single left-pointing angle quotation mark, U+2039 ISO proposed ! 'lsquo': '‘', # left single quotation mark, U+2018 ISOnum ! 'lt': '\74', # less-than sign, U+003C ISOnum ! 'macr': '\257', # macron = spacing macron = overline = APL overbar, U+00AF ISOdia ! 'mdash': '—', # em dash, U+2014 ISOpub ! 'micro': '\265', # micro sign, U+00B5 ISOnum ! 'middot': '\267', # middle dot = Georgian comma = Greek middle dot, U+00B7 ISOnum ! 'minus': '−', # minus sign, U+2212 ISOtech ! 'mu': 'μ', # greek small letter mu, U+03BC ISOgrk3 ! 'nabla': '∇', # nabla = backward difference, U+2207 ISOtech ! 'nbsp': '\240', # no-break space = non-breaking space, U+00A0 ISOnum ! 'ndash': '–', # en dash, U+2013 ISOpub ! 'ne': '≠', # not equal to, U+2260 ISOtech ! 'ni': '∋', # contains as member, U+220B ISOtech ! 'not': '\254', # not sign, U+00AC ISOnum ! 'notin': '∉', # not an element of, U+2209 ISOtech ! 'nsub': '⊄', # not a subset of, U+2284 ISOamsn ! 'ntilde': '\361', # latin small letter n with tilde, U+00F1 ISOlat1 ! 'nu': 'ν', # greek small letter nu, U+03BD ISOgrk3 ! 'oacute': '\363', # latin small letter o with acute, U+00F3 ISOlat1 ! 'ocirc': '\364', # latin small letter o with circumflex, U+00F4 ISOlat1 ! 'oelig': 'œ', # latin small ligature oe, U+0153 ISOlat2 ! 'ograve': '\362', # latin small letter o with grave, U+00F2 ISOlat1 ! 'oline': '‾', # overline = spacing overscore, U+203E NEW ! 'omega': 'ω', # greek small letter omega, U+03C9 ISOgrk3 ! 'omicron': 'ο', # greek small letter omicron, U+03BF NEW ! 'oplus': '⊕', # circled plus = direct sum, U+2295 ISOamsb ! 'or': '∨', # logical or = vee, U+2228 ISOtech ! 'ordf': '\252', # feminine ordinal indicator, U+00AA ISOnum ! 'ordm': '\272', # masculine ordinal indicator, U+00BA ISOnum ! 'oslash': '\370', # latin small letter o with stroke, = latin small letter o slash, U+00F8 ISOlat1 ! 'otilde': '\365', # latin small letter o with tilde, U+00F5 ISOlat1 ! 'otimes': '⊗', # circled times = vector product, U+2297 ISOamsb ! 'ouml': '\366', # latin small letter o with diaeresis, U+00F6 ISOlat1 ! 'para': '\266', # pilcrow sign = paragraph sign, U+00B6 ISOnum ! 'part': '∂', # partial differential, U+2202 ISOtech ! 'permil': '‰', # per mille sign, U+2030 ISOtech ! 'perp': '⊥', # up tack = orthogonal to = perpendicular, U+22A5 ISOtech ! 'phi': 'φ', # greek small letter phi, U+03C6 ISOgrk3 ! 'pi': 'π', # greek small letter pi, U+03C0 ISOgrk3 ! 'piv': 'ϖ', # greek pi symbol, U+03D6 ISOgrk3 ! 'plusmn': '\261', # plus-minus sign = plus-or-minus sign, U+00B1 ISOnum ! 'pound': '\243', # pound sign, U+00A3 ISOnum ! 'prime': '′', # prime = minutes = feet, U+2032 ISOtech ! 'prod': '∏', # n-ary product = product sign, U+220F ISOamsb ! 'prop': '∝', # proportional to, U+221D ISOtech ! 'psi': 'ψ', # greek small letter psi, U+03C8 ISOgrk3 ! 'quot': '\42', # quotation mark = APL quote, U+0022 ISOnum ! 'rArr': '⇒', # rightwards double arrow, U+21D2 ISOtech ! 'radic': '√', # square root = radical sign, U+221A ISOtech ! 'rang': '〉', # right-pointing angle bracket = ket, U+232A ISOtech ! 'raquo': '\273', # right-pointing double angle quotation mark = right pointing guillemet, U+00BB ISOnum ! 'rarr': '→', # rightwards arrow, U+2192 ISOnum ! 'rceil': '⌉', # right ceiling, U+2309 ISOamsc ! 'rdquo': '”', # right double quotation mark, U+201D ISOnum ! 'real': 'ℜ', # blackletter capital R = real part symbol, U+211C ISOamso ! 'reg': '\256', # registered sign = registered trade mark sign, U+00AE ISOnum ! 'rfloor': '⌋', # right floor, U+230B ISOamsc ! 'rho': 'ρ', # greek small letter rho, U+03C1 ISOgrk3 ! 'rlm': '‏', # right-to-left mark, U+200F NEW RFC 2070 ! 'rsaquo': '›', # single right-pointing angle quotation mark, U+203A ISO proposed ! 'rsquo': '’', # right single quotation mark, U+2019 ISOnum ! 'sbquo': '‚', # single low-9 quotation mark, U+201A NEW ! 'scaron': 'š', # latin small letter s with caron, U+0161 ISOlat2 ! 'sdot': '⋅', # dot operator, U+22C5 ISOamsb ! 'sect': '\247', # section sign, U+00A7 ISOnum ! 'shy': '\255', # soft hyphen = discretionary hyphen, U+00AD ISOnum ! 'sigma': 'σ', # greek small letter sigma, U+03C3 ISOgrk3 ! 'sigmaf': 'ς', # greek small letter final sigma, U+03C2 ISOgrk3 ! 'sim': '∼', # tilde operator = varies with = similar to, U+223C ISOtech ! 'spades': '♠', # black spade suit, U+2660 ISOpub ! 'sub': '⊂', # subset of, U+2282 ISOtech ! 'sube': '⊆', # subset of or equal to, U+2286 ISOtech ! 'sum': '∑', # n-ary sumation, U+2211 ISOamsb ! 'sup': '⊃', # superset of, U+2283 ISOtech ! 'sup1': '\271', # superscript one = superscript digit one, U+00B9 ISOnum ! 'sup2': '\262', # superscript two = superscript digit two = squared, U+00B2 ISOnum ! 'sup3': '\263', # superscript three = superscript digit three = cubed, U+00B3 ISOnum ! 'supe': '⊇', # superset of or equal to, U+2287 ISOtech ! 'szlig': '\337', # latin small letter sharp s = ess-zed, U+00DF ISOlat1 ! 'tau': 'τ', # greek small letter tau, U+03C4 ISOgrk3 ! 'there4': '∴', # therefore, U+2234 ISOtech ! 'theta': 'θ', # greek small letter theta, U+03B8 ISOgrk3 ! 'thetasym': 'ϑ', # greek small letter theta symbol, U+03D1 NEW ! 'thinsp': ' ', # thin space, U+2009 ISOpub ! 'thorn': '\376', # latin small letter thorn with, U+00FE ISOlat1 ! 'tilde': '˜', # small tilde, U+02DC ISOdia ! 'times': '\327', # multiplication sign, U+00D7 ISOnum ! 'trade': '™', # trade mark sign, U+2122 ISOnum ! 'uArr': '⇑', # upwards double arrow, U+21D1 ISOamsa ! 'uacute': '\372', # latin small letter u with acute, U+00FA ISOlat1 ! 'uarr': '↑', # upwards arrow, U+2191 ISOnum ! 'ucirc': '\373', # latin small letter u with circumflex, U+00FB ISOlat1 ! 'ugrave': '\371', # latin small letter u with grave, U+00F9 ISOlat1 ! 'uml': '\250', # diaeresis = spacing diaeresis, U+00A8 ISOdia ! 'upsih': 'ϒ', # greek upsilon with hook symbol, U+03D2 NEW ! 'upsilon': 'υ', # greek small letter upsilon, U+03C5 ISOgrk3 ! 'uuml': '\374', # latin small letter u with diaeresis, U+00FC ISOlat1 ! 'weierp': '℘', # script capital P = power set = Weierstrass p, U+2118 ISOamso ! 'xi': 'ξ', # greek small letter xi, U+03BE ISOgrk3 ! 'yacute': '\375', # latin small letter y with acute, U+00FD ISOlat1 ! 'yen': '\245', # yen sign = yuan sign, U+00A5 ISOnum ! 'yuml': '\377', # latin small letter y with diaeresis, U+00FF ISOlat1 ! 'zeta': 'ζ', # greek small letter zeta, U+03B6 ISOgrk3 ! 'zwj': '‍', # zero width joiner, U+200D NEW RFC 2070 ! 'zwnj': '‌', # zero width non-joiner, U+200C NEW RFC 2070 } Index: htmllib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/htmllib.py,v retrieving revision 1.14 retrieving revision 1.15 diff -C2 -r1.14 -r1.15 *** htmllib.py 1999/05/03 18:10:15 1.14 --- htmllib.py 2001/01/14 23:47:14 1.15 *************** *** 412,416 **** if f is not sys.stdin: f.close() ! if silent: f = formatter.NullFormatter() --- 412,416 ---- if f is not sys.stdin: f.close() ! if silent: f = formatter.NullFormatter() Index: httplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/httplib.py,v retrieving revision 1.29 retrieving revision 1.30 diff -C2 -r1.29 -r1.30 *** httplib.py 2001/01/14 21:03:01 1.29 --- httplib.py 2001/01/14 23:47:14 1.30 *************** *** 94,105 **** # from the Status-Line of the response ! self.version = _UNKNOWN # HTTP-Version ! self.status = _UNKNOWN # Status-Code ! self.reason = _UNKNOWN # Reason-Phrase ! ! self.chunked = _UNKNOWN # is "chunked" being used? ! self.chunk_left = _UNKNOWN # bytes left to read in current chunk ! self.length = _UNKNOWN # number of bytes left in response ! self.will_close = _UNKNOWN # conn will close at end of response def begin(self): --- 94,105 ---- # from the Status-Line of the response ! self.version = _UNKNOWN # HTTP-Version ! self.status = _UNKNOWN # Status-Code ! self.reason = _UNKNOWN # Reason-Phrase ! ! self.chunked = _UNKNOWN # is "chunked" being used? ! self.chunk_left = _UNKNOWN # bytes left to read in current chunk ! self.length = _UNKNOWN # number of bytes left in response ! self.will_close = _UNKNOWN # conn will close at end of response def begin(self): *************** *** 131,135 **** self.version = 10 elif version.startswith('HTTP/1.'): ! self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1 elif version == 'HTTP/0.9': self.version = 9 --- 131,135 ---- self.version = 10 elif version.startswith('HTTP/1.'): ! self.version = 11 # use HTTP/1.1 code for HTTP/1.x where x>=1 elif version == 'HTTP/0.9': self.version = 9 *************** *** 187,193 **** # does the body have a fixed length? (of zero) ! if (status == 204 or # No Content ! status == 304 or # Not Modified ! 100 <= status < 200): # 1xx codes self.length = 0 --- 187,193 ---- # does the body have a fixed length? (of zero) ! if (status == 204 or # No Content ! status == 304 or # Not Modified ! 100 <= status < 200): # 1xx codes self.length = 0 *************** *** 226,230 **** i = line.find(';') if i >= 0: ! line = line[:i] # strip chunk-extensions chunk_left = int(line, 16) if chunk_left == 0: --- 226,230 ---- i = line.find(';') if i >= 0: ! line = line[:i] # strip chunk-extensions chunk_left = int(line, 16) if chunk_left == 0: *************** *** 238,242 **** elif amt == chunk_left: value = value + self._safe_read(amt) ! self._safe_read(2) # toss the CRLF at the end of the chunk self.chunk_left = None return value --- 238,242 ---- elif amt == chunk_left: value = value + self._safe_read(amt) ! self._safe_read(2) # toss the CRLF at the end of the chunk self.chunk_left = None return value *************** *** 246,250 **** # we read the whole chunk, get another ! self._safe_read(2) # toss the CRLF at the end of the chunk chunk_left = None --- 246,250 ---- # we read the whole chunk, get another ! self._safe_read(2) # toss the CRLF at the end of the chunk chunk_left = None *************** *** 267,271 **** else: s = self._safe_read(self.length) ! self.close() # we read everything return s --- 267,271 ---- else: s = self._safe_read(self.length) ! self.close() # we read everything return s *************** *** 356,360 **** """Close the connection to the HTTP server.""" if self.sock: ! self.sock.close() # close it manually... there may be other refs self.sock = None if self.__response: --- 356,360 ---- """Close the connection to the HTTP server.""" if self.sock: ! self.sock.close() # close it manually... there may be other refs self.sock = None if self.__response: *************** *** 381,385 **** self.sock.send(str) except socket.error, v: ! if v[0] == 32: # Broken pipe self.close() raise --- 381,385 ---- self.sock.send(str) except socket.error, v: ! if v[0] == 32: # Broken pipe self.close() raise Index: ihooks.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ihooks.py,v retrieving revision 1.10 retrieving revision 1.11 diff -C2 -r1.10 -r1.11 *** ihooks.py 2000/04/13 14:52:27 1.10 --- ihooks.py 2001/01/14 23:47:14 1.11 *************** *** 110,114 **** def find_module(self, name, path = None): ! if path is None: path = [None] + self.default_path() for dir in path: --- 110,114 ---- def find_module(self, name, path = None): ! if path is None: path = [None] + self.default_path() for dir in path: *************** *** 391,395 **** """A module importer that supports packages.""" ! def import_module(self, name, globals=None, locals=None, fromlist=None): parent = self.determine_parent(globals) --- 391,395 ---- """A module importer that supports packages.""" ! def import_module(self, name, globals=None, locals=None, fromlist=None): parent = self.determine_parent(globals) Index: imaplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imaplib.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** imaplib.py 2000/05/25 03:25:26 1.21 --- imaplib.py 2001/01/14 23:47:14 1.22 *************** *** 1,17 **** - """IMAP4 client. Based on RFC 2060. ! Public class: IMAP4 ! Public variable: Debug ! Public functions: Internaldate2tuple ! Int2AP ! ParseFlags [...2204 lines suppressed...] ! if (cmd,args) != ('uid', ('SEARCH', 'ALL')): ! continue ! ! uid = string.split(dat[-1]) ! if not uid: continue ! run('uid', ('FETCH', '%s' % uid[-1], ! '(FLAGS INTERNALDATE RFC822.SIZE RFC822.HEADER RFC822.TEXT)')) ! print '\nAll tests OK.' ! except: ! print '\nTests failed.' ! if not Debug: ! print ''' If you would like to see debugging output, try: %s -d5 ''' % sys.argv[0] ! raise Index: imghdr.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imghdr.py,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -r1.9 -r1.10 *** imghdr.py 2000/02/04 15:10:33 1.9 --- imghdr.py 2001/01/14 23:47:14 1.10 *************** *** 15,19 **** h = file.read(32) file.seek(location) ! f = None else: f = None --- 15,19 ---- h = file.read(32) file.seek(location) ! f = None else: f = None *************** *** 104,108 **** if h[:2] == 'BM': return 'bmp' ! tests.append(test_bmp) --- 104,108 ---- if h[:2] == 'BM': return 'bmp' ! tests.append(test_bmp) Index: imputil.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/imputil.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** imputil.py 2000/12/12 23:20:44 1.15 --- imputil.py 2001/01/14 23:47:14 1.16 *************** *** 6,10 **** # note: avoid importing non-builtin modules ! import imp ### not available in JPython? import sys import strop --- 6,10 ---- # note: avoid importing non-builtin modules ! import imp ### not available in JPython? import sys import strop *************** *** 16,20 **** _StringType = type('') ! _ModuleType = type(sys) ### doesn't work in JPython... class ImportManager: --- 16,20 ---- _StringType = type('') ! _ModuleType = type(sys) ### doesn't work in JPython... class ImportManager: *************** *** 664,668 **** # # Guido's comments on sys.path caching: ! # # We could cache this in a dictionary: the ImportManager can have a # cache dict mapping pathnames to importer objects, and a separate --- 664,668 ---- # # Guido's comments on sys.path caching: ! # # We could cache this in a dictionary: the ImportManager can have a # cache dict mapping pathnames to importer objects, and a separate *************** *** 680,693 **** # # > However, we still have a tension occurring here: ! # > # > 1) implementing policy in ImportManager assists in single-point policy # > changes for app/rexec situations # > 2) implementing policy in Importer assists in package-private policy # > changes for normal, operating conditions ! # > # > I'll see if I can sort out a way to do this. Maybe the Importer class will # > implement the methods (which can be overridden to change policy) by # > delegating to ImportManager. ! # # Maybe also think about what kind of policies an Importer would be # likely to want to change. I have a feeling that a lot of the code --- 680,693 ---- # # > However, we still have a tension occurring here: ! # > # > 1) implementing policy in ImportManager assists in single-point policy # > changes for app/rexec situations # > 2) implementing policy in Importer assists in package-private policy # > changes for normal, operating conditions ! # > # > I'll see if I can sort out a way to do this. Maybe the Importer class will # > implement the methods (which can be overridden to change policy) by # > delegating to ImportManager. ! # # Maybe also think about what kind of policies an Importer would be # likely to want to change. I have a feeling that a lot of the code Index: macurl2path.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/macurl2path.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** macurl2path.py 2000/12/12 23:20:44 1.8 --- macurl2path.py 2001/01/14 23:47:14 1.9 *************** *** 17,21 **** # Turn starting /// into /, an empty hostname means current host if pathname[:3] == '///': ! pathname = pathname[2:] elif pathname[:2] == '//': raise RuntimeError, 'Cannot convert non-local URL to pathname' --- 17,21 ---- # Turn starting /// into /, an empty hostname means current host if pathname[:3] == '///': ! pathname = pathname[2:] elif pathname[:2] == '//': raise RuntimeError, 'Cannot convert non-local URL to pathname' *************** *** 69,77 **** else: return string.join(components, '/') ! def _pncomp2url(component): ! component = urllib.quote(component[:31], safe='') # We want to quote slashes ! return component ! def test(): for url in ["index.html", --- 69,77 ---- else: return string.join(components, '/') ! def _pncomp2url(component): ! component = urllib.quote(component[:31], safe='') # We want to quote slashes ! return component ! def test(): for url in ["index.html", Index: mailcap.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mailcap.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** mailcap.py 2000/12/12 23:20:44 1.6 --- mailcap.py 2001/01/14 23:47:14 1.7 *************** *** 9,13 **** def getcaps(): """Return a dictionary containing the mailcap database. ! The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain') to a list of dictionaries corresponding to mailcap entries. The list --- 9,13 ---- def getcaps(): """Return a dictionary containing the mailcap database. ! The dictionary maps a MIME type (in all lowercase, e.g. 'text/plain') to a list of dictionaries corresponding to mailcap entries. The list *************** *** 138,142 **** def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): """Find a match for a mailcap entry. ! Return a tuple containing the command line, and the mailcap entry used; (None, None) if no match is found. This may invoke the --- 138,142 ---- def findmatch(caps, MIMEtype, key='view', filename="/dev/null", plist=[]): """Find a match for a mailcap entry. ! Return a tuple containing the command line, and the mailcap entry used; (None, None) if no match is found. This may invoke the *************** *** 146,150 **** """ entries = lookup(caps, MIMEtype, key) ! # XXX This code should somehow check for the needsterminal flag. for e in entries: if e.has_key('test'): --- 146,150 ---- """ entries = lookup(caps, MIMEtype, key) ! # XXX This code should somehow check for the needsterminal flag. for e in entries: if e.has_key('test'): Index: mimetools.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimetools.py,v retrieving revision 1.20 retrieving revision 1.21 diff -C2 -r1.20 -r1.21 *** mimetools.py 2000/12/15 15:49:08 1.20 --- mimetools.py 2001/01/14 23:47:14 1.21 *************** *** 8,90 **** class Message(rfc822.Message): ! """A derived class of rfc822.Message that knows about MIME headers and ! contains some hooks for decoding encoded and multipart messages.""" ! def __init__(self, fp, seekable = 1): ! rfc822.Message.__init__(self, fp, seekable) ! self.encodingheader = \ ! self.getheader('content-transfer-encoding') ! self.typeheader = \ ! self.getheader('content-type') ! self.parsetype() ! self.parseplist() ! ! def parsetype(self): ! str = self.typeheader ! if str is None: ! str = 'text/plain' ! if ';' in str: ! i = str.index(';') ! self.plisttext = str[i:] ! str = str[:i] ! else: ! self.plisttext = '' ! fields = str.split('/') ! for i in range(len(fields)): ! fields[i] = fields[i].strip().lower() ! self.type = '/'.join(fields) ! self.maintype = fields[0] ! self.subtype = '/'.join(fields[1:]) ! ! def parseplist(self): ! str = self.plisttext ! self.plist = [] ! while str[:1] == ';': ! str = str[1:] ! if ';' in str: ! # XXX Should parse quotes! ! end = str.index(';') ! else: ! end = len(str) ! f = str[:end] ! if '=' in f: ! i = f.index('=') ! f = f[:i].strip().lower() + \ ! '=' + f[i+1:].strip() ! self.plist.append(f.strip()) ! str = str[end:] ! ! def getplist(self): ! return self.plist ! ! def getparam(self, name): ! name = name.lower() + '=' ! n = len(name) ! for p in self.plist: ! if p[:n] == name: ! return rfc822.unquote(p[n:]) ! return None ! ! def getparamnames(self): ! result = [] ! for p in self.plist: ! i = p.find('=') ! if i >= 0: ! result.append(p[:i].lower()) ! return result ! ! def getencoding(self): ! if self.encodingheader is None: ! return '7bit' ! return self.encodingheader.lower() ! def gettype(self): ! return self.type ! def getmaintype(self): ! return self.maintype ! def getsubtype(self): ! return self.subtype --- 8,90 ---- class Message(rfc822.Message): ! """A derived class of rfc822.Message that knows about MIME headers and ! contains some hooks for decoding encoded and multipart messages.""" ! def __init__(self, fp, seekable = 1): ! rfc822.Message.__init__(self, fp, seekable) ! self.encodingheader = \ ! self.getheader('content-transfer-encoding') ! self.typeheader = \ ! self.getheader('content-type') ! self.parsetype() ! self.parseplist() ! ! def parsetype(self): ! str = self.typeheader ! if str is None: ! str = 'text/plain' ! if ';' in str: ! i = str.index(';') ! self.plisttext = str[i:] ! str = str[:i] ! else: ! self.plisttext = '' ! fields = str.split('/') ! for i in range(len(fields)): ! fields[i] = fields[i].strip().lower() ! self.type = '/'.join(fields) ! self.maintype = fields[0] ! self.subtype = '/'.join(fields[1:]) ! ! def parseplist(self): ! str = self.plisttext ! self.plist = [] ! while str[:1] == ';': ! str = str[1:] ! if ';' in str: ! # XXX Should parse quotes! ! end = str.index(';') ! else: ! end = len(str) ! f = str[:end] ! if '=' in f: ! i = f.index('=') ! f = f[:i].strip().lower() + \ ! '=' + f[i+1:].strip() ! self.plist.append(f.strip()) ! str = str[end:] ! ! def getplist(self): ! return self.plist ! ! def getparam(self, name): ! name = name.lower() + '=' ! n = len(name) ! for p in self.plist: ! if p[:n] == name: ! return rfc822.unquote(p[n:]) ! return None ! ! def getparamnames(self): ! result = [] ! for p in self.plist: ! i = p.find('=') ! if i >= 0: ! result.append(p[:i].lower()) ! return result ! ! def getencoding(self): ! if self.encodingheader is None: ! return '7bit' ! return self.encodingheader.lower() ! def gettype(self): ! return self.type ! def getmaintype(self): ! return self.maintype ! def getsubtype(self): ! return self.subtype *************** *** 98,128 **** def choose_boundary(): ! """Return a random string usable as a multipart boundary. ! The method used is so that it is *very* unlikely that the same ! string of characters will every occur again in the Universe, ! so the caller needn't check the data it is packing for the ! occurrence of the boundary. ! ! The boundary contains dots so you have to quote it in the header.""" ! ! global _prefix ! import time ! import random ! if _prefix is None: ! import socket ! import os ! hostid = socket.gethostbyname(socket.gethostname()) ! try: ! uid = `os.getuid()` ! except: ! uid = '1' ! try: ! pid = `os.getpid()` ! except: ! pid = '1' ! _prefix = hostid + '.' + uid + '.' + pid ! timestamp = '%.3f' % time.time() ! seed = `random.randint(0, 32767)` ! return _prefix + '.' + timestamp + '.' + seed --- 98,128 ---- def choose_boundary(): ! """Return a random string usable as a multipart boundary. ! The method used is so that it is *very* unlikely that the same ! string of characters will every occur again in the Universe, ! so the caller needn't check the data it is packing for the ! occurrence of the boundary. ! ! The boundary contains dots so you have to quote it in the header.""" ! ! global _prefix ! import time ! import random ! if _prefix is None: ! import socket ! import os ! hostid = socket.gethostbyname(socket.gethostname()) ! try: ! uid = `os.getuid()` ! except: ! uid = '1' ! try: ! pid = `os.getpid()` ! except: ! pid = '1' ! _prefix = hostid + '.' + uid + '.' + pid ! timestamp = '%.3f' % time.time() ! seed = `random.randint(0, 32767)` ! return _prefix + '.' + timestamp + '.' + seed *************** *** 130,169 **** def decode(input, output, encoding): ! """Decode common content-transfer-encodings (base64, quopri, uuencode).""" ! if encoding == 'base64': ! import base64 ! return base64.decode(input, output) ! if encoding == 'quoted-printable': ! import quopri ! return quopri.decode(input, output) ! if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): ! import uu ! return uu.decode(input, output) ! if encoding in ('7bit', '8bit'): ! return output.write(input.read()) ! if decodetab.has_key(encoding): ! pipethrough(input, decodetab[encoding], output) ! else: ! raise ValueError, \ ! 'unknown Content-Transfer-Encoding: %s' % encoding def encode(input, output, encoding): ! """Encode common content-transfer-encodings (base64, quopri, uuencode).""" ! if encoding == 'base64': ! import base64 ! return base64.encode(input, output) ! if encoding == 'quoted-printable': ! import quopri ! return quopri.encode(input, output, 0) ! if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): ! import uu ! return uu.encode(input, output) ! if encoding in ('7bit', '8bit'): ! return output.write(input.read()) ! if encodetab.has_key(encoding): ! pipethrough(input, encodetab[encoding], output) ! else: ! raise ValueError, \ ! 'unknown Content-Transfer-Encoding: %s' % encoding # The following is no longer used for standard encodings --- 130,169 ---- def decode(input, output, encoding): ! """Decode common content-transfer-encodings (base64, quopri, uuencode).""" ! if encoding == 'base64': ! import base64 ! return base64.decode(input, output) ! if encoding == 'quoted-printable': ! import quopri ! return quopri.decode(input, output) ! if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): ! import uu ! return uu.decode(input, output) ! if encoding in ('7bit', '8bit'): ! return output.write(input.read()) ! if decodetab.has_key(encoding): ! pipethrough(input, decodetab[encoding], output) ! else: ! raise ValueError, \ ! 'unknown Content-Transfer-Encoding: %s' % encoding def encode(input, output, encoding): ! """Encode common content-transfer-encodings (base64, quopri, uuencode).""" ! if encoding == 'base64': ! import base64 ! return base64.encode(input, output) ! if encoding == 'quoted-printable': ! import quopri ! return quopri.encode(input, output, 0) ! if encoding in ('uuencode', 'x-uuencode', 'uue', 'x-uue'): ! import uu ! return uu.encode(input, output) ! if encoding in ('7bit', '8bit'): ! return output.write(input.read()) ! if encodetab.has_key(encoding): ! pipethrough(input, encodetab[encoding], output) ! else: ! raise ValueError, \ ! 'unknown Content-Transfer-Encoding: %s' % encoding # The following is no longer used for standard encodings *************** *** 179,228 **** decodetab = { ! 'uuencode': uudecode_pipe, ! 'x-uuencode': uudecode_pipe, ! 'uue': uudecode_pipe, ! 'x-uue': uudecode_pipe, ! 'quoted-printable': 'mmencode -u -q', ! 'base64': 'mmencode -u -b', } encodetab = { ! 'x-uuencode': 'uuencode tempfile', ! 'uuencode': 'uuencode tempfile', ! 'x-uue': 'uuencode tempfile', ! 'uue': 'uuencode tempfile', ! 'quoted-printable': 'mmencode -q', ! 'base64': 'mmencode -b', } def pipeto(input, command): ! pipe = os.popen(command, 'w') ! copyliteral(input, pipe) ! pipe.close() def pipethrough(input, command, output): ! tempname = tempfile.mktemp() ! try: ! temp = open(tempname, 'w') ! except IOError: ! print '*** Cannot create temp file', `tempname` ! return ! copyliteral(input, temp) ! temp.close() ! pipe = os.popen(command + ' <' + tempname, 'r') ! copybinary(pipe, output) ! pipe.close() ! os.unlink(tempname) def copyliteral(input, output): ! while 1: ! line = input.readline() ! if not line: break ! output.write(line) def copybinary(input, output): ! BUFSIZE = 8192 ! while 1: ! line = input.read(BUFSIZE) ! if not line: break ! output.write(line) --- 179,228 ---- decodetab = { ! 'uuencode': uudecode_pipe, ! 'x-uuencode': uudecode_pipe, ! 'uue': uudecode_pipe, ! 'x-uue': uudecode_pipe, ! 'quoted-printable': 'mmencode -u -q', ! 'base64': 'mmencode -u -b', } encodetab = { ! 'x-uuencode': 'uuencode tempfile', ! 'uuencode': 'uuencode tempfile', ! 'x-uue': 'uuencode tempfile', ! 'uue': 'uuencode tempfile', ! 'quoted-printable': 'mmencode -q', ! 'base64': 'mmencode -b', } def pipeto(input, command): ! pipe = os.popen(command, 'w') ! copyliteral(input, pipe) ! pipe.close() def pipethrough(input, command, output): ! tempname = tempfile.mktemp() ! try: ! temp = open(tempname, 'w') ! except IOError: ! print '*** Cannot create temp file', `tempname` ! return ! copyliteral(input, temp) ! temp.close() ! pipe = os.popen(command + ' <' + tempname, 'r') ! copybinary(pipe, output) ! pipe.close() ! os.unlink(tempname) def copyliteral(input, output): ! while 1: ! line = input.readline() ! if not line: break ! output.write(line) def copybinary(input, output): ! BUFSIZE = 8192 ! while 1: ! line = input.read(BUFSIZE) ! if not line: break ! output.write(line) Index: mimify.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mimify.py,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -r1.15 -r1.16 *** mimify.py 2000/02/04 15:39:29 1.15 --- mimify.py 2001/01/14 23:47:14 1.16 *************** *** 7,12 **** Usage: ! mimify(input, output) ! unmimify(input, output, decode_base64 = 0) to encode and decode respectively. Input and output may be the name of a file or an open file object. Only a readline() method is used --- 7,12 ---- Usage: ! mimify(input, output) ! unmimify(input, output, decode_base64 = 0) to encode and decode respectively. Input and output may be the name of a file or an open file object. Only a readline() method is used *************** *** 16,21 **** Interactive usage: ! mimify.py -e [infile [outfile]] ! mimify.py -d [infile [outfile]] to encode and decode respectively. Infile defaults to standard input and outfile to standard output. --- 16,21 ---- Interactive usage: ! mimify.py -e [infile [outfile]] ! mimify.py -d [infile [outfile]] to encode and decode respectively. Infile defaults to standard input and outfile to standard output. *************** *** 23,29 **** # Configure ! MAXLEN = 200 # if lines longer than this, encode as quoted-printable ! CHARSET = 'ISO-8859-1' # default charset for non-US-ASCII mail ! QUOTE = '> ' # string replies are quoted with # End configure --- 23,29 ---- # Configure ! MAXLEN = 200 # if lines longer than this, encode as quoted-printable ! CHARSET = 'ISO-8859-1' # default charset for non-US-ASCII mail ! QUOTE = '> ' # string replies are quoted with # End configure *************** *** 40,219 **** class File: ! """A simple fake file object that knows about limited read-ahead and ! boundaries. The only supported method is readline().""" ! def __init__(self, file, boundary): ! self.file = file ! self.boundary = boundary ! self.peek = None ! ! def readline(self): ! if self.peek is not None: ! return '' ! line = self.file.readline() ! if not line: ! return line ! if self.boundary: ! if line == self.boundary + '\n': ! self.peek = line ! return '' ! if line == self.boundary + '--\n': ! self.peek = line ! return '' ! return line class HeaderFile: ! def __init__(self, file): ! self.file = file ! self.peek = None ! ! def readline(self): ! if self.peek is not None: ! line = self.peek ! self.peek = None ! else: ! line = self.file.readline() ! if not line: ! return line ! if he.match(line): ! return line ! while 1: ! self.peek = self.file.readline() ! if len(self.peek) == 0 or \ ! (self.peek[0] != ' ' and self.peek[0] != '\t'): ! return line ! line = line + self.peek ! self.peek = None def mime_decode(line): ! """Decode a single line of quoted-printable text to 8bit.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_code.search(line, pos) ! if res is None: ! break ! newline = newline + line[pos:res.start(0)] + \ ! chr(string.atoi(res.group(1), 16)) ! pos = res.end(0) ! return newline + line[pos:] def mime_decode_header(line): ! """Decode a header line to 8bit.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_head.search(line, pos) ! if res is None: ! break ! match = res.group(1) ! # convert underscores to spaces (before =XX conversion!) ! match = string.join(string.split(match, '_'), ' ') ! newline = newline + line[pos:res.start(0)] + mime_decode(match) ! pos = res.end(0) ! return newline + line[pos:] def unmimify_part(ifile, ofile, decode_base64 = 0): ! """Convert a quoted-printable part of a MIME mail message to 8bit.""" ! multipart = None ! quoted_printable = 0 ! is_base64 = 0 ! is_repl = 0 ! if ifile.boundary and ifile.boundary[:2] == QUOTE: ! prefix = QUOTE ! else: ! prefix = '' ! ! # read header ! hfile = HeaderFile(ifile) ! while 1: ! line = hfile.readline() ! if not line: ! return ! if prefix and line[:len(prefix)] == prefix: ! line = line[len(prefix):] ! pref = prefix ! else: ! pref = '' ! line = mime_decode_header(line) ! if qp.match(line): ! quoted_printable = 1 ! continue # skip this header ! if decode_base64 and base64_re.match(line): ! is_base64 = 1 ! continue ! ofile.write(pref + line) ! if not prefix and repl.match(line): ! # we're dealing with a reply message ! is_repl = 1 ! mp_res = mp.match(line) ! if mp_res: ! multipart = '--' + mp_res.group(1) ! if he.match(line): ! break ! if is_repl and (quoted_printable or multipart): ! is_repl = 0 ! ! # read body ! while 1: ! line = ifile.readline() ! if not line: ! return ! line = re.sub(mime_head, '\\1', line) ! if prefix and line[:len(prefix)] == prefix: ! line = line[len(prefix):] ! pref = prefix ! else: ! pref = '' ! ## if is_repl and len(line) >= 4 and line[:4] == QUOTE+'--' and line[-3:] != '--\n': ! ## multipart = line[:-1] ! while multipart: ! if line == multipart + '--\n': ! ofile.write(pref + line) ! multipart = None ! line = None ! break ! if line == multipart + '\n': ! ofile.write(pref + line) ! nifile = File(ifile, multipart) ! unmimify_part(nifile, ofile, decode_base64) ! line = nifile.peek ! if not line: ! # premature end of file ! break ! continue ! # not a boundary between parts ! break ! if line and quoted_printable: ! while line[-2:] == '=\n': ! line = line[:-2] ! newline = ifile.readline() ! if newline[:len(QUOTE)] == QUOTE: ! newline = newline[len(QUOTE):] ! line = line + newline ! line = mime_decode(line) ! if line and is_base64 and not pref: ! import base64 ! line = base64.decodestring(line) ! if line: ! ofile.write(pref + line) def unmimify(infile, outfile, decode_base64 = 0): ! """Convert quoted-printable parts of a MIME mail message to 8bit.""" ! if type(infile) == type(''): ! ifile = open(infile) ! if type(outfile) == type('') and infile == outfile: ! import os ! d, f = os.path.split(infile) ! os.rename(infile, os.path.join(d, ',' + f)) ! else: ! ifile = infile ! if type(outfile) == type(''): ! ofile = open(outfile, 'w') ! else: ! ofile = outfile ! nifile = File(ifile, None) ! unmimify_part(nifile, ofile, decode_base64) ! ofile.flush() mime_char = re.compile('[=\177-\377]') # quote these chars in body --- 40,219 ---- class File: ! """A simple fake file object that knows about limited read-ahead and ! boundaries. The only supported method is readline().""" ! def __init__(self, file, boundary): ! self.file = file ! self.boundary = boundary ! self.peek = None ! ! def readline(self): ! if self.peek is not None: ! return '' ! line = self.file.readline() ! if not line: ! return line ! if self.boundary: ! if line == self.boundary + '\n': ! self.peek = line ! return '' ! if line == self.boundary + '--\n': ! self.peek = line ! return '' ! return line class HeaderFile: ! def __init__(self, file): ! self.file = file ! self.peek = None ! ! def readline(self): ! if self.peek is not None: ! line = self.peek ! self.peek = None ! else: ! line = self.file.readline() ! if not line: ! return line ! if he.match(line): ! return line ! while 1: ! self.peek = self.file.readline() ! if len(self.peek) == 0 or \ ! (self.peek[0] != ' ' and self.peek[0] != '\t'): ! return line ! line = line + self.peek ! self.peek = None def mime_decode(line): ! """Decode a single line of quoted-printable text to 8bit.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_code.search(line, pos) ! if res is None: ! break ! newline = newline + line[pos:res.start(0)] + \ ! chr(string.atoi(res.group(1), 16)) ! pos = res.end(0) ! return newline + line[pos:] def mime_decode_header(line): ! """Decode a header line to 8bit.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_head.search(line, pos) ! if res is None: ! break ! match = res.group(1) ! # convert underscores to spaces (before =XX conversion!) ! match = string.join(string.split(match, '_'), ' ') ! newline = newline + line[pos:res.start(0)] + mime_decode(match) ! pos = res.end(0) ! return newline + line[pos:] def unmimify_part(ifile, ofile, decode_base64 = 0): ! """Convert a quoted-printable part of a MIME mail message to 8bit.""" ! multipart = None ! quoted_printable = 0 ! is_base64 = 0 ! is_repl = 0 ! if ifile.boundary and ifile.boundary[:2] == QUOTE: ! prefix = QUOTE ! else: ! prefix = '' ! ! # read header ! hfile = HeaderFile(ifile) ! while 1: ! line = hfile.readline() ! if not line: ! return ! if prefix and line[:len(prefix)] == prefix: ! line = line[len(prefix):] ! pref = prefix ! else: ! pref = '' ! line = mime_decode_header(line) ! if qp.match(line): ! quoted_printable = 1 ! continue # skip this header ! if decode_base64 and base64_re.match(line): ! is_base64 = 1 ! continue ! ofile.write(pref + line) ! if not prefix and repl.match(line): ! # we're dealing with a reply message ! is_repl = 1 ! mp_res = mp.match(line) ! if mp_res: ! multipart = '--' + mp_res.group(1) ! if he.match(line): ! break ! if is_repl and (quoted_printable or multipart): ! is_repl = 0 ! ! # read body ! while 1: ! line = ifile.readline() ! if not line: ! return ! line = re.sub(mime_head, '\\1', line) ! if prefix and line[:len(prefix)] == prefix: ! line = line[len(prefix):] ! pref = prefix ! else: ! pref = '' ! ## if is_repl and len(line) >= 4 and line[:4] == QUOTE+'--' and line[-3:] != '--\n': ! ## multipart = line[:-1] ! while multipart: ! if line == multipart + '--\n': ! ofile.write(pref + line) ! multipart = None ! line = None ! break ! if line == multipart + '\n': ! ofile.write(pref + line) ! nifile = File(ifile, multipart) ! unmimify_part(nifile, ofile, decode_base64) ! line = nifile.peek ! if not line: ! # premature end of file ! break ! continue ! # not a boundary between parts ! break ! if line and quoted_printable: ! while line[-2:] == '=\n': ! line = line[:-2] ! newline = ifile.readline() ! if newline[:len(QUOTE)] == QUOTE: ! newline = newline[len(QUOTE):] ! line = line + newline ! line = mime_decode(line) ! if line and is_base64 and not pref: ! import base64 ! line = base64.decodestring(line) ! if line: ! ofile.write(pref + line) def unmimify(infile, outfile, decode_base64 = 0): ! """Convert quoted-printable parts of a MIME mail message to 8bit.""" ! if type(infile) == type(''): ! ifile = open(infile) ! if type(outfile) == type('') and infile == outfile: ! import os ! d, f = os.path.split(infile) ! os.rename(infile, os.path.join(d, ',' + f)) ! else: ! ifile = infile ! if type(outfile) == type(''): ! ofile = open(outfile, 'w') ! else: ! ofile = outfile ! nifile = File(ifile, None) ! unmimify_part(nifile, ofile, decode_base64) ! ofile.flush() mime_char = re.compile('[=\177-\377]') # quote these chars in body *************** *** 221,270 **** def mime_encode(line, header): ! """Code a single line as quoted-printable. ! If header is set, quote some extra characters.""" ! if header: ! reg = mime_header_char ! else: ! reg = mime_char ! newline = '' ! pos = 0 ! if len(line) >= 5 and line[:5] == 'From ': ! # quote 'From ' at the start of a line for stupid mailers ! newline = string.upper('=%02x' % ord('F')) ! pos = 1 ! while 1: ! res = reg.search(line, pos) ! if res is None: ! break ! newline = newline + line[pos:res.start(0)] + \ ! string.upper('=%02x' % ord(res.group(0))) ! pos = res.end(0) ! line = newline + line[pos:] ! ! newline = '' ! while len(line) >= 75: ! i = 73 ! while line[i] == '=' or line[i-1] == '=': ! i = i - 1 ! i = i + 1 ! newline = newline + line[:i] + '=\n' ! line = line[i:] ! return newline + line mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)([ \t)]|\n)') def mime_encode_header(line): ! """Code a single header line as quoted-printable.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_header.search(line, pos) ! if res is None: ! break ! newline = '%s%s%s=?%s?Q?%s?=%s' % \ ! (newline, line[pos:res.start(0)], res.group(1), ! CHARSET, mime_encode(res.group(2), 1), res.group(3)) ! pos = res.end(0) ! return newline + line[pos:] mv = re.compile('^mime-version:', re.I) --- 221,270 ---- def mime_encode(line, header): ! """Code a single line as quoted-printable. ! If header is set, quote some extra characters.""" ! if header: ! reg = mime_header_char ! else: ! reg = mime_char ! newline = '' ! pos = 0 ! if len(line) >= 5 and line[:5] == 'From ': ! # quote 'From ' at the start of a line for stupid mailers ! newline = string.upper('=%02x' % ord('F')) ! pos = 1 ! while 1: ! res = reg.search(line, pos) ! if res is None: ! break ! newline = newline + line[pos:res.start(0)] + \ ! string.upper('=%02x' % ord(res.group(0))) ! pos = res.end(0) ! line = newline + line[pos:] ! ! newline = '' ! while len(line) >= 75: ! i = 73 ! while line[i] == '=' or line[i-1] == '=': ! i = i - 1 ! i = i + 1 ! newline = newline + line[:i] + '=\n' ! line = line[i:] ! return newline + line mime_header = re.compile('([ \t(]|^)([-a-zA-Z0-9_+]*[\177-\377][-a-zA-Z0-9_+\177-\377]*)([ \t)]|\n)') def mime_encode_header(line): ! """Code a single header line as quoted-printable.""" ! newline = '' ! pos = 0 ! while 1: ! res = mime_header.search(line, pos) ! if res is None: ! break ! newline = '%s%s%s=?%s?Q?%s?=%s' % \ ! (newline, line[pos:res.start(0)], res.group(1), ! CHARSET, mime_encode(res.group(2), 1), res.group(3)) ! pos = res.end(0) ! return newline + line[pos:] mv = re.compile('^mime-version:', re.I) *************** *** 273,463 **** def mimify_part(ifile, ofile, is_mime): ! """Convert an 8bit part of a MIME mail message to quoted-printable.""" ! has_cte = is_qp = is_base64 = 0 ! multipart = None ! must_quote_body = must_quote_header = has_iso_chars = 0 ! ! header = [] ! header_end = '' ! message = [] ! message_end = '' ! # read header ! hfile = HeaderFile(ifile) ! while 1: ! line = hfile.readline() ! if not line: ! break ! if not must_quote_header and iso_char.search(line): ! must_quote_header = 1 ! if mv.match(line): ! is_mime = 1 ! if cte.match(line): ! has_cte = 1 ! if qp.match(line): ! is_qp = 1 ! elif base64_re.match(line): ! is_base64 = 1 ! mp_res = mp.match(line) ! if mp_res: ! multipart = '--' + mp_res.group(1) ! if he.match(line): ! header_end = line ! break ! header.append(line) ! ! # read body ! while 1: ! line = ifile.readline() ! if not line: ! break ! if multipart: ! if line == multipart + '--\n': ! message_end = line ! break ! if line == multipart + '\n': ! message_end = line ! break ! if is_base64: ! message.append(line) ! continue ! if is_qp: ! while line[-2:] == '=\n': ! line = line[:-2] ! newline = ifile.readline() ! if newline[:len(QUOTE)] == QUOTE: ! newline = newline[len(QUOTE):] ! line = line + newline ! line = mime_decode(line) ! message.append(line) ! if not has_iso_chars: ! if iso_char.search(line): ! has_iso_chars = must_quote_body = 1 ! if not must_quote_body: ! if len(line) > MAXLEN: ! must_quote_body = 1 ! ! # convert and output header and body ! for line in header: ! if must_quote_header: ! line = mime_encode_header(line) ! chrset_res = chrset.match(line) ! if chrset_res: ! if has_iso_chars: ! # change us-ascii into iso-8859-1 ! if string.lower(chrset_res.group(2)) == 'us-ascii': ! line = '%s%s%s' % (chrset_res.group(1), ! CHARSET, ! chrset_res.group(3)) ! else: ! # change iso-8859-* into us-ascii ! line = '%sus-ascii%s' % chrset_res.group(1, 3) ! if has_cte and cte.match(line): ! line = 'Content-Transfer-Encoding: ' ! if is_base64: ! line = line + 'base64\n' ! elif must_quote_body: ! line = line + 'quoted-printable\n' ! else: ! line = line + '7bit\n' ! ofile.write(line) ! if (must_quote_header or must_quote_body) and not is_mime: ! ofile.write('Mime-Version: 1.0\n') ! ofile.write('Content-Type: text/plain; ') ! if has_iso_chars: ! ofile.write('charset="%s"\n' % CHARSET) ! else: ! ofile.write('charset="us-ascii"\n') ! if must_quote_body and not has_cte: ! ofile.write('Content-Transfer-Encoding: quoted-printable\n') ! ofile.write(header_end) ! ! for line in message: ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) ! ofile.write(message_end) ! ! line = message_end ! while multipart: ! if line == multipart + '--\n': ! # read bit after the end of the last part ! while 1: ! line = ifile.readline() ! if not line: ! return ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) ! if line == multipart + '\n': ! nifile = File(ifile, multipart) ! mimify_part(nifile, ofile, 1) ! line = nifile.peek ! if not line: ! # premature end of file ! break ! ofile.write(line) ! continue ! # unexpectedly no multipart separator--copy rest of file ! while 1: ! line = ifile.readline() ! if not line: ! return ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) def mimify(infile, outfile): ! """Convert 8bit parts of a MIME mail message to quoted-printable.""" ! if type(infile) == type(''): ! ifile = open(infile) ! if type(outfile) == type('') and infile == outfile: ! import os ! d, f = os.path.split(infile) ! os.rename(infile, os.path.join(d, ',' + f)) ! else: ! ifile = infile ! if type(outfile) == type(''): ! ofile = open(outfile, 'w') ! else: ! ofile = outfile ! nifile = File(ifile, None) ! mimify_part(nifile, ofile, 0) ! ofile.flush() import sys if __name__ == '__main__' or (len(sys.argv) > 0 and sys.argv[0] == 'mimify'): ! import getopt ! usage = 'Usage: mimify [-l len] -[ed] [infile [outfile]]' ! decode_base64 = 0 ! opts, args = getopt.getopt(sys.argv[1:], 'l:edb') ! if len(args) not in (0, 1, 2): ! print usage ! sys.exit(1) ! if (('-e', '') in opts) == (('-d', '') in opts) or \ ! ((('-b', '') in opts) and (('-d', '') not in opts)): ! print usage ! sys.exit(1) ! for o, a in opts: ! if o == '-e': ! encode = mimify ! elif o == '-d': ! encode = unmimify ! elif o == '-l': ! try: ! MAXLEN = string.atoi(a) ! except: ! print usage ! sys.exit(1) ! elif o == '-b': ! decode_base64 = 1 ! if len(args) == 0: ! encode_args = (sys.stdin, sys.stdout) ! elif len(args) == 1: ! encode_args = (args[0], sys.stdout) ! else: ! encode_args = (args[0], args[1]) ! if decode_base64: ! encode_args = encode_args + (decode_base64,) ! apply(encode, encode_args) ! --- 273,462 ---- def mimify_part(ifile, ofile, is_mime): ! """Convert an 8bit part of a MIME mail message to quoted-printable.""" ! has_cte = is_qp = is_base64 = 0 ! multipart = None ! must_quote_body = must_quote_header = has_iso_chars = 0 ! ! header = [] ! header_end = '' ! message = [] ! message_end = '' ! # read header ! hfile = HeaderFile(ifile) ! while 1: ! line = hfile.readline() ! if not line: ! break ! if not must_quote_header and iso_char.search(line): ! must_quote_header = 1 ! if mv.match(line): ! is_mime = 1 ! if cte.match(line): ! has_cte = 1 ! if qp.match(line): ! is_qp = 1 ! elif base64_re.match(line): ! is_base64 = 1 ! mp_res = mp.match(line) ! if mp_res: ! multipart = '--' + mp_res.group(1) ! if he.match(line): ! header_end = line ! break ! header.append(line) ! ! # read body ! while 1: ! line = ifile.readline() ! if not line: ! break ! if multipart: ! if line == multipart + '--\n': ! message_end = line ! break ! if line == multipart + '\n': ! message_end = line ! break ! if is_base64: ! message.append(line) ! continue ! if is_qp: ! while line[-2:] == '=\n': ! line = line[:-2] ! newline = ifile.readline() ! if newline[:len(QUOTE)] == QUOTE: ! newline = newline[len(QUOTE):] ! line = line + newline ! line = mime_decode(line) ! message.append(line) ! if not has_iso_chars: ! if iso_char.search(line): ! has_iso_chars = must_quote_body = 1 ! if not must_quote_body: ! if len(line) > MAXLEN: ! must_quote_body = 1 ! ! # convert and output header and body ! for line in header: ! if must_quote_header: ! line = mime_encode_header(line) ! chrset_res = chrset.match(line) ! if chrset_res: ! if has_iso_chars: ! # change us-ascii into iso-8859-1 ! if string.lower(chrset_res.group(2)) == 'us-ascii': ! line = '%s%s%s' % (chrset_res.group(1), ! CHARSET, ! chrset_res.group(3)) ! else: ! # change iso-8859-* into us-ascii ! line = '%sus-ascii%s' % chrset_res.group(1, 3) ! if has_cte and cte.match(line): ! line = 'Content-Transfer-Encoding: ' ! if is_base64: ! line = line + 'base64\n' ! elif must_quote_body: ! line = line + 'quoted-printable\n' ! else: ! line = line + '7bit\n' ! ofile.write(line) ! if (must_quote_header or must_quote_body) and not is_mime: ! ofile.write('Mime-Version: 1.0\n') ! ofile.write('Content-Type: text/plain; ') ! if has_iso_chars: ! ofile.write('charset="%s"\n' % CHARSET) ! else: ! ofile.write('charset="us-ascii"\n') ! if must_quote_body and not has_cte: ! ofile.write('Content-Transfer-Encoding: quoted-printable\n') ! ofile.write(header_end) ! ! for line in message: ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) ! ofile.write(message_end) ! ! line = message_end ! while multipart: ! if line == multipart + '--\n': ! # read bit after the end of the last part ! while 1: ! line = ifile.readline() ! if not line: ! return ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) ! if line == multipart + '\n': ! nifile = File(ifile, multipart) ! mimify_part(nifile, ofile, 1) ! line = nifile.peek ! if not line: ! # premature end of file ! break ! ofile.write(line) ! continue ! # unexpectedly no multipart separator--copy rest of file ! while 1: ! line = ifile.readline() ! if not line: ! return ! if must_quote_body: ! line = mime_encode(line, 0) ! ofile.write(line) def mimify(infile, outfile): ! """Convert 8bit parts of a MIME mail message to quoted-printable.""" ! if type(infile) == type(''): ! ifile = open(infile) ! if type(outfile) == type('') and infile == outfile: ! import os ! d, f = os.path.split(infile) ! os.rename(infile, os.path.join(d, ',' + f)) ! else: ! ifile = infile ! if type(outfile) == type(''): ! ofile = open(outfile, 'w') ! else: ! ofile = outfile ! nifile = File(ifile, None) ! mimify_part(nifile, ofile, 0) ! ofile.flush() import sys if __name__ == '__main__' or (len(sys.argv) > 0 and sys.argv[0] == 'mimify'): ! import getopt ! usage = 'Usage: mimify [-l len] -[ed] [infile [outfile]]' ! decode_base64 = 0 ! opts, args = getopt.getopt(sys.argv[1:], 'l:edb') ! if len(args) not in (0, 1, 2): ! print usage ! sys.exit(1) ! if (('-e', '') in opts) == (('-d', '') in opts) or \ ! ((('-b', '') in opts) and (('-d', '') not in opts)): ! print usage ! sys.exit(1) ! for o, a in opts: ! if o == '-e': ! encode = mimify ! elif o == '-d': ! encode = unmimify ! elif o == '-l': ! try: ! MAXLEN = string.atoi(a) ! except: ! print usage ! sys.exit(1) ! elif o == '-b': ! decode_base64 = 1 ! if len(args) == 0: ! encode_args = (sys.stdin, sys.stdout) ! elif len(args) == 1: ! encode_args = (args[0], sys.stdout) ! else: ! encode_args = (args[0], args[1]) ! if decode_base64: ! encode_args = encode_args + (decode_base64,) ! apply(encode, encode_args) Index: multifile.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/multifile.py,v retrieving revision 1.13 retrieving revision 1.14 diff -C2 -r1.13 -r1.14 *** multifile.py 2000/12/23 14:20:24 1.13 --- multifile.py 2001/01/14 23:47:14 1.14 *************** *** 14,19 **** fp.push(separator) while 1: ! "read lines from fp until it returns an empty string" (A) ! if not fp.next(): break fp.pop() "read remaining lines from fp until it returns an empty string" --- 14,19 ---- fp.push(separator) while 1: ! "read lines from fp until it returns an empty string" (A) ! if not fp.next(): break fp.pop() "read remaining lines from fp until it returns an empty string" *************** *** 32,164 **** class Error(Exception): ! pass class MultiFile: ! seekable = 0 ! def __init__(self, fp, seekable=1): ! self.fp = fp ! self.stack = [] # Grows down ! self.level = 0 ! self.last = 0 ! if seekable: ! self.seekable = 1 ! self.start = self.fp.tell() ! self.posstack = [] # Grows down ! ! def tell(self): ! if self.level > 0: ! return self.lastpos ! return self.fp.tell() - self.start ! ! def seek(self, pos, whence=0): ! here = self.tell() ! if whence: ! if whence == 1: ! pos = pos + here ! elif whence == 2: ! if self.level > 0: ! pos = pos + self.lastpos ! else: ! raise Error, "can't use whence=2 yet" ! if not 0 <= pos <= here or \ ! self.level > 0 and pos > self.lastpos: ! raise Error, 'bad MultiFile.seek() call' ! self.fp.seek(pos + self.start) ! self.level = 0 ! self.last = 0 ! ! def readline(self): ! if self.level > 0: ! return '' ! line = self.fp.readline() ! # Real EOF? ! if not line: ! self.level = len(self.stack) ! self.last = (self.level > 0) ! if self.last: ! raise Error, 'sudden EOF in MultiFile.readline()' ! return '' ! assert self.level == 0 ! # Fast check to see if this is just data ! if self.is_data(line): ! return line ! else: ! # Ignore trailing whitespace on marker lines ! k = len(line) - 1 ! while line[k] in string.whitespace: ! k = k - 1 ! marker = line[:k+1] ! # No? OK, try to match a boundary. ! # Return the line (unstripped) if we don't. ! for i in range(len(self.stack)): ! sep = self.stack[i] ! if marker == self.section_divider(sep): ! self.last = 0 ! break ! elif marker == self.end_marker(sep): ! self.last = 1 ! break ! else: ! return line ! # We only get here if we see a section divider or EOM line ! if self.seekable: ! self.lastpos = self.tell() - len(line) ! self.level = i+1 ! if self.level > 1: ! raise Error,'Missing endmarker in MultiFile.readline()' ! return '' ! ! def readlines(self): ! list = [] ! while 1: ! line = self.readline() ! if not line: break ! list.append(line) ! return list ! ! def read(self): # Note: no size argument -- read until EOF only! ! return string.joinfields(self.readlines(), '') ! ! def next(self): ! while self.readline(): pass ! if self.level > 1 or self.last: ! return 0 ! self.level = 0 ! self.last = 0 ! if self.seekable: ! self.start = self.fp.tell() ! return 1 ! ! def push(self, sep): ! if self.level > 0: ! raise Error, 'bad MultiFile.push() call' ! self.stack.insert(0, sep) ! if self.seekable: ! self.posstack.insert(0, self.start) ! self.start = self.fp.tell() ! ! def pop(self): ! if self.stack == []: ! raise Error, 'bad MultiFile.pop() call' ! if self.level <= 1: ! self.last = 0 ! else: ! abslastpos = self.lastpos + self.start ! self.level = max(0, self.level - 1) ! del self.stack[0] ! if self.seekable: ! self.start = self.posstack[0] ! del self.posstack[0] ! if self.level > 0: ! self.lastpos = abslastpos - self.start ! def is_data(self, line): ! return line[:2] != '--' ! def section_divider(self, str): ! return "--" + str ! def end_marker(self, str): ! return "--" + str + "--" --- 32,164 ---- class Error(Exception): ! pass class MultiFile: ! seekable = 0 ! def __init__(self, fp, seekable=1): ! self.fp = fp ! self.stack = [] # Grows down ! self.level = 0 ! self.last = 0 ! if seekable: ! self.seekable = 1 ! self.start = self.fp.tell() ! self.posstack = [] # Grows down ! ! def tell(self): ! if self.level > 0: ! return self.lastpos ! return self.fp.tell() - self.start ! ! def seek(self, pos, whence=0): ! here = self.tell() ! if whence: ! if whence == 1: ! pos = pos + here ! elif whence == 2: ! if self.level > 0: ! pos = pos + self.lastpos ! else: ! raise Error, "can't use whence=2 yet" ! if not 0 <= pos <= here or \ ! self.level > 0 and pos > self.lastpos: ! raise Error, 'bad MultiFile.seek() call' ! self.fp.seek(pos + self.start) ! self.level = 0 ! self.last = 0 ! ! def readline(self): ! if self.level > 0: ! return '' ! line = self.fp.readline() ! # Real EOF? ! if not line: ! self.level = len(self.stack) ! self.last = (self.level > 0) ! if self.last: ! raise Error, 'sudden EOF in MultiFile.readline()' ! return '' ! assert self.level == 0 ! # Fast check to see if this is just data ! if self.is_data(line): ! return line ! else: ! # Ignore trailing whitespace on marker lines ! k = len(line) - 1 ! while line[k] in string.whitespace: ! k = k - 1 ! marker = line[:k+1] ! # No? OK, try to match a boundary. ! # Return the line (unstripped) if we don't. ! for i in range(len(self.stack)): ! sep = self.stack[i] ! if marker == self.section_divider(sep): ! self.last = 0 ! break ! elif marker == self.end_marker(sep): ! self.last = 1 ! break ! else: ! return line ! # We only get here if we see a section divider or EOM line ! if self.seekable: ! self.lastpos = self.tell() - len(line) ! self.level = i+1 ! if self.level > 1: ! raise Error,'Missing endmarker in MultiFile.readline()' ! return '' ! ! def readlines(self): ! list = [] ! while 1: ! line = self.readline() ! if not line: break ! list.append(line) ! return list ! ! def read(self): # Note: no size argument -- read until EOF only! ! return string.joinfields(self.readlines(), '') ! ! def next(self): ! while self.readline(): pass ! if self.level > 1 or self.last: ! return 0 ! self.level = 0 ! self.last = 0 ! if self.seekable: ! self.start = self.fp.tell() ! return 1 ! ! def push(self, sep): ! if self.level > 0: ! raise Error, 'bad MultiFile.push() call' ! self.stack.insert(0, sep) ! if self.seekable: ! self.posstack.insert(0, self.start) ! self.start = self.fp.tell() ! ! def pop(self): ! if self.stack == []: ! raise Error, 'bad MultiFile.pop() call' ! if self.level <= 1: ! self.last = 0 ! else: ! abslastpos = self.lastpos + self.start ! self.level = max(0, self.level - 1) ! del self.stack[0] ! if self.seekable: ! self.start = self.posstack[0] ! del self.posstack[0] ! if self.level > 0: ! self.lastpos = abslastpos - self.start ! def is_data(self, line): ! return line[:2] != '--' ! def section_divider(self, str): ! return "--" + str ! def end_marker(self, str): ! return "--" + str + "--" Index: mutex.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/mutex.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** mutex.py 2000/02/04 15:10:33 1.6 --- mutex.py 2001/01/14 23:47:14 1.7 *************** *** 14,51 **** class mutex: ! def __init__(self): ! """Create a new mutex -- initially unlocked.""" ! self.locked = 0 ! self.queue = [] ! def test(self): ! """Test the locked bit of the mutex.""" ! return self.locked ! def testandset(self): ! """Atomic test-and-set -- grab the lock if it is not set, ! return true if it succeeded.""" ! if not self.locked: ! self.locked = 1 ! return 1 ! else: ! return 0 ! def lock(self, function, argument): ! """Lock a mutex, call the function with supplied argument ! when it is acquired. If the mutex is already locked, place ! function and argument in the queue.""" ! if self.testandset(): ! function(argument) ! else: ! self.queue.append((function, argument)) ! def unlock(self): ! """Unlock a mutex. If the queue is not empty, call the next ! function with its argument.""" ! if self.queue: ! function, argument = self.queue[0] ! del self.queue[0] ! function(argument) ! else: ! self.locked = 0 --- 14,51 ---- class mutex: ! def __init__(self): ! """Create a new mutex -- initially unlocked.""" ! self.locked = 0 ! self.queue = [] ! def test(self): ! """Test the locked bit of the mutex.""" ! return self.locked ! def testandset(self): ! """Atomic test-and-set -- grab the lock if it is not set, ! return true if it succeeded.""" ! if not self.locked: ! self.locked = 1 ! return 1 ! else: ! return 0 ! def lock(self, function, argument): ! """Lock a mutex, call the function with supplied argument ! when it is acquired. If the mutex is already locked, place ! function and argument in the queue.""" ! if self.testandset(): ! function(argument) ! else: ! self.queue.append((function, argument)) ! def unlock(self): ! """Unlock a mutex. If the queue is not empty, call the next ! function with its argument.""" ! if self.queue: ! function, argument = self.queue[0] ! del self.queue[0] ! function(argument) ! else: ! self.locked = 0 From python-dev@python.org Sun Jan 14 23:55:57 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 15:55:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/Modules _sre.c,2.48,2.49 Message-ID: Update of /cvsroot/python/python/dist/src/Modules In directory usw-pr-cvs1:/tmp/cvs-serv30958/Modules Modified Files: _sre.c Log Message: -- don't use recursion for unbounded non-greedy repeat (bugs #115903, #115696) This is based on a patch by Darrel Gallion. I'm not 100% sure about this fix, but I haven't managed to come up with any test case it cannot handle... Index: _sre.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Modules/_sre.c,v retrieving revision 2.48 retrieving revision 2.49 diff -C2 -r2.48 -r2.49 *** _sre.c 2001/01/14 15:06:10 2.48 --- _sre.c 2001/01/14 23:55:55 2.49 *************** *** 25,28 **** --- 25,29 ---- * 2000-12-21 fl fixed memory leak in groupdict * 2001-01-02 fl properly reset pointer after failed assertion in MIN_UNTIL + * 2001-01-15 fl don't use recursion for unbounded MIN_UTIL * * Copyright (c) 1997-2001 by Secret Labs AB. All rights reserved. *************** *** 39,43 **** #ifndef SRE_RECURSIVE ! char copyright[] = " SRE 0.9.9 Copyright (c) 1997-2000 by Secret Labs AB "; #include "Python.h" --- 40,44 ---- #ifndef SRE_RECURSIVE ! char copyright[] = " SRE 0.9.9 Copyright (c) 1997-2001 by Secret Labs AB "; #include "Python.h" *************** *** 1013,1021 **** /* see if the tail matches */ state->repeat = rp->prev; ! i = SRE_MATCH(state, pattern, level + 1); if (i) { /* free(rp); */ return i; } state->ptr = ptr; state->repeat = rp; --- 1014,1032 ---- /* see if the tail matches */ state->repeat = rp->prev; ! if (rp->pattern[2] == 65535) { ! /* unbounded repeat */ ! for (;;) { ! i = SRE_MATCH(state, pattern, level + 1); ! if (i || ptr >= end) ! break; ! state->ptr = ++ptr; ! } ! } else ! i = SRE_MATCH(state, pattern, level + 1); if (i) { /* free(rp); */ return i; } + state->ptr = ptr; state->repeat = rp; From python-dev@python.org Sun Jan 14 23:55:57 2001 From: python-dev@python.org (Fredrik Lundh) Date: Sun, 14 Jan 2001 15:55:57 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib/test test_sre.py,1.16,1.17 Message-ID: Update of /cvsroot/python/python/dist/src/Lib/test In directory usw-pr-cvs1:/tmp/cvs-serv30958/Lib/test Modified Files: test_sre.py Log Message: -- don't use recursion for unbounded non-greedy repeat (bugs #115903, #115696) This is based on a patch by Darrel Gallion. I'm not 100% sure about this fix, but I haven't managed to come up with any test case it cannot handle... Index: test_sre.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/test/test_sre.py,v retrieving revision 1.16 retrieving revision 1.17 diff -C2 -r1.16 -r1.17 *** test_sre.py 2001/01/14 15:15:37 1.16 --- test_sre.py 2001/01/14 23:55:55 1.17 *************** *** 249,253 **** (0, 50001), RuntimeError) test(r"""sre.match(r'(x)*?y', 50000*'x'+'y').span()""", ! (0, 50001), RuntimeError) from re_tests import * --- 249,253 ---- (0, 50001), RuntimeError) test(r"""sre.match(r'(x)*?y', 50000*'x'+'y').span()""", ! (0, 50001)) # this works in 2.1 from re_tests import * From python-dev@python.org Mon Jan 15 00:50:55 2001 From: python-dev@python.org (Tim Peters) Date: Sun, 14 Jan 2001 16:50:55 -0800 Subject: [Python-checkins] CVS: python/dist/src/Lib netrc.py,1.8,1.9 nntplib.py,1.21,1.22 ntpath.py,1.32,1.33 nturl2path.py,1.6,1.7 os.py,1.39,1.40 pdb.py,1.46,1.47 pickle.py,1.41,1.42 pipes.py,1.6,1.7 poplib.py,1.10,1.11 posixfile.py,1.16,1.17 posixpath.py,1.38,1.39 pre.py,1.3,1.4 profile.py,1.24,1.25 pstats.py,1.8,1.9 pty.py,1.5,1.6 pyclbr.py,1.15,1.16 quopri.py,1.8,1.9 Message-ID: Update of /cvsroot/python/python/dist/src/Lib In directory usw-pr-cvs1:/tmp/cvs-serv3619/python/dist/src/lib Modified Files: netrc.py nntplib.py ntpath.py nturl2path.py os.py pdb.py pickle.py pipes.py poplib.py posixfile.py posixpath.py pre.py profile.py pstats.py pty.py pyclbr.py quopri.py Log Message: Whitespace normalization. Index: netrc.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/netrc.py,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -r1.8 -r1.9 *** netrc.py 2000/12/23 14:20:24 1.8 --- netrc.py 2001/01/15 00:50:52 1.9 *************** *** 1,5 **** """An object-oriented interface to .netrc files.""" ! # Module and documentation by Eric S. Raymond, 21 Dec 1998 import os, shlex --- 1,5 ---- """An object-oriented interface to .netrc files.""" ! # Module and documentation by Eric S. Raymond, 21 Dec 1998 import os, shlex *************** *** 13,17 **** self.macros = {} lexer = shlex.shlex(fp) ! # Allows @ in hostnames. Not a big deal... lexer.wordchars = lexer.wordchars + '.-@' while 1: --- 13,17 ---- self.macros = {} lexer = shlex.shlex(fp) ! # Allows @ in hostnames. Not a big deal... lexer.wordchars = lexer.wordchars + '.-@' while 1: *************** *** 24,28 **** elif tt == 'default': entryname = 'default' ! elif tt == 'macdef': # Just skip to end of macdefs entryname = lexer.get_token() self.macros[entryname] = [] --- 24,28 ---- elif tt == 'default': entryname = 'default' ! elif tt == 'macdef': # Just skip to end of macdefs entryname = lexer.get_token() self.macros[entryname] = [] *************** *** 37,41 **** else: raise SyntaxError, "bad toplevel token %s, file %s, line %d" \ ! % (tt, file, lexer.lineno) # We're looking at start of an entry for a named machine or default. --- 37,41 ---- else: raise SyntaxError, "bad toplevel token %s, file %s, line %d" \ ! % (tt, file, lexer.lineno) # We're looking at start of an entry for a named machine or default. *************** *** 88,92 **** return rep ! if __name__ == '__main__': print netrc() - --- 88,91 ---- return rep ! if __name__ == '__main__': print netrc() Index: nntplib.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/nntplib.py,v retrieving revision 1.21 retrieving revision 1.22 diff -C2 -r1.21 -r1.22 *** nntplib.py 2000/12/12 23:20:45 1.21 --- nntplib.py 2001/01/15 00:50:52 1.22 *************** *** 35,68 **** ! # Exceptions raised when an error or invalid response is received class NNTPError(Exception): ! """Base class for all nntplib exceptions""" ! def __init__(self, *args): ! apply(Exception.__init__, (self,)+args) ! try: ! self.response = args[0] ! except IndexError: ! self.response = 'No response given' class NNTPReplyError(NNTPError): ! """Unexpected [123]xx reply""" ! pass class NNTPTemporaryError(NNTPError): ! """4xx errors""" ! pass class NNTPPermanentError(NNTPError): ! """5xx errors""" ! pass class NNTPProtocolError(NNTPError): ! """Response does not begin with [1-5]""" ! pass class NNTPDataError(NNTPError): ! """Error in response data""" ! pass # for backwards compatibility --- 35,68 ---- ! # Exceptions raised when an error or invalid response is received class NNTPError(Exception): ! """Base class for all nntplib exceptions""" ! def __init__(self, *args): ! apply(Exception.__init__, (self,)+args) ! try: ! self.response = args[0] ! except IndexError: ! self.response = 'No response given' class NNTPReplyError(NNTPError): ! """Unexpected [123]xx reply""" ! pass class NNTPTemporaryError(NNTPError): ! """4xx errors""" ! pass class NNTPPermanentError(NNTPError): ! """5xx errors""" ! pass class NNTPProtocolError(NNTPError): ! """Response does not begin with [1-5]""" ! pass class NNTPDataError(NNTPError): ! """Error in response data""" ! pass # for backwards compatibility *************** *** 73,78 **** error_data = NNTPDataError - # Standard port used by NNTP servers NNTP_PORT = 119 --- 73,78 ---- error_data = NNTPDataError + # Standard port used by NNTP servers NNTP_PORT = 119 *************** *** 86,535 **** CRLF = '\r\n' - # The class itself class NNTP: ! def __init__(self, host, port=NNTP_PORT, user=None, password=None, ! readermode=None): ! """Initialize an instance. Arguments: ! - host: hostname to connect to ! - port: port to connect to (default the standard NNTP port) ! - user: username to authenticate with ! - password: password to use with username ! - readermode: if true, send 'mode reader' command after ! connecting. ! ! readermode is sometimes necessary if you are connecting to an ! NNTP server on the local machine and intend to call ! reader-specific comamnds, such as `group'. If you get ! unexpected NNTPPermanentErrors, you might need to set ! readermode. ! """ ! self.host = host ! self.port = port ! self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ! self.sock.connect((self.host, self.port)) ! self.file = self.sock.makefile('rb') ! self.debugging = 0 ! self.welcome = self.getresp() ! if readermode: ! try: ! self.welcome = self.shortcmd('mode reader') ! except NNTPPermanentError: ! # error 500, probably 'not implemented' ! pass ! if user: ! resp = self.shortcmd('authinfo user '+user) ! if resp[:3] == '381': ! if not password: ! raise NNTPReplyError(resp) ! else: ! resp = self.shortcmd( ! 'authinfo pass '+password) ! if resp[:3] != '281': ! raise NNTPPermanentError(resp) ! ! # Get the welcome message from the server ! # (this is read and squirreled away by __init__()). ! # If the response code is 200, posting is allowed; ! # if it 201, posting is not allowed ! ! def getwelcome(self): ! """Get the welcome message from the server ! (this is read and squirreled away by __init__()). ! If the response code is 200, posting is allowed; ! if it 201, posting is not allowed.""" ! ! if self.debugging: print '*welcome*', `self.welcome` ! return self.welcome ! ! def set_debuglevel(self, level): ! """Set the debugging level. Argument 'level' means: ! 0: no debugging output (default) ! 1: print commands and responses but not body text etc. ! 2: also print raw lines read and sent before stripping CR/LF""" ! ! self.debugging = level ! debug = set_debuglevel ! ! def putline(self, line): ! """Internal: send one line to the server, appending CRLF.""" ! line = line + CRLF ! if self.debugging > 1: print '*put*', `line` ! self.sock.send(line) ! ! def putcmd(self, line): ! """Internal: send one command to the server (through putline()).""" ! if self.debugging: print '*cmd*', `line` ! self.putline(line) ! ! def getline(self): ! """Internal: return one line from the server, stripping CRLF. ! Raise EOFError if the connection is closed.""" ! line = self.file.readline() ! if self.debugging > 1: ! print '*get*', `line` ! if not line: raise EOFError ! if line[-2:] == CRLF: line = line[:-2] ! elif line[-1:] in CRLF: line = line[:-1] ! return line ! ! def getresp(self): ! """Internal: get a response from the server. ! Raise various errors if the response indicates an error.""" ! resp = self.getline() ! if self.debugging: print '*resp*', `resp` ! c = resp[:1] ! if c == '4': ! raise NNTPTemporaryError(resp) ! if c == '5': ! raise NNTPPermanentError(resp) ! if c not in '123': ! raise NNTPProtocolError(resp) ! return resp ! ! def getlongresp(self): ! """Internal: get a response plus following text from the server. ! Raise various errors if the response indicates an error.""" ! resp = self.getresp() ! if resp[:3] not in LONGRESP: ! raise NNTPReplyError(resp) ! list = [] ! while 1: ! line = self.getline() ! if line == '.': ! break ! if line[:2] == '..': ! line = line[1:] ! list.append(line) ! return resp, list ! ! def shortcmd(self, line): ! """Internal: send a command and get the response.""" ! self.putcmd(line) ! return self.getresp() ! ! def longcmd(self, line): ! """Internal: send a command and get the response plus following text.""" ! self.putcmd(line) ! return self.getlongresp() ! ! def newgroups(self, date, time): ! """Process a NEWGROUPS command. Arguments: ! - date: string 'yymmdd' indicating the date ! - time: string 'hhmmss' indicating the time ! Return: ! - resp: server response if successful ! - list: list of newsgroup names""" ! ! return self.longcmd('NEWGROUPS ' + date + ' ' + time) ! ! def newnews(self, group, date, time): ! """Process a NEWNEWS command. Arguments: ! - group: group name or '*' ! - date: string 'yymmdd' indicating the date ! - time: string 'hhmmss' indicating the time ! Return: ! - resp: server response if successful ! - list: list of article ids""" ! ! cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time ! return self.longcmd(cmd) ! ! def list(self): ! """Process a LIST command. Return: ! - resp: server response if successful ! - list: list of (group, last, first, flag) (strings)""" ! ! resp, list = self.longcmd('LIST') ! for i in range(len(list)): ! # Parse lines into "group last first flag" ! list[i] = tuple(string.split(list[i])) ! return resp, list ! ! def group(self, name): ! """Process a GROUP command. Argument: ! - group: the group name ! Returns: ! - resp: server response if successful ! - count: number of articles (string) ! - first: first article number (string) ! - last: last article number (string) ! - name: the group name""" ! ! resp = self.shortcmd('GROUP ' + name) ! if resp[:3] != '211': ! raise NNTPReplyError(resp) ! words = string.split(resp) ! count = first = last = 0 ! n = len(words) ! if n > 1: ! count = words[1] ! if n > 2: ! first = words[2] ! if n > 3: ! last = words[3] ! if n > 4: ! name = string.lower(words[4]) ! return resp, count, first, last, name ! ! def help(self): ! """Process a HELP command. Returns: ! - resp: server response if successful ! - list: list of strings""" ! ! return self.longcmd('HELP') ! ! def statparse(self, resp): ! """Internal: parse the response of a STAT, NEXT or LAST command.""" ! if resp[:2] != '22': ! raise NNTPReplyError(resp) ! words = string.split(resp) ! nr = 0 ! id = '' ! n = len(words) ! if n > 1: ! nr = words[1] ! if n > 2: ! id = words[2] ! return resp, nr, id ! ! def statcmd(self, line): ! """Internal: process a STAT, NEXT or LAST command.""" ! resp = self.shortcmd(line) ! return self.statparse(resp) ! ! def stat(self, id): ! """Process a STAT command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: the article number ! - id: the article id""" ! ! return self.statcmd('STAT ' + id) ! ! def next(self): ! """Process a NEXT command. No arguments. Return as for STAT.""" ! return self.statcmd('NEXT') ! ! def last(self): ! """Process a LAST command. No arguments. Return as for STAT.""" ! return self.statcmd('LAST') ! ! def artcmd(self, line): ! """Internal: process a HEAD, BODY or ARTICLE command.""" ! resp, list = self.longcmd(line) ! resp, nr, id = self.statparse(resp) ! return resp, nr, id, list ! ! def head(self, id): ! """Process a HEAD command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article's header""" ! ! return self.artcmd('HEAD ' + id) ! ! def body(self, id): ! """Process a BODY command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article's body""" ! ! return self.artcmd('BODY ' + id) ! ! def article(self, id): ! """Process an ARTICLE command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article""" ! ! return self.artcmd('ARTICLE ' + id) ! ! def slave(self): ! """Process a SLAVE command. Returns: ! - resp: server response if successful""" ! ! return self.shortcmd('SLAVE') ! ! def xhdr(self, hdr, str): ! """Process an XHDR command (optional server extension). Arguments: ! - hdr: the header type (e.g. 'subject') ! - str: an article nr, a message id, or a range nr1-nr2 ! Returns: ! - resp: server response if successful ! - list: list of (nr, value) strings""" ! ! pat = re.compile('^([0-9]+) ?(.*)\n?') ! resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str) ! for i in range(len(lines)): ! line = lines[i] ! m = pat.match(line) ! if m: ! lines[i] = m.group(1, 2) ! return resp, lines ! ! def xover(self,start,end): ! """Process an XOVER command (optional server extension) Arguments: ! - start: start of range ! - end: end of range ! Returns: ! - resp: server response if successful ! - list: list of (art-nr, subject, poster, date, ! id, references, size, lines)""" ! ! resp, lines = self.longcmd('XOVER ' + start + '-' + end) ! xover_lines = [] ! for line in lines: ! elem = string.splitfields(line,"\t") ! try: ! xover_lines.append((elem[0], ! elem[1], ! elem[2], ! elem[3], ! elem[4], ! string.split(elem[5]), ! elem[6], ! elem[7])) ! except IndexError: ! raise NNTPDataError(line) ! return resp,xover_lines ! ! def xgtitle(self, group): ! """Process an XGTITLE command (optional server extension) Arguments: ! - group: group name wildcard (i.e. news.*) ! Returns: ! - resp: server response if successful ! - list: list of (name,title) strings""" ! ! line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$") ! resp, raw_lines = self.longcmd('XGTITLE ' + group) ! lines = [] ! for raw_line in raw_lines: ! match = line_pat.search(string.strip(raw_line)) ! if match: ! lines.append(match.group(1, 2)) ! return resp, lines ! ! def xpath(self,id): ! """Process an XPATH command (optional server extension) Arguments: ! - id: Message id of article ! Returns: ! resp: server response if successful ! path: directory path to article""" ! ! resp = self.shortcmd("XPATH " + id) ! if resp[:3] != '223': ! raise NNTPReplyError(resp) ! try: ! [resp_num, path] = string.split(resp) ! except ValueError: ! raise NNTPReplyError(resp) ! else: ! return resp, path ! ! def date (self): ! """Process the DATE command. Arguments: ! None ! Returns: ! resp: server response if successful ! date: Date suitable for newnews/newgroups commands etc. ! time: Time suitable for newnews/newgroups commands etc.""" ! ! resp = self.shortcmd("DATE") ! if resp[:3] != '111': ! raise NNTPReplyError(resp) ! elem = string.split(resp) ! if len(elem) != 2: ! raise NNTPDataError(resp) ! date = elem[1][2:8] ! time = elem[1][-6:] ! if len(date) != 6 or len(time) != 6: ! raise NNTPDataError(resp) ! return resp, date, time ! ! ! def post(self, f): ! """Process a POST command. Arguments: ! - f: file containing the article ! Returns: ! - resp: server response if successful""" ! ! resp = self.shortcmd('POST') ! # Raises error_??? if posting is not allowed ! if resp[0] != '3': ! raise NNTPReplyError(resp) ! while 1: ! line = f.readline() ! if not line: ! break ! if line[-1] == '\n': ! line = line[:-1] ! if line[:1] == '.': ! line = '.' + line ! self.putline(line) ! self.putline('.') ! return self.getresp() ! ! def ihave(self, id, f): ! """Process an IHAVE command. Arguments: ! - id: message-id of the article ! - f: file containing the article ! Returns: ! - resp: server response if successful ! Note that if the server refuses the article an exception is raised.""" ! ! resp = self.shortcmd('IHAVE ' + id) ! # Raises error_??? if the server already has it ! if resp[0] != '3': ! raise NNTPReplyError(resp) ! while 1: ! line = f.readline() ! if not line: ! break ! if line[-1] == '\n': ! line = line[:-1] ! if line[:1] == '.': ! line = '.' + line ! self.putline(line) ! self.putline('.') ! return self.getresp() ! ! def quit(self): ! """Process a QUIT command and close the socket. Returns: ! - resp: server response if successful""" ! ! resp = self.shortcmd('QUIT') ! self.file.close() ! self.sock.close() ! del self.file, self.sock ! return resp def _test(): ! """Minimal test function.""" ! s = NNTP('news', readermode='reader') ! resp, count, first, last, name = s.group('comp.lang.python') ! print resp ! print 'Group', name, 'has', count, 'articles, range', first, 'to', last ! resp, subs = s.xhdr('subject', first + '-' + last) ! print resp ! for item in subs: ! print "%7s %s" % item ! resp = s.quit() ! print resp # Run the test when run as a script if __name__ == '__main__': ! _test() --- 86,535 ---- CRLF = '\r\n' + # The class itself class NNTP: ! def __init__(self, host, port=NNTP_PORT, user=None, password=None, ! readermode=None): ! """Initialize an instance. Arguments: ! - host: hostname to connect to ! - port: port to connect to (default the standard NNTP port) ! - user: username to authenticate with ! - password: password to use with username ! - readermode: if true, send 'mode reader' command after ! connecting. ! ! readermode is sometimes necessary if you are connecting to an ! NNTP server on the local machine and intend to call ! reader-specific comamnds, such as `group'. If you get ! unexpected NNTPPermanentErrors, you might need to set ! readermode. ! """ ! self.host = host ! self.port = port ! self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) ! self.sock.connect((self.host, self.port)) ! self.file = self.sock.makefile('rb') ! self.debugging = 0 ! self.welcome = self.getresp() ! if readermode: ! try: ! self.welcome = self.shortcmd('mode reader') ! except NNTPPermanentError: ! # error 500, probably 'not implemented' ! pass ! if user: ! resp = self.shortcmd('authinfo user '+user) ! if resp[:3] == '381': ! if not password: ! raise NNTPReplyError(resp) ! else: ! resp = self.shortcmd( ! 'authinfo pass '+password) ! if resp[:3] != '281': ! raise NNTPPermanentError(resp) ! ! # Get the welcome message from the server ! # (this is read and squirreled away by __init__()). ! # If the response code is 200, posting is allowed; ! # if it 201, posting is not allowed ! ! def getwelcome(self): ! """Get the welcome message from the server ! (this is read and squirreled away by __init__()). ! If the response code is 200, posting is allowed; ! if it 201, posting is not allowed.""" ! ! if self.debugging: print '*welcome*', `self.welcome` ! return self.welcome ! ! def set_debuglevel(self, level): ! """Set the debugging level. Argument 'level' means: ! 0: no debugging output (default) ! 1: print commands and responses but not body text etc. ! 2: also print raw lines read and sent before stripping CR/LF""" ! ! self.debugging = level ! debug = set_debuglevel ! ! def putline(self, line): ! """Internal: send one line to the server, appending CRLF.""" ! line = line + CRLF ! if self.debugging > 1: print '*put*', `line` ! self.sock.send(line) ! ! def putcmd(self, line): ! """Internal: send one command to the server (through putline()).""" ! if self.debugging: print '*cmd*', `line` ! self.putline(line) ! ! def getline(self): ! """Internal: return one line from the server, stripping CRLF. ! Raise EOFError if the connection is closed.""" ! line = self.file.readline() ! if self.debugging > 1: ! print '*get*', `line` ! if not line: raise EOFError ! if line[-2:] == CRLF: line = line[:-2] ! elif line[-1:] in CRLF: line = line[:-1] ! return line ! ! def getresp(self): ! """Internal: get a response from the server. ! Raise various errors if the response indicates an error.""" ! resp = self.getline() ! if self.debugging: print '*resp*', `resp` ! c = resp[:1] ! if c == '4': ! raise NNTPTemporaryError(resp) ! if c == '5': ! raise NNTPPermanentError(resp) ! if c not in '123': ! raise NNTPProtocolError(resp) ! return resp ! ! def getlongresp(self): ! """Internal: get a response plus following text from the server. ! Raise various errors if the response indicates an error.""" ! resp = self.getresp() ! if resp[:3] not in LONGRESP: ! raise NNTPReplyError(resp) ! list = [] ! while 1: ! line = self.getline() ! if line == '.': ! break ! if line[:2] == '..': ! line = line[1:] ! list.append(line) ! return resp, list ! ! def shortcmd(self, line): ! """Internal: send a command and get the response.""" ! self.putcmd(line) ! return self.getresp() ! ! def longcmd(self, line): ! """Internal: send a command and get the response plus following text.""" ! self.putcmd(line) ! return self.getlongresp() ! ! def newgroups(self, date, time): ! """Process a NEWGROUPS command. Arguments: ! - date: string 'yymmdd' indicating the date ! - time: string 'hhmmss' indicating the time ! Return: ! - resp: server response if successful ! - list: list of newsgroup names""" ! ! return self.longcmd('NEWGROUPS ' + date + ' ' + time) ! ! def newnews(self, group, date, time): ! """Process a NEWNEWS command. Arguments: ! - group: group name or '*' ! - date: string 'yymmdd' indicating the date ! - time: string 'hhmmss' indicating the time ! Return: ! - resp: server response if successful ! - list: list of article ids""" ! ! cmd = 'NEWNEWS ' + group + ' ' + date + ' ' + time ! return self.longcmd(cmd) ! ! def list(self): ! """Process a LIST command. Return: ! - resp: server response if successful ! - list: list of (group, last, first, flag) (strings)""" ! ! resp, list = self.longcmd('LIST') ! for i in range(len(list)): ! # Parse lines into "group last first flag" ! list[i] = tuple(string.split(list[i])) ! return resp, list ! ! def group(self, name): ! """Process a GROUP command. Argument: ! - group: the group name ! Returns: ! - resp: server response if successful ! - count: number of articles (string) ! - first: first article number (string) ! - last: last article number (string) ! - name: the group name""" ! ! resp = self.shortcmd('GROUP ' + name) ! if resp[:3] != '211': ! raise NNTPReplyError(resp) ! words = string.split(resp) ! count = first = last = 0 ! n = len(words) ! if n > 1: ! count = words[1] ! if n > 2: ! first = words[2] ! if n > 3: ! last = words[3] ! if n > 4: ! name = string.lower(words[4]) ! return resp, count, first, last, name ! ! def help(self): ! """Process a HELP command. Returns: ! - resp: server response if successful ! - list: list of strings""" ! ! return self.longcmd('HELP') ! ! def statparse(self, resp): ! """Internal: parse the response of a STAT, NEXT or LAST command.""" ! if resp[:2] != '22': ! raise NNTPReplyError(resp) ! words = string.split(resp) ! nr = 0 ! id = '' ! n = len(words) ! if n > 1: ! nr = words[1] ! if n > 2: ! id = words[2] ! return resp, nr, id ! ! def statcmd(self, line): ! """Internal: process a STAT, NEXT or LAST command.""" ! resp = self.shortcmd(line) ! return self.statparse(resp) ! ! def stat(self, id): ! """Process a STAT command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: the article number ! - id: the article id""" ! ! return self.statcmd('STAT ' + id) ! ! def next(self): ! """Process a NEXT command. No arguments. Return as for STAT.""" ! return self.statcmd('NEXT') ! ! def last(self): ! """Process a LAST command. No arguments. Return as for STAT.""" ! return self.statcmd('LAST') ! ! def artcmd(self, line): ! """Internal: process a HEAD, BODY or ARTICLE command.""" ! resp, list = self.longcmd(line) ! resp, nr, id = self.statparse(resp) ! return resp, nr, id, list ! ! def head(self, id): ! """Process a HEAD command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article's header""" ! ! return self.artcmd('HEAD ' + id) ! ! def body(self, id): ! """Process a BODY command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article's body""" ! ! return self.artcmd('BODY ' + id) ! ! def article(self, id): ! """Process an ARTICLE command. Argument: ! - id: article number or message id ! Returns: ! - resp: server response if successful ! - nr: article number ! - id: message id ! - list: the lines of the article""" ! ! return self.artcmd('ARTICLE ' + id) ! ! def slave(self): ! """Process a SLAVE command. Returns: ! - resp: server response if successful""" ! ! return self.shortcmd('SLAVE') ! ! def xhdr(self, hdr, str): ! """Process an XHDR command (optional server extension). Arguments: ! - hdr: the header type (e.g. 'subject') ! - str: an article nr, a message id, or a range nr1-nr2 ! Returns: ! - resp: server response if successful ! - list: list of (nr, value) strings""" ! ! pat = re.compile('^([0-9]+) ?(.*)\n?') ! resp, lines = self.longcmd('XHDR ' + hdr + ' ' + str) ! for i in range(len(lines)): ! line = lines[i] ! m = pat.match(line) ! if m: ! lines[i] = m.group(1, 2) ! return resp, lines ! ! def xover(self,start,end): ! """Process an XOVER command (optional server extension) Arguments: ! - start: start of range ! - end: end of range ! Returns: ! - resp: server response if successful ! - list: list of (art-nr, subject, poster, date, ! id, references, size, lines)""" ! ! resp, lines = self.longcmd('XOVER ' + start + '-' + end) ! xover_lines = [] ! for line in lines: ! elem = string.splitfields(line,"\t") ! try: ! xover_lines.append((elem[0], ! elem[1], ! elem[2], ! elem[3], ! elem[4], ! string.split(elem[5]), ! elem[6], ! elem[7])) ! except IndexError: ! raise NNTPDataError(line) ! return resp,xover_lines ! ! def xgtitle(self, group): ! """Process an XGTITLE command (optional server extension) Arguments: ! - group: group name wildcard (i.e. news.*) ! Returns: ! - resp: server response if successful ! - list: list of (name,title) strings""" ! ! line_pat = re.compile("^([^ \t]+)[ \t]+(.*)$") ! resp, raw_lines = self.longcmd('XGTITLE ' + group) ! lines = [] ! for raw_line in raw_lines: ! match = line_pat.search(string.strip(raw_line)) ! if match: ! lines.append(match.group(1, 2)) ! return resp, lines ! ! def xpath(self,id): ! """Process an XPATH command (optional server extension) Arguments: ! - id: Message id of article ! Returns: ! resp: server response if successful ! path: directory path to article""" ! ! resp = self.shortcmd("XPATH " + id) ! if resp[:3] != '223': ! raise NNTPReplyError(resp) ! try: ! [resp_num, path] = string.split(resp) ! except ValueError: ! raise NNTPReplyError(resp) ! else: ! return resp, path ! ! def date (self): ! """Process the DATE command. Arguments: ! None ! Returns: ! resp: server response if successful ! date: Date suitable for newnews/newgroups commands etc. ! time: Time suitable for newnews/newgroups commands etc.""" ! ! resp = self.shortcmd("DATE") ! if resp[:3] != '111': ! raise NNTPReplyError(resp) ! elem = string.split(resp) ! if len(elem) != 2: ! raise NNTPDataError(resp) ! date = elem[1][2:8] ! time = elem[1][-6:] ! if len(date) != 6 or len(time) != 6: ! raise NNTPDataError(resp) ! return resp, date, time ! ! ! def post(self, f): ! """Process a POST command. Arguments: ! - f: file containing the article ! Returns: ! - resp: server response if successful""" ! ! resp = self.shortcmd('POST') ! # Raises error_??? if posting is not allowed ! if resp[0] != '3': ! raise NNTPReplyError(resp) ! while 1: ! line = f.readline() ! if not line: ! break ! if line[-1] == '\n': ! line = line[:-1] ! if line[:1] == '.': ! line = '.' + line ! self.putline(line) ! self.putline('.') ! return self.getresp() ! ! def ihave(self, id, f): ! """Process an IHAVE command. Arguments: ! - id: message-id of the article ! - f: file containing the article ! Returns: ! - resp: server response if successful ! Note that if the server refuses the article an exception is raised.""" ! ! resp = self.shortcmd('IHAVE ' + id) ! # Raises error_??? if the server already has it ! if resp[0] != '3': ! raise NNTPReplyError(resp) ! while 1: ! line = f.readline() ! if not line: ! break ! if line[-1] == '\n': ! line = line[:-1] ! if line[:1] == '.': ! line = '.' + line ! self.putline(line) ! self.putline('.') ! return self.getresp() ! ! def quit(self): ! """Process a QUIT command and close the socket. Returns: ! - resp: server response if successful""" ! ! resp = self.shortcmd('QUIT') ! self.file.close() ! self.sock.close() ! del self.file, self.sock ! return resp def _test(): ! """Minimal test function.""" ! s = NNTP('news', readermode='reader') ! resp, count, first, last, name = s.group('comp.lang.python') ! print resp ! print 'Group', name, 'has', count, 'articles, range', first, 'to', last ! resp, subs = s.xhdr('subject', first + '-' + last) ! print resp ! for item in subs: ! print "%7s %s" % item ! resp = s.quit() ! print resp # Run the test when run as a script if __name__ == '__main__': ! _test() Index: ntpath.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/ntpath.py,v retrieving revision 1.32 retrieving revision 1.33 diff -C2 -r1.32 -r1.33 *** ntpath.py 2000/12/12 23:20:45 1.32 --- ntpath.py 2001/01/15 00:50:52 1.33 *************** *** 1,4 **** # Module 'ntpath' -- common operations on WinNT/Win95 pathnames ! """Common pathname manipulations, WindowsNT/95 version. Instead of importing this module directly, import os and refer to this --- 1,4 ---- # Module 'ntpath' -- common operations on WinNT/Win95 pathnames ! """Common pathname manipulations, WindowsNT/95 version. Instead of importing this module directly, import os and refer to this *************** *** 255,259 **** """Directory tree walk whth callback function. ! walk(top, func, arg) calls func(arg, d, files) for each directory d in the tree rooted at top (including top itself); files is a list of all the files and subdirs in directory d.""" --- 255,259 ---- """Directory tree walk whth callback function. ! walk(top, func, arg) calls func(arg, d, files) for each directory d in the tree rooted at top (including top itself); files is a list of all the files and subdirs in directory d.""" *************** *** 314,318 **** # XXX except '^|<>='. ! def expandvars(path): """Expand shell variables of form $var and ${var}. --- 314,318 ---- # XXX except '^|<>='. ! def expandvars(path): """Expand shell variables of form $var and ${var}. Index: nturl2path.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/nturl2path.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** nturl2path.py 2000/05/30 13:25:34 1.6 --- nturl2path.py 2001/01/15 00:50:52 1.7 *************** *** 2,66 **** def url2pathname(url): ! r"""Convert a URL to a DOS path. ! ///C|/foo/bar/spam.foo ! becomes ! C:\foo\bar\spam.foo ! """ ! import string, urllib ! if not '|' in url: ! # No drive specifier, just convert slashes ! if url[:4] == '////': ! # path is something like ////host/path/on/remote/host ! # convert this to \\host\path\on\remote\host ! # (notice halving of slashes at the start of the path) ! url = url[2:] ! components = string.split(url, '/') ! # make sure not to convert quoted slashes :-) ! return urllib.unquote(string.join(components, '\\')) ! comp = string.split(url, '|') ! if len(comp) != 2 or comp[0][-1] not in string.letters: ! error = 'Bad URL: ' + url ! raise IOError, error ! drive = string.upper(comp[0][-1]) ! components = string.split(comp[1], '/') ! path = drive + ':' ! for comp in components: ! if comp: ! path = path + '\\' + urllib.unquote(comp) ! return path def pathname2url(p): ! r"""Convert a DOS path name to a file url. ! C:\foo\bar\spam.foo ! becomes ! ///C|/foo/bar/spam.foo ! """ ! import string, urllib ! if not ':' in p: ! # No drive specifier, just convert slashes and quote the name ! if p[:2] == '\\\\': ! # path is something like \\host\path\on\remote\host ! # convert this to ////host/path/on/remote/host ! # (notice doubling of slashes at the start of the path) ! p = '\\\\' + p ! components = string.split(p, '\\') ! return urllib.quote(string.join(components, '/')) ! comp = string.split(p, ':') ! if len(comp) != 2 or len(comp[0]) > 1: ! error = 'Bad path: ' + p ! raise IOError, error ! ! drive = urllib.quote(string.upper(comp[0])) ! components = string.split(comp[1], '\\') ! path = '///' + drive + '|' ! for comp in components: ! if comp: ! path = path + '/' + urllib.quote(comp) ! return path --- 2,66 ---- def url2pathname(url): ! r"""Convert a URL to a DOS path. ! ///C|/foo/bar/spam.foo ! becomes ! C:\foo\bar\spam.foo ! """ ! import string, urllib ! if not '|' in url: ! # No drive specifier, just convert slashes ! if url[:4] == '////': ! # path is something like ////host/path/on/remote/host ! # convert this to \\host\path\on\remote\host ! # (notice halving of slashes at the start of the path) ! url = url[2:] ! components = string.split(url, '/') ! # make sure not to convert quoted slashes :-) ! return urllib.unquote(string.join(components, '\\')) ! comp = string.split(url, '|') ! if len(comp) != 2 or comp[0][-1] not in string.letters: ! error = 'Bad URL: ' + url ! raise IOError, error ! drive = string.upper(comp[0][-1]) ! components = string.split(comp[1], '/') ! path = drive + ':' ! for comp in components: ! if comp: ! path = path + '\\' + urllib.unquote(comp) ! return path def pathname2url(p): ! r"""Convert a DOS path name to a file url. ! C:\foo\bar\spam.foo ! becomes ! ///C|/foo/bar/spam.foo ! """ ! import string, urllib ! if not ':' in p: ! # No drive specifier, just convert slashes and quote the name ! if p[:2] == '\\\\': ! # path is something like \\host\path\on\remote\host ! # convert this to ////host/path/on/remote/host ! # (notice doubling of slashes at the start of the path) ! p = '\\\\' + p ! components = string.split(p, '\\') ! return urllib.quote(string.join(components, '/')) ! comp = string.split(p, ':') ! if len(comp) != 2 or len(comp[0]) > 1: ! error = 'Bad path: ' + p ! raise IOError, error ! ! drive = urllib.quote(string.upper(comp[0])) ! components = string.split(comp[1], '\\') ! path = '///' + drive + '|' ! for comp in components: ! if comp: ! path = path + '/' + urllib.quote(comp) ! return path Index: os.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/os.py,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -r1.39 -r1.40 *** os.py 2000/09/28 19:10:56 1.39 --- os.py 2001/01/15 00:50:52 1.40 *************** *** 214,218 **** Execute the executable file (which is searched for along $PATH) with argument list args and environment env, replacing the current ! process. """ env = args[-1] execvpe(file, args[:-1], env) --- 214,218 ---- Execute the executable file (which is searched for along $PATH) with argument list args and environment env, replacing the current ! process. """ env = args[-1] execvpe(file, args[:-1], env) *************** *** 232,236 **** with argument list args and environment env , replacing the current process. ! args may be a list or tuple of strings. """ _execvpe(file, args, env) --- 232,236 ---- with argument list args and environment env , replacing the current process. ! args may be a list or tuple of strings. """ _execvpe(file, args, env) *************** *** 371,375 **** If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; ! otherwise return -SIG, where SIG is the signal that killed it. """ return _spawnvef(mode, file, args, None, execv) --- 371,375 ---- If mode == P_NOWAIT return the pid of the process. If mode == P_WAIT return the process's exit code if it exits normally; ! otherwise return -SIG, where SIG is the signal that killed it. """ return _spawnvef(mode, file, args, None, execv) Index: pdb.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pdb.py,v retrieving revision 1.46 retrieving revision 1.47 diff -C2 -r1.46 -r1.47 *** pdb.py 2001/01/14 23:29:48 1.46 --- pdb.py 2001/01/15 00:50:52 1.47 *************** *** 15,36 **** def find_function(funcname, filename): ! cre = re.compile(r'def\s+%s\s*[(]' % funcname) ! try: ! fp = open(filename) ! except IOError: ! return None ! # consumer of this info expects the first line to be 1 ! lineno = 1 ! answer = None [...1826 lines suppressed...] ! run('execfile(' + `filename` + ')') --- 928,944 ---- # When invoked as main program, invoke the debugger on a script if __name__=='__main__': ! if not sys.argv[1:]: ! print "usage: pdb.py scriptfile [arg] ..." ! sys.exit(2) ! ! mainpyfile = filename = sys.argv[1] # Get script filename ! if not os.path.exists(filename): ! print 'Error:', `filename`, 'does not exist' ! sys.exit(1) ! mainmodule = os.path.basename(filename) ! del sys.argv[0] # Hide "pdb.py" from argument list ! # Insert script directory in front of module search path ! sys.path.insert(0, os.path.dirname(filename)) ! run('execfile(' + `filename` + ')') Index: pickle.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pickle.py,v retrieving revision 1.41 retrieving revision 1.42 diff -C2 -r1.41 -r1.42 *** pickle.py 2000/12/19 01:29:00 1.41 --- pickle.py 2001/01/15 00:50:52 1.42 *************** *** 124,128 **** return GET + `i` + '\n' ! def save(self, object, pers_save = 0): memo = self.memo --- 124,128 ---- return GET + `i` + '\n' ! def save(self, object, pers_save = 0): memo = self.memo *************** *** 135,139 **** d = id(object) ! t = type(object) --- 135,139 ---- d = id(object) ! t = type(object) *************** *** 180,184 **** l = len(tup) ! if ((l != 2) and (l != 3)): raise PicklingError, "tuple returned by %s must contain " \ --- 180,184 ---- l = len(tup) ! if ((l != 2) and (l != 3)): raise PicklingError, "tuple returned by %s must contain " \ *************** *** 187,191 **** callable = tup[0] arg_tup = tup[1] ! if (l > 2): state = tup[2] --- 187,191 ---- callable = tup[0] arg_tup = tup[1] ! if (l > 2): state = tup[2] *************** *** 197,201 **** "by %s must be a tuple" % reduce ! self.save_reduce(callable, arg_tup, state) memo_len = len(memo) self.write(self.put(memo_len)) --- 197,201 ---- "by %s must be a tuple" % reduce ! self.save_reduce(callable, arg_tup, state) memo_len = len(memo) self.write(self.put(memo_len)) *************** *** 225,229 **** save(arg_tup) write(REDUCE) ! if (state is not None): save(state) --- 225,229 ---- save(arg_tup) write(REDUCE) ! if (state is not None): save(state) *************** *** 318,322 **** write(POP_MARK + self.get(memo[d][0])) return ! write(POP * (len(object) + 1) + self.get(memo[d][0])) return --- 318,322 ---- write(POP_MARK + self.get(memo[d][0])) return ! write(POP * (len(object) + 1) + self.get(memo[d][0])) return *************** *** 353,357 **** for element in object: save(element) ! if (not using_appends): write(APPEND) --- 353,357 ---- for element in object: save(element) ! if (not using_appends): write(APPEND) *************** *** 543,547 **** def load_binpersid(self): stack = self.stack ! pid = stack[-1] del stack[-1] --- 543,547 ---- def load_binpersid(self): stack = self.stack ! pid = stack[-1] del stack[-1] *************** *** 569,573 **** self.append(mloads('i' + self.read(2) + '\000\000')) dispatch[BININT2] = load_binint2 ! def load_long(self): self.append(long(self.readline()[:-1], 0)) --- 569,573 ---- self.append(mloads('i' + self.read(2) + '\000\000')) dispatch[BININT2] = load_binint2 ! def load_long(self): self.append(long(self.readline()[:-1], 0)) *************** *** 711,715 **** klass = stack[k + 1] del stack[k + 1] ! args = tuple(stack[k + 1:]) del stack[k:] instantiated = 0 --- 711,715 ---- klass = stack[k + 1] del stack[k + 1] ! args = tuple(stack[k + 1:]) del stack[k:] instantiated = 0 *************** *** 727,731 **** value = apply(klass, args) self.append(value) ! dispatch[OBJ] = load_obj def load_global(self): --- 727,731 ---- value = apply(klass, args) self.append(value) ! dispatch[OBJ] = load_obj def load_global(self): *************** *** 762,767 **** if (not safe): ! raise UnpicklingError, "%s is not safe for " \ ! "unpickling" % callable if arg_tup is None: --- 762,767 ---- if (not safe): ! raise UnpicklingError, "%s is not safe for " \ ! "unpickling" % callable if arg_tup is None: *************** *** 830,834 **** del stack[mark:] dispatch[APPENDS] = load_appends ! def load_setitem(self): stack = self.stack --- 830,834 ---- del stack[mark:] dispatch[APPENDS] = load_appends ! def load_setitem(self): stack = self.stack Index: pipes.py =================================================================== RCS file: /cvsroot/python/python/dist/src/Lib/pipes.py,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -r1.6 -r1.7 *** pipes.py 2000/12/12 23:20:45 1.6 --- pipes.py 2001/01/15 00:50:52 1.7 *************** *** 70,284 **** # Conversion step kinds ! FILEIN_FILEOUT = 'ff' # Must read & write real files ! STDIN_FILEOUT = '-f' # Must write a real file ! FILEIN_STDOUT = 'f-' # Must read a real file ! STDIN_STDOUT = '--' # Normal pipeline element ! SOURCE = '.-' # Must be first, writes stdout ! SINK = '-.' # Must be last, reads stdin stepkinds = [FILEIN_FILEOUT, STDIN_FILEOUT, FILEIN_STDOUT, STDIN_STDOUT, \ ! SOURCE, SINK] class Template: ! """Class representing a pipeline template.""" ! def __init__(self): ! """Template() returns a fresh pipeline template.""" ! self.debugging = 0 ! self.reset() ! ! def __repr__(self): ! """t.__repr__() implements `t`.""" ! return '